diff --git a/src/interpret.c b/src/interpret.c index 8864e95f20347eed183c924ce32966cd9e3a849a..cf20f0dc505b09e049a9bba212bb1595d05a7b40 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: interpret.c,v 1.217 2001/07/09 11:37:20 grubba Exp $"); +RCSID("$Id: interpret.c,v 1.218 2001/07/09 14:19:15 grubba Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -66,6 +66,7 @@ RCSID("$Id: interpret.c,v 1.217 2001/07/09 11:37:20 grubba Exp $"); #ifdef HAVE_COMPUTED_GOTO PIKE_OPCODE_T *fcode_to_opcode = NULL; +struct op_2_f *opcode_to_fcode = NULL; #endif /* HAVE_COMPUTED_GOTO */ PMOD_EXPORT const char *Pike_check_stack_errmsg = @@ -691,7 +692,7 @@ void dump_backlog(void) fprintf(stderr,"%s:%ld: %s", file, (long)line, - low_get_f_name(backlog[e].instruction, backlog[e].program)); + get_opcode_name(backlog[e].instruction)); #else /* !HAVE_COMPUTED_GOTO */ if(backlog[e].instruction < 0 || backlog[e].instruction+F_OFFSET > F_MAX_OPCODE) { @@ -741,6 +742,14 @@ static int o_catch(PIKE_OPCODE_T *pc); #define EVAL_INSTR_RET_CHECK(x) #endif +#ifdef HAVE_COMPUTED_GOTO +int lookup_sort_fun(const void *a, const void *b) +{ + return (int)(((ptrdiff_t)((struct op_2_f *)a)->opcode) - + ((ptrdiff_t)((struct op_2_f *)b)->opcode)); +} +#endif /* HAVE_COMPUTED_GOTO */ + /* NOTE: Due to the implementation of computed goto, * interpreter.h may only be included once. */ @@ -1241,7 +1250,7 @@ int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2) { int num_args; int num_locals; - unsigned char *pc; + PIKE_OPCODE_T *pc; #ifdef PIKE_DEBUG if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_FREE) @@ -1250,9 +1259,14 @@ int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2) debug_malloc_touch(Pike_fp); pc=new_frame->context.prog->program + function->func.offset; - - num_locals=EXTRACT_UCHAR(pc++); - num_args=EXTRACT_UCHAR(pc++); + +#ifdef HAVE_COMPUTED_GOTO + num_locals = (int)(ptrdiff_t)((pc++)[0]); + num_args = (int)(ptrdiff_t)((pc++)[0]); +#else /* !HAVE_COMPUTED_GOTO */ + num_locals = EXTRACT_UCHAR(pc++); + num_args = EXTRACT_UCHAR(pc++); +#endif /* HAVE_COMPUTED_GOTO */ #ifdef PIKE_DEBUG if(num_locals < num_args) @@ -1294,7 +1308,7 @@ int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2) new_frame->save_mark_sp=Pike_mark_sp; new_frame->mark_sp_base=Pike_mark_sp; check_threads_etc(); - new_frame->pc=pc; + new_frame->pc = pc; return 1; } } diff --git a/src/interpreter.h b/src/interpreter.h index 71e784a0aff8d87c219fbb2e099a334e8876cd6e..141e240eccb1cdef9ba27895e77d853c515d5f48 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -135,7 +135,7 @@ static int eval_instruction(PIKE_OPCODE_T *pc) file,(long)linep, DO_NOT_WARN((long)(pc-Pike_fp->context.prog->program-1)), #ifdef HAVE_COMPUTED_GOTO - get_f_name(instr), + get_opcode_name(instr), #else /* !HAVE_COMPUTED_GOTO */ get_f_name(instr + F_OFFSET), #endif /* HAVE_COMPUTED_GOTO */ @@ -144,7 +144,8 @@ static int eval_instruction(PIKE_OPCODE_T *pc) } #ifdef HAVE_COMPUTED_GOTO - ADD_RUNNED(instr); + if (instr) + ADD_RUNNED(instr); #else /* !HAVE_COMPUTED_GOTO */ if(instr + F_OFFSET < F_MAX_OPCODE) ADD_RUNNED(instr + F_OFFSET); @@ -383,6 +384,44 @@ static int eval_instruction(PIKE_OPCODE_T *pc) LABEL(F_RETURN_LOCAL), LABEL(F_RETURN_IF_TRUE), +#include "interpret_protos.h" + }; + + static struct op_2_f lookup[] = { +#undef LABEL +#define LABEL(OP) { &&PIKE_CONCAT(LABEL_, OP), OP } +#undef NULL_LABEL +#define NULL_LABEL(OP) { NULL, OP } + + NULL_LABEL(F_OFFSET), + + NULL_LABEL(F_PREFIX_256), + NULL_LABEL(F_PREFIX_512), + NULL_LABEL(F_PREFIX_768), + NULL_LABEL(F_PREFIX_1024), + NULL_LABEL(F_PREFIX_CHARX256), + NULL_LABEL(F_PREFIX_WORDX256), + NULL_LABEL(F_PREFIX_24BITX256), + + NULL_LABEL(F_PREFIX2_256), + NULL_LABEL(F_PREFIX2_512), + NULL_LABEL(F_PREFIX2_768), + NULL_LABEL(F_PREFIX2_1024), + NULL_LABEL(F_PREFIX2_CHARX256), + NULL_LABEL(F_PREFIX2_WORDX256), + NULL_LABEL(F_PREFIX2_24BITX256), + + LABEL(F_INDEX), + LABEL(F_POS_INT_INDEX), + LABEL(F_NEG_INT_INDEX), + + LABEL(F_RETURN), + LABEL(F_DUMB_RETURN), + LABEL(F_RETURN_0), + LABEL(F_RETURN_1), + LABEL(F_RETURN_LOCAL), + LABEL(F_RETURN_IF_TRUE), + #include "interpret_protos.h" }; @@ -393,6 +432,11 @@ static int eval_instruction(PIKE_OPCODE_T *pc) DO_NOT_WARN((long)((F_MAX_OPCODE-F_OFFSET)*sizeof(void *)))); #endif /* PIKE_DEBUG */ fcode_to_opcode = table; + opcode_to_fcode = lookup; + + qsort(lookup, F_MAX_OPCODE-F_OFFSET, sizeof(struct op_2_f), + lookup_sort_fun); + return 0; } #endif /* HAVE_COMPUTED_GOTO */ diff --git a/src/lex.c b/src/lex.c index 598d36493d2441d6454dd53ce985487e998dfa70..59cb097e300a3ef7298a49e023db428b8d963cc1 100644 --- a/src/lex.c +++ b/src/lex.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: lex.c,v 1.95 2001/07/09 11:37:21 grubba Exp $"); +RCSID("$Id: lex.c,v 1.96 2001/07/09 14:19:16 grubba Exp $"); #include "language.h" #include "array.h" #include "lex.h" @@ -85,7 +85,9 @@ void add_runned(PIKE_OPCODE_T instr) tmp=tmp[0]->next + last_instruction[e]; last_instruction[e]=last_instruction[e+1]; } +#ifndef HAVE_COMPUTED_GOTO ((char **)(tmp))[0]++; +#endif /* !HAVE_COMPUTED_GOTO */ last_instruction[e]=instr; } @@ -323,6 +325,34 @@ char *get_f_name(int n) } } +#ifdef HAVE_COMPUTED_GOTO +char *get_opcode_name(PIKE_OPCODE_T n) +{ + int fcode; + int low = 0; + int high = F_MAX_OPCODE - F_OFFSET; + static char buf[64]; + + if (!n) { + return "<NULL opcode!>"; + } + + while (low < high) { + int mid = (low+high)/2; + if (opcode_to_fcode[mid].opcode < n) { + low = mid + 1; + } else if (opcode_to_fcode[mid].opcode > n) { + high = mid; + } else { + return get_f_name(opcode_to_fcode[mid].fcode); + } + } + + sprintf(buf, "<Unknown opcode 0x%p>", n); + return buf; +} +#endif /* HAVE_COMPUTED_GOTO */ + char *get_token_name(int n) { static char buf[30]; diff --git a/src/lex.h b/src/lex.h index 661a722faf35a96de0a7a690742d01fa0f815d68..96a47efe29cdaa6db6aaf43c609e157c35f359ac 100644 --- a/src/lex.h +++ b/src/lex.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: lex.h,v 1.17 2001/07/09 11:37:20 grubba Exp $ + * $Id: lex.h,v 1.18 2001/07/09 14:19:16 grubba Exp $ */ #ifndef LEX_H #define LEX_H @@ -90,6 +90,11 @@ struct reserved; void init_lex(void); char *low_get_f_name(int n,struct program *p); char *get_f_name(int n); +#ifdef HAVE_COMPUTED_GOTO +char *get_opcode_name(PIKE_OPCODE_T n); +#else /* !HAVE_COMPUTED_GOTO */ +#define get_opcode_name(n) get_f_name(n) +#endif /* HAVE_COMPUTED_GOTO */ char *get_token_name(int n); int yylex0(YYSTYPE *); diff --git a/src/peep.c b/src/peep.c index 767ea3f7fed9d6abb34ca7c1119c32ccd0a1a32a..d005636506bbdb64b9bc8ff0af6406695a291cfc 100644 --- a/src/peep.c +++ b/src/peep.c @@ -17,7 +17,7 @@ #include "builtin_functions.h" #include "constants.h" -RCSID("$Id: peep.c,v 1.52 2001/07/09 12:50:18 grubba Exp $"); +RCSID("$Id: peep.c,v 1.53 2001/07/09 14:19:16 grubba Exp $"); static void asm_opt(void); @@ -360,7 +360,9 @@ void assemble(void) case F_START_FUNCTION: break; case F_ALIGN: +#ifndef HAVE_COMPUTED_GOTO while(PC % c->arg) add_to_program(0); +#endif /* HAVE_COMPUTED_GOTO */ break; case F_BYTE: @@ -447,9 +449,16 @@ void assemble(void) fatal("Hyperspace error: unknown jump point %ld at %d (pc=%x).\n", PTRDIFF_T_TO_LONG(e), labels[e], jumps[e]); #endif +#ifdef HAVE_COMPUTED_GOTO + tmp = (int)(ptrdiff_t)(Pike_compiler->new_program->program[jumps[e]]); + Pike_compiler->new_program->program[jumps[e]] = + (PIKE_OPCODE_T)(ptrdiff_t)(tmp2 - jumps[e]); + jumps[e] = tmp; +#else /* !HAVE_COMPUTED_GOTO */ tmp=read_int(jumps[e]); upd_int(jumps[e], tmp2 - jumps[e]); jumps[e]=tmp; +#endif /* HAVE_COMPUTED_GOTO */ } } diff --git a/src/program.h b/src/program.h index 78414a2ab1031f18cda29afde14c431a8118cc91..8baa09cbfaa0dae1eedb59e7eb2de22258c80973 100644 --- a/src/program.h +++ b/src/program.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: program.h,v 1.135 2001/07/09 11:37:19 grubba Exp $ + * $Id: program.h,v 1.136 2001/07/09 14:19:16 grubba Exp $ */ #ifndef PROGRAM_H #define PROGRAM_H @@ -30,6 +30,10 @@ PMOD_PROTO extern struct program_state * Pike_compiler; #ifdef HAVE_COMPUTED_GOTO #define PIKE_OPCODE_T void * extern PIKE_OPCODE_T *fcode_to_opcode; +extern struct op_2_f { + PIKE_OPCODE_T opcode; + INT32 fcode; +} *opcode_to_fcode; #else /* !HAVE_COMPUTED_GOTO */ #ifdef SHORT_PIKE_OPCODE #define PIKE_OPCODE_T unsigned INT16