# New Ticket Created by Leopold Toetsch # Please include the string: [perl #17468] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=17468 >
This patch - removes check_fingerprint (this should be done in PBC unpack) - simplifies init_prederef - separates dynamic oplib loading from prederef - changes not to run prederef, when e.g. tracing is on - avoids an endless loop, if JIT was ended under restart conditions (a test case for the latter will follow) Please apply, TIA, leo -- attachment 1 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/38205/31048/4ec37c/interpreter.patch
--- parrot/include/parrot/oplib.h Sun Sep 15 10:13:59 2002 +++ parrot-leo/include/parrot/oplib.h Sat Sep 21 12:21:49 2002 @@ -26,7 +26,7 @@ INTVAL major_version; INTVAL minor_version; INTVAL patch_version; - INTVAL op_count; + size_t op_count; op_info_t * op_info_table; void * op_func_table; int (*op_code)(const char * name, int full); --- parrot/interpreter.c Sun Sep 15 10:13:58 2002 +++ parrot-leo/interpreter.c Sat Sep 21 13:35:28 2002 @@ -23,42 +23,6 @@ #endif -/*=for api interpreter check_fingerprint - * TODO: Not really part of the API, but here's the docs. - * Check the bytecode's opcode table fingerprint. - */ -static void -check_fingerprint(struct Parrot_Interp *interpreter) -{ - /* if (PNCONST == 0) { */ - UNUSED(interpreter); - return; - -#if 0 - if (interpreter->code->const_table->const_count == 0) { - fprintf(stderr, - "Warning: Bytecode does not include opcode table fingerprint!\n"); - } - else { - const char *fp_data; - INTVAL fp_len; - - fp_data = PCONST(0)->string->strstart; - fp_len = PCONST(0)->string->buflen; - - if (strncmp(OPCODE_FINGERPRINT, fp_data, fp_len)) { - fprintf(stderr, - "Error: Opcode table fingerprint in bytecode does not match interpreter!\n"); - fprintf(stderr, " Bytecode: %*s\n", (int)-fp_len, - fp_data); - fprintf(stderr, " Interpreter: %s\n", OPCODE_FINGERPRINT); - exit(1); - } - } -#endif - -} - /*=for api interpreter runops_generic * TODO: Not really part of the API, but here's the docs. @@ -72,8 +36,6 @@ UINTVAL code_size; /* in opcodes */ opcode_t *code_end; - check_fingerprint(interpreter); - code_start = interpreter->code->byte_code; code_size = interpreter->code->byte_code_size / sizeof(opcode_t); code_end = interpreter->code->byte_code + code_size; @@ -89,146 +51,76 @@ /*=for api interpreter init_prederef * - * Dynamically load the prederef oplib so its opfuncs can be used in - * place of the standard ones. + * interpreter->op_lib = prederefed oplib * - * TODO: These static variables need to be moved into the interpreter - * structure, or something else smarter than this needs to be done - * with them. + * the "normal" op_lib has a copy in the interpreter structure */ -static void *prederef_oplib_handle = NULL; -static oplib_init_f prederef_oplib_init = (oplib_init_f)NULLfunc; -static op_lib_t *prederef_oplib = NULL; -static INTVAL prederef_op_count = 0; -static op_info_t *prederef_op_info = NULL; -static op_func_t *prederef_op_func = NULL; static void init_prederef(struct Parrot_Interp *interpreter) { -#ifndef DYNAMIC_OPLIBS extern op_lib_t *PARROT_CORE_PREDEREF_OPLIB_INIT(void); -#endif - char file_name[50]; - char func_name[50]; - UNUSED(interpreter); - -#ifdef DYNAMIC_OPLIBS - fprintf(stderr, "FIXME: Dynamic oplibs currently broken.\n"); - exit(0); -# if 0 - /* FIXME: This is platform specific code and needs to go elsewhere */ - - sprintf(file_name, "lib%s_prederef.so.%s", PARROT_CORE_OPLIB_NAME, - PARROT_VERSION); - - sprintf(func_name, "Parrot_DynOp_%s_prederef_%d_%d_%d", - PARROT_CORE_OPLIB_NAME, PARROT_MAJOR_VERSION, - PARROT_MINOR_VERSION, PARROT_PATCH_VERSION); - - /* - * Get a handle to the library file: - */ - - prederef_oplib_handle = Parrot_dlopen(file_name); - - if (!prederef_oplib_handle) { + interpreter->op_lib = PARROT_CORE_PREDEREF_OPLIB_INIT(); + if (interpreter->op_lib->op_count != interpreter->op_count) internal_exception(PREDEREF_LOAD_ERROR, - "Unable to dynamically load oplib file '%s' for oplib '%s_prederef' version %s!\n", - file_name, PARROT_CORE_OPLIB_NAME, PARROT_VERSION); - } + "Illegal op count (%d) in prederef oplib\n", + (int)interpreter->op_lib->op_count); +} - /* - * Look up the init function: +/*=for api interpreter load_oplib + * + * dynamically load an op_lib extension + * returns dll handle on success, else 0 + * + * TODO how do we run these ops */ - - prederef_oplib_init = - (oplib_init_f)(ptrcast_t)Parrot_dlsym(prederef_oplib_handle, -# endif - func_name); -#else - prederef_oplib_init = PARROT_CORE_PREDEREF_OPLIB_INIT; +#if 0 +void * +load_oplib(struct Parrot_Interp * interpreter, + const char *file, const char *init_func_name) +{ + void *handle = Parrot_dlopen(file); + oplib_init_f init_func; + op_lib_t *oplib; + + if (!handle) + internal_exception(1, "Could't load oplib file '%s': %s\n", + file, Parrot_dlerror()); + init_func = + (oplib_init_f)(ptrcast_t)Parrot_dlsym(handle, init_func_name); + if (!init_func) + internal_exception(1, "Invalid oplib, '%s' not exported\n", + init_func_name); + oplib = init_func(); + /* XXX now what + * if oplib is a prederefed oplib, and matches the current + * oplib, we would run it */ + return handle; +} #endif - if (!prederef_oplib_init) { - internal_exception(PREDEREF_LOAD_ERROR, - "No exported symbol for oplib init function '%s' from oplib file '%s' for oplib '%s_prederef' version %s!\n", - func_name, file_name, PARROT_CORE_OPLIB_NAME, - PARROT_VERSION); - } - - /* - * Run the init function to get the oplib info: - */ - - prederef_oplib = prederef_oplib_init(); - - if (!prederef_oplib) { - internal_exception(PREDEREF_LOAD_ERROR, - "No oplib info returned by oplib init function '%s' from oplib file '%s' for oplib '%s_prederef' version %s!\n", - func_name, file_name, PARROT_CORE_OPLIB_NAME, - PARROT_VERSION); - } - - /* - * Validate the op count: - */ - - prederef_op_count = prederef_oplib->op_count; - - if (prederef_op_count <= 0) { - internal_exception(PREDEREF_LOAD_ERROR, - "Illegal op count (%d) from oplib file '%s' for oplib '%s_prederef' version %s!\n", - (int)prederef_op_count, file_name, - PARROT_CORE_OPLIB_NAME, PARROT_VERSION); - } - - /* - * Validate the op info table: - */ - - prederef_op_info = prederef_oplib->op_info_table; - - if (!prederef_op_info) { - internal_exception(PREDEREF_LOAD_ERROR, - "No op info table in oplib file '%s' for oplib '%s_prederef' version %s!\n", - file_name, PARROT_CORE_OPLIB_NAME, PARROT_VERSION); - } - - /* - * Validate the op func table: +/*=for api interpreter unload_oplib + * + * unload op_lib extension */ - - prederef_op_func = prederef_oplib->op_func_table; - - if (!prederef_op_func) { - internal_exception(PREDEREF_LOAD_ERROR, - "No op func table in oplib file '%s' for oplib '%s_prederef' version %s!\n", - file_name, PARROT_CORE_OPLIB_NAME, PARROT_VERSION); - } +#if 0 +void +unload_oplib(void *handle) +{ + Parrot_dlclose(handle); } - +#endif /*=for api interpreter stop_prederef * * Unload the prederef oplib. */ static void -stop_prederef(void) +stop_prederef(struct Parrot_Interp *interpreter) { - prederef_op_func = NULL; - prederef_op_info = NULL; - prederef_op_count = 0; - -#ifdef DYNAMIC_OPLIBS - Parrot_dlclose(prederef_oplib_handle); -#endif - - prederef_oplib = NULL; - prederef_oplib_init = (oplib_init_f)NULLfunc; - prederef_oplib_handle = NULL; + interpreter->op_lib = PARROT_CORE_OPLIB_INIT(); } /*=for api interpreter prederef @@ -254,7 +146,8 @@ { size_t offset = pc_prederef - interpreter->prederef_code; opcode_t *pc = ((opcode_t *)interpreter->code->byte_code) + offset; - op_info_t *opinfo = &prederef_op_info[*pc]; + op_info_t *opinfo = &interpreter->op_lib->op_info_table[*pc]; + op_func_t *prederef_op_func = interpreter->op_lib->op_func_table; int i; for (i = 0; i < opinfo->arg_count; i++) { @@ -334,14 +227,18 @@ opcode_t *code_end; jit_f jit_code; - check_fingerprint(interpreter); - code_start = interpreter->code->byte_code; code_size = interpreter->code->byte_code_size / sizeof(opcode_t); code_end = interpreter->code->byte_code + code_size; jit_code = build_asm(interpreter, pc, code_start, code_end); (jit_code) (interpreter); + /* if we fall out of runloop with restart, there is + * currently no way, to continue in JIT, so stop it + * + * This is borken too, but better as endless loops + */ + Interp_flags_CLEAR(interpreter, PARROT_JIT_FLAG); #endif } @@ -373,8 +270,6 @@ opcode_t *code_end; void **code_start_prederef; - check_fingerprint(interpreter); - code_start = interpreter->code->byte_code; code_size = interpreter->code->byte_code_size / sizeof(opcode_t); code_end = interpreter->code->byte_code + code_size; @@ -389,7 +284,7 @@ interpreter); } - stop_prederef(); + stop_prederef(interpreter); if (pc_prederef == 0) { pc = 0; @@ -451,7 +346,7 @@ } } - if (Interp_flags_TEST(interpreter, PARROT_PREDEREF_FLAG)) { + if (!which && Interp_flags_TEST(interpreter, PARROT_PREDEREF_FLAG)) { offset = pc - (opcode_t *)interpreter->code->byte_code; if (!interpreter->prederef_code) {