# 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) {

Reply via email to