diff --git a/src/interpret.c b/src/interpret.c index ddff98c3e8ba80b06341299d8ba9284b6b94681e..4da7768bbb034ca3ccb9b656424ef27a6fe31443 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: interpret.c,v 1.179 2001/01/10 19:56:37 mast Exp $"); +RCSID("$Id: interpret.c,v 1.180 2001/01/11 23:28:30 mast Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -754,6 +754,18 @@ void dump_backlog(void) #endif static int o_catch(unsigned char *pc); +struct light_frame_info +{ + struct svalue *expendible; + struct svalue *locals; +}; + +static void restore_light_frame_info(struct light_frame_info *info) +{ + Pike_fp->expendible = info->expendible; + Pike_fp->locals = info->locals; +} + #ifdef PIKE_DEBUG #define EVAL_INSTR_RET_CHECK(x) \ if (x == -2) \ diff --git a/src/interpret_functions.h b/src/interpret_functions.h index 23fa38d494a4df8420672a27135c6e623230c218..1f621d17f1ada5b66259d39a92293b9c1c17b1b5 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -1,5 +1,5 @@ /* - * $Id: interpret_functions.h,v 1.37 2001/01/10 19:56:37 mast Exp $ + * $Id: interpret_functions.h,v 1.38 2001/01/11 23:28:30 mast Exp $ * * Opcode definitions for the interpreter. */ @@ -1485,19 +1485,42 @@ BREAK; /* Assume that the number of arguments is correct */ -OPCODE0_JUMP(F_RECUR,"recur") +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) + { + apply_low(Pike_fp->current_object, + arg1+Pike_fp->context.identifier_level, + DO_NOT_WARN(Pike_sp - *--Pike_mark_sp)); + pc+=sizeof(INT32); + DONE; + } +} +/* FALL THROUGH */ + +/* Assume that the number of arguments is correct */ +OPCODE0_TAILJUMP(F_RECUR,"recur") { int x; INT32 num_locals, args; char *addr; - struct svalue *expendible=Pike_fp->expendible; - struct svalue *locals=Pike_fp->locals; + struct light_frame_info info; struct svalue *save_sp, **save_mark_sp; + ONERROR uwp; fast_check_threads_etc(6); check_c_stack(8192); check_stack(256); + info.expendible = Pike_fp->expendible; + info.locals = Pike_fp->locals; + SET_ONERROR(uwp, restore_light_frame_info, &info); + save_sp = Pike_fp->expendible = Pike_fp->locals = *--Pike_mark_sp; args = DO_NOT_WARN(Pike_sp - Pike_fp->locals); save_mark_sp = Pike_mark_sp; @@ -1528,8 +1551,7 @@ OPCODE0_JUMP(F_RECUR,"recur") assign_svalue(save_sp,Pike_sp-1); pop_n_elems(Pike_sp-save_sp-1); } - Pike_fp->expendible=expendible; - Pike_fp->locals=locals; + CALL_AND_UNSET_ONERROR(uwp); print_return_value(); #ifdef PIKE_DEBUG if(Pike_sp != save_sp+1) @@ -1538,73 +1560,6 @@ OPCODE0_JUMP(F_RECUR,"recur") } BREAK -/* Assume that the number of arguments is correct */ -OPCODE1_JUMP(F_COND_RECUR,"recur if not overloaded") -{ - int x; - INT32 num_locals,args; - char *addr; - - struct svalue *expendible=Pike_fp->expendible; - struct svalue *locals=Pike_fp->locals; - struct svalue *save_sp, **save_mark_sp; - - /* 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) - { - apply_low(Pike_fp->current_object, - arg1+Pike_fp->context.identifier_level, - DO_NOT_WARN(Pike_sp - *--Pike_mark_sp)); - pc+=sizeof(INT32); - }else{ - fast_check_threads_etc(6); - check_c_stack(8192); - check_stack(256); - - save_sp = Pike_fp->expendible = Pike_fp->locals = *--Pike_mark_sp; - args = DO_NOT_WARN(Pike_sp - Pike_fp->locals); - save_mark_sp = Pike_mark_sp; - - addr=pc+EXTRACT_INT(pc); - num_locals=EXTRACT_UCHAR(addr-2); - -#ifdef PIKE_DEBUG - if(args != EXTRACT_UCHAR(addr-1)) - fatal("Wrong number of arguments in F_RECUR %d!=%d\n",args,EXTRACT_UCHAR(addr-1)); -#endif - - clear_svalues(Pike_sp, num_locals - args); - Pike_sp += num_locals - args; - - x=eval_instruction(addr); - EVAL_INSTR_RET_CHECK(x); -#ifdef PIKE_DEBUG - if(Pike_mark_sp < save_mark_sp) - fatal("mark Pike_sp underflow in F_RECUR.\n"); -#endif - Pike_mark_sp=save_mark_sp; - if(x>=0) mega_apply(APPLY_STACK, x, 0,0); - pc+=sizeof(INT32); - if(save_sp+1 < Pike_sp) - { - assign_svalue(save_sp,Pike_sp-1); - pop_n_elems(Pike_sp-save_sp-1); - } - Pike_fp->expendible=expendible; - Pike_fp->locals=locals; - print_return_value(); -#ifdef PIKE_DEBUG - if(Pike_sp != save_sp+1) - fatal("Stack whack in F_RECUR Pike_sp=%p, expected=%p\n",Pike_sp,save_sp+1); -#endif - } -} -BREAK - /* Assume that the number of arguments is correct */ /* FIXME: adjust Pike_mark_sp */ OPCODE0_JUMP(F_TAIL_RECUR,"tail recursion") diff --git a/src/interpreter.h b/src/interpreter.h index cc48afe492a332e0d1649a4caa0f1ad21d1bdc7e..f3bf32eb6ab432ab6419ddda7b8d4b0a73677d61 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -194,9 +194,9 @@ static int eval_instruction(unsigned char *pc) #define OPCODE2_TAILJUMP(OP,DESC) } CASE(OP) {; - #define BREAK break; } - +#define DONE break + #include "interpret_functions.h" default: