Branch: Tag:

2004-10-06

2004-10-06 18:35:02 by Martin Stjernholm <mast@lysator.liu.se>

Clear the subtype properly in a number of opcodes that can produce nonzero
integer svalues. Otherwise the zero type can remain in calculations that
start with UNDEFINED.

Rev: src/interpret_functions.h:1.175

2:   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: interpret_functions.h,v 1.174 2004/10/01 13:26:40 grubba Exp $ + || $Id: interpret_functions.h,v 1.175 2004/10/06 18:35:02 mast Exp $   */      /*
320:    } else {    /* Not found. */    tmp.type = T_INT; -  tmp.subtype = 1; +  tmp.subtype = NUMBER_UNDEFINED;    tmp.u.integer = 0;    }    } else {
513:   OPCODE1(F_CLEAR_2_LOCAL, "clear 2 local", 0, {    free_mixed_svalues(Pike_fp->locals + arg1, 2);    Pike_fp->locals[arg1].type = PIKE_T_INT; -  Pike_fp->locals[arg1].subtype = 0; +  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER;    Pike_fp->locals[arg1].u.integer = 0;    Pike_fp->locals[arg1+1].type = PIKE_T_INT; -  Pike_fp->locals[arg1+1].subtype = 0; +  Pike_fp->locals[arg1+1].subtype = NUMBER_NUMBER;    Pike_fp->locals[arg1+1].u.integer = 0;   });   
526:    for(e = 0; e < 4; e++)    {    Pike_fp->locals[arg1+e].type = PIKE_T_INT; -  Pike_fp->locals[arg1+e].subtype = 0; +  Pike_fp->locals[arg1+e].subtype = NUMBER_NUMBER;    Pike_fp->locals[arg1+e].u.integer = 0;    }   });
534:   OPCODE1(F_CLEAR_LOCAL, "clear local", 0, {    free_svalue(Pike_fp->locals + arg1);    Pike_fp->locals[arg1].type = PIKE_T_INT; -  Pike_fp->locals[arg1].subtype = 0; +  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER;    Pike_fp->locals[arg1].u.integer = 0;   });   
546:    )    {    push_int(++(Pike_fp->locals[arg1].u.integer)); +  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    } else {    push_svalue(Pike_fp->locals+arg1);    push_int(1);
564:    )    {    Pike_fp->locals[arg1].u.integer++; +  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    } else {    push_svalue(Pike_fp->locals + arg1);    push_int(1);
580:    )    {    Pike_fp->locals[arg1].u.integer++; +  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    } else {    push_svalue( Pike_fp->locals + arg1);    push_int(1);
596:    )    {    push_int(--(Pike_fp->locals[arg1].u.integer)); +  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    } else {    push_svalue(Pike_fp->locals+arg1);    push_int(1);
614:    )    {    Pike_fp->locals[arg1].u.integer--; +  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    } else {    push_svalue(Pike_fp->locals + arg1);    push_int(1);    o_subtract();    stack_pop_to(Pike_fp->locals + arg1);    } -  /* Pike_fp->locals[instr].u.integer--; */ +    });      OPCODE1(F_DEC_LOCAL_AND_POP, "--local and pop", 0, {
631:    )    {    Pike_fp->locals[arg1].u.integer--; +  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    } else {    push_svalue(Pike_fp->locals + arg1);    push_int(1);
656:    Pike_sp++;    lvalue_to_svalue_no_free(Pike_sp-2, Pike_sp-4);    -  /* this is so that foo+=bar (and similar things) will be faster, this -  * is done by freeing the old reference to foo after it has been pushed -  * on the stack. That way foo can have only 1 reference if we are lucky, -  * and then the low array/multiset/mapping manipulation routines can be -  * destructive if they like +  /* This is so that foo+=bar (and similar things) will be faster. +  * It's done by freeing the old reference to foo after it has been +  * pushed on the stack. That way foo can have only 1 reference if we +  * are lucky, and then the low array/multiset/mapping manipulation +  * routines can be destructive if they like.    */    if( (1 << Pike_sp[-2].type) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    {    LOCAL_VAR(struct svalue tmp);    tmp.type = PIKE_T_INT; -  tmp.subtype = 0; +  tmp.subtype = NUMBER_NUMBER;    tmp.u.integer = 0;    assign_lvalue(Pike_sp-4, &tmp);    }
680:    Pike_sp++;    lvalue_to_svalue_no_free(Pike_sp-3, Pike_sp-5);    -  /* this is so that foo=foo[x..y] (and similar things) will be faster, this -  * is done by freeing the old reference to foo after it has been pushed -  * on the stack. That way foo can have only 1 reference if we are lucky, -  * and then the low array/multiset/mapping manipulation routines can be -  * destructive if they like +  /* This is so that foo=foo[x..y] (and similar things) will be faster. +  * It's done by freeing the old reference to foo after it has been +  * pushed on the stack. That way foo can have only 1 reference if we +  * are lucky, and then the low array/multiset/mapping manipulation +  * routines can be destructive if they like.    */    if( (1 << Pike_sp[-3].type) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    {    LOCAL_VAR(struct svalue tmp);    tmp.type = PIKE_T_INT; -  tmp.subtype = 0; +  tmp.subtype = NUMBER_NUMBER;    tmp.u.integer = 0;    assign_lvalue(Pike_sp-5, &tmp);    }
712:    {    /* Optimization for a rather common case. Makes it 30% faster. */    INT_TYPE val = (Pike_sp[-1].u.integer += Pike_sp[-2].u.integer); +  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    assign_lvalue(Pike_sp-4,Pike_sp-1);    Pike_sp-=2;    pop_2_elems();
719:    goto add_to_done;    }    } -  /* this is so that foo+=bar (and similar things) will be faster, this -  * is done by freeing the old reference to foo after it has been pushed -  * on the stack. That way foo can have only 1 reference if we are lucky, -  * and then the low array/multiset/mapping manipulation routines can be -  * destructive if they like +  /* This is so that foo+=bar (and similar things) will be faster. +  * It's done by freeing the old reference to foo after it has been +  * pushed on the stack. That way foo can have only 1 reference if we +  * are lucky, and then the low array/multiset/mapping manipulation +  * routines can be destructive if they like.    */    if( (1 << Pike_sp[-2].type) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    {    LOCAL_VAR(struct svalue tmp);    tmp.type=PIKE_T_INT; -  tmp.subtype=0; +  tmp.subtype=NUMBER_NUMBER;    tmp.u.integer=0;    assign_lvalue(Pike_sp-4, &tmp);    } else if (Pike_sp[-2].type == T_OBJECT) {
770:    {    /* Optimization for a rather common case. Makes it 30% faster. */    Pike_sp[-1].u.integer += Pike_sp[-2].u.integer; +  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    assign_lvalue(Pike_sp-4,Pike_sp-1);    Pike_sp-=2;    pop_2_elems();    goto add_to_and_pop_done;    }    } -  /* this is so that foo+=bar (and similar things) will be faster, this -  * is done by freeing the old reference to foo after it has been pushed -  * on the stack. That way foo can have only 1 reference if we are lucky, -  * and then the low array/multiset/mapping manipulation routines can be -  * destructive if they like +  /* This is so that foo+=bar (and similar things) will be faster. +  * It's done by freeing the old reference to foo after it has been +  * pushed on the stack. That way foo can have only 1 reference if we +  * are lucky, and then the low array/multiset/mapping manipulation +  * routines can be destructive if they like.    */    if( (1 << Pike_sp[-2].type) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    {    LOCAL_VAR(struct svalue tmp);    tmp.type=PIKE_T_INT; -  tmp.subtype=0; +  tmp.subtype=NUMBER_NUMBER;    tmp.u.integer=0;    assign_lvalue(Pike_sp-4, &tmp);    } else if (Pike_sp[-2].type == PIKE_T_OBJECT) {
1378:    }   });    - OPCODE0_BRANCH(F_FOREACH, "foreach", 0, { /* array, lvalue, X, i */ + OPCODE0_BRANCH(F_FOREACH, "foreach", 0, { /* array, lvalue, i */    if(Pike_sp[-4].type != PIKE_T_ARRAY)    PIKE_ERROR("foreach", "Bad argument 1.\n", Pike_sp-3, 1);    if(Pike_sp[-1].u.integer < Pike_sp[-4].u.array->size)    {    if(Pike_sp[-1].u.integer < 0) -  +  /* Isn't this an internal compiler error? /mast */    Pike_error("Foreach loop variable is negative!\n");    assign_lvalue(Pike_sp-3, Pike_sp[-4].u.array->item + Pike_sp[-1].u.integer);    DO_BRANCH();    Pike_sp[-1].u.integer++; -  +  DO_IF_DEBUG ( +  if (Pike_sp[-1].subtype) +  Pike_fatal ("Got unexpected subtype in loop variable.\n"); +  );    }else{    /* write_to_stderr("foreach\n", 8); */    DONT_BRANCH();
1480:    }    else    ) +  {    Pike_sp[-1].u.integer =- Pike_sp[-1].u.integer; -  +  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    } -  +  }    else if(Pike_sp[-1].type == PIKE_T_FLOAT)    {    Pike_sp[-1].u.float_number =- Pike_sp[-1].u.float_number;
1497:    {    case PIKE_T_INT:    Pike_sp[-1].u.integer =! Pike_sp[-1].u.integer; +  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    break;       case PIKE_T_FUNCTION:
1514:    default:    free_svalue(Pike_sp-1);    Pike_sp[-1].type=PIKE_T_INT; +  Pike_sp[-1].subtype = NUMBER_NUMBER;    Pike_sp[-1].u.integer=0;    }   });
1547:    )    {    Pike_sp[-2].u.integer+=Pike_sp[-1].u.integer; +  Pike_sp[-2].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    dmalloc_touch_svalue(Pike_sp-1);    Pike_sp--;    }else{
1581:    )    {    Pike_sp[-1].u.integer+=arg1; +  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    }else{    push_int(arg1);    f_add(2);
1595:    )    {    Pike_sp[-1].u.integer-=arg1; +  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */    }else{    push_int(-arg1);    f_add(2);