Branch: Tag:

2004-03-12

2004-03-12 21:56:52 by Martin Stjernholm <mast@lysator.liu.se>

Separated the return address from Pike_fp->pc. pc always points to the
current opcode now, which makes everything a lot simpler. This fixes
off-by-one bugs that could occur for the innermost line in backtraces when
machine code is used.

Rev: src/builtin.cmod:1.150
Rev: src/interpret.h:1.150
Rev: src/interpret_functions.h:1.164
Rev: src/opcodes.h:1.39
Rev: src/peep.c:1.98

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.163 2003/12/03 14:39:19 grubba Exp $ + || $Id: interpret_functions.h,v 1.164 2004/03/12 21:56:52 mast Exp $   */      /*
167:    \    DO_IF_DEBUG(if (Pike_interpreter.trace_level > 5) \    fprintf(stderr, "Returning to 0x%p\n", \ -  Pike_fp->pc)); \ -  DO_JUMP_TO(Pike_fp->pc); \ +  Pike_fp->return_addr)); \ +  DO_JUMP_TO(Pike_fp->return_addr); \    } \    DO_IF_DEBUG(if (Pike_interpreter.trace_level > 5) \    fprintf(stderr, "Inter return\n")); \
1244:    DO_DUMB_RETURN;    case 2:    /* Escape catch, continue after the escape instruction. */ -  DO_JUMP_TO(Pike_fp->pc); +  DO_JUMP_TO(Pike_fp->return_addr);    break;    default:    DOJUMP();
1252:    /* NOT_REACHED in byte-code and computed goto cases. */   });    - OPCODE0_RETURN(F_ESCAPE_CATCH, "escape catch", I_PC_AT_NEXT, { -  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); + OPCODE0_RETURN(F_ESCAPE_CATCH, "escape catch", 0, { +  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    INTER_ESCAPE_CATCH;   });    - OPCODE0_RETURN(F_EXIT_CATCH, "exit catch", I_PC_AT_NEXT|I_UPDATE_SP, { + OPCODE0_RETURN(F_EXIT_CATCH, "exit catch", I_UPDATE_SP, {    push_undefined(); -  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); +  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    INTER_ESCAPE_CATCH;   });   
1837:      #define MKAPPLY(OP,OPCODE,NAME,TYPE, ARG2, ARG3) \    PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT(F_,OPCODE),NAME, \ -  I_PC_AT_NEXT|I_UPDATE_ALL, { \ - JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); \ +  I_UPDATE_ALL, { \ + JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \   if(low_mega_apply(TYPE,DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)), \    ARG2, ARG3)) \   { \
1851:   }); \    \    PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT3(F_,OPCODE,_AND_POP),NAME " & pop", \ -  I_PC_AT_NEXT|I_UPDATE_ALL, { \ -  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); \ +  I_UPDATE_ALL, { \ +  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \    if(low_mega_apply(TYPE, DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)), \    ARG2, ARG3)) \    { \
1885:   MKAPPLY(OP,OPCODE,NAME,TYPE, ARG2, ARG3); \    \   PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT(F_MARK_,OPCODE),"mark, " NAME, \ -  I_PC_AT_NEXT|I_UPDATE_ALL, { \ -  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); \ +  I_UPDATE_ALL, { \ +  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \    if(low_mega_apply(TYPE, 0, \    ARG2, ARG3)) \    { \
1900:    \   PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT3(F_MARK_,OPCODE,_AND_POP), \    "mark, " NAME " & pop", \ -  I_PC_AT_NEXT|I_UPDATE_ALL, { \ -  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); \ +  I_UPDATE_ALL, { \ +  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \    if(low_mega_apply(TYPE, 0, \    ARG2, ARG3)) \    { \
1938:      MKAPPLY(OPCODE0,CALL_FUNCTION,"call function",APPLY_STACK, 0,0);    - OPCODE1_JUMP(F_CALL_OTHER,"call other", I_PC_AT_NEXT|I_UPDATE_ALL, { + OPCODE1_JUMP(F_CALL_OTHER,"call other", I_UPDATE_ALL, {    INT32 args=DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp));    struct svalue *s=Pike_sp-args; -  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); +  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    if(s->type == T_OBJECT)    {    struct object *o=s->u.object;
1992:    }   });    - OPCODE1_JUMP(F_CALL_OTHER_AND_POP,"call other & pop", I_PC_AT_NEXT|I_UPDATE_ALL, { + OPCODE1_JUMP(F_CALL_OTHER_AND_POP,"call other & pop", I_UPDATE_ALL, {    INT32 args=DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp));    struct svalue *s=Pike_sp-args; -  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); +  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);    if(s->type == T_OBJECT)    {    struct object *o=s->u.object;
2205:    new_frame->next=Pike_fp; \    \    JUMP_SET_TO_PC_AT_NEXT (addr); \ -  Pike_fp->pc = (PIKE_OPCODE_T *)(((INT32 *) addr) + 1); \ +  Pike_fp->return_addr = (PIKE_OPCODE_T *)(((INT32 *) addr) + 1); \    addr += GET_JUMP(); \    \    new_frame->num_locals = READ_INCR_BYTE(addr); \
2251:   }while(0)      /* Assume that the number of arguments is correct */ - OPCODE1_PTRJUMP(F_COND_RECUR, "recur if not overloaded", I_PC_AT_NEXT|I_UPDATE_ALL, { + OPCODE1_PTRJUMP(F_COND_RECUR, "recur if not overloaded", I_UPDATE_ALL, {    struct program *p = Pike_fp->current_object->prog;    PIKE_OPCODE_T *addr;    JUMP_SET_TO_PC_AT_NEXT (addr); -  Pike_fp->pc = (PIKE_OPCODE_T *)(((INT32 *)addr) + 1); +  Pike_fp->return_addr = (PIKE_OPCODE_T *)(((INT32 *)addr) + 1);       /* Test if the function is overloaded.    *