pike.git / src / interpret.c

version» Context lines:

pike.git/src/interpret.c:2073:    struct pike_callsite C;    callsite_init(&C, args);    callsite_resolve_fun(&C, o, fun);    if (C.type == CALLTYPE_PIKEFUN) {    FAST_CHECK_THREADS_ON_CALL();    return C.ptr;    }    /* This is only needed for pike functions right now:    * callsite_prepare(&C); */    callsite_execute(&C); -  callsite_return(&C); +     callsite_free(&C);    return NULL;   }      /* Apply a function.    *    * Application types:    *    * APPLY_STACK: Apply Pike_sp[-args] with args-1 arguments.    *
pike.git/src/interpret.c:2128:    Pike_fatal("Deprecated. Use lower_mega_apply instead.\n");    break;    }       if (C.type == CALLTYPE_PIKEFUN) {    FAST_CHECK_THREADS_ON_CALL();    return C.ptr;    }       callsite_execute(&C); -  callsite_return(&C); +     callsite_free(&C);       return NULL;   }      /* TAILCALL optimization variants. They try to reuse the current frame */   void* low_mega_apply_tailcall(enum apply_type type, INT32 args, void *arg1, void *arg2) {    struct pike_frame *frame = Pike_fp;    struct pike_callsite C;   
pike.git/src/interpret.c:2178:    */    if (C.frame == frame) {    if (C.type == CALLTYPE_PIKEFUN) {    FAST_CHECK_THREADS_ON_CALL();    return C.ptr;    } else C.frame = NULL;    }       callsite_prepare(&C);    callsite_execute(&C); -  callsite_return(&C); +     callsite_free(&C);       return NULL;   }      /* NOTE: see comments in low_mega_apply_tailcall() */   void* lower_mega_apply_tailcall(INT32 args, struct object *o, ptrdiff_t fun) {    struct pike_frame *frame = Pike_fp;    struct pike_callsite C;   
pike.git/src/interpret.c:2206:       if (C.frame == frame) {    if (C.type == CALLTYPE_PIKEFUN) {    FAST_CHECK_THREADS_ON_CALL();    return C.ptr;    } else C.frame = NULL;    }       callsite_prepare(&C);    callsite_execute(&C); -  callsite_return(&C); +     callsite_free(&C);       return NULL;   }      void low_return(void)   {    struct svalue *save_sp = frame_get_save_sp(Pike_fp);    struct object *o = Pike_fp->current_object;    int fun = Pike_fp->fun;
pike.git/src/interpret.c:2765:    pop_n_elems(args);    push_int(0);    }else{    ptrdiff_t expected_stack=Pike_sp-args+1 - Pike_interpreter.evaluator_stack;    struct pike_callsite C;       callsite_init(&C, args);    callsite_resolve_svalue(&C, s);    callsite_prepare(&C);    callsite_execute(&C); -  callsite_return(&C); +     callsite_free(&C);       /* Note: do we still need those? I guess callsite_return takes care    * of this stuff */    if(Pike_sp > (expected_stack + Pike_interpreter.evaluator_stack))    {    pop_n_elems(Pike_sp-(expected_stack + Pike_interpreter.evaluator_stack));    }    else if(Pike_sp < (expected_stack + Pike_interpreter.evaluator_stack))    {
pike.git/src/interpret.c:3560:    Pike_fp = n;       /*    * We pop all 'leftover' locals here, since that    * was not done in the last call to callsite_return.    */    if (c->retval + c->args < Pike_sp)    pike_pop_locals(c->retval, c->args);   }    + static void callsite_return_slowpath(const struct pike_callsite *c); +    PMOD_EXPORT void callsite_execute(const struct pike_callsite *c) {    FAST_CHECK_THREADS_ON_CALL();    switch (c->type) {    default:    case CALLTYPE_NONE:   #ifdef PIKE_DEBUG    Pike_fatal("Unknown callsite type: %d\n", c->type);   #endif -  break; +  UNREACHABLE(break);    case CALLTYPE_EFUN:    case CALLTYPE_CFUN:    {    void (*fun)(INT32) = c->ptr;    (* fun)(c->args);    }    break;    case CALLTYPE_PIKEFUN:    {    PIKE_OPCODE_T *pc = c->ptr;   #ifdef ENTRY_PROLOGUE_SIZE    pc -= ENTRY_PROLOGUE_SIZE;   #endif    eval_instruction(pc);    } -  break; +  goto do_return;    case CALLTYPE_CAST:    o_cast(c->ptr, compile_type_to_runtime_type(c->ptr));    break;    case CALLTYPE_ARRAY:    /* TODO: reenable destructive operation */    apply_array(c->ptr, c->args, 0);    break;    case CALLTYPE_CLONE:    push_object(clone_object(c->ptr, c->args));    break;
pike.git/src/interpret.c:3606:    {    struct object *tmp;    tmp=parent_clone_object(c->ptr,    c->frame->current_object,    c->frame->fun,    c->args);    push_object(tmp);    }    break;    } +  +  if (LIKELY(c->retval+1 == Pike_sp)) return; + do_return: +  callsite_return_slowpath(c);   }      PMOD_EXPORT void callsite_save_jmpbuf(struct pike_callsite *c) {   #ifdef PIKE_DEBUG    if (c->type != CALLTYPE_PIKEFUN)    Pike_fatal("callsite_save_jmpbuf called for non pike frame.\n");   #endif       c->saved_jmpbuf = Pike_interpreter.catching_eval_jmpbuf;    SET_ONERROR (c->onerror, restore_catching_eval_jmpbuf, c->saved_jmpbuf);
pike.git/src/interpret.c:3655:    }       if (c->type != CALLTYPE_PIKEFUN) return;       /* restore catching_eval_jmpbuf */       Pike_interpreter.catching_eval_jmpbuf = c->saved_jmpbuf;    UNSET_ONERROR(c->onerror);   }    - PMOD_EXPORT void callsite_return_slowpath(const struct pike_callsite *c) { + static void callsite_return_slowpath(const struct pike_callsite *c) {    const struct svalue *sp = Pike_sp;    struct svalue *save_sp = c->retval;    struct pike_frame *frame = c->frame;    ptrdiff_t needs_retval = (c->type != CALLTYPE_PIKEFUN || !(frame->flags & PIKE_FRAME_RETURN_POP));      #ifdef PIKE_DEBUG    if(Pike_mark_sp < Pike_fp->save_mark_sp)    Pike_fatal("Popped below save_mark_sp!\n");    if(Pike_sp<Pike_interpreter.evaluator_stack)    Pike_fatal("Stack error (also simple).\n");