pike.git / src / interpret_functions.h

version» Context lines:

pike.git/src/interpret_functions.h:630:    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);    }   });    + /* lval[0], lval[1], *Pike_sp +  * -> +  * lval[0], lval[1], result, *Pike_sp +  */   OPCODE0(F_LTOSVAL, "lvalue to svalue", I_UPDATE_SP, {    dmalloc_touch_svalue(Pike_sp-2);    dmalloc_touch_svalue(Pike_sp-1);    lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2);    Pike_sp++;    print_return_value();   });    - OPCODE0(F_LTOSVAL2, "ltosval2", I_UPDATE_SP, { + /* The F_LTOSVAL*_AND_FREE opcodes are used to optimize foo+=bar and +  * similar things. The optimization is to free the old reference to +  * foo after it has been pushed on the stack. That way we make it +  * possible for foo to have only 1 reference, and then the low +  * array/multiset/mapping manipulation routines can be destructive if +  * they like. +  * +  * Warning: We must not release the interpreter lock while foo is +  * zeroed, or else other threads might read the zero in cases where +  * there's supposed to be none. +  * +  * FIXME: The next opcode must not throw, because then the zeroing +  * becomes permanent and can cause lasting side effects if it's a +  * global variable. F_ADD and most other opcodes currently break this. +  * +  * (Another way to handle both problems above is to restrict this +  * optimization to local variables.) +  */ +  + /* lval[0], lval[1], x, *Pike_sp +  * -> +  * lval[0], lval[1], result, x, *Pike_sp +  */ + OPCODE0(F_LTOSVAL2_AND_FREE, "ltosval2 and free", I_UPDATE_SP, {    dmalloc_touch_svalue(Pike_sp-3);    dmalloc_touch_svalue(Pike_sp-2);    dmalloc_touch_svalue(Pike_sp-1);       move_svalue (Pike_sp, Pike_sp - 1);    mark_free_svalue (Pike_sp - 1);    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. -  * 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 = NUMBER_NUMBER;    tmp.u.integer = 0;    assign_lvalue(Pike_sp-4, &tmp);    }   });    - OPCODE0(F_LTOSVAL3, "ltosval3", I_UPDATE_SP, { + /* lval[0], lval[1], x, y, *Pike_sp +  * -> +  * lval[0], lval[1], result, x, y, *Pike_sp +  */ + OPCODE0(F_LTOSVAL3_AND_FREE, "ltosval3 and free", I_UPDATE_SP, {    dmalloc_touch_svalue(Pike_sp-4);    dmalloc_touch_svalue(Pike_sp-3);    dmalloc_touch_svalue(Pike_sp-2);    dmalloc_touch_svalue(Pike_sp-1);       move_svalue (Pike_sp, Pike_sp - 1);    move_svalue (Pike_sp - 1, Pike_sp - 2);    mark_free_svalue (Pike_sp - 2);    Pike_sp++;    lvalue_to_svalue_no_free(Pike_sp-3, Pike_sp-5);
pike.git/src/interpret_functions.h:693:    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )    {    LOCAL_VAR(struct svalue tmp);    tmp.type = PIKE_T_INT;    tmp.subtype = NUMBER_NUMBER;    tmp.u.integer = 0;    assign_lvalue(Pike_sp-5, &tmp);    }   });    - OPCODE0(F_LTOSVAL1, "ltosval1", I_UPDATE_SP, { + /* lval[0], lval[1], *Pike_sp +  * -> +  * lval[0], lval[1], result, *Pike_sp +  */ + OPCODE0(F_LTOSVAL_AND_FREE, "ltosval and free", I_UPDATE_SP, {    dmalloc_touch_svalue(Pike_sp-2);    dmalloc_touch_svalue(Pike_sp-1);       lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2);    Pike_sp++;       /* See ltosval3. This opcode is used e.g. in foo = foo[..] where no    * bound arguments are pushed on the stack. */    if( (1 << Pike_sp[-1].type) &    (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) )
pike.git/src/interpret_functions.h:1671:    break;       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;    }   });    + /* Used with F_LTOSVAL*_AND_FREE - must not release interpreter lock. */   OPCODE0_ALIAS(F_LSH, "<<", I_UPDATE_SP, o_lsh);   OPCODE0_ALIAS(F_RSH, ">>", I_UPDATE_SP, o_rsh);      #define COMPARISON(ID,DESC,EXPR) \    OPCODE0(ID, DESC, I_UPDATE_SP, { \    INT32 val = EXPR; \    pop_2_elems(); \    push_int(val); \    })      COMPARISON(F_EQ, "==", is_eq(Pike_sp-2,Pike_sp-1));   COMPARISON(F_NE, "!=", !is_eq(Pike_sp-2,Pike_sp-1));   COMPARISON(F_GT, ">", is_gt(Pike_sp-2,Pike_sp-1));   COMPARISON(F_GE, ">=", is_ge(Pike_sp-2,Pike_sp-1));   COMPARISON(F_LT, "<", is_lt(Pike_sp-2,Pike_sp-1));   COMPARISON(F_LE, "<=", is_le(Pike_sp-2,Pike_sp-1));    -  + /* Used with F_LTOSVAL*_AND_FREE - must not release interpreter lock. */   OPCODE0(F_ADD, "+", I_UPDATE_SP, {    f_add(2);   });    -  + /* Used with F_LTOSVAL*_AND_FREE - must not release interpreter lock. */   OPCODE0(F_ADD_INTS, "int+int", I_UPDATE_SP, {    if(Pike_sp[-1].type == T_INT && Pike_sp[-2].type == T_INT    DO_IF_BIGNUM(    && (!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, Pike_sp[-2].u.integer))    )    )    {    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{    f_add(2);    }   });    -  + /* Used with F_LTOSVAL*_AND_FREE - must not release interpreter lock. */   OPCODE0(F_ADD_FLOATS, "float+float", I_UPDATE_SP, {    if(Pike_sp[-1].type == T_FLOAT && Pike_sp[-2].type == T_FLOAT)    {    Pike_sp[-2].u.float_number+=Pike_sp[-1].u.float_number;    dmalloc_touch_svalue(Pike_sp-1);    Pike_sp--;    }else{    f_add(2);    }   });    -  + /* Used with F_LTOSVAL*_AND_FREE - must not release interpreter lock. */   OPCODE0_ALIAS(F_SUBTRACT, "-", I_UPDATE_SP, o_subtract);   OPCODE0_ALIAS(F_AND, "&", I_UPDATE_SP, o_and);   OPCODE0_ALIAS(F_OR, "|", I_UPDATE_SP, o_or);   OPCODE0_ALIAS(F_XOR, "^", I_UPDATE_SP, o_xor);   OPCODE0_ALIAS(F_MULTIPLY, "*", I_UPDATE_SP, o_multiply);   OPCODE0_ALIAS(F_DIVIDE, "/", I_UPDATE_SP, o_divide);   OPCODE0_ALIAS(F_MOD, "%", I_UPDATE_SP, o_mod);      OPCODE1(F_ADD_INT, "add integer", 0, {    if(Pike_sp[-1].type == T_INT
pike.git/src/interpret_functions.h:1913:    struct pike_string *t = describe_type(Pike_sp[-2].u.type);    fprintf(stderr, "Soft cast to %s\n", t->str);    free_string(t);    }    });    }    stack_swap();    pop_stack();   });    + /* Used with F_LTOSVAL*_AND_FREE - must not release interpreter lock. */   OPCODE1_ALIAS(F_RANGE, "range", I_UPDATE_SP, o_range2);      OPCODE0(F_COPY_VALUE, "copy_value", 0, {    LOCAL_VAR(struct svalue tmp);    copy_svalues_recursively_no_free(&tmp,Pike_sp-1,1,0);    free_svalue(Pike_sp-1);    move_svalue (Pike_sp - 1, &tmp);    print_return_value();   });