[svn:parrot] r40529 - in branches/pluggable_runcore: compilers/imcc config/gen/makefiles include/parrot src src/call src/interp src/ops src/pmc src/runcore t/run

chromatic at svn.parrot.org chromatic at svn.parrot.org
Thu Aug 13 21:34:57 UTC 2009


Author: chromatic
Date: Thu Aug 13 21:34:51 2009
New Revision: 40529
URL: https://trac.parrot.org/parrot/changeset/40529

Log:
Refactored runcore handling to improve encapsulation.

Added new Parrot_runcore_t struct and Parrot_runcore_register() function with
their supporting accoutrements.
Added Parrot_runcore_register() to register new runcores.
Added Parrot_runcore_t parameter to all runcore functions.
Moved runops functions to src/runcore/cores.c.
Used runcore names in embedding functions.
Added Parrot_runcore_switch() function to switch runcores.
Changed Parrot_set_run_core() to use Parrot_runcore_switch().
Modified IMCC to use Parrot_set_run_core() and RUNCORE flags, rather than
poking in runcores directly.
Fixed PCC to switch runcores appropriately.
Fixed run_sub() to use new runcore switching code.
Fixed the runcore switch in Parrot_set_flag() to use Parrot_runcore_switch().
Fixed most of t/run/options.t to run with new runcore changes.  In particular,
the trace runcore no longer enables CGP and JIT, if you have them.
Fixed coding standards violations.
Reheaderized code.
Made all runops functions static.

Modified:
   branches/pluggable_runcore/compilers/imcc/main.c
   branches/pluggable_runcore/config/gen/makefiles/root.in
   branches/pluggable_runcore/include/parrot/interpreter.h
   branches/pluggable_runcore/include/parrot/pic.h
   branches/pluggable_runcore/include/parrot/runcore_api.h
   branches/pluggable_runcore/src/call/pcc.c
   branches/pluggable_runcore/src/debug.c
   branches/pluggable_runcore/src/embed.c
   branches/pluggable_runcore/src/exec_start.c
   branches/pluggable_runcore/src/interp/inter_create.c
   branches/pluggable_runcore/src/interp/inter_misc.c
   branches/pluggable_runcore/src/ops/core.ops
   branches/pluggable_runcore/src/packfile.c
   branches/pluggable_runcore/src/parrot_debugger.c
   branches/pluggable_runcore/src/pic.c
   branches/pluggable_runcore/src/pic_jit.c
   branches/pluggable_runcore/src/pmc/parrotinterpreter.pmc
   branches/pluggable_runcore/src/runcore/cores.c
   branches/pluggable_runcore/src/runcore/main.c
   branches/pluggable_runcore/t/run/options.t

Modified: branches/pluggable_runcore/compilers/imcc/main.c
==============================================================================
--- branches/pluggable_runcore/compilers/imcc/main.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/compilers/imcc/main.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -33,6 +33,7 @@
 #include "parrot/embed.h"
 #include "parrot/longopt.h"
 #include "parrot/imcc.h"
+#include "parrot/runcore_api.h"
 #include "pbc.h"
 #include "parser.h"
 
@@ -279,7 +280,6 @@
 #define SET_FLAG(flag)   Parrot_set_flag(interp, (flag))
 #define SET_DEBUG(flag)  Parrot_set_debug(interp, (flag))
 #define SET_TRACE(flag)  Parrot_set_trace(interp, (flag))
-#define SET_CORE(core)   interp->run_core |= (core)
 
 #define OPT_GC_DEBUG       128
 #define OPT_DESTROY_FLAG   129
@@ -356,8 +356,10 @@
 const char *
 parseflags(PARROT_INTERP, int *argc, char **argv[])
 {
-    struct longopt_opt_info opt = LONGOPT_OPT_INFO_INIT;
-    int   status;
+    struct longopt_opt_info opt  = LONGOPT_OPT_INFO_INIT;
+    INTVAL                  core = 0;
+    int                     status;
+
     if (*argc == 1) {
         usage(stderr);
         exit(EXIT_SUCCESS);
@@ -370,34 +372,28 @@
         switch (opt.opt_id) {
             case 'R':
                 if (STREQ(opt.opt_arg, "slow") || STREQ(opt.opt_arg, "bounds"))
-                    SET_CORE(PARROT_SLOW_CORE);
+                    core |= PARROT_SLOW_CORE;
                 else if (STREQ(opt.opt_arg, "fast") || STREQ(opt.opt_arg, "function"))
-                    SET_CORE(PARROT_FAST_CORE);
+                    core |= PARROT_FAST_CORE;
                 else if (STREQ(opt.opt_arg, "switch"))
-                    SET_CORE(PARROT_SWITCH_CORE);
+                    core |= PARROT_SWITCH_CORE;
                 else if (STREQ(opt.opt_arg, "cgp"))
-                    SET_CORE(PARROT_CGP_CORE);
+                    core |= PARROT_CGP_CORE;
                 else if (STREQ(opt.opt_arg, "cgoto"))
-                    SET_CORE(PARROT_CGOTO_CORE);
+                    core |= PARROT_CGOTO_CORE;
                 else if (STREQ(opt.opt_arg, "jit"))
-                    SET_CORE(PARROT_JIT_CORE);
+                    core |= PARROT_JIT_CORE;
                 else if (STREQ(opt.opt_arg, "cgp-jit"))
-                    SET_CORE(PARROT_CGP_JIT_CORE);
+                    core |= PARROT_CGP_JIT_CORE;
                 else if (STREQ(opt.opt_arg, "switch-jit"))
-                    SET_CORE(PARROT_SWITCH_JIT_CORE);
+                    core |= PARROT_SWITCH_JIT_CORE;
                 else if (STREQ(opt.opt_arg, "exec"))
-                    SET_CORE(PARROT_EXEC_CORE);
+                    core |= PARROT_EXEC_CORE;
                 else if (STREQ(opt.opt_arg, "trace")) {
-                    SET_CORE(PARROT_SLOW_CORE);
-#ifdef HAVE_COMPUTED_GOTO
-                    SET_CORE(PARROT_CGP_CORE);
-#endif
-#if JIT_CAPABLE
-                    SET_CORE(PARROT_JIT_CORE);
-#endif
+                    core |= PARROT_SLOW_CORE;
                 }
                 else if (STREQ(opt.opt_arg, "gcdebug"))
-                    SET_CORE(PARROT_GC_DEBUG_CORE);
+                    core |= PARROT_GC_DEBUG_CORE;
                 else
                     Parrot_ex_throw_from_c_args(interp, NULL, 1,
                         "main: Unrecognized runcore '%s' specified."
@@ -498,7 +494,7 @@
                 IMCC_INFO(interp)->allocator = IMCC_GRAPH_ALLOCATOR;
                 /* currently not ok due to different register allocation */
                 if (strchr(opt.opt_arg, 'j')) {
-                    SET_CORE(PARROT_JIT_CORE);
+                    core |= PARROT_JIT_CORE;
                 }
                 if (strchr(opt.opt_arg, '1')) {
                     IMCC_INFO(interp)->optimizer_level |= OPT_PRE;
@@ -507,12 +503,12 @@
                     IMCC_INFO(interp)->optimizer_level |= (OPT_PRE | OPT_CFG);
                 }
                 if (strchr(opt.opt_arg, 't')) {
-                    SET_CORE(PARROT_SWITCH_CORE);
+                    core |= PARROT_SWITCH_CORE;
 #ifdef HAVE_COMPUTED_GOTO
-                    SET_CORE(PARROT_CGP_CORE);
+                    core |= PARROT_CGP_CORE;
 #endif
 #if JIT_CAPABLE
-                    SET_CORE(PARROT_JIT_CORE);
+                    core |= PARROT_JIT_CORE;
 #endif
                 }
                 break;
@@ -546,11 +542,13 @@
                     (*argv)[0]);
         }
     }
+
     if (status == -1) {
         fprintf(stderr, "%s\n", opt.opt_error);
         usage(stderr);
         exit(EX_USAGE);
     }
+
     /* reached the end of the option list and consumed all of argv */
     if (*argc == opt.opt_index) {
         if (interp->output_file) {
@@ -563,9 +561,11 @@
         usage(stderr);
         exit(EX_USAGE);
     }
+
     *argc -= opt.opt_index;
     *argv += opt.opt_index;
 
+    Parrot_set_run_core(interp, core);
     return (*argv)[0];
 }
 
@@ -719,10 +719,10 @@
     if (opt_level & OPT_SUB)
         opt_desc[i++] = 'c';
 
-    if (interp->run_core & PARROT_JIT_CORE)
+    if (PARROT_RUNCORE_JIT_OPS_TEST(interp->run_core))
         opt_desc[i++] = 'j';
 
-    if (interp->run_core & PARROT_SWITCH_CORE)
+    if (PARROT_RUNCORE_PREDEREF_OPS_TEST(interp->run_core))
         opt_desc[i++] = 't';
 
     opt_desc[i] = '\0';

Modified: branches/pluggable_runcore/config/gen/makefiles/root.in
==============================================================================
--- branches/pluggable_runcore/config/gen/makefiles/root.in	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/config/gen/makefiles/root.in	Thu Aug 13 21:34:51 2009	(r40529)
@@ -635,6 +635,7 @@
     $(SRC_DIR)/pmc.str \
     $(SRC_DIR)/pmc_freeze.str \
     $(SRC_DIR)/oo.str \
+    $(SRC_DIR)/runcore/cores.str \
     $(SRC_DIR)/scheduler.str \
     $(SRC_DIR)/spf_render.str \
     $(SRC_DIR)/spf_vtable.str \
@@ -1214,7 +1215,7 @@
 
 $(SRC_DIR)/gc/alloc_register$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/pmc/pmc_sub.h
 
-$(SRC_DIR)/runcore/cores$(O) : $(GENERAL_H_FILES)
+$(SRC_DIR)/runcore/cores$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/runcore/cores.str
 
 $(SRC_DIR)/stacks$(O) : $(GENERAL_H_FILES)
 

Modified: branches/pluggable_runcore/include/parrot/interpreter.h
==============================================================================
--- branches/pluggable_runcore/include/parrot/interpreter.h	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/include/parrot/interpreter.h	Thu Aug 13 21:34:51 2009	(r40529)
@@ -72,7 +72,8 @@
     PARROT_SWITCH_JIT_CORE  = 0x12,         /* J P                */
     PARROT_EXEC_CORE        = 0x20,         /* TODO Parrot_exec_run variants */
     PARROT_GC_DEBUG_CORE    = 0x40,         /* run GC before each op */
-    PARROT_DEBUGGER_CORE    = 0x80          /* used by parrot debugger */
+    PARROT_DEBUGGER_CORE    = 0x80,         /* used by parrot debugger */
+    PARROT_PROFILE_CORE     = 0x160         /* used by parrot debugger */
 } Parrot_Run_core_t;
 /* &end_gen */
 
@@ -339,7 +340,9 @@
 
     UINTVAL debug_flags;                      /* debug settings */
 
-    INTVAL run_core;                          /* type of core to run the ops */
+    struct runcore_t  *run_core;              /* type of core to run the ops */
+    struct runcore_t **cores;                 /* array of known runcores */
+    UINTVAL            num_cores;             /* number of known runcores */
 
     /* TODO profile per code segment or global */
     RunProfile *profile;                      /* profile counters */
@@ -696,8 +699,7 @@
     void *prederef_arena);
 void prepare_for_run(PARROT_INTERP);
 void *init_jit(PARROT_INTERP, opcode_t *pc);
-PARROT_EXPORT void dynop_register(PARROT_INTERP, PMC* op_lib);
-void do_prederef(void **pc_prederef, PARROT_INTERP, int type);
+PARROT_EXPORT void dynop_register(PARROT_INTERP, PMC *op_lib);
 
 /* interpreter.pmc */
 void clone_interpreter(Parrot_Interp dest, Parrot_Interp self, INTVAL flags);

Modified: branches/pluggable_runcore/include/parrot/pic.h
==============================================================================
--- branches/pluggable_runcore/include/parrot/pic.h	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/include/parrot/pic.h	Thu Aug 13 21:34:51 2009	(r40529)
@@ -13,6 +13,8 @@
 #ifndef PARROT_PIC_H_GUARD
 #define PARROT_PIC_H_GUARD
 
+#include "parrot/runcore_api.h"
+
 /*
  * one cache slot
  *
@@ -125,9 +127,10 @@
 void parrot_PIC_prederef(PARROT_INTERP,
     opcode_t op,
     ARGOUT(void **pc_pred),
-    int core)
+    ARGIN(Parrot_runcore_t *core))
         __attribute__nonnull__(1)
         __attribute__nonnull__(3)
+        __attribute__nonnull__(4)
         FUNC_MODIFIES(*pc_pred);
 
 #define ASSERT_ARGS_parrot_PIC_alloc_mic __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
@@ -153,7 +156,8 @@
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_parrot_PIC_prederef __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc_pred)
+    || PARROT_ASSERT_ARG(pc_pred) \
+    || PARROT_ASSERT_ARG(core)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/pic.c */
 

Modified: branches/pluggable_runcore/include/parrot/runcore_api.h
==============================================================================
--- branches/pluggable_runcore/include/parrot/runcore_api.h	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/include/parrot/runcore_api.h	Thu Aug 13 21:34:51 2009	(r40529)
@@ -9,11 +9,66 @@
 #ifndef PARROT_RUNCORE_API_H_GUARD
 #define PARROT_RUNCORE_API_H_GUARD
 
+struct runcore_t;
+typedef struct runcore_t Parrot_runcore_t;
+
 #include "parrot/parrot.h"
 #include "parrot/op.h"
 
 #  define DO_OP(PC, INTERP) ((PC) = (((INTERP)->op_func_table)[*(PC)])((PC), (INTERP)))
 
+typedef opcode_t * (*runcore_runops_fn_type)(PARROT_INTERP, ARGIN(Parrot_runcore_t *), ARGIN(opcode_t *pc));
+typedef       void (*runcore_destroy_fn_type)(PARROT_INTERP, ARGIN(Parrot_runcore_t *));
+typedef     void * (*runcore_prepare_fn_type)(PARROT_INTERP, ARGIN(Parrot_runcore_t *));
+
+struct runcore_t {
+    STRING                  *name;
+    oplib_init_f             opinit;
+    runcore_runops_fn_type   runops;
+    runcore_destroy_fn_type  destroy;
+    runcore_prepare_fn_type  prepare_run;
+    INTVAL                   flags;
+};
+
+typedef enum Parrot_runcore_flags {
+    RUNCORE_REENTRANT_FLAG    = 1 << 0,
+    RUNCORE_FUNC_TABLE_FLAG   = 1 << 1,
+    RUNCORE_EVENT_CHECK_FLAG  = 1 << 2,
+    RUNCORE_PREDEREF_OPS_FLAG = 1 << 3,
+    RUNCORE_CGOTO_OPS_FLAG    = 1 << 4,
+    RUNCORE_JIT_OPS_FLAG      = 1 << 5
+} Parrot_runcore_flags;
+
+#define Runcore_flag_SET(runcore, flag) \
+    ((runcore)->flags |= flag)
+#define Runcore_flag_TEST(runcore, flag) \
+    ((runcore)->flags & flag)
+
+#define PARROT_RUNCORE_FUNC_TABLE_TEST(runcore) \
+    Runcore_flag_TEST(runcore, RUNCORE_FUNC_TABLE_FLAG)
+#define PARROT_RUNCORE_FUNC_TABLE_SET(runcore) \
+    Runcore_flag_SET(runcore, RUNCORE_FUNC_TABLE_FLAG)
+
+#define PARROT_RUNCORE_EVENT_CHECK_TEST(runcore) \
+    Runcore_flag_TEST(runcore, RUNCORE_EVENT_CHECK_FLAG)
+#define PARROT_RUNCORE_EVENT_CHECK_SET(runcore) \
+    Runcore_flag_SET(runcore, RUNCORE_EVENT_CHECK_FLAG)
+
+#define PARROT_RUNCORE_PREDEREF_OPS_TEST(runcore) \
+    Runcore_flag_TEST(runcore, RUNCORE_PREDEREF_OPS_FLAG)
+#define PARROT_RUNCORE_PREDEREF_OPS_SET(runcore) \
+    Runcore_flag_SET(runcore, RUNCORE_PREDEREF_OPS_FLAG)
+
+#define PARROT_RUNCORE_CGOTO_OPS_TEST(runcore) \
+    Runcore_flag_TEST(runcore, RUNCORE_CGOTO_OPS_FLAG)
+#define PARROT_RUNCORE_CGOTO_OPS_SET(runcore) \
+    Runcore_flag_SET(runcore, RUNCORE_CGOTO_OPS_FLAG)
+
+#define PARROT_RUNCORE_JIT_OPS_TEST(runcore) \
+    Runcore_flag_TEST(runcore, RUNCORE_JIT_OPS_FLAG)
+#define PARROT_RUNCORE_JIT_OPS_SET(runcore) \
+    Runcore_flag_SET(runcore, RUNCORE_JIT_OPS_FLAG)
+
 /* HEADERIZER BEGIN: src/runcore/main.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
@@ -25,10 +80,25 @@
 void enable_event_checking(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-void do_prederef(ARGIN(void **pc_prederef), PARROT_INTERP, int type)
+PARROT_EXPORT
+INTVAL Parrot_runcore_register(PARROT_INTERP,
+    ARGIN(const Parrot_runcore_t *coredata))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_runcore_switch(PARROT_INTERP, ARGIN(STRING *name))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+void do_prederef(
+    ARGIN(void **pc_prederef),
+    PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
 void dynop_register(PARROT_INTERP, ARGIN(PMC *lib_pmc))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -45,6 +115,9 @@
 void Parrot_runcore_destroy(PARROT_INTERP)
         __attribute__nonnull__(1);
 
+void Parrot_runcore_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
 void Parrot_setup_event_func_ptrs(PARROT_INTERP)
         __attribute__nonnull__(1);
 
@@ -58,9 +131,16 @@
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_enable_event_checking __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_register __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(coredata)
+#define ASSERT_ARGS_Parrot_runcore_switch __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(name)
 #define ASSERT_ARGS_do_prederef __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(pc_prederef) \
-    || PARROT_ASSERT_ARG(interp)
+    || PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore)
 #define ASSERT_ARGS_dynop_register __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(lib_pmc)
@@ -71,6 +151,8 @@
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_runcore_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_setup_event_func_ptrs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_prepare_for_run __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -84,70 +166,98 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
 PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-opcode_t * runops_cgoto_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+PARROT_CANNOT_RETURN_NULL
+oplib_init_f get_core_op_lib_init(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-opcode_t * runops_debugger_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+PARROT_CANNOT_RETURN_NULL
+void * init_jit_run(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-opcode_t * runops_fast_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+void * init_prederef(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-opcode_t * runops_gc_debug_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+void load_prederef(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-opcode_t * runops_profile_core(PARROT_INTERP, ARGIN(opcode_t *pc))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
+void Parrot_runcore_cgoto_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-opcode_t * runops_slow_core(PARROT_INTERP, ARGIN(opcode_t *pc))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
+void Parrot_runcore_cgp_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
 
-#define ASSERT_ARGS_runops_cgoto_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc)
-#define ASSERT_ARGS_runops_debugger_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc)
-#define ASSERT_ARGS_runops_fast_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+void Parrot_runcore_cgp_jit_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_runcore_debugger_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_runcore_exec_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_runcore_fast_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_runcore_gc_debug_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_runcore_jit_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_runcore_slow_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_runcore_switch_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+void Parrot_runcore_switch_jit_init(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+#define ASSERT_ARGS_get_core_op_lib_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc)
-#define ASSERT_ARGS_runops_gc_debug_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+    || PARROT_ASSERT_ARG(runcore)
+#define ASSERT_ARGS_init_jit_run __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc)
-#define ASSERT_ARGS_runops_profile_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+    || PARROT_ASSERT_ARG(runcore)
+#define ASSERT_ARGS_init_prederef __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc)
-#define ASSERT_ARGS_runops_slow_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+    || PARROT_ASSERT_ARG(runcore)
+#define ASSERT_ARGS_load_prederef __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc)
+    || PARROT_ASSERT_ARG(runcore)
+#define ASSERT_ARGS_Parrot_runcore_cgoto_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_cgp_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_cgp_jit_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_debugger_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_exec_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_fast_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_gc_debug_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_jit_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_slow_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_switch_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_runcore_switch_jit_init \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/runcore/cores.c */
 
-opcode_t *runops_fast_core(PARROT_INTERP, opcode_t *);
-
-opcode_t *runops_cgoto_core(PARROT_INTERP, opcode_t *);
-
-opcode_t *runops_slow_core(PARROT_INTERP, opcode_t *);
-
-opcode_t *runops_profile_core(PARROT_INTERP, opcode_t *);
-
 #endif /* PARROT_RUNCORE_API_H_GUARD */
 
 

Modified: branches/pluggable_runcore/src/call/pcc.c
==============================================================================
--- branches/pluggable_runcore/src/call/pcc.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/call/pcc.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -19,6 +19,7 @@
 
 #include "parrot/parrot.h"
 #include "parrot/oplib/ops.h"
+#include "parrot/runcore_api.h"
 #include "pcc.str"
 #include "../pmc/pmc_key.h"
 #include "../pmc/pmc_continuation.h"
@@ -3010,17 +3011,15 @@
     /* Invoke the function */
     dest = VTABLE_invoke(interp, sub_obj, NULL);
 
-    /* PIR Subs need runops to run their opcodes. Methods and NCI subs
-     * don't. */
+    /* PIR Subs need runops to run their opcodes. Methods and NCI subs don't. */
     if (sub_obj->vtable->base_type == enum_class_Sub
-            && PMC_IS_NULL(interp->current_object)) {
-        const INTVAL old_core = interp->run_core;
-        const opcode_t offset = dest - interp->code->base.data;
+    &&  PMC_IS_NULL(interp->current_object)) {
+        Parrot_runcore_t *old_core = interp->run_core;
+        const opcode_t    offset   = dest - interp->code->base.data;
 
         /* can't re-enter the runloop from here with PIC cores: RT #60048 */
-        if (interp->run_core == PARROT_CGP_CORE
-        ||  interp->run_core == PARROT_SWITCH_CORE)
-            interp->run_core = PARROT_SLOW_CORE;
+        if (PARROT_RUNCORE_PREDEREF_OPS_TEST(interp->run_core))
+            Parrot_runcore_switch(interp, CONST_STRING(interp, "slow"));
 
         runops(interp, offset);
         interp->run_core = old_core;

Modified: branches/pluggable_runcore/src/debug.c
==============================================================================
--- branches/pluggable_runcore/src/debug.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/debug.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -1422,8 +1422,9 @@
         pdb->state |= PDB_STOPPED;
         return;
     }
+
     pdb->tracing = n;
-    pdb->debugee->run_core = PARROT_DEBUGGER_CORE;
+    Parrot_runcore_switch(pdb->debugee, CONST_STRING(interp, "debugger"));
 
     TRACEDEB_MSG("PDB_next finished");
 }
@@ -1469,8 +1470,8 @@
         return;
     }
     pdb->tracing = n;
-    pdb->debugee->run_core = PARROT_DEBUGGER_CORE;
-    pdb->state |= PDB_TRACING;
+    pdb->state  |= PDB_TRACING;
+    Parrot_runcore_switch(pdb->debugee, CONST_STRING(interp, "debugger"));
 
     /* Clear the following when done some testing */
 
@@ -1927,8 +1928,9 @@
     */
 
     #if 0
-    pdb->tracing = 0;
-    pdb->debugee->run_core = PARROT_DEBUGGER_CORE;
+    pdb->tracing           = 0;
+    Parrot_runcore_switch(pdb->debugee, CONST_STRING(interp, "debugger"));
+
     new_internal_exception(pdb->debugee);
     if (setjmp(pdb->debugee->exceptions->destination)) {
         Parrot_eprintf(pdb->debugee, "Unhandled exception while debugging: %Ss\n",

Modified: branches/pluggable_runcore/src/embed.c
==============================================================================
--- branches/pluggable_runcore/src/embed.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/embed.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -22,6 +22,7 @@
 #include "parrot/embed.h"
 #include "parrot/oplib/ops.h"
 #include "pmc/pmc_sub.h"
+#include "parrot/runcore_api.h"
 
 #include "../compilers/imcc/imc.h"
 
@@ -157,7 +158,7 @@
     switch (flag) {
         case PARROT_BOUNDS_FLAG:
         case PARROT_PROFILE_FLAG:
-            Interp_core_SET(interp, PARROT_SLOW_CORE);
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "slow"));
             break;
         default:
             break;
@@ -220,7 +221,7 @@
 Parrot_set_trace(PARROT_INTERP, UINTVAL flag)
 {
     CONTEXT(interp)->trace_flags |= flag;
-    Interp_core_SET(interp, PARROT_SLOW_CORE);
+    Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "slow"));
 }
 
 
@@ -346,7 +347,44 @@
 void
 Parrot_set_run_core(PARROT_INTERP, Parrot_Run_core_t core)
 {
-    Interp_core_SET(interp, core);
+    switch (core) {
+        case PARROT_SLOW_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "slow"));
+            break;
+        case PARROT_FAST_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "fast"));
+            break;
+        case PARROT_SWITCH_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "switch"));
+            break;
+        case PARROT_CGP_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "cgp"));
+            break;
+        case PARROT_CGOTO_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "cgoto"));
+            break;
+        case PARROT_JIT_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "jit"));
+            break;
+        case PARROT_CGP_JIT_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "cgp_jit"));
+            break;
+        case PARROT_SWITCH_JIT_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "switch_jit"));
+            break;
+        case PARROT_EXEC_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "exec"));
+            break;
+        case PARROT_GC_DEBUG_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "gc_debug"));
+            break;
+        case PARROT_DEBUGGER_CORE:
+            Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "debugger"));
+            break;
+        default:
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNIMPLEMENTED,
+                "Invalid runcore requested\n");
+    }
 }
 
 
@@ -829,38 +867,8 @@
         if (Interp_trace_TEST(interp, PARROT_TRACE_OPS_FLAG))
             Parrot_io_eprintf(interp, "*** Parrot VM: Tracing enabled. ***\n");
 
-        Parrot_io_eprintf(interp, "*** Parrot VM: ");
-
-        switch (interp->run_core) {
-            case PARROT_SLOW_CORE:
-                Parrot_io_eprintf(interp, "Slow core");
-                break;
-            case PARROT_FAST_CORE:
-                Parrot_io_eprintf(interp, "Fast core");
-                break;
-            case PARROT_SWITCH_CORE:
-            case PARROT_SWITCH_JIT_CORE:
-                Parrot_io_eprintf(interp, "Switch core");
-                break;
-            case PARROT_CGP_CORE:
-            case PARROT_CGP_JIT_CORE:
-                Parrot_io_eprintf(interp, "CGP core");
-                break;
-            case PARROT_CGOTO_CORE:
-                Parrot_io_eprintf(interp, "CGoto core");
-                break;
-            case PARROT_JIT_CORE:
-                Parrot_io_eprintf(interp, "JIT core");
-                break;
-            case PARROT_EXEC_CORE:
-                Parrot_io_eprintf(interp, "EXEC core");
-                break;
-            default:
-                Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                     "Unknown run core");
-        }
-
-        Parrot_io_eprintf(interp, " ***\n");
+        Parrot_io_eprintf(interp, "*** Parrot VM: %Ss core ***\n",
+                interp->run_core->name);
     }
 
     /* Set up @ARGS (or whatever this language calls it) in userargv. */
@@ -869,7 +877,8 @@
 #if EXEC_CAPABLE
 
     /* s. runops_exec interpreter.c */
-    if (Interp_core_TEST(interp, PARROT_EXEC_CORE))
+    if (Parrot_str_equal(interp, interp->run_core->name,
+        Parrot_str_new_constant(interp, "exec")))
         Parrot_exec_run = 1;
 
 #endif

Modified: branches/pluggable_runcore/src/exec_start.c
==============================================================================
--- branches/pluggable_runcore/src/exec_start.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/exec_start.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 2001-2006, Parrot Foundation.
+Copyright (C) 2001-2009, Parrot Foundation.
 $Id$
 
 =head1 NAME
@@ -97,7 +97,7 @@
 #if defined(JIT_CGP)
     exec_init_prederef(interp, &exec_prederef_code);
 #endif
-    /* Parrot_set_run_core(interp, PARROT_EXEC_CORE);
+    /* Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "exec"));
     interp->code->base.data =
         (opcode_t *)&((&program_code)[bytecode_offset]);
     Parrot_exec_run = 0; */

Modified: branches/pluggable_runcore/src/interp/inter_create.c
==============================================================================
--- branches/pluggable_runcore/src/interp/inter_create.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/interp/inter_create.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -221,6 +221,9 @@
     CONTEXT(interp)->current_cont   = NULL;
     CONTEXT(interp)->current_object = NULL;
 
+    /* initialize built-in runcores */
+    Parrot_runcore_init(interp);
+
     /* Load the core op func and info tables */
     interp->op_lib          = PARROT_CORE_OPLIB_INIT(1);
     interp->op_count        = interp->op_lib->op_count;

Modified: branches/pluggable_runcore/src/interp/inter_misc.c
==============================================================================
--- branches/pluggable_runcore/src/interp/inter_misc.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/interp/inter_misc.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -256,8 +256,35 @@
             ret = Parrot_gc_extended_pmcs(interp);
             break;
         case CURRENT_RUNCORE:
-            ret = interp->run_core;
+        {
+            STRING *name = interp->run_core->name;
+
+            if (Parrot_str_equal(interp, name, CONST_STRING(interp, "slow")))
+                ret = PARROT_SLOW_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "fast")))
+                ret = PARROT_FAST_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "switch")))
+                ret = PARROT_SWITCH_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "cgp")))
+                ret = PARROT_CGP_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "cgoto")))
+                ret = PARROT_CGOTO_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "jit")))
+                ret = PARROT_JIT_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "cgp_jit")))
+                ret = PARROT_CGP_JIT_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "switch_jit")))
+                ret = PARROT_SWITCH_JIT_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "exec")))
+                ret = PARROT_EXEC_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "gc_debug")))
+                ret = PARROT_GC_DEBUG_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "debugger")))
+                ret = PARROT_DEBUGGER_CORE;
+            else if (Parrot_str_equal(interp, name, CONST_STRING(interp, "profile")))
+                ret = PARROT_PROFILE_CORE;
             break;
+        }
         default:        /* or a warning only? */
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNIMPLEMENTED,
                 "illegal argument in interpinfo");

Modified: branches/pluggable_runcore/src/ops/core.ops
==============================================================================
--- branches/pluggable_runcore/src/ops/core.ops	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/ops/core.ops	Thu Aug 13 21:34:51 2009	(r40529)
@@ -111,7 +111,7 @@
        we want to throw an error. Seriously people: Do not use this opcode
        directly in PIR. Ever. It absolutely makes no sense and it doesn't do
        anything productive. You've been warned. */
-    if (interp->run_core & PARROT_JIT_CORE) {
+   if (PARROT_RUNCORE_JIT_OPS_TEST(interp->run_core)) {
 #ifdef __GNUC__
 #  ifdef I386
         __asm__("ret");
@@ -148,12 +148,12 @@
 
 inline op prederef__() :internal :flow {
     opcode_t * const _this = CUR_OPCODE;
-    if (interp->run_core & PARROT_CGOTO_CORE) {
+    if (PARROT_RUNCORE_CGOTO_OPS_TEST(interp->run_core)) {
         /* must be CGP then - check for events in not yet prederefed code */
         Parrot_cx_runloop_wake(interp, interp->scheduler);
     /*    _this = CHECK_EVENTS(interp, _this); */
     }
-    do_prederef((void**)cur_opcode, interp, op_lib.core_type);
+    do_prederef((void**)cur_opcode, interp, interp->run_core);
     goto ADDRESS(_this); /* force this being a branch op */
 }
 

Modified: branches/pluggable_runcore/src/packfile.c
==============================================================================
--- branches/pluggable_runcore/src/packfile.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/packfile.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -27,6 +27,7 @@
 #include "parrot/parrot.h"
 #include "parrot/embed.h"
 #include "parrot/packfile.h"
+#include "parrot/runcore_api.h"
 #include "jit.h"
 #include "../compilers/imcc/imc.h"
 #include "packfile.str"
@@ -671,20 +672,19 @@
 run_sub(PARROT_INTERP, ARGIN(PMC *sub_pmc))
 {
     ASSERT_ARGS(run_sub)
-    const INTVAL old = interp->run_core;
-    PMC *retval;
+    Parrot_runcore_t *old_core = interp->run_core;
+    PMC              *retval;
 
     /* turn off JIT and prederef - both would act on the whole
      * PackFile which probably isn't worth the effort */
-    if (interp->run_core != PARROT_CGOTO_CORE
-    &&  interp->run_core != PARROT_SLOW_CORE
-    &&  interp->run_core != PARROT_FAST_CORE)
-            interp->run_core = PARROT_FAST_CORE;
+    if (PARROT_RUNCORE_JIT_OPS_TEST(interp->run_core)
+    ||  PARROT_RUNCORE_PREDEREF_OPS_TEST(interp->run_core))
+        Parrot_runcore_switch(interp, CONST_STRING(interp, "fast"));
 
     CONTEXT(interp)->constants = interp->code->const_table->constants;
 
     retval           = (PMC *)Parrot_runops_fromc_args(interp, sub_pmc, "P");
-    interp->run_core = old;
+    interp->run_core = old_core;
 
     return retval;
 }

Modified: branches/pluggable_runcore/src/parrot_debugger.c
==============================================================================
--- branches/pluggable_runcore/src/parrot_debugger.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/parrot_debugger.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -232,10 +232,9 @@
     else
         PDB_printwelcome();
 
-    interp->run_core = PARROT_DEBUGGER_CORE;
+    Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "debugger"));
     PDB_run_code(interp, argc - nextarg, argv + nextarg);
 
-
     Parrot_exit(interp, 0);
 }
 

Modified: branches/pluggable_runcore/src/pic.c
==============================================================================
--- branches/pluggable_runcore/src/pic.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/pic.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -78,6 +78,7 @@
 
 #include "parrot/parrot.h"
 #include "parrot/oplib/ops.h"
+#include "parrot/runcore_api.h"
 #include "pmc/pmc_fixedintegerarray.h"
 #include "pmc/pmc_continuation.h"
 #ifdef HAVE_COMPUTED_GOTO
@@ -109,10 +110,11 @@
 static int is_pic_func(PARROT_INTERP,
     ARGIN(void **pc),
     ARGOUT(Parrot_MIC *mic),
-    int core_type)
+    ARGIN(Parrot_runcore_t *runcore))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
+        __attribute__nonnull__(4)
         FUNC_MODIFIES(*mic);
 
 static int is_pic_param(PARROT_INTERP,
@@ -197,7 +199,8 @@
 #define ASSERT_ARGS_is_pic_func __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pc) \
-    || PARROT_ASSERT_ARG(mic)
+    || PARROT_ASSERT_ARG(mic) \
+    || PARROT_ASSERT_ARG(runcore)
 #define ASSERT_ARGS_is_pic_param __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pc) \
@@ -417,9 +420,10 @@
 #ifdef HAVE_COMPUTED_GOTO
     op_lib_t *cg_lib;
 #endif
-    const int core = interp->run_core;
+    const Parrot_runcore_t *core = interp->run_core;
 
-    if (core == PARROT_SWITCH_CORE || core == PARROT_SWITCH_JIT_CORE)
+    if (PARROT_RUNCORE_PREDEREF_OPS_TEST(core)
+    && !PARROT_RUNCORE_CGOTO_OPS_TEST(core))
         return (void *)op;
 #ifdef HAVE_COMPUTED_GOTO
     cg_lib = PARROT_CORE_CGP_OPLIB_INIT(1);
@@ -427,6 +431,7 @@
 #else
     return NULL;
 #endif
+
 }
 
 /*
@@ -766,15 +771,16 @@
 
 /*
 
-=item C<static int is_pic_func(PARROT_INTERP, void **pc, Parrot_MIC *mic, int
-core_type)>
+=item C<static int is_pic_func(PARROT_INTERP, void **pc, Parrot_MIC *mic,
+Parrot_runcore_t *runcore)>
 
 =cut
 
 */
 
 static int
-is_pic_func(PARROT_INTERP, ARGIN(void **pc), ARGOUT(Parrot_MIC *mic), int core_type)
+is_pic_func(PARROT_INTERP, ARGIN(void **pc), ARGOUT(Parrot_MIC *mic),
+            ARGIN(Parrot_runcore_t *runcore))
 {
     ASSERT_ARGS(is_pic_func)
     /*
@@ -811,7 +817,7 @@
     if (*op != PARROT_OP_set_p_pc)
         return 0;
 
-    do_prederef(pc, interp, core_type);
+    do_prederef(pc, interp, runcore);
     sub = (PMC *)(pc[2]);
 
     PARROT_ASSERT(PObj_is_PMC_TEST(sub));
@@ -825,7 +831,7 @@
     if (*op != PARROT_OP_get_results_pc)
         return 0;
 
-    do_prederef(pc, interp, core_type);
+    do_prederef(pc, interp, runcore);
     sig_results = (PMC *)(pc[1]);
     ASSERT_SIG_PMC(sig_results);
 
@@ -841,8 +847,8 @@
 
 /*
 
-=item C<void parrot_PIC_prederef(PARROT_INTERP, opcode_t op, void **pc_pred, int
-core)>
+=item C<void parrot_PIC_prederef(PARROT_INTERP, opcode_t op, void **pc_pred,
+Parrot_runcore_t *core)>
 
 Define either the normal prederef function or the PIC stub, if PIC for
 this opcode function is available. Called from C<do_prederef>.
@@ -852,7 +858,8 @@
 */
 
 void
-parrot_PIC_prederef(PARROT_INTERP, opcode_t op, ARGOUT(void **pc_pred), int core)
+parrot_PIC_prederef(PARROT_INTERP, opcode_t op, ARGOUT(void **pc_pred),
+    ARGIN(Parrot_runcore_t *core))
 {
     ASSERT_ARGS(parrot_PIC_prederef)
     op_func_t * const prederef_op_func = interp->op_lib->op_func_table;
@@ -897,7 +904,8 @@
     }
 
     /* rewrite opcode */
-    if (core == PARROT_SWITCH_CORE || core == PARROT_SWITCH_JIT_CORE)
+    if (PARROT_RUNCORE_PREDEREF_OPS_TEST(core)
+    && !PARROT_RUNCORE_CGOTO_OPS_TEST(core))
         *pc_pred = (void **)op;
     else
         *pc_pred = ((void **)prederef_op_func)[op];

Modified: branches/pluggable_runcore/src/pic_jit.c
==============================================================================
--- branches/pluggable_runcore/src/pic_jit.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/pic_jit.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -34,6 +34,7 @@
 #include "parrot/parrot.h"
 #include "parrot/oplib/ops.h"
 #include "pmc/pmc_sub.h"
+#include "parrot/runcore_api.h"
 
 /* HEADERIZER HFILE: include/parrot/pic.h */
 
@@ -488,7 +489,7 @@
      * 0) if runcore setting doesn't contain JIT
      *    forget it
      */
-    if (!(interp->run_core & PARROT_JIT_CORE))
+    if (!(PARROT_RUNCORE_JIT_OPS_TEST(interp->run_core)))
         return 0;
 
     /* 1) if the JIT system can't JIT_CODE_SUB_REGS_ONLY

Modified: branches/pluggable_runcore/src/pmc/parrotinterpreter.pmc
==============================================================================
--- branches/pluggable_runcore/src/pmc/parrotinterpreter.pmc	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/pmc/parrotinterpreter.pmc	Thu Aug 13 21:34:51 2009	(r40529)
@@ -28,6 +28,7 @@
 #include "parrot/embed.h"
 #include "parrot/dynext.h"
 #include "parrot/io.h"
+#include "parrot/runcore_api.h"
 #include "pmc_class.h"
 #include "pmc_sub.h"
 
@@ -55,8 +56,9 @@
     d->scheduler = pmc_new(d, enum_class_Scheduler);
     d->scheduler = VTABLE_share_ro(d, d->scheduler);
 
+    /* can't copy directly, unless you want double-frees */
     if (flags & PARROT_CLONE_RUNOPS)
-        d->run_core = s->run_core;
+        Parrot_runcore_switch(d, s->run_core->name);
 
     if (flags & PARROT_CLONE_INTERP_FLAGS) {
         /* XXX setting of IS_THREAD? */

Modified: branches/pluggable_runcore/src/runcore/cores.c
==============================================================================
--- branches/pluggable_runcore/src/runcore/cores.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/runcore/cores.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -241,9 +241,21 @@
 #include "parrot/runcore_api.h"
 #include "parrot/embed.h"
 #include "parrot/runcore_trace.h"
+#include "cores.str"
+
+#include "parrot/oplib/ops.h"
+#include "parrot/oplib/core_ops.h"
+#include "parrot/oplib/core_ops_switch.h"
+#include "parrot/dynext.h"
 
 #ifdef HAVE_COMPUTED_GOTO
 #  include "parrot/oplib/core_ops_cg.h"
+#  include "parrot/oplib/core_ops_cgp.h"
+#endif
+
+#if JIT_CAPABLE
+#  include "parrot/exec.h"
+#  include "../jit.h"
 #endif
 
 /* HEADERIZER HFILE: include/parrot/runcore_api.h */
@@ -253,19 +265,473 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-static opcode_t * runops_trace_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+static opcode_t * runops_cgoto_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static opcode_t * runops_cgp_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static opcode_t * runops_debugger_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static opcode_t * runops_exec_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static opcode_t * runops_fast_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static opcode_t * runops_gc_debug_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static opcode_t * runops_jit_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
 
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static opcode_t * runops_profile_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static opcode_t * runops_slow_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static opcode_t * runops_switch_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static opcode_t * runops_trace_core(PARROT_INTERP,
+    ARGIN(Parrot_runcore_t *runcore),
+    ARGIN(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+#define ASSERT_ARGS_runops_cgoto_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
+    || PARROT_ASSERT_ARG(pc)
+#define ASSERT_ARGS_runops_cgp_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
+    || PARROT_ASSERT_ARG(pc)
+#define ASSERT_ARGS_runops_debugger_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
+    || PARROT_ASSERT_ARG(pc)
+#define ASSERT_ARGS_runops_exec_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
+    || PARROT_ASSERT_ARG(pc)
+#define ASSERT_ARGS_runops_fast_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
+    || PARROT_ASSERT_ARG(pc)
+#define ASSERT_ARGS_runops_gc_debug_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
+    || PARROT_ASSERT_ARG(pc)
+#define ASSERT_ARGS_runops_jit_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
+    || PARROT_ASSERT_ARG(pc)
+#define ASSERT_ARGS_runops_profile_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
+    || PARROT_ASSERT_ARG(pc)
+#define ASSERT_ARGS_runops_slow_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
+    || PARROT_ASSERT_ARG(pc)
+#define ASSERT_ARGS_runops_switch_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
+    || PARROT_ASSERT_ARG(pc)
 #define ASSERT_ARGS_runops_trace_core __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(runcore) \
     || PARROT_ASSERT_ARG(pc)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
+
+/*
+
+=item C<void Parrot_runcore_slow_init(PARROT_INTERP)>
+
+Registers the slow runcore with Parrot.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_slow_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_slow_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "slow");
+    coredata->opinit           = PARROT_CORE_OPLIB_INIT;
+    coredata->runops           = runops_slow_core;
+    coredata->prepare_run      = NULL;
+    coredata->destroy          = NULL;
+
+    PARROT_RUNCORE_FUNC_TABLE_SET(coredata);
+
+    Parrot_runcore_register(interp, coredata);
+
+    /* it's the first runcore and the default runcore */
+    Parrot_runcore_switch(interp, coredata->name);
+}
+
+
+/*
+
+=item C<void Parrot_runcore_fast_init(PARROT_INTERP)>
+
+Registers the fast runcore with Parrot.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_fast_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_fast_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "fast");
+    coredata->opinit           = PARROT_CORE_OPLIB_INIT;
+    coredata->runops           = runops_fast_core;
+    coredata->destroy          = NULL;
+    coredata->prepare_run      = NULL;
+
+    PARROT_RUNCORE_FUNC_TABLE_SET(coredata);
+
+    Parrot_runcore_register(interp, coredata);
+}
+
+
+/*
+
+=item C<void Parrot_runcore_switch_init(PARROT_INTERP)>
+
+Registers the switch runcore with Parrot.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_switch_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_switch_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "switch");
+    coredata->opinit           = PARROT_CORE_SWITCH_OPLIB_INIT;
+    coredata->runops           = runops_switch_core;
+    coredata->prepare_run      = init_prederef;
+    coredata->destroy          = NULL;
+
+    PARROT_RUNCORE_PREDEREF_OPS_SET(coredata);
+
+    Parrot_runcore_register(interp, coredata);
+}
+
+
+/*
+
+=item C<void Parrot_runcore_jit_init(PARROT_INTERP)>
+
+Registers the jit runcore with Parrot.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_jit_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_jit_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "jit");
+    coredata->opinit           = PARROT_CORE_OPLIB_INIT;
+    coredata->prepare_run      = init_jit_run;
+    coredata->runops           = runops_jit_core;
+    coredata->destroy          = NULL;
+
+    PARROT_RUNCORE_JIT_OPS_SET(coredata);
+
+    Parrot_runcore_register(interp, coredata);
+}
+
+
+/*
+
+=item C<void Parrot_runcore_switch_jit_init(PARROT_INTERP)>
+
+Registers the switch_jit runcore with Parrot.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_switch_jit_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_switch_jit_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "switch_jit");
+    coredata->opinit           = PARROT_CORE_SWITCH_OPLIB_INIT;
+    coredata->destroy          = NULL;
+    coredata->prepare_run      = init_prederef;
+    coredata->runops           = runops_switch_core;
+
+    PARROT_RUNCORE_PREDEREF_OPS_SET(coredata);
+    PARROT_RUNCORE_JIT_OPS_SET(coredata);
+
+    Parrot_runcore_register(interp, coredata);
+}
+
+
+/*
+
+=item C<void Parrot_runcore_exec_init(PARROT_INTERP)>
+
+Registers the exec runcore with Parrot.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_exec_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_exec_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "exec");
+    coredata->opinit           = PARROT_CORE_OPLIB_INIT;
+    coredata->runops           = runops_exec_core;
+    coredata->destroy          = NULL;
+    coredata->prepare_run      = NULL;
+
+    Parrot_runcore_register(interp, coredata);
+}
+
+
+/*
+
+=item C<void Parrot_runcore_gc_debug_init(PARROT_INTERP)>
+
+Registers the gc_debug runcore with Parrot.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_gc_debug_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_gc_debug_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "gc_debug");
+    coredata->opinit           = PARROT_CORE_OPLIB_INIT;
+    coredata->runops           = runops_gc_debug_core;
+    coredata->destroy          = NULL;
+    coredata->prepare_run      = NULL;
+
+    PARROT_RUNCORE_FUNC_TABLE_SET(coredata);
+
+    Parrot_runcore_register(interp, coredata);
+}
+
+
+/*
+
+=item C<void Parrot_runcore_debugger_init(PARROT_INTERP)>
+
+Registers the debugger runcore with Parrot.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_debugger_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_debugger_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "debugger");
+    coredata->opinit           = PARROT_CORE_OPLIB_INIT;
+    coredata->prepare_run      = init_prederef;
+    coredata->runops           = runops_debugger_core;
+    coredata->destroy          = NULL;
+
+    PARROT_RUNCORE_FUNC_TABLE_SET(coredata);
+
+    Parrot_runcore_register(interp, coredata);
+}
+
+
 /*
 
-=item C<opcode_t * runops_fast_core(PARROT_INTERP, opcode_t *pc)>
+=item C<void Parrot_runcore_cgp_init(PARROT_INTERP)>
+
+Registers the CGP runcore with Parrot.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_cgp_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_cgp_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "cgp");
+    coredata->opinit           = PARROT_CORE_CGP_OPLIB_INIT;
+    coredata->prepare_run      = init_prederef;
+    coredata->runops           = runops_cgp_core;
+
+    coredata->destroy          = NULL;
+
+    PARROT_RUNCORE_CGOTO_OPS_SET(coredata);
+    PARROT_RUNCORE_EVENT_CHECK_SET(coredata);
+    PARROT_RUNCORE_PREDEREF_OPS_SET(coredata);
+
+    Parrot_runcore_register(interp, coredata);
+}
+
+
+/*
+
+=item C<void Parrot_runcore_cgoto_init(PARROT_INTERP)>
+
+Registers the cgoto runcore with Parrot.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_cgoto_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_cgoto_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "cgoto");
+    coredata->opinit           = PARROT_CORE_CG_OPLIB_INIT;
+    coredata->runops           = runops_cgoto_core;
+    coredata->destroy          = NULL;
+    coredata->prepare_run      = NULL;
+
+    PARROT_RUNCORE_FUNC_TABLE_SET(coredata);
+    PARROT_RUNCORE_CGOTO_OPS_SET(coredata);
+
+    Parrot_runcore_register(interp, coredata);
+}
+
+
+/*
+
+=item C<void Parrot_runcore_cgp_jit_init(PARROT_INTERP)>
+
+Registers the CGP/JIT runcore with Parrot.
+
+=cut
+
+*/
+
+
+void
+Parrot_runcore_cgp_jit_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_cgp_jit_init)
+
+    Parrot_runcore_t *coredata = mem_allocate_typed(Parrot_runcore_t);
+    coredata->name             = CONST_STRING(interp, "cgp_jit");
+    coredata->opinit           = PARROT_CORE_CGP_OPLIB_INIT;
+    coredata->prepare_run      = init_prederef;
+    coredata->runops           = runops_cgp_core;
+    coredata->destroy          = NULL;
+
+    PARROT_RUNCORE_JIT_OPS_SET(coredata);
+    PARROT_RUNCORE_CGOTO_OPS_SET(coredata);
+    PARROT_RUNCORE_EVENT_CHECK_SET(coredata);
+    PARROT_RUNCORE_PREDEREF_OPS_SET(coredata);
+
+    Parrot_runcore_register(interp, coredata);
+}
+
+
+/*
+
+=item C<static opcode_t * runops_fast_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
 
 Runs the Parrot operations starting at C<pc> until there are no more
 operations.  This performs no bounds checking, profiling, or tracing.
@@ -276,8 +742,8 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-opcode_t *
-runops_fast_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+static opcode_t *
+runops_fast_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
 {
     ASSERT_ARGS(runops_fast_core)
 
@@ -294,7 +760,8 @@
 
 /*
 
-=item C<opcode_t * runops_cgoto_core(PARROT_INTERP, opcode_t *pc)>
+=item C<static opcode_t * runops_cgoto_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
 
 Runs the Parrot operations starting at C<pc> until there are no more
 operations, using the computed C<goto> core, performing no bounds checking,
@@ -308,8 +775,8 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-opcode_t *
-runops_cgoto_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+static opcode_t *
+runops_cgoto_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
 {
     ASSERT_ARGS(runops_cgoto_core)
 
@@ -340,7 +807,8 @@
 
 /*
 
-=item C<static opcode_t * runops_trace_core(PARROT_INTERP, opcode_t *pc)>
+=item C<static opcode_t * runops_trace_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
 
 Runs the Parrot operations starting at C<pc> until there are no more
 operations, using the tracing interpreter.
@@ -352,7 +820,7 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static opcode_t *
-runops_trace_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+runops_trace_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
 {
     ASSERT_ARGS(runops_trace_core)
 
@@ -429,7 +897,8 @@
 
 /*
 
-=item C<opcode_t * runops_slow_core(PARROT_INTERP, opcode_t *pc)>
+=item C<static opcode_t * runops_slow_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
 
 Runs the Parrot operations starting at C<pc> until there are no more
 operations, with tracing and bounds checking enabled.
@@ -440,13 +909,13 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-opcode_t *
-runops_slow_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+static opcode_t *
+runops_slow_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
 {
     ASSERT_ARGS(runops_slow_core)
 
     if (Interp_trace_TEST(interp, PARROT_TRACE_OPS_FLAG))
-        return runops_trace_core(interp, pc);
+        return runops_trace_core(interp, runcore, pc);
 #if 0
     if (interp->debugger && interp->debugger->pdb)
         return Parrot_debug(interp, interp->debugger, pc);
@@ -468,7 +937,8 @@
 
 /*
 
-=item C<opcode_t * runops_gc_debug_core(PARROT_INTERP, opcode_t *pc)>
+=item C<static opcode_t * runops_gc_debug_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
 
 Runs the Parrot operations starting at C<pc> until there are no more
 operations, performing a full GC run before each op.  This is very slow, but
@@ -480,8 +950,8 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-opcode_t *
-runops_gc_debug_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+static opcode_t *
+runops_gc_debug_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
 {
     ASSERT_ARGS(runops_gc_debug_core)
     while (pc) {
@@ -501,7 +971,8 @@
 
 /*
 
-=item C<opcode_t * runops_profile_core(PARROT_INTERP, opcode_t *pc)>
+=item C<static opcode_t * runops_profile_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
 
 Runs the Parrot operations starting at C<pc> until there are no more
 operations, with tracing, bounds checking, and profiling enabled.
@@ -512,8 +983,8 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-opcode_t *
-runops_profile_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+static opcode_t *
+runops_profile_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
 {
     ASSERT_ARGS(runops_profile_core)
 
@@ -537,14 +1008,14 @@
             exit(1);
         }
     }
-    
+
     interp_counter++;
     fprintf(prof_fd, "NEW RUNLOOP (%d)\n", interp_counter);
 
     prev_ctx = CONTEXT(interp);
     Parrot_Context_get_info(interp, CONTEXT(interp), &curr_info);
     fprintf(prof_fd, "F:%s\n", curr_info.file->strstart);
-    fprintf(prof_fd, "S:%s;%s\n", 
+    fprintf(prof_fd, "S:%s;%s\n",
             VTABLE_get_string(interp, prev_ctx->current_namespace)->strstart,
             curr_info.subname->strstart);
 
@@ -559,15 +1030,15 @@
         }
 
         /* avoid an extra call to Parrot_Context_get_info */
-        mem_sys_memcopy(&prev_info, &curr_info, sizeof(Parrot_Context_info));
+        mem_sys_memcopy(&prev_info, &curr_info, sizeof (Parrot_Context_info));
 
         Parrot_Context_get_info(interp, CONTEXT(interp), &curr_info);
         file_preop = prev_info.file->strstart;
         sub_preop  = prev_info.subname->strstart;
 
         CONTEXT(interp)->current_pc = pc;
-        prev_ctx = CONTEXT(interp);
-        prev_pc = pc;
+        prev_ctx                    = CONTEXT(interp);
+        prev_pc                     = pc;
         clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &preop);
         DO_OP(pc, interp);
         clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &postop);
@@ -587,7 +1058,7 @@
             if (strcmp(file_preop, file_postop))
                 fprintf(prof_fd, "F:%s\n", file_postop);
             if (strcmp(sub_preop, sub_postop))
-                fprintf(prof_fd, "S:%s;%s\n", 
+                fprintf(prof_fd, "S:%s;%s\n",
                         VTABLE_get_string(interp, prev_ctx->current_namespace)->strstart,
                         sub_postop);
             fprintf(prof_fd, "%d:%lli:%d:%s\n",
@@ -599,7 +1070,7 @@
     fprintf(prof_fd, "END OF RUNLOOP (%d)\n", interp_counter);
     interp_counter--;
 
-    if (interp_counter == 0) 
+    if (interp_counter == 0)
         fclose(prof_fd);
     return pc;
 
@@ -611,7 +1082,8 @@
 
 /*
 
-=item C<opcode_t * runops_debugger_core(PARROT_INTERP, opcode_t *pc)>
+=item C<static opcode_t * runops_debugger_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
 
 Used by the debugger, under construction
 
@@ -621,17 +1093,15 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-opcode_t *
-runops_debugger_core(PARROT_INTERP, ARGIN(opcode_t *pc))
+static opcode_t *
+runops_debugger_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
 {
     ASSERT_ARGS(runops_debugger_core)
-    /*fprintf(stderr, "Enter runops_debugger_core\n");*/
 
     PARROT_ASSERT(interp->pdb);
 
-    if (interp->pdb->state & PDB_ENTER) {
+    if (interp->pdb->state & PDB_ENTER)
         Parrot_debugger_start(interp, pc);
-    }
 
     while (pc) {
         if (pc < interp->code->base.data || pc >= interp->code->base.data + interp->code->base.size)
@@ -655,24 +1125,335 @@
         if (interp->pdb->state & PDB_STOPPED) {
             Parrot_debugger_start(interp, pc);
         }
-        else
-        {
+        else {
             if (PDB_break(interp)) {
                 Parrot_debugger_start(interp, pc);
                 continue;
             }
 
-            if (interp->pdb->tracing) {
-                if (--interp->pdb->tracing == 0) {
-                    Parrot_debugger_start(interp, pc);
-                }
-            }
+            if (interp->pdb->tracing && --interp->pdb->tracing == 0)
+                Parrot_debugger_start(interp, pc);
         }
     }
 
     return pc;
 }
 
+
+/*
+
+=item C<static opcode_t * runops_switch_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
+
+Runs the C<switch> core.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static opcode_t *
+runops_switch_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
+{
+    ASSERT_ARGS(runops_switch_core)
+    opcode_t * const code_start = (opcode_t *)interp->code->base.data;
+    opcode_t        *pc_prederef;
+
+    init_prederef(interp, runcore);
+    pc_prederef = (opcode_t*)interp->code->prederef.code + (pc - code_start);
+
+    return switch_core(pc_prederef, interp);
+}
+
+
+/*
+
+=item C<void * init_prederef(PARROT_INTERP, Parrot_runcore_t *runcore)>
+
+Initialize: load prederef C<func_table>, file prederef.code.
+
+=cut
+
+*/
+
+PARROT_CAN_RETURN_NULL
+void *
+init_prederef(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
+{
+    ASSERT_ARGS(init_prederef)
+    load_prederef(interp, runcore);
+
+    if (!interp->code->prederef.code) {
+        void        *pred_func;
+        opcode_t    *pc = interp->code->base.data;
+        const size_t N  = interp->code->base.size;
+        size_t       i, n_pics;
+
+/* Parrot_memalign_if_possible in OpenBSD allocates 256 if you ask for 312
+   -- Need to verify this, it may have been a bug elsewhere. If it works now,
+   we can remove the mem_sys_allocate_zeroed line below. */
+
+#if 0
+        void **temp = (void **)mem_sys_allocate_zeroed(N * sizeof (void *));
+#else
+        void **temp = (void **)Parrot_memalign_if_possible(256,
+                N * sizeof (void *));
+#endif
+        /* calc and remember pred_offset */
+        CONTEXT(interp)->pred_offset = pc - (opcode_t *)temp;
+
+        /* fill with the prederef__ opcode function */
+        if (PARROT_RUNCORE_PREDEREF_OPS_TEST(runcore)
+        && !PARROT_RUNCORE_CGOTO_OPS_TEST(runcore))
+            pred_func = (void *)CORE_OPS_prederef__;
+        else {
+            PARROT_ASSERT(interp->op_lib->op_func_table);
+            pred_func = ((void **)
+                    interp->op_lib->op_func_table)[CORE_OPS_prederef__];
+        }
+
+        for (i = n_pics = 0; i < N;) {
+            op_info_t * const opinfo = &interp->op_info_table[*pc];
+            size_t            n      = opinfo->op_count;
+
+            temp[i] = pred_func;
+
+            ADD_OP_VAR_PART(interp, interp->code, pc, n);
+
+            /* count ops that need a PIC */
+            if (parrot_PIC_op_is_cached(*pc))
+                n_pics++;
+
+            pc += n;
+            i  += n;
+        }
+
+        interp->code->prederef.code = temp;
+
+        /* allocate pic store, which starts from 1 */
+        if (n_pics)
+            parrot_PIC_alloc_store(interp->code, n_pics + 1);
+    }
+
+    return NULL;
+}
+
+
+/*
+
+=item C<void load_prederef(PARROT_INTERP, Parrot_runcore_t *runcore)>
+
+C<< interp->op_lib >> = prederefed oplib.
+
+=cut
+
+*/
+
+void
+load_prederef(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
+{
+    ASSERT_ARGS(load_prederef)
+    const oplib_init_f init_func = get_core_op_lib_init(interp, runcore);
+
+    int (*get_op)(const char * name, int full);
+
+    get_op          = interp->op_lib->op_code;
+    interp->op_lib  = init_func(1);
+
+    /* preserve the get_op function */
+    interp->op_lib->op_code = get_op;
+
+    if (interp->op_lib->op_count != interp->op_count)
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PREDEREF_LOAD_ERROR,
+            "Illegal op count (%d) in prederef oplib\n",
+            (int)interp->op_lib->op_count);
+}
+
+
+/*
+
+=item C<oplib_init_f get_core_op_lib_init(PARROT_INTERP, Parrot_runcore_t
+*runcore)>
+
+Returns an opcode's library C<op_lib> init function.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+oplib_init_f
+get_core_op_lib_init(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
+{
+    ASSERT_ARGS(get_core_op_lib_init)
+    return runcore->opinit;
+}
+
+
+/*
+
+=item C<void * init_jit_run(PARROT_INTERP, Parrot_runcore_t *runcore)>
+
+Initializes JIT function for the specified opcode and runs it.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+void *
+init_jit_run(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
+{
+    ASSERT_ARGS(init_jit_run)
+    return init_jit(interp, interp->code->base.data);
+}
+
+
+#ifdef PARROT_EXEC_OS_AIX
+extern void* aix_get_toc();
+#endif
+
+/*
+
+=item C<static opcode_t * runops_jit_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
+
+Runs the JIT code for the specified opcode.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static opcode_t *
+runops_jit_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
+{
+    ASSERT_ARGS(runops_jit_core)
+#if JIT_CAPABLE
+#  ifdef PARROT_EXEC_OS_AIX
+    /* AIX calling convention requires that function-call-by-ptr be made
+       through the following struct: */
+    struct ptrgl_t { jit_f functPtr; void *toc; void *env; } ptrgl_t;
+
+    ptrgl_t.functPtr = (jit_f) D2FPTR(init_jit(interp, pc));
+    ptrgl_t.env      = NULL;
+
+    /* r2 (TOC) needs to point back here so we can return from non-JIT
+       functions */
+    ptrgl_t.toc = aix_get_toc();
+
+    ((jit_f) D2FPTR(&ptrgl_t)) (interp, pc);
+#  else
+    jit_f jit_code = (jit_f)(init_jit(interp, pc));
+    (jit_code) (interp, pc);
+#  endif
+#else
+    UNUSED(interp);
+    UNUSED(pc);
+#endif
+    return NULL;
+}
+
+
+/*
+
+=item C<static opcode_t * runops_exec_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
+
+Runs the native executable version of the specified opcode.
+
+=cut
+
+*/
+
+#if EXEC_CAPABLE
+    extern int Parrot_exec_run;
+#endif
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static opcode_t *
+runops_exec_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
+{
+    ASSERT_ARGS(runops_exec_core)
+#if EXEC_CAPABLE
+    opcode_t *code_start = interp->code->base.data;
+
+    /* size in opcodes */
+    UINTVAL   code_size  = interp->code->base.size;
+    opcode_t *code_end   = code_start + code_size;
+
+#  if defined HAVE_COMPUTED_GOTO && defined USE_CGP
+#    ifdef __GNUC__
+#      ifdef PARROT_I386
+    init_prederef(interp, PARROT_CGP_CORE);
+#      endif
+#    endif
+#  endif
+    if (Parrot_exec_run == 2) {
+        void *ignored;
+        Parrot_exec_run = 0;
+
+        Parrot_runcore_switch(interp, CONST_STRING(interp, "jit"));
+
+        ignored         = runops_jit_core(interp, runcore, pc);
+        UNUSED(ignored);
+
+        Parrot_runcore_switch(interp, CONST_STRING(interp, "exec"));
+    }
+    else if (Parrot_exec_run == 1)
+        Parrot_exec(interp, pc, code_start, code_end);
+    else
+        run_native(interp, pc, code_start);
+
+#else
+    UNUSED(interp);
+    UNUSED(pc);
+#endif
+
+    return NULL;
+}
+
+
+/*
+
+=item C<static opcode_t * runops_cgp_core(PARROT_INTERP, Parrot_runcore_t
+*runcore, opcode_t *pc)>
+
+Runs the computed goto and predereferenced core.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static opcode_t *
+runops_cgp_core(PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore), ARGIN(opcode_t *pc))
+{
+    ASSERT_ARGS(runops_cgp_core)
+#ifdef HAVE_COMPUTED_GOTO
+    opcode_t * const code_start = (opcode_t *)interp->code->base.data;
+    opcode_t        *pc_prederef;
+
+    init_prederef(interp, runcore);
+
+    pc_prederef = (opcode_t *)interp->code->prederef.code + (pc - code_start);
+    return cgp_core(pc_prederef, interp);
+
+#else
+    UNUSED(pc);
+    Parrot_io_eprintf(interp,
+            "Computed goto unavailable in this configuration.\n");
+    Parrot_exit(interp, 1);
+#endif
+
+}
+
 /*
 
 =back

Modified: branches/pluggable_runcore/src/runcore/main.c
==============================================================================
--- branches/pluggable_runcore/src/runcore/main.c	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/src/runcore/main.c	Thu Aug 13 21:34:51 2009	(r40529)
@@ -64,23 +64,12 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-static oplib_init_f get_core_op_lib_init(PARROT_INTERP, int which)
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
 static oplib_init_f get_dynamic_op_lib_init(SHIM_INTERP,
     ARGIN(const PMC *lib))
         __attribute__nonnull__(2);
 
-static void init_prederef(PARROT_INTERP, int which)
-        __attribute__nonnull__(1);
-
-static void load_prederef(PARROT_INTERP, int which)
-        __attribute__nonnull__(1);
-
 static void notify_func_table(PARROT_INTERP,
-    ARGIN(op_func_t* table),
+    ARGIN(op_func_t *table),
     int on)
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -96,30 +85,6 @@
         __attribute__nonnull__(4)
         FUNC_MODIFIES(*pc_prederef);
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static opcode_t * runops_cgp(PARROT_INTERP, ARGIN(opcode_t *pc))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-static opcode_t * runops_exec(PARROT_INTERP, ARGIN(opcode_t *pc))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-static opcode_t * runops_jit(PARROT_INTERP, ARGIN(opcode_t *pc))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static opcode_t * runops_switch(PARROT_INTERP, ARGIN(opcode_t *pc))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
 static void stop_prederef(PARROT_INTERP)
         __attribute__nonnull__(1);
 
@@ -129,14 +94,8 @@
 #define ASSERT_ARGS_dynop_register_switch __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_dynop_register_xx __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_get_core_op_lib_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_get_dynamic_op_lib_init __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(lib)
-#define ASSERT_ARGS_init_prederef __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_load_prederef __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_notify_func_table __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(table)
@@ -145,18 +104,6 @@
     || PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pc) \
     || PARROT_ASSERT_ARG(opinfo)
-#define ASSERT_ARGS_runops_cgp __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc)
-#define ASSERT_ARGS_runops_exec __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc)
-#define ASSERT_ARGS_runops_jit __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc)
-#define ASSERT_ARGS_runops_switch __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pc)
 #define ASSERT_ARGS_stop_prederef __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_turn_ev_check __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -164,9 +111,102 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
-#if EXEC_CAPABLE
-    extern int Parrot_exec_run;
+/*
+
+=item C<void Parrot_runcore_init(PARROT_INTERP)>
+
+Initializes the runcores.
+
+=cut
+
+*/
+
+void
+Parrot_runcore_init(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_runcore_init)
+
+    interp->cores     = NULL;
+    interp->num_cores = 0;
+
+    Parrot_runcore_slow_init(interp);
+    Parrot_runcore_fast_init(interp);
+    Parrot_runcore_switch_init(interp);
+
+    Parrot_runcore_jit_init(interp);
+    Parrot_runcore_switch_jit_init(interp);
+    Parrot_runcore_exec_init(interp);
+    Parrot_runcore_gc_debug_init(interp);
+    Parrot_runcore_debugger_init(interp);
+
+#ifdef HAVE_COMPUTED_GOTO
+    Parrot_runcore_cgp_init(interp);
+    Parrot_runcore_cgoto_init(interp);
+    Parrot_runcore_cgp_jit_init(interp);
 #endif
+}
+
+
+/*
+
+=item C<INTVAL Parrot_runcore_register(PARROT_INTERP, const Parrot_runcore_t
+*coredata)>
+
+Registers a new runcore with Parrot.  Returns 1 on success, 0 on failure.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+INTVAL
+Parrot_runcore_register(PARROT_INTERP, ARGIN(const Parrot_runcore_t *coredata))
+{
+    ASSERT_ARGS(Parrot_runcore_register)
+    size_t num_cores = ++interp->num_cores;
+
+    mem_realloc_n_typed(interp->cores, num_cores, Parrot_runcore_t *);
+
+    interp->cores[num_cores - 1] = coredata;
+
+    return 1;
+}
+
+
+/*
+
+=item C<void Parrot_runcore_switch(PARROT_INTERP, STRING *name)>
+
+Switches to a named runcore.  Throws an exception on an unknown runcore.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_runcore_switch(PARROT_INTERP, ARGIN(STRING *name))
+{
+    ASSERT_ARGS(Parrot_runcore_switch)
+
+    size_t num_cores = interp->num_cores;
+    size_t i;
+
+    if (interp->run_core
+    &&  Parrot_str_equal(interp, name, interp->run_core->name))
+        return;
+
+    for (i = 0; i < num_cores; ++i) {
+        if (Parrot_str_equal(interp, name, interp->cores[i]->name)) {
+            interp->run_core = interp->cores[i];
+            return;
+        }
+    }
+
+    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNIMPLEMENTED,
+        "Invalid runcore %Ss requested\n", name);
+}
+
 
 /*
 
@@ -286,7 +326,8 @@
 
 /*
 
-=item C<void do_prederef(void **pc_prederef, PARROT_INTERP, int type)>
+=item C<void do_prederef(void **pc_prederef, PARROT_INTERP, Parrot_runcore_t
+*runcore)>
 
 This is called from within the run cores to predereference the current
 opcode.
@@ -298,7 +339,7 @@
 */
 
 void
-do_prederef(ARGIN(void **pc_prederef), PARROT_INTERP, int type)
+do_prederef(ARGIN(void **pc_prederef), PARROT_INTERP, ARGIN(Parrot_runcore_t *runcore))
 {
     ASSERT_ARGS(do_prederef)
     const size_t     offset = pc_prederef - interp->code->prederef.code;
@@ -319,18 +360,11 @@
 
     prederef_args(pc_prederef, interp, pc, opinfo);
 
-    switch (type) {
-        case PARROT_SWITCH_CORE:
-        case PARROT_SWITCH_JIT_CORE:
-        case PARROT_CGP_CORE:
-        case PARROT_CGP_JIT_CORE:
-            parrot_PIC_prederef(interp, *pc, pc_prederef, type);
-            break;
-        default:
-            Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                "Tried to prederef wrong core");
-            break;
-    }
+    if (PARROT_RUNCORE_PREDEREF_OPS_TEST(runcore))
+        parrot_PIC_prederef(interp, *pc, pc_prederef, interp->run_core);
+    else
+        Parrot_ex_throw_from_c_args(interp, NULL, 1,
+            "Tried to prederef wrong core");
 
     /* now remember backward branches, invoke and similar opcodes */
     n = opinfo->op_count;
@@ -405,57 +439,6 @@
 
 /*
 
-=item C<static oplib_init_f get_core_op_lib_init(PARROT_INTERP, int which)>
-
-Returns an opcode's library C<op_lib> init function.
-
-C<which> is the run core type.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static oplib_init_f
-get_core_op_lib_init(PARROT_INTERP, int which)
-{
-    ASSERT_ARGS(get_core_op_lib_init)
-    oplib_init_f init_func;
-    switch (which) {
-        case PARROT_SWITCH_CORE:
-        case PARROT_SWITCH_JIT_CORE:
-            init_func = PARROT_CORE_SWITCH_OPLIB_INIT;
-            break;
-#ifdef HAVE_COMPUTED_GOTO
-        case PARROT_CGP_CORE:
-        case PARROT_CGP_JIT_CORE:
-            init_func = PARROT_CORE_CGP_OPLIB_INIT;
-            break;
-        case PARROT_CGOTO_CORE:
-            init_func = PARROT_CORE_CG_OPLIB_INIT;
-            break;
-#endif
-        /* normal func core */
-        case PARROT_EXEC_CORE:
-        case PARROT_JIT_CORE:
-        case PARROT_SLOW_CORE:
-        case PARROT_FAST_CORE:
-        case PARROT_GC_DEBUG_CORE:
-        case PARROT_DEBUGGER_CORE:
-            init_func = PARROT_CORE_OPLIB_INIT;
-            break;
-        default:
-            Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                "Couldn't find init_func for core %d", which);
-    }
-
-    return init_func;
-}
-
-
-/*
-
 =item C<static oplib_init_f get_dynamic_op_lib_init(PARROT_INTERP, const PMC
 *lib)>
 
@@ -480,103 +463,6 @@
 
 /*
 
-=item C<static void load_prederef(PARROT_INTERP, int which)>
-
-C<< interp->op_lib >> = prederefed oplib.
-
-=cut
-
-*/
-
-static void
-load_prederef(PARROT_INTERP, int which)
-{
-    ASSERT_ARGS(load_prederef)
-    const oplib_init_f init_func = get_core_op_lib_init(interp, which);
-
-    int (*get_op)(const char * name, int full);
-
-    get_op          = interp->op_lib->op_code;
-    interp->op_lib  = init_func(1);
-
-    /* preserve the get_op function */
-    interp->op_lib->op_code = get_op;
-
-    if (interp->op_lib->op_count != interp->op_count)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PREDEREF_LOAD_ERROR,
-            "Illegal op count (%d) in prederef oplib\n",
-            (int)interp->op_lib->op_count);
-}
-
-
-/*
-
-=item C<static void init_prederef(PARROT_INTERP, int which)>
-
-Initialize: load prederef C<func_table>, file prederef.code.
-
-=cut
-
-*/
-
-static void
-init_prederef(PARROT_INTERP, int which)
-{
-    ASSERT_ARGS(init_prederef)
-    load_prederef(interp, which);
-    if (!interp->code->prederef.code) {
-        void        *pred_func;
-        opcode_t    *pc = interp->code->base.data;
-        const size_t N  = interp->code->base.size;
-        size_t       i, n_pics;
-
-/* Parrot_memalign_if_possible in OpenBSD allocates 256 if you ask for 312
-   -- Need to verify this, it may have been a bug elsewhere. If it works now,
-   we can remove the mem_sys_allocate_zeroed line below. */
-
-#if 0
-        void **temp = (void **)mem_sys_allocate_zeroed(N * sizeof (void *));
-#else
-        void **temp = (void **)Parrot_memalign_if_possible(256,
-                N * sizeof (void *));
-#endif
-        /* calc and remember pred_offset */
-        CONTEXT(interp)->pred_offset = pc - (opcode_t *)temp;
-
-        /* fill with the prederef__ opcode function */
-        if (which == PARROT_SWITCH_CORE || which == PARROT_SWITCH_JIT_CORE)
-            pred_func = (void *)CORE_OPS_prederef__;
-        else
-            pred_func = ((void **)
-                    interp->op_lib->op_func_table)[CORE_OPS_prederef__];
-
-        for (i = n_pics = 0; i < N;) {
-            op_info_t * const opinfo = &interp->op_info_table[*pc];
-            size_t            n      = opinfo->op_count;
-
-            temp[i] = pred_func;
-
-            ADD_OP_VAR_PART(interp, interp->code, pc, n);
-
-            /* count ops that need a PIC */
-            if (parrot_PIC_op_is_cached(*pc))
-                n_pics++;
-
-            pc += n;
-            i  += n;
-        }
-
-        interp->code->prederef.code = temp;
-
-        /* allocate pic store, which starts from 1 */
-        if (n_pics)
-            parrot_PIC_alloc_store(interp->code, n_pics + 1);
-    }
-}
-
-
-/*
-
 =item C<static void stop_prederef(PARROT_INTERP)>
 
 Restore the interpreter's op function tables to their initial state.
@@ -622,7 +508,11 @@
 exec_init_prederef(PARROT_INTERP, ARGIN(void *prederef_arena))
 {
     ASSERT_ARGS(exec_init_prederef)
-    load_prederef(interp, PARROT_CGP_CORE);
+    Parrot_runcore_t *old_runcore = interp->run_core;
+    Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "cgp"));
+
+    load_prederef(interp, interp->run_core);
+    interp->run_core = old_runcore;
 
     if (!interp->code->prederef.code) {
         void ** const temp = (void **)prederef_arena;
@@ -699,185 +589,10 @@
 prepare_for_run(PARROT_INTERP)
 {
     ASSERT_ARGS(prepare_for_run)
-    void *ignored;
-
-    switch (interp->run_core) {
-        case PARROT_JIT_CORE:
-            ignored = init_jit(interp, interp->code->base.data);
-            UNUSED(ignored);
-            break;
-        case PARROT_SWITCH_CORE:
-        case PARROT_SWITCH_JIT_CORE:
-        case PARROT_CGP_CORE:
-        case PARROT_CGP_JIT_CORE:
-        case PARROT_DEBUGGER_CORE:
-            init_prederef(interp, interp->run_core);
-            break;
-        default:
-            break;
-    }
-}
-
-
-#ifdef PARROT_EXEC_OS_AIX
-extern void* aix_get_toc();
-#endif
-
-/*
-
-=item C<static opcode_t * runops_jit(PARROT_INTERP, opcode_t *pc)>
-
-Runs the JIT code for the specified opcode.
-
-=cut
-
-*/
+    const runcore_prepare_fn_type prepare_run = interp->run_core->prepare_run;
 
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-static opcode_t *
-runops_jit(PARROT_INTERP, ARGIN(opcode_t *pc))
-{
-    ASSERT_ARGS(runops_jit)
-#if JIT_CAPABLE
-#  ifdef PARROT_EXEC_OS_AIX
-    /* AIX calling convention requires that function-call-by-ptr be made
-       through the following struct: */
-    struct ptrgl_t { jit_f functPtr; void *toc; void *env; } ptrgl_t;
-
-    ptrgl_t.functPtr = (jit_f) D2FPTR(init_jit(interp, pc));
-    ptrgl_t.env      = NULL;
-
-    /* r2 (TOC) needs to point back here so we can return from non-JIT
-       functions */
-    ptrgl_t.toc = aix_get_toc();
-
-    ((jit_f) D2FPTR(&ptrgl_t)) (interp, pc);
-#  else
-    jit_f jit_code = (jit_f)(init_jit(interp, pc));
-    (jit_code) (interp, pc);
-#  endif
-#else
-    UNUSED(interp);
-    UNUSED(pc);
-#endif
-    return NULL;
-}
-
-
-/*
-
-=item C<static opcode_t * runops_exec(PARROT_INTERP, opcode_t *pc)>
-
-Runs the native executable version of the specified opcode.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-static opcode_t *
-runops_exec(PARROT_INTERP, ARGIN(opcode_t *pc))
-{
-    ASSERT_ARGS(runops_exec)
-#if EXEC_CAPABLE
-    opcode_t *code_start;
-    UINTVAL   code_size;          /* in opcodes */
-    opcode_t *code_end;
-
-    code_start = interp->code->base.data;
-    code_size = interp->code->base.size;
-    code_end = code_start + code_size;
-#  if defined HAVE_COMPUTED_GOTO && defined USE_CGP
-#    ifdef __GNUC__
-#      ifdef PARROT_I386
-    init_prederef(interp, PARROT_CGP_CORE);
-#      endif
-#    endif
-#  endif
-    if (Parrot_exec_run == 2) {
-        void *ignored;
-        Parrot_exec_run = 0;
-
-        Interp_core_SET(interp, PARROT_JIT_CORE);
-        ignored         = runops_jit(interp, pc);
-        UNUSED(ignored);
-
-        Interp_core_SET(interp, PARROT_EXEC_CORE);
-    }
-    else if (Parrot_exec_run == 1)
-        Parrot_exec(interp, pc, code_start, code_end);
-    else
-        run_native(interp, pc, code_start);
-
-#else
-    UNUSED(interp);
-    UNUSED(pc);
-#endif
-
-    return NULL;
-}
-
-
-/*
-
-=item C<static opcode_t * runops_cgp(PARROT_INTERP, opcode_t *pc)>
-
-Runs the C C<goto>, predereferenced core.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static opcode_t *
-runops_cgp(PARROT_INTERP, ARGIN(opcode_t *pc))
-{
-    ASSERT_ARGS(runops_cgp)
-#ifdef HAVE_COMPUTED_GOTO
-    opcode_t * const code_start = (opcode_t *)interp->code->base.data;
-    opcode_t        *pc_prederef;
-
-    init_prederef(interp, PARROT_CGP_CORE);
-
-    pc_prederef = (opcode_t*)interp->code->prederef.code + (pc - code_start);
-    return cgp_core(pc_prederef, interp);
-
-#else
-    UNUSED(pc);
-    Parrot_io_eprintf(interp,
-            "Computed goto unavailable in this configuration.\n");
-    Parrot_exit(interp, 1);
-#endif
-
-}
-
-
-/*
-
-=item C<static opcode_t * runops_switch(PARROT_INTERP, opcode_t *pc)>
-
-Runs the C<switch> core.
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static opcode_t *
-runops_switch(PARROT_INTERP, ARGIN(opcode_t *pc))
-{
-    ASSERT_ARGS(runops_switch)
-    opcode_t * const code_start = (opcode_t *)interp->code->base.data;
-    opcode_t        *pc_prederef;
-
-    init_prederef(interp, PARROT_SWITCH_CORE);
-    pc_prederef = (opcode_t*)interp->code->prederef.code + (pc - code_start);
-
-    return switch_core(pc_prederef, interp);
+    if (prepare_run)
+        (*prepare_run)(interp, interp->run_core);
 }
 
 
@@ -898,7 +613,6 @@
 runops_int(PARROT_INTERP, size_t offset)
 {
     ASSERT_ARGS(runops_int)
-    opcode_t *(*core) (PARROT_INTERP, opcode_t *) = NULL;
 
     /* setup event function ptrs */
     if (!interp->save_func_table)
@@ -910,81 +624,12 @@
     while (interp->resume_flag & RESUME_RESTART) {
         opcode_t * const pc = (opcode_t *)
             interp->code->base.data + interp->resume_offset;
+        const runcore_runops_fn_type core = interp->run_core->runops;
 
         interp->resume_offset = 0;
         interp->resume_flag  &= ~(RESUME_RESTART | RESUME_INITIAL);
 
-        switch (interp->run_core) {
-            case PARROT_SLOW_CORE:
-                core = runops_slow_core;
-
-                if (Interp_flags_TEST(interp, PARROT_PROFILE_FLAG)) {
-                    core = runops_profile_core;
-                    if (interp->profile == NULL) {
-                        interp->profile = mem_allocate_zeroed_typed(RunProfile);
-                        interp->profile->data =
-                            mem_allocate_n_typed((interp->op_count +
-                                        PARROT_PROF_EXTRA), ProfData);
-                    }
-                }
-                break;
-            case PARROT_FAST_CORE:
-                core = runops_fast_core;
-                break;
-            case PARROT_CGOTO_CORE:
-#ifdef HAVE_COMPUTED_GOTO
-                core = runops_cgoto_core;
-#else
-                Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                    "Error: PARROT_CGOTO_CORE not available");
-#endif
-                break;
-            case PARROT_CGP_CORE:
-            case PARROT_CGP_JIT_CORE:
-#ifdef HAVE_COMPUTED_GOTO
-                core = runops_cgp;
-#else
-                Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                    "Error: PARROT_CGP_CORE not available");
-#endif
-                break;
-            case PARROT_SWITCH_CORE:
-            case PARROT_SWITCH_JIT_CORE:
-                core = runops_switch;
-                break;
-            case PARROT_JIT_CORE:
-#if !JIT_CAPABLE
-                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_UNAVAILABLE,
-                    "Error: PARROT_JIT_FLAG is set, "
-                    "but interpreter is not JIT_CAPABLE!\n");
-#else
-                core = runops_jit;
-#endif
-                break;
-            case PARROT_EXEC_CORE:
-#if !EXEC_CAPABLE
-                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_EXEC_UNAVAILABLE,
-                    "Error: PARROT_EXEC_FLAG is set, "
-                    "but interpreter is not EXEC_CAPABLE!\n");
-#else
-                core = runops_exec;
-#endif
-                break;
-            case PARROT_GC_DEBUG_CORE:
-                core = runops_gc_debug_core;
-                break;
-            case PARROT_DEBUGGER_CORE:
-                core = runops_debugger_core;
-                break;
-            default:
-                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNIMPLEMENTED,
-                    "ambigious runcore switch used");
-                break;
-        }
-
-
-        /* run it finally */
-        core(interp, pc);
+        (*core)(interp, interp->run_core, pc);
 
         /* if we have fallen out with resume and we were running CGOTO, set
          * the stacktop again to a sane value, so that restarting the runloop
@@ -1053,10 +698,14 @@
 Parrot_runcore_destroy(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_runcore_destroy)
-    op_lib_t    *cg_lib;
+    op_lib_t         *cg_lib;
+    size_t            num_cores = interp->cores ?
+                      sizeof (interp->cores) / sizeof (Parrot_runcore_t *) : 1;
+    size_t            i;
 
 #ifdef HAVE_COMPUTED_GOTO
     cg_lib = PARROT_CORE_CGP_OPLIB_INIT(1);
+
     if (cg_lib->op_func_table)
         mem_sys_free(cg_lib->op_func_table);
     cg_lib->op_func_table = NULL;
@@ -1066,6 +715,22 @@
         mem_sys_free(cg_lib->op_func_table);
     cg_lib->op_func_table = NULL;
 #endif
+
+    for (i = 0; i < num_cores; ++i) {
+        Parrot_runcore_t        *core    = interp->cores[i];
+        runcore_destroy_fn_type  destroy = core->destroy;
+
+        if (destroy)
+            (*destroy)(interp, core);
+
+        mem_sys_free(core);
+    }
+
+    if (interp->cores)
+        mem_sys_free(interp->cores);
+
+    interp->cores    = NULL;
+    interp->run_core = NULL;
 }
 
 
@@ -1330,7 +995,7 @@
 
 /*
 
-=item C<static void notify_func_table(PARROT_INTERP, op_func_t* table, int on)>
+=item C<static void notify_func_table(PARROT_INTERP, op_func_t *table, int on)>
 
 Tell the interpreter's running core about the new function table.
 
@@ -1339,27 +1004,20 @@
 */
 
 static void
-notify_func_table(PARROT_INTERP, ARGIN(op_func_t* table), int on)
+notify_func_table(PARROT_INTERP, ARGIN(op_func_t *table), int on)
 {
     ASSERT_ARGS(notify_func_table)
     const oplib_init_f init_func = get_core_op_lib_init(interp, interp->run_core);
 
     init_func((long) table);
-    switch (interp->run_core) {
-        case PARROT_SLOW_CORE:      /* normal func core */
-        case PARROT_FAST_CORE:      /* normal func core */
-        case PARROT_CGOTO_CORE:     /* cgoto address list  */
-        case PARROT_DEBUGGER_CORE:
-            PARROT_ASSERT(table);
-            interp->op_func_table = table;
-            break;
-        case PARROT_CGP_CORE:
-        case PARROT_CGP_JIT_CORE:
-            turn_ev_check(interp, on);
-            break;
-        default:
-            break;
+
+    if (PARROT_RUNCORE_FUNC_TABLE_TEST(interp->run_core)) {
+        PARROT_ASSERT(table);
+        interp->op_func_table = table;
     }
+
+    if (PARROT_RUNCORE_EVENT_CHECK_TEST(interp->run_core))
+        turn_ev_check(interp, on);
 }
 
 

Modified: branches/pluggable_runcore/t/run/options.t
==============================================================================
--- branches/pluggable_runcore/t/run/options.t	Thu Aug 13 20:17:29 2009	(r40528)
+++ branches/pluggable_runcore/t/run/options.t	Thu Aug 13 21:34:51 2009	(r40529)
@@ -88,7 +88,7 @@
     is( qx{$cmd}, "second\n", "-r option <$cmd>" );
 
     $cmd = qq{"$PARROT" -D 8 -R slow "$second_pir_file" 2>&1};
-    like( qx{$cmd}, qr/Parrot VM: Slow core/, "-r option <$cmd>" );
+    like( qx{$cmd}, qr/Parrot VM: slow core/, "-r option <$cmd>" );
 }
 
 ## RT#46815 test remaining options


More information about the parrot-commits mailing list