pike.git / src / interpret_functions.h

version» Context lines:

pike.git/src/interpret_functions.h:1:   /* -  * $Id: interpret_functions.h,v 1.85 2001/07/28 00:33:50 hubbe Exp $ +  * $Id: interpret_functions.h,v 1.86 2001/08/15 09:26:33 hubbe Exp $    *    * Opcode definitions for the interpreter.    */      #include "global.h"      #undef CJUMP   #undef AUTO_BIGNUM_LOOP_TEST   #undef LOOP   #undef COMPARISON
pike.git/src/interpret_functions.h:108:    SET_PROG_COUNTER(NEWPC); \    FETCH; \    DONE; \   }      #undef DO_DUMB_RETURN   #define DO_DUMB_RETURN { \    if(Pike_fp -> flags & PIKE_FRAME_RETURN_INTERNAL) \    { \    int f=Pike_fp->flags; \ +  if(f & PIKE_FRAME_RETURN_POP) \ +  low_return_pop(); \ +  else \    low_return(); \ -  +  \    DO_IF_DEBUG(if (t_flag) \    fprintf(stderr, "Returning to 0x%p\n", \    Pike_fp->pc)); \ -  if(f & PIKE_FRAME_RETURN_POP) \ -  pop_stack(); \ +     DO_JUMP_TO(Pike_fp->pc); \    } \    DO_IF_DEBUG(if (t_flag) \    fprintf(stderr, "Inter return\n")); \    INTER_RETURN; \   }      #undef DO_RETURN   #ifndef PIKE_DEBUG   #define DO_RETURN DO_DUMB_RETURN
pike.git/src/interpret_functions.h:137:    if(d_flag>4) do_debug(); \    check_threads_etc(); \    DO_DUMB_RETURN; \   }   #endif      #undef DO_INDEX   #define DO_INDEX do { \    struct svalue s; \    index_no_free(&s,Pike_sp-2,Pike_sp-1); \ -  pop_n_elems(2); \ +  pop_2_elems(); \    *Pike_sp=s; \    Pike_sp++; \    print_return_value(); \   }while(0)         OPCODE0(F_UNDEFINED, "push UNDEFINED", {    push_int(0);    Pike_sp[-1].subtype=NUMBER_UNDEFINED;   });
pike.git/src/interpret_functions.h:421:    Pike_sp[-1].u.array->flags |= ARRAY_LVALUE;    Pike_sp[-1].u.array->type_field |= BIT_UNFINISHED | BIT_MIXED;    /* FIXME: Shouldn't a ref be added here? */    Pike_sp[0] = Pike_sp[-1];    Pike_sp[-1].type = T_ARRAY_LVALUE;    dmalloc_touch_svalue(Pike_sp);    Pike_sp++;   });      OPCODE1(F_CLEAR_2_LOCAL, "clear 2 local", { -  free_svalues(Pike_fp->locals + arg1, 2, -1); +  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].u.integer = 0;    Pike_fp->locals[arg1+1].type = PIKE_T_INT;    Pike_fp->locals[arg1+1].subtype = 0;    Pike_fp->locals[arg1+1].u.integer = 0;   });      OPCODE1(F_CLEAR_4_LOCAL, "clear 4 local", {    int e; -  free_svalues(Pike_fp->locals + arg1, 4, -1); +  free_mixed_svalues(Pike_fp->locals + arg1, 4);    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].u.integer = 0;    }   });      OPCODE1(F_CLEAR_LOCAL, "clear local", {    free_svalue(Pike_fp->locals + arg1);
pike.git/src/interpret_functions.h:623:    Pike_sp[-2].type == PIKE_T_INT )    {    DO_IF_BIGNUM(    if(!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, Pike_sp[-2].u.integer))    )    {    /* Optimization for a rather common case. Makes it 30% faster. */    Pike_sp[-1].u.integer += Pike_sp[-2].u.integer;    assign_lvalue(Pike_sp-4,Pike_sp-1);    Pike_sp-=2; -  pop_n_elems(2); +  pop_2_elems();    goto add_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    */    if( (1 << Pike_sp[-2].type) &
pike.git/src/interpret_functions.h:681:      OPCODE0(F_INC, "++x", {    union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT);    if(u    DO_IF_BIGNUM(    && !INT_TYPE_ADD_OVERFLOW(u->integer, 1)    )    )    {    INT32 val = ++u->integer; -  pop_n_elems(2); +  pop_2_elems();    push_int(val);    } else {    lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++;    push_int(1);    f_add(2);    assign_lvalue(Pike_sp-3, Pike_sp-1);    stack_unlink(2);    }   });      OPCODE0(F_DEC, "--x", {    union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT);    if(u    DO_IF_BIGNUM(    && !INT_TYPE_SUB_OVERFLOW(u->integer, 1)    )    )    {    INT32 val = --u->integer; -  pop_n_elems(2); +  pop_2_elems();    push_int(val);    } else {    lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++;    push_int(1);    o_subtract();    assign_lvalue(Pike_sp-3, Pike_sp-1);    stack_unlink(2);    }   });      OPCODE0(F_DEC_AND_POP, "x-- and pop", {    union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT);    if(u    DO_IF_BIGNUM(    && !INT_TYPE_SUB_OVERFLOW(u->integer, 1)    )   )    {    --u->integer; -  pop_n_elems(2); +  pop_2_elems();    }else{    lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++;    push_int(1);    o_subtract();    assign_lvalue(Pike_sp-3, Pike_sp-1);    pop_n_elems(3);    }   });      OPCODE0(F_INC_AND_POP, "x++ and pop", {    union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT);    if(u    DO_IF_BIGNUM(    && !INT_TYPE_ADD_OVERFLOW(u->integer, 1)    )    )    {    ++u->integer; -  pop_n_elems(2); +  pop_2_elems();    } else {    lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++;    push_int(1);    f_add(2);    assign_lvalue(Pike_sp-3, Pike_sp-1);    pop_n_elems(3);    }   });      OPCODE0(F_POST_INC, "x++", {    union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT);    if(u    DO_IF_BIGNUM(    && !INT_TYPE_ADD_OVERFLOW(u->integer, 1)    )    )    {    INT32 val = u->integer++; -  pop_n_elems(2); +  pop_2_elems();    push_int(val);    } else {    lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++;    stack_dup();    push_int(1);    f_add(2);    assign_lvalue(Pike_sp-4, Pike_sp-1);    pop_stack();    stack_unlink(2);    print_return_value();
pike.git/src/interpret_functions.h:782:      OPCODE0(F_POST_DEC, "x--", {    union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT);    if(u    DO_IF_BIGNUM(    && !INT_TYPE_SUB_OVERFLOW(u->integer, 1)    )    )    {    INT32 val = u->integer--; -  pop_n_elems(2); +  pop_2_elems();    push_int(val);    } else {    lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++;    stack_dup();    push_int(1);    o_subtract();    assign_lvalue(Pike_sp-4, Pike_sp-1);    pop_stack();    stack_unlink(2);    print_return_value();
pike.git/src/interpret_functions.h:1027:    }   });      #define CJUMP(X, DESC, Y) \    OPCODE0_JUMP(X, DESC, { \    if(Y(Pike_sp-2,Pike_sp-1)) { \    DOJUMP(); \    }else{ \    SKIPJUMP(); \    } \ -  pop_n_elems(2); \ +  pop_2_elems(); \    })      CJUMP(F_BRANCH_WHEN_EQ, "branch if ==", is_eq);   CJUMP(F_BRANCH_WHEN_NE, "branch if !=", !is_eq);   CJUMP(F_BRANCH_WHEN_LT, "branch if <", is_lt);   CJUMP(F_BRANCH_WHEN_LE, "branch if <=", !is_gt);   CJUMP(F_BRANCH_WHEN_GT, "branch if >", is_gt);   CJUMP(F_BRANCH_WHEN_GE, "branch if >=", !is_lt);      OPCODE0_JUMP(F_BRANCH_AND_POP_WHEN_ZERO, "branch & pop if zero", {
pike.git/src/interpret_functions.h:1080:    SKIPJUMP();    pop_stack();    }else{    DOJUMP();    }   });      OPCODE0_JUMP(F_EQ_OR, "==||", {    if(!is_eq(Pike_sp-2,Pike_sp-1))    { -  pop_n_elems(2); +  pop_2_elems();    SKIPJUMP();    }else{ -  pop_n_elems(2); +  pop_2_elems();    push_int(1);    DOJUMP();    }   });      OPCODE0_JUMP(F_EQ_AND, "==&&", {    if(is_eq(Pike_sp-2,Pike_sp-1))    { -  pop_n_elems(2); +  pop_2_elems();    SKIPJUMP();    }else{ -  pop_n_elems(2); +  pop_2_elems();    push_int(0);    DOJUMP();    }   });      OPCODE0_JUMP(F_CATCH, "catch", { -  +  check_c_stack(8192);    switch (o_catch((PIKE_OPCODE_T *)(((INT32 *)PROG_COUNTER)+1)))    {    case 1:    /* There was a return inside the evaluated code */    DO_DUMB_RETURN;    case 2:    DO_JUMP_TO(Pike_fp->pc);    break;    default:    DO_JUMP_TO(PROG_COUNTER + GET_JUMP());
pike.git/src/interpret_functions.h:1227:    * l2:    * loop(l1)    */   OPCODE0_JUMP(F_LOOP, "loop", { /* loopcnt */    /* Use >= and 1 to be able to reuse the 1 for the subtraction. */    push_int(1);    if (!is_lt(sp-2, sp-1)) {    o_subtract();    DOJUMP();    } else { -  pop_n_elems(2); +  pop_2_elems();    SKIPJUMP();    }   });      OPCODE0_JUMP(F_FOREACH, "foreach", { /* array, lvalue, X, 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)
pike.git/src/interpret_functions.h:1372:    o_lsh();   });      OPCODE0(F_RSH, ">>", {    o_rsh();   });      #define COMPARISON(ID,DESC,EXPR) \    OPCODE0(ID, DESC, { \    INT32 val = EXPR; \ -  pop_n_elems(2); \ +  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_lt(Pike_sp-2,Pike_sp-1));   COMPARISON(F_LT, "<", is_lt(Pike_sp-2,Pike_sp-1));   COMPARISON(F_LE, "<=", !is_gt(Pike_sp-2,Pike_sp-1));   
pike.git/src/interpret_functions.h:1672:    copy_svalues_recursively_no_free(&tmp,Pike_sp-1,1,0);    free_svalue(Pike_sp-1);    Pike_sp[-1]=tmp;   });      OPCODE0(F_INDIRECT, "indirect", {    struct svalue s;    lvalue_to_svalue_no_free(&s,Pike_sp-2);    if(s.type != PIKE_T_STRING)    { -  pop_n_elems(2); +  pop_2_elems();    *Pike_sp=s;    Pike_sp++;    }else{    struct object *o;    o=low_clone(string_assignment_program);    ((struct string_assignment_storage *)o->storage)->lval[0]=Pike_sp[-2];    ((struct string_assignment_storage *)o->storage)->lval[1]=Pike_sp[-1];    ((struct string_assignment_storage *)o->storage)->s=s.u.string;    Pike_sp-=2;    push_object(o);
pike.git/src/interpret_functions.h:1862:      OPCODE1(F_CALL_BUILTIN1, "call builtin 1", {    DO_CALL_BUILTIN(1);   });      OPCODE1(F_CALL_BUILTIN1_AND_POP, "call builtin1 & pop", {    DO_CALL_BUILTIN(1);    pop_stack();   });    + #define DO_RECUR(XFLAGS) do{ \ +  PIKE_OPCODE_T *addr; \ +  register struct pike_frame *new_frame; \ +  ptrdiff_t args; \ +  \ +  fast_check_threads_etc(6); \ +  check_stack(256); \ +  \ +  new_frame=alloc_pike_frame(); \ +  \ +  new_frame->refs=1; \ +  new_frame->next=Pike_fp; \ +  \ +  Pike_fp->pc = (PIKE_OPCODE_T *)(((INT32 *)PROG_COUNTER) + 1); \ +  addr = PROG_COUNTER+GET_JUMP(); \ +  args=addr[-1]; \ +  \ +  new_frame->num_args = new_frame->args = args; \ +  new_frame->locals=new_frame->save_sp=new_frame->expendible=Pike_sp-args; \ +  new_frame->save_mark_sp = new_frame->mark_sp_base = Pike_mark_sp; \ +  \ +  push_zeroes((new_frame->num_locals = (ptrdiff_t)addr[-2]) - args); \ +  \ +  DO_IF_DEBUG({ \ +  if(t_flag > 3) \ +  fprintf(stderr,"- Allocating %d extra locals.\n", \ +  new_frame->num_locals - new_frame->num_args); \ +  }); \ +  \ +  \ +  new_frame->fun=Pike_fp->fun; \ +  new_frame->ident=Pike_fp->ident; \ +  new_frame->current_storage=Pike_fp->current_storage; \ +  if(Pike_fp->scope) add_ref(new_frame->scope=Pike_fp->scope); \ +  add_ref(new_frame->current_object=Pike_fp->current_object); \ +  new_frame->context=Pike_fp->context; \ +  add_ref(new_frame->context.prog); \ +  if(new_frame->context.parent) \ +  add_ref(new_frame->context.parent); \ +  Pike_fp=new_frame; \ +  new_frame->flags=PIKE_FRAME_RETURN_INTERNAL | XFLAGS; \ +  \ +  DO_JUMP_TO(addr); \ + }while(0) +  +    /* Assume that the number of arguments is correct */   OPCODE1_JUMP(F_COND_RECUR, "recur if not overloaded", {    /* FIXME:    * this test should actually test if this function is    * overloaded or not. Currently it only tests if    * this context is inherited or not.    */    if(Pike_fp->current_object->prog != Pike_fp->context.prog)    {    PIKE_OPCODE_T *addr = (PIKE_OPCODE_T *)(((INT32 *)PROG_COUNTER) + 1); -  +  PIKE_OPCODE_T *faddr = PROG_COUNTER+GET_JUMP(); +  ptrdiff_t args=faddr[-1]; +     if(low_mega_apply(APPLY_LOW, -  DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)), +  args,    Pike_fp->current_object,    (void *)(arg1+Pike_fp->context.identifier_level)))    {    Pike_fp->next->pc=addr;    Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL;    addr = Pike_fp->pc;    }    DO_JUMP_TO(addr);    }       /* FALL THROUGH */       /* Assume that the number of arguments is correct */ -  /* FIXME: Use new recursion stuff */ -  OPCODE0_TAILJUMP(F_RECUR, "recur", { -  PIKE_OPCODE_T *addr; -  struct pike_frame *new_frame; +     -  fast_check_threads_etc(6); -  check_c_stack(8192); -  check_stack(256); -  -  new_frame=alloc_pike_frame(); -  new_frame[0]=Pike_fp[0]; -  -  new_frame->refs=1; -  new_frame->next=Pike_fp; -  -  new_frame->save_sp = new_frame->expendible = -  new_frame->locals = *--Pike_mark_sp; -  new_frame->num_args = new_frame->args = -  DO_NOT_WARN((INT32)(Pike_sp - new_frame->locals)); -  new_frame->save_mark_sp = Pike_mark_sp; -  new_frame->mark_sp_base = Pike_mark_sp; -  -  addr = PROG_COUNTER+GET_JUMP(); -  new_frame->num_locals = (ptrdiff_t)addr[-2]; -  -  DO_IF_DEBUG({ -  if(new_frame->num_args != (ptrdiff_t)addr[-1]) -  fatal("Wrong number of arguments in F_RECUR %d!=%d\n", -  new_frame->num_args, -  (ptrdiff_t)addr[-1]); -  -  if(t_flag > 3) -  fprintf(stderr,"- Allocating %d extra locals.\n", -  new_frame->num_locals - new_frame->num_args); +  OPCODE0_TAILJUMP(F_RECUR, "recur", { +  DO_RECUR(0);    }); -  -  Pike_fp->pc = (PIKE_OPCODE_T *)(((INT32 *)PROG_COUNTER) + 1); -  -  clear_svalues(Pike_sp, new_frame->num_locals - new_frame->num_args); -  Pike_sp += new_frame->num_locals - new_frame->args; -  -  if(new_frame->scope) add_ref(new_frame->scope); -  add_ref(new_frame->current_object); -  add_ref(new_frame->context.prog); -  if(new_frame->context.parent) -  add_ref(new_frame->context.parent); -  Pike_fp=new_frame; -  new_frame->flags=PIKE_FRAME_RETURN_INTERNAL; -  -  DO_JUMP_TO(addr); +    }); - }); +       /* Ugly code duplication */   OPCODE0_JUMP(F_RECUR_AND_POP, "recur & pop", { -  PIKE_OPCODE_T *addr; -  struct pike_frame *new_frame; -  -  fast_check_threads_etc(6); -  check_c_stack(8192); -  check_stack(256); -  -  new_frame=alloc_pike_frame(); -  new_frame[0]=Pike_fp[0]; -  -  new_frame->refs=1; -  new_frame->next=Pike_fp; -  -  new_frame->save_sp = new_frame->expendible = -  new_frame->locals = *--Pike_mark_sp; -  new_frame->num_args = new_frame->args = -  DO_NOT_WARN((INT32)(Pike_sp - new_frame->locals)); -  new_frame->save_mark_sp = Pike_mark_sp; -  new_frame->mark_sp_base = Pike_mark_sp; -  -  addr = PROG_COUNTER+GET_JUMP(); -  new_frame->num_locals = (ptrdiff_t)addr[-2]; -  -  DO_IF_DEBUG({ -  if(new_frame->num_args != (ptrdiff_t)addr[-1]) -  fatal("Wrong number of arguments in F_RECUR %d!=%d\n", -  new_frame->num_args, -  (ptrdiff_t)addr[-1]); -  -  if(t_flag > 3) -  fprintf(stderr,"- Allocating %d extra locals.\n", -  new_frame->num_locals - new_frame->num_args); +  DO_RECUR(PIKE_FRAME_RETURN_POP);   });    -  Pike_fp->pc = (PIKE_OPCODE_T *)(((INT32 *)PROG_COUNTER) + 1); +     -  clear_svalues(Pike_sp, new_frame->num_locals - new_frame->num_args); -  Pike_sp += new_frame->num_locals - new_frame->args; -  -  if(new_frame->scope) add_ref(new_frame->scope); -  add_ref(new_frame->current_object); -  add_ref(new_frame->context.prog); -  if(new_frame->context.parent) -  add_ref(new_frame->context.parent); -  Pike_fp=new_frame; -  new_frame->flags=PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP; -  -  DO_JUMP_TO(addr); - }); -  -  +    /* Assume that the number of arguments is correct */   /* FIXME: adjust Pike_mark_sp */   OPCODE0_JUMP(F_TAIL_RECUR, "tail recursion", {    int x;    INT32 num_locals;    PIKE_OPCODE_T *addr; -  INT32 args = DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)); +  INT32 args;       fast_check_threads_etc(6);       addr=PROG_COUNTER+GET_JUMP(); -  num_locals=EXTRACT_UCHAR(addr-2); +  args=addr[-1]; +  num_locals=addr[-2];          DO_IF_DEBUG({    if(args != EXTRACT_UCHAR(addr-1))    fatal("Wrong number of arguments in F_TAIL_RECUR %d != %d\n",    args, EXTRACT_UCHAR(addr-1));    });       if(Pike_sp-args != Pike_fp->locals)    {    DO_IF_DEBUG({    if (Pike_sp < Pike_fp->locals + args)    fatal("Pike_sp (%p) < Pike_fp->locals (%p) + args (%d)\n",    Pike_sp, Pike_fp->locals, args);    });    assign_svalues(Pike_fp->locals, Pike_sp-args, args, BIT_MIXED);    pop_n_elems(Pike_sp - (Pike_fp->locals + args));    }    -  clear_svalues(Pike_sp, num_locals - args); -  Pike_sp += num_locals - args; +  push_zeroes(num_locals - args);       DO_IF_DEBUG({    if(Pike_sp != Pike_fp->locals + Pike_fp->num_locals)    fatal("Sp whacked!\n");    });       DO_JUMP_TO(addr);   });      OPCODE0(F_BREAKPOINT, "breakpoint", {