[svn:parrot] r40958 - in trunk: . compilers/imcc config/gen/makefiles include/parrot lib/Parrot/OpTrans lib/Parrot/Ops2c lib/Parrot/Pmc2c src src/call src/gc src/interp src/jit/amd64 src/jit/i386 src/jit/ppc src/jit/sun4 src/ops src/pmc src/runcore t/compilers/pge t/native_pbc t/op t/pmc

bacek at svn.parrot.org bacek at svn.parrot.org
Thu Sep 3 11:56:57 UTC 2009


Author: bacek
Date: Thu Sep  3 11:56:50 2009
New Revision: 40958
URL: https://trac.parrot.org/parrot/changeset/40958

Log:
Merge context_pmc3 branch into trunk.

DRAGONS ENTER THE BUILDING.

Added:
   trunk/include/parrot/context.h
   trunk/src/call/context.c
   trunk/src/pmc/context.pmc
   trunk/t/pmc/context.t
Modified:
   trunk/MANIFEST
   trunk/compilers/imcc/imcc.y
   trunk/compilers/imcc/imcparser.c
   trunk/compilers/imcc/parser_util.c
   trunk/compilers/imcc/pbc.c
   trunk/config/gen/makefiles/root.in
   trunk/include/parrot/call.h
   trunk/include/parrot/interpreter.h
   trunk/include/parrot/register.h
   trunk/include/parrot/sub.h
   trunk/include/parrot/warnings.h
   trunk/lib/Parrot/OpTrans/C.pm
   trunk/lib/Parrot/OpTrans/CGP.pm
   trunk/lib/Parrot/OpTrans/CGoto.pm
   trunk/lib/Parrot/OpTrans/CPrederef.pm
   trunk/lib/Parrot/OpTrans/CSwitch.pm
   trunk/lib/Parrot/Ops2c/Utils.pm
   trunk/lib/Parrot/Pmc2c/PCCMETHOD.pm
   trunk/src/call/ops.c
   trunk/src/call/pcc.c
   trunk/src/debug.c
   trunk/src/embed.c
   trunk/src/exceptions.c
   trunk/src/extend.c
   trunk/src/gc/alloc_register.c
   trunk/src/gc/mark_sweep.c
   trunk/src/global.c
   trunk/src/global_setup.c
   trunk/src/hll.c
   trunk/src/interp/inter_create.c
   trunk/src/interp/inter_misc.c
   trunk/src/jit.c
   trunk/src/jit/amd64/jit_defs.c
   trunk/src/jit/i386/core.jit
   trunk/src/jit/i386/jit_defs.c
   trunk/src/jit/ppc/core.jit
   trunk/src/jit/ppc/jit_emit.h
   trunk/src/jit/sun4/jit_emit.h
   trunk/src/multidispatch.c
   trunk/src/oo.c
   trunk/src/ops/core.ops
   trunk/src/ops/debug.ops
   trunk/src/ops/object.ops
   trunk/src/ops/pic.ops
   trunk/src/ops/var.ops
   trunk/src/packfile.c
   trunk/src/pic.c
   trunk/src/pmc.c
   trunk/src/pmc/class.pmc
   trunk/src/pmc/continuation.pmc
   trunk/src/pmc/coroutine.pmc
   trunk/src/pmc/exception.pmc
   trunk/src/pmc/exporter.pmc
   trunk/src/pmc/lexpad.pmc
   trunk/src/pmc/nci.pmc
   trunk/src/pmc/object.pmc
   trunk/src/pmc/parrotinterpreter.pmc
   trunk/src/pmc/retcontinuation.pmc
   trunk/src/pmc/role.pmc
   trunk/src/pmc/scheduler.pmc
   trunk/src/pmc/sub.pmc
   trunk/src/runcore/cores.c
   trunk/src/runcore/main.c
   trunk/src/scheduler.c
   trunk/src/sub.c
   trunk/src/warnings.c
   trunk/t/compilers/pge/06-grammar.t
   trunk/t/native_pbc/annotations.pbc
   trunk/t/native_pbc/integer_1.pbc
   trunk/t/native_pbc/number_1.pbc
   trunk/t/native_pbc/string_1.pbc
   trunk/t/op/annotate.t
   trunk/t/pmc/exceptionhandler.t

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/MANIFEST	Thu Sep  3 11:56:50 2009	(r40958)
@@ -951,6 +951,7 @@
 include/parrot/cclass.h                                     [main]include
 include/parrot/charset.h                                    [main]include
 include/parrot/compiler.h                                   [main]include
+include/parrot/context.h                                    [main]include
 include/parrot/core_types.h                                 [main]include
 include/parrot/datatypes.h                                  [main]include
 include/parrot/debugger.h                                   [main]include
@@ -1242,6 +1243,7 @@
 src/atomic/gcc_x86.c                                        []
 src/atomic/sparc_v9.s                                       []
 src/byteorder.c                                             []
+src/call/context.c                                          []
 src/call/ops.c                                              []
 src/call/pcc.c                                              []
 src/datatypes.c                                             []
@@ -1392,6 +1394,7 @@
 src/pmc/class.pmc                                           [devel]src
 src/pmc/codestring.pmc                                      [devel]src
 src/pmc/complex.pmc                                         [devel]src
+src/pmc/context.pmc                                         [devel]src
 src/pmc/continuation.pmc                                    [devel]src
 src/pmc/coroutine.pmc                                       [devel]src
 src/pmc/cpointer.pmc                                        [devel]src
@@ -1845,6 +1848,7 @@
 t/pmc/codestring.t                                          [test]
 t/pmc/complex.t                                             [test]
 t/pmc/config.t                                              [test]
+t/pmc/context.t                                             [test]
 t/pmc/continuation.t                                        [test]
 t/pmc/coroutine.t                                           [test]
 t/pmc/cpointer.t                                            [test]

Modified: trunk/compilers/imcc/imcc.y
==============================================================================
--- trunk/compilers/imcc/imcc.y	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/compilers/imcc/imcc.y	Thu Sep  3 11:56:50 2009	(r40958)
@@ -1210,8 +1210,8 @@
      HLL STRINGC
          {
             STRING * const hll_name = Parrot_str_unescape(interp, $2 + 1, '"', NULL);
-            CONTEXT(interp)->current_HLL =
-                Parrot_register_HLL(interp, hll_name);
+            Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp),
+                Parrot_register_HLL(interp, hll_name));
 
             IMCC_INFO(interp)->cur_namespace = NULL;
             mem_sys_free($2);

Modified: trunk/compilers/imcc/imcparser.c
==============================================================================
--- trunk/compilers/imcc/imcparser.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/compilers/imcc/imcparser.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -3318,8 +3318,8 @@
 #line 1211 "compilers/imcc/imcc.y"
     {
             STRING * const hll_name = Parrot_str_unescape(interp, (yyvsp[(2) - (2)].s) + 1, '"', NULL);
-            CONTEXT(interp)->current_HLL =
-                Parrot_register_HLL(interp, hll_name);
+            Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp),
+                Parrot_register_HLL(interp, hll_name));
 
             IMCC_INFO(interp)->cur_namespace = NULL;
             mem_sys_free((yyvsp[(2) - (2)].s));

Modified: trunk/compilers/imcc/parser_util.c
==============================================================================
--- trunk/compilers/imcc/parser_util.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/compilers/imcc/parser_util.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -626,7 +626,7 @@
     struct _imc_info_t    *imc_info = NULL;
     struct parser_state_t *next;
     void                  *yyscanner;
-    Parrot_Context        *ignored;
+    PMC                   *ignored;
     INTVAL regs_used[4] = {3, 3, 3, 3};
     INTVAL eval_number;
 
@@ -869,10 +869,10 @@
      * Continuations (this happens when something is the target of a :outer)
      * trying to return values using them when invoked. (See TT#500 for the
      * report of the bug this fixes). */
-    opcode_t *save_results = CONTEXT(interp)->current_results;
-    CONTEXT(interp)->current_results = NULL;
+    opcode_t *save_results = Parrot_pcc_get_results(interp, CURRENT_CONTEXT(interp));
+    Parrot_pcc_set_results(interp, CURRENT_CONTEXT(interp), NULL);
     sub = imcc_compile(interp, s, 0, &error_message);
-    CONTEXT(interp)->current_results = save_results;
+    Parrot_pcc_set_results(interp, CURRENT_CONTEXT(interp), save_results);
 
     if (sub)
         return sub;
@@ -904,7 +904,7 @@
     const char                *ext;
     FILE                      *fp;
     STRING                    *fs;
-    Parrot_Context            *ignored;
+    PMC                       *ignored;
 
     /* need at least 3 regs for compilation of constant math e.g.
      * add_i_ic_ic - see also IMCC_subst_constants() */

Modified: trunk/compilers/imcc/pbc.c
==============================================================================
--- trunk/compilers/imcc/pbc.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/compilers/imcc/pbc.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -1280,9 +1280,9 @@
     }
 
     /* could be eval too; check if :outer is the current sub */
-    current = CONTEXT(interp)->current_sub;
+    current = Parrot_pcc_get_sub(interp, CURRENT_CONTEXT(interp));
 
-    if (!current)
+    if (PMC_IS_NULL(current))
         IMCC_fatal(interp, 1, "Undefined :outer sub '%s'.\n",
                    unit->outer->name);
 
@@ -1434,7 +1434,7 @@
     sub->namespace_name = ns_pmc;
     sub->start_offs     = offs;
     sub->end_offs       = end;
-    sub->HLL_id         = CONTEXT(interp)->current_HLL;
+    sub->HLL_id         = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp));
 
     for (i = 0; i < 4; ++i)
         sub->n_regs_used[i] = unit->n_regs_used[i];

Modified: trunk/config/gen/makefiles/root.in
==============================================================================
--- trunk/config/gen/makefiles/root.in	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/config/gen/makefiles/root.in	Thu Sep  3 11:56:50 2009	(r40958)
@@ -441,6 +441,7 @@
     $(SRC_DIR)/interp/inter_create$(O)  \
     $(SRC_DIR)/interp/inter_misc$(O)  \
     $(SRC_DIR)/call/ops$(O)  \
+    $(SRC_DIR)/call/context$(O) \
     $(SRC_DIR)/key$(O) \
     $(SRC_DIR)/library$(O) \
     $(SRC_DIR)/list$(O) \

Modified: trunk/include/parrot/call.h
==============================================================================
--- trunk/include/parrot/call.h	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/include/parrot/call.h	Thu Sep  3 11:56:50 2009	(r40958)
@@ -16,6 +16,23 @@
 #ifndef PARROT_INTER_CALL_H_GUARD
 #define PARROT_INTER_CALL_H_GUARD
 
+#include "parrot/context.h"
+
+/* Wrap the jump buffer in a struct, to make it a linked list. Jump buffers are
+ * used to resume execution at a point in the runloop where an exception
+ * handler can be run. Ultimately this information should be part of
+ * Parrot_Context, but at this point a new context isn't created for every
+ * runloop ID, so it still needs to be a separate stack for a while longer. */
+
+typedef struct parrot_runloop_t {
+    Parrot_jump_buff         resume;        /* jmp_buf */
+    struct parrot_runloop_t *prev;          /* interpreter's runloop
+                                             * jump buffer stack */
+    opcode_t                *handler_start; /* Used in exception handling */
+} parrot_runloop_t;
+
+typedef parrot_runloop_t Parrot_runloop;
+
 typedef enum call_state_mode {
     /* argument fetching/putting modes */
     CALL_STATE_SIG     = 0x100, /* runops, nci. In case we're interfacing with
@@ -51,7 +68,7 @@
         } op;
     } u;
 
-    Parrot_Context *ctx;     /* the source or destination context */
+    PMC   *ctx;              /* the source or destination context */
     INTVAL used;             /* src: whether this argument has been consumed
                               * (or: whether the previous arg has?) */
     INTVAL i;                /* number of args/params already processed */
@@ -131,7 +148,7 @@
 
 PARROT_EXPORT
 int Parrot_init_arg_indexes_and_sig_pmc(PARROT_INTERP,
-    ARGIN(Parrot_Context *ctx),
+    ARGIN(PMC *ctx),
     ARGIN_NULLOK(opcode_t *indexes),
     ARGIN_NULLOK(PMC *sig_pmc),
     ARGMOD(call_state_item *sti))
@@ -151,7 +168,7 @@
 
 PARROT_EXPORT
 int Parrot_init_arg_op(PARROT_INTERP,
-    ARGIN(Parrot_Context *ctx),
+    ARGIN(PMC *ctx),
     ARGIN_NULLOK(opcode_t *pc),
     ARGIN(call_state_item *sti))
         __attribute__nonnull__(1)
@@ -160,7 +177,7 @@
 
 PARROT_EXPORT
 int Parrot_init_arg_sig(PARROT_INTERP,
-    ARGIN(Parrot_Context *ctx),
+    ARGIN(PMC *ctx),
     ARGIN(const char *sig),
     ARGIN_NULLOK(void *ap),
     ARGMOD(call_state_item *sti))
@@ -181,8 +198,8 @@
 
 PARROT_EXPORT
 void parrot_pass_args(PARROT_INTERP,
-    ARGMOD(Parrot_Context *src_ctx),
-    ARGMOD(Parrot_Context *dest_ctx),
+    ARGMOD(PMC *src_ctx),
+    ARGMOD(PMC *dest_ctx),
     ARGMOD_NULLOK(opcode_t *src_indexes),
     ARGMOD_NULLOK(opcode_t *dest_indexes),
     arg_pass_t param_or_result)
@@ -254,7 +271,8 @@
         FUNC_MODIFIES(*st);
 
 PARROT_EXPORT
-int Parrot_store_arg(SHIM_INTERP, ARGIN(const call_state *st))
+int Parrot_store_arg(PARROT_INTERP, ARGIN(const call_state *st))
+        __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_CANNOT_RETURN_NULL
@@ -262,7 +280,7 @@
 opcode_t * parrot_pass_args_fromc(PARROT_INTERP,
     ARGIN(const char *sig),
     ARGMOD(opcode_t *dest),
-    ARGIN(Parrot_Context *old_ctxp),
+    ARGIN(PMC *old_ctxp),
     va_list ap)
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -272,29 +290,27 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-void * set_retval(PARROT_INTERP, int sig_ret, ARGIN(Parrot_Context *ctx))
+void * set_retval(PARROT_INTERP, int sig_ret, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
-FLOATVAL set_retval_f(PARROT_INTERP,
-    int sig_ret,
-    ARGIN(Parrot_Context *ctx))
+FLOATVAL set_retval_f(PARROT_INTERP, int sig_ret, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
-INTVAL set_retval_i(PARROT_INTERP, int sig_ret, ARGIN(Parrot_Context *ctx))
+INTVAL set_retval_i(PARROT_INTERP, int sig_ret, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-PMC* set_retval_p(PARROT_INTERP, int sig_ret, ARGIN(Parrot_Context *ctx))
+PMC* set_retval_p(PARROT_INTERP, int sig_ret, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-STRING* set_retval_s(PARROT_INTERP, int sig_ret, ARGIN(Parrot_Context *ctx))
+STRING* set_retval_s(PARROT_INTERP, int sig_ret, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
         __attribute__nonnull__(3);
 
@@ -362,7 +378,8 @@
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(st)
 #define ASSERT_ARGS_Parrot_store_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(st)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(st)
 #define ASSERT_ARGS_parrot_pass_args_fromc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(sig) \
@@ -495,7 +512,7 @@
 PARROT_EXPORT
 PARROT_IGNORABLE_RESULT
 PARROT_CANNOT_RETURN_NULL
-Parrot_Context * Parrot_runops_fromc(PARROT_INTERP, ARGIN(PMC *sub))
+PMC * Parrot_runops_fromc(PARROT_INTERP, ARGIN(PMC *sub))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -684,6 +701,449 @@
     } \
 } while (0)
 
+/* Context manipulating functions */
+
+/* HEADERIZER BEGIN: src/call/context.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+struct PackFile_Constant ** Parrot_pcc_constants(PARROT_INTERP,
+    ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+UINTVAL Parrot_pcc_dec_recursion_depth(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_errors_off(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_errors_on(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+UINTVAL Parrot_pcc_errors_test(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    UINTVAL flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC* Parrot_pcc_get_caller_ctx(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+Parrot_Context* Parrot_pcc_get_context_struct(PARROT_INTERP,
+    ARGIN_NULLOK(PMC *ctx))
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC* Parrot_pcc_get_continuation(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC* Parrot_pcc_get_handlers(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+INTVAL Parrot_pcc_get_HLL(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+INTVAL Parrot_pcc_get_int_constant(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    INTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC* Parrot_pcc_get_lex_pad(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC* Parrot_pcc_get_namespace(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+FLOATVAL Parrot_pcc_get_num_constant(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    INTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC* Parrot_pcc_get_object(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC* Parrot_pcc_get_outer_ctx(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+opcode_t* Parrot_pcc_get_pc(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC* Parrot_pcc_get_pmc_constant(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+size_t Parrot_pcc_get_pred_offset(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+UINTVAL Parrot_pcc_get_recursion_depth(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+opcode_t* Parrot_pcc_get_results(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC* Parrot_pcc_get_results_signature(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+STRING* Parrot_pcc_get_string_constant(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    INTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC* Parrot_pcc_get_sub(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+UINTVAL Parrot_pcc_inc_recursion_depth(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_set_caller_ctx(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN(PMC *caller_ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+void Parrot_pcc_set_constants(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN_NULLOK(struct PackFile_Constant **constants))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_set_continuation(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN_NULLOK(PMC *_continuation))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_set_handers(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN(PMC *handlers))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_EXPORT
+void Parrot_pcc_set_HLL(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL hll)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_set_lex_pad(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN(PMC *lex_pad))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_EXPORT
+void Parrot_pcc_set_namespace(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN_NULLOK(PMC *_namespace))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_set_object(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN_NULLOK(PMC *object))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_set_outer_ctx(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN(PMC *outer_ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_EXPORT
+void Parrot_pcc_set_pc(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN_NULLOK(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_set_pred_offset(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    size_t pred_offset)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_set_results(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN_NULLOK(opcode_t *pc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_set_results_signature(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN_NULLOK(PMC *sig))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_set_sub(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN_NULLOK(PMC *sub))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_trace_flags_off(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    UINTVAL flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_trace_flags_on(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    UINTVAL flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+UINTVAL Parrot_pcc_trace_flags_test(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    UINTVAL flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_pcc_warnings_off(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+UINTVAL Parrot_pcc_warnings_on(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    UINTVAL flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+UINTVAL Parrot_pcc_warnings_test(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    UINTVAL flags)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+#define ASSERT_ARGS_Parrot_pcc_constants __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_dec_recursion_depth \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_errors_off __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_errors_on __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_errors_test __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_caller_ctx __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_context_struct __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_pcc_get_continuation __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_handlers __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_HLL __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_int_constant __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_lex_pad __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_num_constant __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_object __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_outer_ctx __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_pc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_pmc_constant __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_pred_offset __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_recursion_depth \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_results __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_results_signature \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_string_constant \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_sub __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_inc_recursion_depth \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_caller_ctx __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx) \
+    || PARROT_ASSERT_ARG(caller_ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_constants __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_continuation __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_handers __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx) \
+    || PARROT_ASSERT_ARG(handlers)
+#define ASSERT_ARGS_Parrot_pcc_set_HLL __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_lex_pad __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx) \
+    || PARROT_ASSERT_ARG(lex_pad)
+#define ASSERT_ARGS_Parrot_pcc_set_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_object __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_outer_ctx __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx) \
+    || PARROT_ASSERT_ARG(outer_ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_pc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_pred_offset __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_results __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_results_signature \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_sub __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_trace_flags_off __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_trace_flags_on __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_trace_flags_test __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_warnings_off __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_warnings_on __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_warnings_test __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: src/call/context.c */
 
 #endif /* PARROT_INTER_CALL_H_GUARD */
 

Added: trunk/include/parrot/context.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/include/parrot/context.h	Thu Sep  3 11:56:50 2009	(r40958)
@@ -0,0 +1,74 @@
+/* context.h
+ *  Copyright (C) 2009, Parrot Foundation.
+ *  SVN Info
+ *     $Id$
+ *  Overview:
+ *     Context
+ */
+
+#ifndef PARROT_CONTEXT_H_GUARD
+#define PARROT_CONTEXT_H_GUARD
+
+struct PackFile_Constant;
+
+typedef union {
+    PMC         **regs_p;
+    STRING      **regs_s;
+} Regs_ps;
+
+typedef union {
+    FLOATVAL     *regs_n;
+    INTVAL       *regs_i;
+} Regs_ni;
+
+struct Parrot_Context {
+    PMC     *caller_ctx;      /* caller context */
+    Regs_ni  bp;              /* pointers to FLOATVAL & INTVAL */
+    Regs_ps  bp_ps;           /* pointers to PMC & STR */
+
+    /* end common header */
+    INTVAL   n_regs_used[4];   /* INSP in PBC points to Sub */
+    PMC      *lex_pad;         /* LexPad PMC */
+    PMC      *outer_ctx;       /* outer context, if a closure */
+
+    /* new call scheme and introspective variables */
+    PMC      *current_sub;           /* the Sub we are executing */
+
+    /* for now use a return continuation PMC */
+    PMC      *handlers;              /* local handlers for the context */
+    PMC      *current_cont;          /* the return continuation PMC */
+    PMC      *current_object;        /* current object if a method call */
+    PMC      *current_namespace;     /* The namespace we're currently in */
+    PMC      *results_signature;     /* non-const results signature PMC */
+    opcode_t *current_pc;            /* program counter of Sub invocation */
+    opcode_t *current_results;       /* ptr into code with get_results opcode */
+
+    /* deref the constants - we need it all the time */
+    struct PackFile_Constant **constants;
+
+    INTVAL                 current_HLL;     /* see also src/hll.c */
+
+    UINTVAL                warns;           /* Keeps track of what warnings
+                                             * have been activated */
+    UINTVAL                errors;          /* fatals that can be turned off */
+    UINTVAL                trace_flags;
+    UINTVAL                recursion_depth; /* Sub call recursion depth */
+
+    /* code->prederefed.code - code->base.data in opcodes
+     * to simplify conversion between code ptrs in e.g. invoke */
+    size_t pred_offset;
+};
+
+typedef struct Parrot_Context Parrot_Context;
+
+#define PMC_context(pmc) Parrot_cx_get_context(interp, (pmc))
+
+
+#endif /* PARROT_CONTEXT_H_GUARD */
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Modified: trunk/include/parrot/interpreter.h
==============================================================================
--- trunk/include/parrot/interpreter.h	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/include/parrot/interpreter.h	Thu Sep  3 11:56:50 2009	(r40958)
@@ -124,9 +124,9 @@
 #define Interp_debug_CLEAR(interp, flag) ((interp)->debug_flags &= ~(flag))
 #define Interp_debug_TEST(interp, flag)  ((interp)->debug_flags & (flag))
 
-#define Interp_trace_SET(interp, flag)   (CONTEXT(interp)->trace_flags |= (flag))
-#define Interp_trace_CLEAR(interp, flag) (CONTEXT(interp)->trace_flags &= ~(flag))
-#define Interp_trace_TEST(interp, flag)  (CONTEXT(interp)->trace_flags & (flag))
+#define Interp_trace_SET(interp, flag)   Parrot_pcc_trace_flags_on(interp, interp->ctx, (flag))
+#define Interp_trace_CLEAR(interp, flag) Parrot_pcc_trace_flags_off(interp, interp->ctx, (flag))
+#define Interp_trace_TEST(interp, flag)  Parrot_pcc_trace_flags_test(interp, interp->ctx, (flag))
 
 #define Interp_core_SET(interp, core)   ((interp)->run_core = (core))
 #define Interp_core_TEST(interp, core)  ((interp)->run_core == (core))
@@ -140,6 +140,7 @@
 
 #include "parrot/debugger.h"
 #include "parrot/multidispatch.h"
+#include "parrot/call.h"
 
 typedef struct warnings_t {
     Warnings_classes classes;
@@ -176,64 +177,6 @@
  * defined in imcc/imc.h */
 struct _imc_info_t;
 
-typedef union {
-    PMC         **regs_p;
-    STRING      **regs_s;
-} Regs_ps;
-
-typedef union {
-    FLOATVAL     *regs_n;
-    INTVAL       *regs_i;
-} Regs_ni;
-
-/* If CTX_LEAK_DEBUG is enabled, then turning on PARROT_CTX_DESTROY_DEBUG_FLAG
-   will print tons of detail about when Parrot_Context structures are allocated
-   and deallocated to stderr.  If CTX_LEAK_DEBUG is disabled, then all of the
-   relevant code is omitted, and PARROT_CTX_DESTROY_DEBUG_FLAG has no effect.
- */
-#define CTX_LEAK_DEBUG 1
-
-struct Parrot_Context {
-    /* common header with Interp_Context */
-    struct Parrot_Context *caller_ctx;      /* caller context */
-    Regs_ni                bp;              /* pointers to FLOATVAL & INTVAL */
-    Regs_ps                bp_ps;           /* pointers to PMC & STR */
-
-    /* end common header */
-    INTVAL                n_regs_used[4];   /* INSP in PBC points to Sub */
-    PMC                   *lex_pad;         /* LexPad PMC */
-    struct Parrot_Context *outer_ctx;       /* outer context, if a closure */
-
-    /* new call scheme and introspective variables */
-    PMC      *current_sub;           /* the Sub we are executing */
-
-    /* for now use a return continuation PMC */
-    PMC      *handlers;              /* local handlers for the context */
-    PMC      *current_cont;          /* the return continuation PMC */
-    PMC      *current_object;        /* current object if a method call */
-    PMC      *current_namespace;     /* The namespace we're currently in */
-    PMC      *results_signature;     /* non-const results signature PMC */
-    opcode_t *current_pc;            /* program counter of Sub invocation */
-    opcode_t *current_results;       /* ptr into code with get_results opcode */
-
-    /* deref the constants - we need it all the time */
-    struct PackFile_Constant **constants;
-
-    INTVAL                 current_HLL;     /* see also src/hll.c */
-    size_t                 regs_mem_size;   /* memory occupied by registers */
-    int                    ref_count;       /* how often refered to */
-    int                    gc_mark;         /* marked in gc run */
-
-    UINTVAL                warns;           /* Keeps track of what warnings
-                                             * have been activated */
-    UINTVAL                errors;          /* fatals that can be turned off */
-    UINTVAL                trace_flags;
-    UINTVAL                recursion_depth; /* Sub call recursion depth */
-
-    /* code->prederefed.code - code->base.data in opcodes
-     * to simplify conversion between code ptrs in e.g. invoke */
-    size_t pred_offset;
-};
 
 struct _Thread_data;    /* in thread.h */
 struct _Caches;         /* caches .h */
@@ -250,21 +193,19 @@
     size_t n_allocated;                 /* allocated size of it */
 } Prederef;
 
+/*
+ * Get Context from interpeter.
+ */
+#define CONTEXT(interp)         Parrot_pcc_get_context_struct((interp), (interp)->ctx)
 
 /*
- * This is an 'inlined' copy of the first 3 Context items for
- * faster access of registers mainly
- * During a context switch a 3 pointers are set
+ * Helper macros to fetch fields from context.
+ *
+ * Not considered as part of public API. Should be replaced with proper accessor
+ * functions to manipulate Context.
  */
-typedef struct Interp_Context {
-    /* common header */
-    struct Parrot_Context *state;       /* context  */
-    Regs_ni                bp;          /* pointers to FLOATVAL & INTVAL */
-    Regs_ps                bp_ps;       /* pointers to PMC & STR */
-    /* end common header */
-} Interp_Context;
+#define CURRENT_CONTEXT(interp) ((interp)->ctx)
 
-#define CONTEXT(interp) ((interp)->ctx.state)
 
 #define CHUNKED_CTX_MEM 0           /* no longer works, but will be reinstated
                                      * some day; see src/register.c for details.
@@ -283,28 +224,12 @@
 
 } context_mem;
 
-/* Wrap the jump buffer in a struct, to make it a linked list. Jump buffers are
- * used to resume execution at a point in the runloop where an exception
- * handler can be run. Ultimately this information should be part of
- * Parrot_Context, but at this point a new context isn't created for every
- * runloop ID, so it still needs to be a separate stack for a while longer. */
-
-typedef struct parrot_runloop_t {
-    Parrot_jump_buff         resume;        /* jmp_buf */
-    struct parrot_runloop_t *prev;          /* interpreter's runloop
-                                             * jump buffer stack */
-    opcode_t                *handler_start; /* Used in exception handling */
-} parrot_runloop_t;
-
-typedef parrot_runloop_t Parrot_runloop;
-
 
 struct _handler_node_t; /* forward def - exit.h */
 
 /* The actual interpreter structure */
 struct parrot_interp_t {
-    struct Interp_Context ctx;
-    context_mem           ctx_mem;            /* ctx memory managment */
+    PMC           *ctx;                       /* current Context */
 
     struct Arenas *arena_base;                /* Pointer to this interpreter's
                                                * arena */
@@ -707,12 +632,6 @@
 PARROT_EXPORT void disable_event_checking(PARROT_INTERP);
 PARROT_EXPORT void enable_event_checking(PARROT_INTERP);
 
-#if CTX_LEAK_DEBUG
-#  define Parrot_context_ref(a, b) Parrot_context_ref_trace((a), (b), __FILE__, __LINE__)
-#else /* !CTX_LEAK_DEBUG */
-#  define Parrot_context_ref(a, b) (((b)->ref_count++), (b))
-#endif /* CTX_LEAK_DEBUG */
-
 #else /* !PARROT_IN_CORE */
 
 typedef void * *(*native_func_t)(PARROT_INTERP,

Modified: trunk/include/parrot/register.h
==============================================================================
--- trunk/include/parrot/register.h	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/include/parrot/register.h	Thu Sep  3 11:56:50 2009	(r40958)
@@ -15,20 +15,21 @@
 
 #include "parrot/string.h"
 #include "parrot/compiler.h"
+#include "parrot/context.h"         /* Parrot_Context */
 
 /*
  * Macros to make accessing registers more convenient/readable.
  */
 
-#define CTX_REG_NUM(ctx, x) (ctx)->bp.regs_n[-1L-(x)]
-#define CTX_REG_INT(ctx, x) (ctx)->bp.regs_i[x]
-#define CTX_REG_PMC(ctx, x) (ctx)->bp_ps.regs_p[-1L-(x)]
-#define CTX_REG_STR(ctx, x) (ctx)->bp_ps.regs_s[x]
-
-#define REG_NUM(interp, x) CTX_REG_NUM(&(interp)->ctx, (x))
-#define REG_INT(interp, x) CTX_REG_INT(&(interp)->ctx, (x))
-#define REG_PMC(interp, x) CTX_REG_PMC(&(interp)->ctx, (x))
-#define REG_STR(interp, x) CTX_REG_STR(&(interp)->ctx, (x))
+#define CTX_REG_NUM(p, x) (*Parrot_pcc_get_FLOATVAL_reg(interp, (p), (x)))
+#define CTX_REG_INT(p, x) (*Parrot_pcc_get_INTVAL_reg(interp, (p), (x)))
+#define CTX_REG_PMC(p, x) (*Parrot_pcc_get_PMC_reg(interp, (p), (x)))
+#define CTX_REG_STR(p, x) (*Parrot_pcc_get_STRING_reg(interp, (p), (x)))
+
+#define REG_NUM(interp, x) (*Parrot_pcc_get_FLOATVAL_reg((interp), (interp)->ctx, (x)))
+#define REG_INT(interp, x) (*Parrot_pcc_get_INTVAL_reg((interp), (interp)->ctx, (x)))
+#define REG_PMC(interp, x) (*Parrot_pcc_get_PMC_reg((interp), (interp)->ctx, (x)))
+#define REG_STR(interp, x) (*Parrot_pcc_get_STRING_reg((interp), (interp)->ctx, (x)))
 
 /*
  * and a set of macros to access a register by offset, used
@@ -43,7 +44,7 @@
 #define REGNO_STR 2
 #define REGNO_PMC 3
 
-#define __CTX interp->ctx.state
+#define __CTX Parrot_pcc_get_context_struct(interp, interp->ctx)
 #define _SIZEOF_INTS    (sizeof (INTVAL) * __CTX->n_regs_used[REGNO_INT])
 #define _SIZEOF_NUMS    (sizeof (FLOATVAL) * __CTX->n_regs_used[REGNO_NUM])
 #define _SIZEOF_PMCS    (sizeof (PMC*) * __CTX->n_regs_used[REGNO_PMC])
@@ -56,8 +57,6 @@
 #define REG_OFFS_STR(x) (sizeof (STRING*) * (x) + _SIZEOF_INTS + _SIZEOF_PMCS)
 
 
-typedef struct Parrot_Context Parrot_Context; /* parrot/interpreter.h */
-
 /* HEADERIZER BEGIN: src/gc/alloc_register.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
@@ -78,27 +77,81 @@
         __attribute__nonnull__(1);
 
 PARROT_EXPORT
+void parrot_gc_context(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+FLOATVAL * Parrot_pcc_get_FLOATVAL_reg(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    INTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
-Parrot_Context * Parrot_context_ref_trace(PARROT_INTERP,
-    ARGMOD(Parrot_Context *ctx),
-    ARGIN(const char *file),
-    int line)
+INTVAL * Parrot_pcc_get_INTVAL_reg(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    INTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC ** Parrot_pcc_get_PMC_reg(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+Regs_ni* Parrot_pcc_get_regs_ni(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+Regs_ps* Parrot_pcc_get_regs_ps(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+int Parrot_pcc_get_regs_used(PARROT_INTERP, ARGIN(PMC *ctx), int type)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+STRING ** Parrot_pcc_get_STRING_reg(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    INTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+void Parrot_pcc_set_regs_ni(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN(Regs_ni *bp))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*ctx);
+        __attribute__nonnull__(3);
 
 PARROT_EXPORT
-void Parrot_free_context(PARROT_INTERP,
-    ARGMOD(Parrot_Context *ctx),
-    int deref)
+PARROT_CANNOT_RETURN_NULL
+void Parrot_pcc_set_regs_ps(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN(Regs_ps *bp_ps))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        FUNC_MODIFIES(*ctx);
+        __attribute__nonnull__(3);
 
 PARROT_EXPORT
-void parrot_gc_context(PARROT_INTERP)
-        __attribute__nonnull__(1);
+void Parrot_pcc_set_regs_used(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    int type,
+    INTVAL num)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
 
 PARROT_EXPORT
 void Parrot_pop_context(PARROT_INTERP)
@@ -107,31 +160,24 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-Parrot_Context * Parrot_push_context(PARROT_INTERP,
-    ARGIN(const INTVAL *n_regs_used))
+PMC * Parrot_push_context(PARROT_INTERP, ARGIN(const INTVAL *n_regs_used))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-PARROT_EXPORT
-void Parrot_set_context_threshold(SHIM_INTERP, SHIM(Parrot_Context *ctx));
-
 void create_initial_context(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-void destroy_context(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-Parrot_Context * Parrot_alloc_context(PARROT_INTERP,
+PMC * Parrot_alloc_context(PARROT_INTERP,
     ARGIN(const INTVAL *number_regs_used),
-    ARGIN_NULLOK(Parrot_Context *old))
+    ARGIN_NULLOK(PMC *old))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-Parrot_Context * Parrot_set_new_context(PARROT_INTERP,
+PMC * Parrot_set_new_context(PARROT_INTERP,
     ARGIN(const INTVAL *number_regs_used))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -144,25 +190,47 @@
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_clear_s __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_Parrot_context_ref_trace __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+#define ASSERT_ARGS_parrot_gc_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_pcc_get_FLOATVAL_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_INTVAL_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_PMC_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_regs_ni __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_regs_ps __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_regs_used __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_STRING_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_regs_ni __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx) \
+    || PARROT_ASSERT_ARG(bp)
+#define ASSERT_ARGS_Parrot_pcc_set_regs_ps __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx) \
-    || PARROT_ASSERT_ARG(file)
-#define ASSERT_ARGS_Parrot_free_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+    || PARROT_ASSERT_ARG(bp_ps)
+#define ASSERT_ARGS_Parrot_pcc_set_regs_used __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
-#define ASSERT_ARGS_parrot_gc_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_pop_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_push_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(n_regs_used)
-#define ASSERT_ARGS_Parrot_set_context_threshold __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_create_initial_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
-#define ASSERT_ARGS_destroy_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_alloc_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(number_regs_used)

Modified: trunk/include/parrot/sub.h
==============================================================================
--- trunk/include/parrot/sub.h	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/include/parrot/sub.h	Thu Sep  3 11:56:50 2009	(r40958)
@@ -155,12 +155,12 @@
 
 typedef struct Parrot_cont {
     /* continuation destination */
-    PackFile_ByteCode *seg;          /* bytecode segment */
-    opcode_t *address;               /* start of bytecode, addr to continue */
-    struct Parrot_Context *to_ctx;   /* pointer to dest context */
+    PackFile_ByteCode   *seg;               /* bytecode segment */
+    opcode_t            *address;           /* start of bytecode, addr to continue */
+    PMC                 *to_ctx;            /* pointer to dest context */
     /* a Continuation keeps the from_ctx alive */
-    struct Parrot_Context *from_ctx; /* sub, this cont is returning from */
-    opcode_t *current_results;       /* ptr into code with get_results opcode
+    PMC                 *from_ctx;          /* sub, this cont is returning from */
+    opcode_t            *current_results;   /* ptr into code with get_results opcode
                                         full continuation only */
     int runloop_id;                  /* id of the creating runloop. */
     int invoked;                     /* flag when a handler has been invoked. */
@@ -190,7 +190,7 @@
 
 PARROT_EXPORT
 int Parrot_Context_get_info(PARROT_INTERP,
-    ARGIN(const Parrot_Context *ctx),
+    ARGIN(PMC *ctx),
     ARGOUT(Parrot_Context_info *info))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -200,8 +200,7 @@
 PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-STRING* Parrot_Context_infostr(PARROT_INTERP,
-    ARGIN(const Parrot_Context *ctx))
+STRING* Parrot_Context_infostr(PARROT_INTERP, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -229,11 +228,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*cont);
 
-void mark_context(PARROT_INTERP, ARGMOD(Parrot_Context* ctx))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(* ctx);
-
 void mark_context_start(void);
 PARROT_MALLOC
 PARROT_CANNOT_RETURN_NULL
@@ -268,7 +262,7 @@
 PARROT_WARN_UNUSED_RESULT
 PMC* Parrot_find_pad(PARROT_INTERP,
     ARGIN(STRING *lex_name),
-    ARGIN(const Parrot_Context *ctx))
+    ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3);
@@ -294,9 +288,6 @@
 #define ASSERT_ARGS_invalidate_retc_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(cont)
-#define ASSERT_ARGS_mark_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(ctx)
 #define ASSERT_ARGS_mark_context_start __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_new_continuation __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)

Modified: trunk/include/parrot/warnings.h
==============================================================================
--- trunk/include/parrot/warnings.h	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/include/parrot/warnings.h	Thu Sep  3 11:56:50 2009	(r40958)
@@ -35,19 +35,13 @@
 
 /* &end_gen */
 
-#define PARROT_WARNINGS_on(interp, flag) do { \
-    CONTEXT((interp))->warns |= (flag); } while (0)
-#define PARROT_WARNINGS_off(interp, flag) do { \
-    CONTEXT((interp))->warns &= ~(flag); } while (0)
-#define PARROT_WARNINGS_test(interp, flag)  \
-    (CONTEXT((interp))->warns & (flag))
-
-#define PARROT_ERRORS_on(interp, flag) do { \
-    CONTEXT((interp))->errors |= (flag); } while (0)
-#define PARROT_ERRORS_off(interp, flag) do { \
-    CONTEXT((interp))->errors &= ~(flag); } while (0)
-#define PARROT_ERRORS_test(interp, flag)  \
-    (CONTEXT((interp))->errors & (flag))
+#define PARROT_WARNINGS_on(interp, flag)   Parrot_pcc_warnings_on((interp), (interp)->ctx, (flag))
+#define PARROT_WARNINGS_off(interp, flag)  Parrot_pcc_warnings_off((interp), (interp)->ctx, (flag))
+#define PARROT_WARNINGS_test(interp, flag) Parrot_pcc_warnings_test((interp), (interp)->ctx, (flag))
+
+#define PARROT_ERRORS_on(interp, flag)   Parrot_pcc_errors_on((interp), (interp)->ctx, (flag))
+#define PARROT_ERRORS_off(interp, flag)  Parrot_pcc_errors_off((interp), (interp)->ctx, (flag))
+#define PARROT_ERRORS_test(interp, flag) Parrot_pcc_errors_test((interp), (interp)->ctx, (flag))
 
 #if defined(PARROT_IN_CORE)
 

Modified: trunk/lib/Parrot/OpTrans/C.pm
==============================================================================
--- trunk/lib/Parrot/OpTrans/C.pm	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/lib/Parrot/OpTrans/C.pm	Thu Sep  3 11:56:50 2009	(r40958)
@@ -60,7 +60,7 @@
 #define NREG(i) REG_NUM(interp, cur_opcode[i])
 #define PREG(i) REG_PMC(interp, cur_opcode[i])
 #define SREG(i) REG_STR(interp, cur_opcode[i])
-#define CONST(i) CONTEXT(interp)->constants[cur_opcode[i]]
+#define CONST(i) Parrot_pcc_constants(interp, interp->ctx)[cur_opcode[i]]
 END
 }
 

Modified: trunk/lib/Parrot/OpTrans/CGP.pm
==============================================================================
--- trunk/lib/Parrot/OpTrans/CGP.pm	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/lib/Parrot/OpTrans/CGP.pm	Thu Sep  3 11:56:50 2009	(r40958)
@@ -68,7 +68,7 @@
     return $pred_def . <<END;
 /* defines - $0 -> $type */
 #  define opcode_to_prederef(i, op)   \\
-     (opcode_t *) (op   - CONTEXT(i)->pred_offset)
+     (opcode_t *) (op   - Parrot_pcc_get_pred_offset(interp, i->ctx))
 END
 }
 
@@ -91,7 +91,7 @@
         return "if ($addr == 0)
           return 0;
    Parrot_cx_handle_tasks(interp, interp->scheduler);
-   _reg_base = (char*)interp->ctx.bp.regs_i;
+   _reg_base = (char*)Parrot_pcc_get_regs_ni(interp, CURRENT_CONTEXT(interp))->regs_i;
    goto **(void **)(cur_opcode = opcode_to_prederef(interp, $addr))";
     }
 }
@@ -107,7 +107,7 @@
     my ( $self, $offset ) = @_;
 
     # this must be a single expression, in case it's in a single-statement if
-    return "do {\nCONTEXT(interp)->current_pc = CUR_OPCODE + $offset;\n"
+    return "do {\nParrot_pcc_set_pc(interp, CURRENT_CONTEXT(interp), CUR_OPCODE + $offset);\n"
     .      "goto **(void **)(cur_opcode += $offset);\n} while (1)";
 }
 

Modified: trunk/lib/Parrot/OpTrans/CGoto.pm
==============================================================================
--- trunk/lib/Parrot/OpTrans/CGoto.pm	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/lib/Parrot/OpTrans/CGoto.pm	Thu Sep  3 11:56:50 2009	(r40958)
@@ -72,7 +72,7 @@
 #define NREG(i) REG_NUM(interp, cur_opcode[i])
 #define PREG(i) REG_PMC(interp, cur_opcode[i])
 #define SREG(i) REG_STR(interp, cur_opcode[i])
-#define CONST(i) CONTEXT(interp)->constants[cur_opcode[i]]
+#define CONST(i) Parrot_pcc_constants(interp, interp->ctx)[cur_opcode[i]]
 END
 }
 

Modified: trunk/lib/Parrot/OpTrans/CPrederef.pm
==============================================================================
--- trunk/lib/Parrot/OpTrans/CPrederef.pm	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/lib/Parrot/OpTrans/CPrederef.pm	Thu Sep  3 11:56:50 2009	(r40958)
@@ -38,7 +38,7 @@
 /* defines - $0 -> $type */
 #define REL_PC ((size_t)(cur_opcode - (opcode_t*)interp->code->prederef.code))
 #define CUR_OPCODE \\
-    ((opcode_t*)cur_opcode + CONTEXT(interp)->pred_offset)
+    ((opcode_t*)cur_opcode + Parrot_pcc_get_pred_offset(interp, CURRENT_CONTEXT(interp)))
 #define OP_AS_OFFS(o) (_reg_base + ((opcode_t*)cur_opcode)[o])
 
 END

Modified: trunk/lib/Parrot/OpTrans/CSwitch.pm
==============================================================================
--- trunk/lib/Parrot/OpTrans/CSwitch.pm	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/lib/Parrot/OpTrans/CSwitch.pm	Thu Sep  3 11:56:50 2009	(r40958)
@@ -76,7 +76,7 @@
     return $pred_def . <<END;
 /* defines - $0 -> $type */
 #  define opcode_to_prederef(i, op)   (op ? \\
-     (opcode_t*) (op   - CONTEXT(i)->pred_offset) : (opcode_t*)NULL)
+     (opcode_t*) (op   - Parrot_pcc_get_pred_offset(interp, i->ctx)) : (opcode_t*)NULL)
 END
 }
 
@@ -154,7 +154,7 @@
 #endif
 
 SWITCH_RELOAD:
-    _reg_base = (char*)interp->ctx.bp.regs_i;
+    _reg_base = (char*)Parrot_pcc_get_regs_ni(interp, CURRENT_CONTEXT(interp))->regs_i;
     do {
 SWITCH_AGAIN:
     Parrot_cx_handle_tasks(interp, interp->scheduler);

Modified: trunk/lib/Parrot/Ops2c/Utils.pm
==============================================================================
--- trunk/lib/Parrot/Ops2c/Utils.pm	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/lib/Parrot/Ops2c/Utils.pm	Thu Sep  3 11:56:50 2009	(r40958)
@@ -685,7 +685,7 @@
     __asm__ ("jmp *4(%ebp)");  /* jump to ret addr, used by JIT */
 # endif
 #endif
-    _reg_base = (char*)interp->ctx.bp.regs_i;
+    _reg_base = (char*)Parrot_pcc_get_regs_ni(interp, CURRENT_CONTEXT(interp))->regs_i;
     goto **(void **)cur_opcode;
 
 END_C

Modified: trunk/lib/Parrot/Pmc2c/PCCMETHOD.pm
==============================================================================
--- trunk/lib/Parrot/Pmc2c/PCCMETHOD.pm	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/lib/Parrot/Pmc2c/PCCMETHOD.pm	Thu Sep  3 11:56:50 2009	(r40958)
@@ -394,16 +394,16 @@
     PMC      * const _param_sig   = pmc_new(interp, enum_class_FixedIntegerArray);
     PMC      *_return_sig         = PMCNULL;
 
-    Parrot_Context *_caller_ctx   = CONTEXT(interp);
-    PMC * const _ret_cont         = new_ret_continuation_pmc(interp, NULL);
-    Parrot_Context *_ctx          = Parrot_push_context(interp, _n_regs_used);
-    PMC *_ccont                   = PMCNULL;
+    PMC        *_caller_ctx = interp->ctx;
+    PMC * const _ret_cont   = new_ret_continuation_pmc(interp, NULL);
+    PMC        *_ctx        = Parrot_push_context(interp, _n_regs_used);
+    PMC        *_ccont      = PMCNULL;
 
 $set_params
     UNUSED(_return_indexes);
 
     if (_caller_ctx) {
-        _ccont = _caller_ctx->current_cont;
+        _ccont = Parrot_pcc_get_continuation(interp, _caller_ctx);
     }
     else {
         /* there is no point calling Parrot_ex_throw_from_c_args here, because
@@ -411,11 +411,11 @@
         exit_fatal(1, "No caller_ctx for continuation \%p.", _ccont);
     }
 
-    _ctx->current_cont            = _ret_cont;
-    PMC_cont(_ret_cont)->from_ctx = _ctx;
+    Parrot_pcc_set_continuation(interp, _ctx, _ret_cont);
+    PMC_cont(_ret_cont)->from_ctx       = _ctx;
 
-    _current_args                 = interp->current_args;
-    interp->current_args         = NULL;
+    _current_args                       = interp->current_args;
+    interp->current_args                = NULL;
 
 END
     $e->emit(<<"END");
@@ -429,9 +429,8 @@
 
     if (PObj_get_FLAGS(_ccont) & SUB_FLAG_TAILCALL) {
         PObj_get_FLAGS(_ccont) &= ~SUB_FLAG_TAILCALL;
-        --_ctx->recursion_depth;
-        _ctx->caller_ctx      = _caller_ctx->caller_ctx;
-        Parrot_free_context(interp, _caller_ctx, 1);
+        Parrot_pcc_dec_recursion_depth(interp, _ctx);
+        Parrot_pcc_set_caller_ctx(interp, _ctx, Parrot_pcc_get_caller_ctx(interp, _caller_ctx));
         interp->current_args = NULL;
     }
     /* BEGIN PARMS SCOPE */
@@ -466,7 +465,7 @@
 
     interp->returns_signature = _return_sig;
     parrot_pass_args(interp, _ctx, _caller_ctx, _return_indexes,
-        _caller_ctx->current_results, PARROT_PASS_RESULTS);
+        Parrot_pcc_get_results(interp, _caller_ctx), PARROT_PASS_RESULTS);
 END
     }
     $e_post->emit( <<"END", __FILE__, __LINE__ + 1 );

Added: trunk/src/call/context.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/src/call/context.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -0,0 +1,952 @@
+/*
+Copyright (C) 2009, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/context.c - Parrot_Context functions.
+
+=head1 DESCRIPTION
+
+=head2 Functions
+
+=over 4
+
+=cut
+
+*/
+
+#include "parrot/parrot.h"
+#include "parrot/call.h"
+
+
+/* HEADERIZER HFILE: include/parrot/call.h */
+
+/* HEADERIZER BEGIN: static */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: static */
+
+/*
+
+=item C<void Parrot_pcc_set_constants(PARROT_INTERP, PMC *ctx, struct
+PackFile_Constant **constants)>
+
+Get string constant from context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+void
+Parrot_pcc_set_constants(PARROT_INTERP, ARGIN(PMC *ctx),
+        ARGIN_NULLOK(struct PackFile_Constant **constants))
+{
+    ASSERT_ARGS(Parrot_pcc_set_constants)
+    Parrot_Context * c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->constants = constants;
+}
+
+/*
+
+=item C<INTVAL Parrot_pcc_get_int_constant(PARROT_INTERP, PMC *ctx, INTVAL idx)>
+
+Get FLOATVAL constant from context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+INTVAL
+Parrot_pcc_get_int_constant(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_int_constant)
+    Parrot_Context const * c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->constants[idx]->u.integer;
+}
+
+/*
+
+=item C<FLOATVAL Parrot_pcc_get_num_constant(PARROT_INTERP, PMC *ctx, INTVAL
+idx)>
+
+Get PMC constant from context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+FLOATVAL
+Parrot_pcc_get_num_constant(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_num_constant)
+    Parrot_Context const * c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->constants[idx]->u.number;
+}
+
+/*
+
+=item C<STRING* Parrot_pcc_get_string_constant(PARROT_INTERP, PMC *ctx, INTVAL
+idx)>
+
+Get string constant from context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+STRING*
+Parrot_pcc_get_string_constant(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_string_constant)
+    Parrot_Context const * c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->constants[idx]->u.string;
+}
+
+
+/*
+
+=item C<PMC* Parrot_pcc_get_pmc_constant(PARROT_INTERP, PMC *ctx, INTVAL idx)>
+
+Get PMC constant from context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC*
+Parrot_pcc_get_pmc_constant(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_pmc_constant)
+    Parrot_Context const * c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->constants[idx]->u.key;
+}
+
+
+/*
+
+=item C<struct PackFile_Constant ** Parrot_pcc_constants(PARROT_INTERP, PMC
+*ctx)>
+
+Get reference to constants.
+
+=cut
+
+*/
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+struct PackFile_Constant **
+Parrot_pcc_constants(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_constants)
+    return ((Parrot_Context*)(VTABLE_get_pointer(interp, ctx)))->constants;
+}
+
+
+
+/*
+
+=item C<Parrot_Context* Parrot_pcc_get_context_struct(PARROT_INTERP, PMC *ctx)>
+
+Fetch Parrot_Context from Context PMC.
+
+=cut
+
+*/
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+Parrot_Context*
+Parrot_pcc_get_context_struct(PARROT_INTERP, ARGIN_NULLOK(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_context_struct)
+    if (PMC_IS_NULL(ctx))
+        return NULL;
+
+    return (Parrot_Context*)(VTABLE_get_pointer(interp, ctx));
+}
+
+/*
+
+=item C<UINTVAL Parrot_pcc_get_recursion_depth(PARROT_INTERP, PMC *ctx)>
+
+Get recursion depth from context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+UINTVAL
+Parrot_pcc_get_recursion_depth(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_recursion_depth)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->recursion_depth;
+}
+
+/*
+
+=item C<UINTVAL Parrot_pcc_inc_recursion_depth(PARROT_INTERP, PMC *ctx)>
+
+Increase recurtion depth. Returns previous recursion_depth value.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+UINTVAL
+Parrot_pcc_inc_recursion_depth(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_inc_recursion_depth)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->recursion_depth++;
+}
+
+/*
+
+=item C<UINTVAL Parrot_pcc_dec_recursion_depth(PARROT_INTERP, PMC *ctx)>
+
+Decrease recurtion depth. Returns new recursion_depth value.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+UINTVAL
+Parrot_pcc_dec_recursion_depth(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_dec_recursion_depth)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return --c->recursion_depth;
+}
+
+/*
+
+=item C<PMC* Parrot_pcc_get_caller_ctx(PARROT_INTERP, PMC *ctx)>
+
+Get caller Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC*
+Parrot_pcc_get_caller_ctx(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_caller_ctx)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->caller_ctx;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_caller_ctx(PARROT_INTERP, PMC *ctx, PMC
+*caller_ctx)>
+
+Set caller Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_caller_ctx(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(PMC *caller_ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_set_caller_ctx)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->caller_ctx = caller_ctx;
+}
+
+/*
+
+=item C<PMC* Parrot_pcc_get_outer_ctx(PARROT_INTERP, PMC *ctx)>
+
+Get outer Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC*
+Parrot_pcc_get_outer_ctx(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_outer_ctx)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->outer_ctx;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_outer_ctx(PARROT_INTERP, PMC *ctx, PMC *outer_ctx)>
+
+Set outer Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_outer_ctx(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(PMC *outer_ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_set_outer_ctx)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->outer_ctx = outer_ctx;
+}
+
+/*
+
+=item C<PMC* Parrot_pcc_get_lex_pad(PARROT_INTERP, PMC *ctx)>
+
+Get LexPad.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC*
+Parrot_pcc_get_lex_pad(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_lex_pad)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->lex_pad;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_lex_pad(PARROT_INTERP, PMC *ctx, PMC *lex_pad)>
+
+Set LexPad.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_lex_pad(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(PMC *lex_pad))
+{
+    ASSERT_ARGS(Parrot_pcc_set_lex_pad)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->lex_pad = lex_pad;
+}
+
+/*
+
+=item C<PMC* Parrot_pcc_get_namespace(PARROT_INTERP, PMC *ctx)>
+
+Get namespace of Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC*
+Parrot_pcc_get_namespace(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_namespace)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->current_namespace;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_namespace(PARROT_INTERP, PMC *ctx, PMC *_namespace)>
+
+Set namespace of Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_namespace(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN_NULLOK(PMC *_namespace))
+{
+    ASSERT_ARGS(Parrot_pcc_set_namespace)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->current_namespace = _namespace;
+}
+
+/*
+
+=item C<INTVAL Parrot_pcc_get_HLL(PARROT_INTERP, PMC *ctx)>
+
+Get HLL of Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+INTVAL
+Parrot_pcc_get_HLL(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_HLL)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->current_HLL;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_HLL(PARROT_INTERP, PMC *ctx, INTVAL hll)>
+
+Set HLL of Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_HLL(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL hll)
+{
+    ASSERT_ARGS(Parrot_pcc_set_HLL)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->current_HLL = hll;
+}
+
+/*
+
+=item C<PMC* Parrot_pcc_get_handlers(PARROT_INTERP, PMC *ctx)>
+
+Get scheduler handlers.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC*
+Parrot_pcc_get_handlers(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_handlers)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->handlers;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_handers(PARROT_INTERP, PMC *ctx, PMC *handlers)>
+
+Set scheduler handlers.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_handers(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(PMC *handlers))
+{
+    ASSERT_ARGS(Parrot_pcc_set_handers)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->handlers = handlers;
+}
+
+/*
+
+=item C<PMC* Parrot_pcc_get_continuation(PARROT_INTERP, PMC *ctx)>
+
+Get continuation of Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC*
+Parrot_pcc_get_continuation(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_continuation)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->current_cont;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_continuation(PARROT_INTERP, PMC *ctx, PMC
+*_continuation)>
+
+Set continuation of Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_continuation(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN_NULLOK(PMC *_continuation))
+{
+    ASSERT_ARGS(Parrot_pcc_set_continuation)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->current_cont = _continuation;
+}
+
+/*
+
+=item C<PMC* Parrot_pcc_get_object(PARROT_INTERP, PMC *ctx)>
+
+Get object of Context (in method call).
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC*
+Parrot_pcc_get_object(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_object)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->current_object;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_object(PARROT_INTERP, PMC *ctx, PMC *object)>
+
+Set object of Context (in method call).
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_object(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN_NULLOK(PMC *object))
+{
+    ASSERT_ARGS(Parrot_pcc_set_object)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->current_object = object;
+}
+
+/*
+
+=item C<PMC* Parrot_pcc_get_sub(PARROT_INTERP, PMC *ctx)>
+
+Get Sub executed inside Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC*
+Parrot_pcc_get_sub(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_sub)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->current_sub;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_sub(PARROT_INTERP, PMC *ctx, PMC *sub)>
+
+Set Sub executed inside Context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_sub(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN_NULLOK(PMC *sub))
+{
+    ASSERT_ARGS(Parrot_pcc_set_sub)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->current_sub = sub;
+}
+
+/*
+
+=item C<opcode_t* Parrot_pcc_get_pc(PARROT_INTERP, PMC *ctx)>
+
+Get program counter of Sub invocation.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+opcode_t*
+Parrot_pcc_get_pc(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_pc)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->current_pc;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_pc(PARROT_INTERP, PMC *ctx, opcode_t *pc)>
+
+Set program counter of Sub invocation.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_pc(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN_NULLOK(opcode_t *pc))
+{
+    ASSERT_ARGS(Parrot_pcc_set_pc)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->current_pc = pc;
+}
+
+/*
+
+=item C<opcode_t* Parrot_pcc_get_results(PARROT_INTERP, PMC *ctx)>
+
+Set ptr into code with get_results opcode.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+opcode_t*
+Parrot_pcc_get_results(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_results)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->current_results;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_results(PARROT_INTERP, PMC *ctx, opcode_t *pc)>
+
+Set ptr into code with get_results opcode.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_results(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN_NULLOK(opcode_t *pc))
+{
+    ASSERT_ARGS(Parrot_pcc_set_results)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->current_results = pc;
+}
+
+/*
+
+=item C<PMC* Parrot_pcc_get_results_signature(PARROT_INTERP, PMC *ctx)>
+
+Set ptr into code with get_results opcode.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC*
+Parrot_pcc_get_results_signature(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_results_signature)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->results_signature;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_results_signature(PARROT_INTERP, PMC *ctx, PMC
+*sig)>
+
+Set ptr into code with get_results opcode.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_results_signature(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN_NULLOK(PMC *sig))
+{
+    ASSERT_ARGS(Parrot_pcc_set_results_signature)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->results_signature = sig;
+}
+
+
+/*
+
+=item C<size_t Parrot_pcc_get_pred_offset(PARROT_INTERP, PMC *ctx)>
+
+Get pred_offset
+
+=cut
+
+*/
+
+PARROT_EXPORT
+size_t
+Parrot_pcc_get_pred_offset(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_pred_offset)
+    Parrot_Context const *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->pred_offset;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_set_pred_offset(PARROT_INTERP, PMC *ctx, size_t
+pred_offset)>
+
+Set pred_offset
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_set_pred_offset(PARROT_INTERP, ARGIN(PMC *ctx), size_t pred_offset)
+{
+    ASSERT_ARGS(Parrot_pcc_set_pred_offset)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->pred_offset = pred_offset;
+}
+
+
+/*
+
+=item C<UINTVAL Parrot_pcc_warnings_on(PARROT_INTERP, PMC *ctx, UINTVAL flags)>
+
+Set warnings flags.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+UINTVAL
+Parrot_pcc_warnings_on(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+{
+    ASSERT_ARGS(Parrot_pcc_warnings_on)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->warns |= flags;
+    return c->warns;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_warnings_off(PARROT_INTERP, PMC *ctx, UINTVAL flags)>
+
+Clear warnings flags.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_warnings_off(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+{
+    ASSERT_ARGS(Parrot_pcc_warnings_off)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->warns &= ~flags;
+}
+
+
+/*
+
+=item C<UINTVAL Parrot_pcc_warnings_test(PARROT_INTERP, PMC *ctx, UINTVAL
+flags)>
+
+Test warnings flags.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+UINTVAL
+Parrot_pcc_warnings_test(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+{
+    ASSERT_ARGS(Parrot_pcc_warnings_test)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->warns & flags;
+}
+
+/*
+
+=item C<void Parrot_pcc_errors_on(PARROT_INTERP, PMC *ctx, UINTVAL flags)>
+
+Set errors flags.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_errors_on(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+{
+    ASSERT_ARGS(Parrot_pcc_errors_on)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->errors |= flags;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_errors_off(PARROT_INTERP, PMC *ctx, UINTVAL flags)>
+
+Clear errors flags.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_errors_off(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+{
+    ASSERT_ARGS(Parrot_pcc_errors_off)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->errors &= ~flags;
+}
+
+
+/*
+
+=item C<UINTVAL Parrot_pcc_errors_test(PARROT_INTERP, PMC *ctx, UINTVAL flags)>
+
+Test errors flags.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+UINTVAL
+Parrot_pcc_errors_test(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+{
+    ASSERT_ARGS(Parrot_pcc_errors_test)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->errors & flags;
+}
+
+/*
+
+=item C<void Parrot_pcc_trace_flags_on(PARROT_INTERP, PMC *ctx, UINTVAL flags)>
+
+Set trace flags.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_trace_flags_on(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+{
+    ASSERT_ARGS(Parrot_pcc_trace_flags_on)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->trace_flags |= flags;
+}
+
+
+/*
+
+=item C<void Parrot_pcc_trace_flags_off(PARROT_INTERP, PMC *ctx, UINTVAL flags)>
+
+Clear trace flags.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_trace_flags_off(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+{
+    ASSERT_ARGS(Parrot_pcc_trace_flags_off)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    c->trace_flags &= ~flags;
+}
+
+
+/*
+
+=item C<UINTVAL Parrot_pcc_trace_flags_test(PARROT_INTERP, PMC *ctx, UINTVAL
+flags)>
+
+Test trace flags.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+UINTVAL
+Parrot_pcc_trace_flags_test(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL flags)
+{
+    ASSERT_ARGS(Parrot_pcc_trace_flags_test)
+    Parrot_Context *c = Parrot_pcc_get_context_struct(interp, ctx);
+    return c->trace_flags & flags;
+}
+
+/*
+
+=back
+
+*/
+
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Modified: trunk/src/call/ops.c
==============================================================================
--- trunk/src/call/ops.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/call/ops.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -28,7 +28,7 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-static Parrot_Context * runops_args(PARROT_INTERP,
+static PMC * runops_args(PARROT_INTERP,
     ARGIN(PMC *sub),
     ARGIN_NULLOK(PMC *obj),
     SHIM(STRING *meth),
@@ -134,7 +134,7 @@
 
 /*
 
-=item C<Parrot_Context * Parrot_runops_fromc(PARROT_INTERP, PMC *sub)>
+=item C<PMC * Parrot_runops_fromc(PARROT_INTERP, PMC *sub)>
 
 Runs the Parrot ops, called from C code. The function arguments are
 already setup according to Parrot calling conventions, the C<sub> argument
@@ -147,12 +147,12 @@
 PARROT_EXPORT
 PARROT_IGNORABLE_RESULT
 PARROT_CANNOT_RETURN_NULL
-Parrot_Context *
+PMC *
 Parrot_runops_fromc(PARROT_INTERP, ARGIN(PMC *sub))
 {
     ASSERT_ARGS(Parrot_runops_fromc)
     opcode_t offset, *dest;
-    Parrot_Context *ctx;
+    PMC *ctx;
 
     /* we need one return continuation with a NULL offset */
     PMC * const ret_c    = new_ret_continuation_pmc(interp, NULL);
@@ -169,7 +169,7 @@
         Parrot_ex_throw_from_c_args(interp, NULL, 1,
             "Subroutine returned a NULL address");
 
-    ctx    = CONTEXT(interp);
+    ctx    = CURRENT_CONTEXT(interp);
     offset = dest - interp->code->base.data;
     runops(interp, offset);
     return ctx;
@@ -178,8 +178,8 @@
 
 /*
 
-=item C<static Parrot_Context * runops_args(PARROT_INTERP, PMC *sub, PMC *obj,
-STRING *meth, const char *sig, va_list ap)>
+=item C<static PMC * runops_args(PARROT_INTERP, PMC *sub, PMC *obj, STRING
+*meth, const char *sig, va_list ap)>
 
 Calls the PMC subroutine C<sub> with optional name C<meth>. If PMC object
 C<obj> is provided, the call is treated as a method call on that object.
@@ -202,17 +202,17 @@
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-static Parrot_Context *
+static PMC *
 runops_args(PARROT_INTERP, ARGIN(PMC *sub), ARGIN_NULLOK(PMC *obj),
         SHIM(STRING *meth), ARGIN(const char *sig), va_list ap)
 {
     ASSERT_ARGS(runops_args)
     opcode_t offset, *dest;
-    Parrot_Context *ctx;
+    PMC *ctx;
 
     char new_sig[10];
     const char *sig_p;
-    Parrot_Context * const old_ctx = CONTEXT(interp);
+    PMC * const old_ctx = CURRENT_CONTEXT(interp);
 
     interp->current_cont   = new_ret_continuation_pmc(interp, NULL);
     interp->current_object = obj;
@@ -264,7 +264,7 @@
             "no get_params in sub");
      */
 
-    ctx    = Parrot_context_ref(interp, CONTEXT(interp));
+    ctx    = CURRENT_CONTEXT(interp);
     offset = dest - interp->code->base.data;
     runops(interp, offset);
     return ctx;
@@ -293,7 +293,7 @@
 Parrot_run_meth_fromc(PARROT_INTERP, ARGIN(PMC *sub), ARGIN_NULLOK(PMC *obj), SHIM(STRING *meth))
 {
     ASSERT_ARGS(Parrot_run_meth_fromc)
-    Parrot_Context *ctx;
+    PMC *ctx;
     opcode_t offset, *dest;
 
     interp->current_cont   = new_ret_continuation_pmc(interp, NULL);
@@ -304,7 +304,7 @@
         Parrot_ex_throw_from_c_args(interp, NULL, 1,
             "Subroutine returned a NULL address");
 
-    ctx    = CONTEXT(interp);
+    ctx    = CURRENT_CONTEXT(interp);
     offset = dest - interp->code->base.data;
     runops(interp, offset);
     return set_retval(interp, 0, ctx);
@@ -331,14 +331,13 @@
 {
     ASSERT_ARGS(Parrot_runops_fromc_args)
     va_list args;
-    Parrot_Context *ctx;
+    PMC *ctx;
     PMC *retval;
 
     va_start(args, sig);
     ctx = runops_args(interp, sub, PMCNULL, NULL, sig, args);
     va_end(args);
     retval = (PMC *)set_retval(interp, *sig, ctx);
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -364,7 +363,7 @@
 {
     ASSERT_ARGS(Parrot_runops_fromc_args_event)
     va_list args;
-    Parrot_Context *ctx;
+    PMC *ctx;
     void *retval;
     /*
      * running code from event handlers isn't fully reentrant due to
@@ -380,7 +379,6 @@
     ctx = runops_args(interp, sub, PMCNULL, NULL, sig, args);
     va_end(args);
     retval = set_retval(interp, *sig, ctx);
-    Parrot_free_context(interp, ctx, 1);
 
     interp->current_args     = cargs;
     interp->current_params   = params;
@@ -410,14 +408,13 @@
 {
     ASSERT_ARGS(Parrot_runops_fromc_args_reti)
     va_list args;
-    Parrot_Context *ctx;
+    PMC *ctx;
     INTVAL retval;
 
     va_start(args, sig);
     ctx = runops_args(interp, sub, PMCNULL, NULL, sig, args);
     va_end(args);
     retval = set_retval_i(interp, *sig, ctx);
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -441,15 +438,14 @@
         ARGIN(const char *sig), ...)
 {
     ASSERT_ARGS(Parrot_runops_fromc_args_retf)
-    va_list args;
-    Parrot_Context *ctx;
+    va_list  args;
+    PMC     *ctx;
     FLOATVAL retval;
 
     va_start(args, sig);
     ctx = runops_args(interp, sub, PMCNULL, NULL, sig, args);
     va_end(args);
     retval = set_retval_f(interp, *sig, ctx);
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -475,14 +471,13 @@
 {
     ASSERT_ARGS(Parrot_run_meth_fromc_args)
     va_list args;
-    Parrot_Context *ctx;
-    void* retval;
+    PMC    *ctx;
+    void   *retval;
 
     va_start(args, sig);
     ctx = runops_args(interp, sub, obj, meth, sig, args);
     va_end(args);
     retval = set_retval(interp, *sig, ctx);
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -507,14 +502,13 @@
 {
     ASSERT_ARGS(Parrot_run_meth_fromc_args_reti)
     va_list args;
-    Parrot_Context *ctx;
-    INTVAL retval;
+    PMC    *ctx;
+    INTVAL  retval;
 
     va_start(args, sig);
     ctx = runops_args(interp, sub, obj, meth, sig, args);
     va_end(args);
     retval = set_retval_i(interp, *sig, ctx);
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -539,14 +533,13 @@
 {
     ASSERT_ARGS(Parrot_run_meth_fromc_args_retf)
     va_list args;
-    Parrot_Context *ctx;
+    PMC    *ctx;
     FLOATVAL retval;
 
     va_start(args, sig);
     ctx = runops_args(interp, sub, obj, meth, sig, args);
     va_end(args);
     retval = set_retval_f(interp, *sig, ctx);
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -571,10 +564,9 @@
         ARGIN(const char *sig), va_list args)
 {
     ASSERT_ARGS(Parrot_runops_fromc_arglist)
-    Parrot_Context * const ctx = runops_args(interp, sub, PMCNULL, NULL, sig, args);
+    PMC * const ctx = runops_args(interp, sub, PMCNULL, NULL, sig, args);
     void * const retval = set_retval(interp, *sig, ctx);
 
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -598,10 +590,9 @@
         ARGIN(const char *sig), va_list args)
 {
     ASSERT_ARGS(Parrot_runops_fromc_arglist_reti)
-    Parrot_Context * const ctx = runops_args(interp, sub, PMCNULL, NULL, sig, args);
+    PMC * const ctx = runops_args(interp, sub, PMCNULL, NULL, sig, args);
     const INTVAL retval = set_retval_i(interp, *sig, ctx);
 
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -625,10 +616,9 @@
         ARGIN(const char *sig), va_list args)
 {
     ASSERT_ARGS(Parrot_runops_fromc_arglist_retf)
-    Parrot_Context * const ctx = runops_args(interp, sub, PMCNULL, NULL, sig, args);
+    PMC * const ctx = runops_args(interp, sub, PMCNULL, NULL, sig, args);
     const FLOATVAL retval = set_retval_f(interp, *sig, ctx);
 
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -653,10 +643,9 @@
         ARGIN(STRING *meth), ARGIN(const char *sig), va_list args)
 {
     ASSERT_ARGS(Parrot_run_meth_fromc_arglist)
-    Parrot_Context * const ctx = runops_args(interp, sub, obj, meth, sig, args);
+    PMC * const ctx = runops_args(interp, sub, obj, meth, sig, args);
     void * const retval = set_retval(interp, *sig, ctx);
 
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -682,10 +671,9 @@
         ARGIN(STRING *meth), ARGIN(const char *sig), va_list args)
 {
     ASSERT_ARGS(Parrot_run_meth_fromc_arglist_reti)
-    Parrot_Context * const ctx = runops_args(interp, sub, obj, meth, sig, args);
+    PMC * const ctx = runops_args(interp, sub, obj, meth, sig, args);
     const INTVAL retval = set_retval_i(interp, *sig, ctx);
 
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 
@@ -710,10 +698,9 @@
         ARGIN(STRING *meth), ARGIN(const char *sig), va_list args)
 {
     ASSERT_ARGS(Parrot_run_meth_fromc_arglist_retf)
-    Parrot_Context * const ctx = runops_args(interp, sub, obj, meth, sig, args);
+    PMC * const ctx = runops_args(interp, sub, obj, meth, sig, args);
     const FLOATVAL retval = set_retval_f(interp, *sig, ctx);
 
-    Parrot_free_context(interp, ctx, 1);
     return retval;
 }
 

Modified: trunk/src/call/pcc.c
==============================================================================
--- trunk/src/call/pcc.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/call/pcc.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -52,7 +52,7 @@
     int seen_arrow,
     ARGIN(PMC * const *sigs),
     ARGMOD(opcode_t **indexes),
-    ARGMOD(Parrot_Context *ctx),
+    ARGMOD(PMC *ctx),
     ARGIN_NULLOK(PMC *pmc),
     ARGIN(va_list *list))
         __attribute__nonnull__(1)
@@ -72,7 +72,7 @@
     int seen_arrow,
     ARGIN(PMC * const *sigs),
     ARGMOD(opcode_t **indexes),
-    ARGMOD(Parrot_Context *ctx),
+    ARGMOD(PMC *ctx),
     ARGIN(PMC *sig_obj))
         __attribute__nonnull__(1)
         __attribute__nonnull__(4)
@@ -105,7 +105,7 @@
         FUNC_MODIFIES(*st);
 
 PARROT_CANNOT_RETURN_NULL
-static Parrot_Context * count_signature_elements(PARROT_INTERP,
+static PMC * count_signature_elements(PARROT_INTERP,
     ARGIN(const char *signature),
     ARGMOD(PMC *args_sig),
     ARGMOD(PMC *results_sig),
@@ -156,7 +156,7 @@
     ARGMOD(INTVAL *n_regs_used),
     ARGMOD(PMC **sigs),
     ARGMOD(opcode_t **indexes),
-    ARGMOD(Parrot_Context *ctx),
+    ARGMOD(PMC *ctx),
     ARGMOD(PMC *sig_obj))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -172,7 +172,7 @@
         FUNC_MODIFIES(*sig_obj);
 
 static void set_context_sig_returns(PARROT_INTERP,
-    ARGMOD(Parrot_Context *ctx),
+    ARGMOD(PMC *ctx),
     ARGMOD(opcode_t **indexes),
     ARGIN_NULLOK(const char *ret_x),
     ARGMOD(PMC *result_list))
@@ -185,7 +185,7 @@
         FUNC_MODIFIES(*result_list);
 
 static void set_context_sig_returns_varargs(PARROT_INTERP,
-    ARGMOD(Parrot_Context *ctx),
+    ARGMOD(PMC *ctx),
     ARGMOD(opcode_t **indexes),
     ARGIN(const char *ret_x),
     va_list returns)
@@ -198,7 +198,7 @@
 
 static int set_retval_util(PARROT_INTERP,
     ARGIN(const char *sig),
-    ARGIN(Parrot_Context *ctx),
+    ARGIN(PMC *ctx),
     ARGMOD(call_state *st))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -214,8 +214,11 @@
         __attribute__nonnull__(3)
         FUNC_MODIFIES(*st);
 
-static void store_arg(ARGIN(const call_state *st), INTVAL idx)
-        __attribute__nonnull__(1);
+static void store_arg(PARROT_INTERP,
+    ARGIN(const call_state *st),
+    INTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
 
 static void too_few(PARROT_INTERP,
     ARGIN(const call_state *st),
@@ -319,7 +322,8 @@
     || PARROT_ASSERT_ARG(st) \
     || PARROT_ASSERT_ARG(p_arg)
 #define ASSERT_ARGS_store_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(st)
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(st)
 #define ASSERT_ARGS_too_few __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(st) \
@@ -335,16 +339,6 @@
 /* Make sure we don't conflict with any other MAX() macros defined elsewhere */
 #define PARROT_MAX(a, b) (((a)) > (b) ? (a) : (b))
 
-#define SAVE_OFF_REGS(orig, next, save) \
-        (save).bp = (orig).bp;\
-        (save).bp_ps = (orig).bp_ps;\
-        (orig).bp = (next).bp;\
-        (orig).bp_ps = (next).bp_ps;
-
-#define RESTORE_REGS(orig, save) \
-        (orig).bp = (save).bp;\
-        (orig).bp_ps = (save).bp_ps;
-
 /*
 
 =item C<PMC* Parrot_pcc_build_sig_object_from_varargs(PARROT_INTERP, PMC* obj,
@@ -484,13 +478,13 @@
     init_call_stats(st);
 
     if (PMC_IS_NULL(interp->args_signature))
-        Parrot_init_arg_op(interp, CONTEXT(interp), interp->current_args,
+        Parrot_init_arg_op(interp, CURRENT_CONTEXT(interp), interp->current_args,
                            &st->src);
     else
-        Parrot_init_arg_indexes_and_sig_pmc(interp, CONTEXT(interp),
+        Parrot_init_arg_indexes_and_sig_pmc(interp, CURRENT_CONTEXT(interp),
             interp->current_args, interp->args_signature, &st->src);
 
-    Parrot_init_arg_sig(interp, CONTEXT(interp), sig, NULL, &st->dest);
+    Parrot_init_arg_sig(interp, CURRENT_CONTEXT(interp), sig, NULL, &st->dest);
 }
 
 
@@ -511,8 +505,8 @@
 Parrot_init_ret_nci(PARROT_INTERP, ARGOUT(call_state *st), ARGIN(const char *sig))
 {
     ASSERT_ARGS(Parrot_init_ret_nci)
-    Parrot_Context *ctx                 = CONTEXT(interp);
-    PMC            * const current_cont = ctx->current_cont;
+    PMC *ctx                 = CURRENT_CONTEXT(interp);
+    PMC * const current_cont = Parrot_pcc_get_continuation(interp, ctx);
 
     /* if this NCI call was a taicall, return results to caller's get_results
      * this also means that we pass the caller's register base pointer */
@@ -520,23 +514,24 @@
         ctx = PMC_cont(current_cont)->to_ctx;
 
     /* TODO simplify all */
-    Parrot_init_arg_sig(interp, CONTEXT(interp), sig, NULL, &st->src);
+    Parrot_init_arg_sig(interp, CURRENT_CONTEXT(interp), sig, NULL, &st->src);
 
     /* Non-constant signatures are stored in ctx->results_signature instead of
      * in the constants table. */
-    if (ctx->results_signature)
+    if (Parrot_pcc_get_results_signature(interp, ctx))
         Parrot_init_arg_indexes_and_sig_pmc(interp, ctx,
-                ctx->current_results, ctx->results_signature, &st->dest);
+                Parrot_pcc_get_results(interp, ctx),
+                Parrot_pcc_get_results_signature(interp, ctx), &st->dest);
     else
-        Parrot_init_arg_op(interp, ctx, ctx->current_results, &st->dest);
+        Parrot_init_arg_op(interp, ctx, Parrot_pcc_get_results(interp, ctx), &st->dest);
 
 }
 
 
 /*
 
-=item C<int Parrot_init_arg_indexes_and_sig_pmc(PARROT_INTERP, Parrot_Context
-*ctx, opcode_t *indexes, PMC *sig_pmc, call_state_item *sti)>
+=item C<int Parrot_init_arg_indexes_and_sig_pmc(PARROT_INTERP, PMC *ctx,
+opcode_t *indexes, PMC *sig_pmc, call_state_item *sti)>
 
 Initializes argument transfer with given context registers, register indexes,
 and a signature PMC.
@@ -552,14 +547,14 @@
 
 PARROT_EXPORT
 int
-Parrot_init_arg_indexes_and_sig_pmc(PARROT_INTERP, ARGIN(Parrot_Context *ctx),
+Parrot_init_arg_indexes_and_sig_pmc(PARROT_INTERP, ARGIN(PMC *ctx),
         ARGIN_NULLOK(opcode_t *indexes), ARGIN_NULLOK(PMC *sig_pmc),
         ARGMOD(call_state_item *sti))
 {
     ASSERT_ARGS(Parrot_init_arg_indexes_and_sig_pmc)
     if (!sig_pmc && indexes) {
         ++indexes;
-        sig_pmc = ctx->constants[*indexes]->u.key;
+        sig_pmc = Parrot_pcc_get_pmc_constant(interp, ctx, *indexes);
         ASSERT_SIG_PMC(sig_pmc);
         ++indexes;
     }
@@ -589,7 +584,7 @@
 
 /*
 
-=item C<int Parrot_init_arg_op(PARROT_INTERP, Parrot_Context *ctx, opcode_t *pc,
+=item C<int Parrot_init_arg_op(PARROT_INTERP, PMC *ctx, opcode_t *pc,
 call_state_item *sti)>
 
 Initializes argument transfer with given context registers and opcode location
@@ -601,7 +596,7 @@
 
 PARROT_EXPORT
 int
-Parrot_init_arg_op(PARROT_INTERP, ARGIN(Parrot_Context *ctx),
+Parrot_init_arg_op(PARROT_INTERP, ARGIN(PMC *ctx),
     ARGIN_NULLOK(opcode_t *pc), ARGIN(call_state_item *sti))
 {
     ASSERT_ARGS(Parrot_init_arg_op)
@@ -609,7 +604,7 @@
 
     if (pc) {
         ++pc;
-        sig_pmc = ctx->constants[*pc]->u.key;
+        sig_pmc = Parrot_pcc_get_pmc_constant(interp, ctx, *pc);
         ASSERT_SIG_PMC(sig_pmc);
         ++pc;
     }
@@ -620,8 +615,8 @@
 
 /*
 
-=item C<int Parrot_init_arg_sig(PARROT_INTERP, Parrot_Context *ctx, const char
-*sig, void *ap, call_state_item *sti)>
+=item C<int Parrot_init_arg_sig(PARROT_INTERP, PMC *ctx, const char *sig, void
+*ap, call_state_item *sti)>
 
 Initializes argument transfer with given code segment (holding the
 const_table), registers, function signature, and arguments.
@@ -632,7 +627,7 @@
 
 PARROT_EXPORT
 int
-Parrot_init_arg_sig(PARROT_INTERP, ARGIN(Parrot_Context *ctx),
+Parrot_init_arg_sig(PARROT_INTERP, ARGIN(PMC *ctx),
     ARGIN(const char *sig), ARGIN_NULLOK(void *ap),
     ARGMOD(call_state_item *sti))
 {
@@ -775,7 +770,7 @@
             break;
         case PARROT_ARG_PMC:
             if (st->src.u.sig.sig[st->src.i] == 'O')
-                UVal_pmc(st->val) = CONTEXT(interp)->current_object;
+                UVal_pmc(st->val) = Parrot_pcc_get_object(interp, CURRENT_CONTEXT(interp));
             else {
                 UVal_pmc(st->val) = va_arg(*ap, PMC *);
             }
@@ -831,18 +826,18 @@
             /* ensure that callees don't modify constant caller strings */
             if (constant)
                 UVal_str(st->val) = Parrot_str_new_COW(interp,
-                                        st->src.ctx->constants[idx]->u.string);
+                                        Parrot_pcc_get_string_constant(interp, st->src.ctx, idx));
             else
                 UVal_str(st->val) = CTX_REG_STR(st->src.ctx, idx);
 
             break;
         }
         case PARROT_ARG_FLOATVAL:
-            UVal_num(st->val) = constant ? st->src.ctx->constants[idx]->u.number
+            UVal_num(st->val) = constant ? Parrot_pcc_get_num_constant(interp, st->src.ctx, idx)
                                          : CTX_REG_NUM(st->src.ctx, idx);
             break;
         case PARROT_ARG_PMC:
-            UVal_pmc(st->val) = constant ? st->src.ctx->constants[idx]->u.key
+            UVal_pmc(st->val) = constant ? Parrot_pcc_get_pmc_constant(interp, st->src.ctx, idx)
                                          : CTX_REG_PMC(st->src.ctx, idx);
 
             if (st->src.sig & PARROT_ARG_FLATTEN) {
@@ -1199,12 +1194,23 @@
     for (; key; key = VTABLE_shift_pmc(interp, key)) {
         /* register keys have to be cloned */
         if (PObj_get_FLAGS(key) & KEY_register_FLAG) {
-            Parrot_Context temp_ctx;
+            Regs_ni bp;
+            Regs_ps bp_ps;
 
             /* clone sets key values according to refered register items */
-            SAVE_OFF_REGS(interp->ctx, (*(st->src.ctx)), temp_ctx)
+            bp    = *Parrot_pcc_get_regs_ni(interp, CURRENT_CONTEXT(interp));
+            bp_ps = *Parrot_pcc_get_regs_ps(interp, CURRENT_CONTEXT(interp));
+
+            Parrot_pcc_set_regs_ni(interp, CURRENT_CONTEXT(interp),
+                    Parrot_pcc_get_regs_ni(interp, st->src.ctx));
+            Parrot_pcc_set_regs_ps(interp, CURRENT_CONTEXT(interp),
+                    Parrot_pcc_get_regs_ps(interp, st->src.ctx));
+
             UVal_pmc(st->val) = VTABLE_clone(interp, key);
-            RESTORE_REGS(interp->ctx, temp_ctx)
+
+            Parrot_pcc_set_regs_ni(interp, CURRENT_CONTEXT(interp), &bp);
+            Parrot_pcc_set_regs_ps(interp, CURRENT_CONTEXT(interp), &bp_ps);
+
             return;
         }
     }
@@ -1308,7 +1314,7 @@
         n_named++;
         idx   = st->dest.u.op.pc[i];
         param = PARROT_ARG_CONSTANT_ISSET(st->dest.sig)
-                ? st->dest.ctx->constants[idx]->u.string
+                ? Parrot_pcc_get_string_constant(interp, st->dest.ctx, idx)
                 : CTX_REG_STR(st->dest.ctx, idx);
 
         if (st->name == param || Parrot_str_equal(interp, st->name, param)) {
@@ -1334,7 +1340,7 @@
 
 /*
 
-=item C<static void store_arg(const call_state *st, INTVAL idx)>
+=item C<static void store_arg(PARROT_INTERP, const call_state *st, INTVAL idx)>
 
 Stores the next argument in the destination register appropriately.
 
@@ -1343,7 +1349,7 @@
 */
 
 static void
-store_arg(ARGIN(const call_state *st), INTVAL idx)
+store_arg(PARROT_INTERP, ARGIN(const call_state *st), INTVAL idx)
 {
     ASSERT_ARGS(store_arg)
     switch (st->dest.sig & PARROT_ARG_TYPE_MASK) {
@@ -1379,7 +1385,7 @@
 
 PARROT_EXPORT
 int
-Parrot_store_arg(SHIM_INTERP, ARGIN(const call_state *st))
+Parrot_store_arg(PARROT_INTERP, ARGIN(const call_state *st))
 {
     ASSERT_ARGS(Parrot_store_arg)
     INTVAL idx;
@@ -1389,7 +1395,7 @@
     PARROT_ASSERT(st->dest.mode & CALL_STATE_OP);
     idx = st->dest.u.op.pc[st->dest.i];
     PARROT_ASSERT(idx >= 0);
-    store_arg(st, idx);
+    store_arg(interp, st, idx);
 
     return 1;
 }
@@ -1544,7 +1550,7 @@
                 INTVAL idx;
                 null_val(arg_sig, st);
                 idx = st->dest.u.op.pc[i];
-                store_arg(st, idx);
+                store_arg(interp, st, idx);
 
                 /* Don't walk off the end of the array */
                 if (i+1 >= st->dest.n)
@@ -1561,7 +1567,7 @@
             else {
                 const   INTVAL idx   = st->dest.u.op.pc[last_name_pos];
                 STRING * const param = PARROT_ARG_CONSTANT_ISSET(sig)
-                    ? st->dest.ctx->constants[idx]->u.string
+                    ? Parrot_pcc_get_string_constant(interp, st->dest.ctx, idx)
                     : CTX_REG_STR(st->dest.ctx, idx);
 
                 Parrot_ex_throw_from_c_args(interp, NULL,
@@ -1673,7 +1679,7 @@
                 /* actually store the argument */
                 idx = st->dest.u.op.pc[st->dest.i];
                 PARROT_ASSERT(idx >= 0);
-                store_arg(st, idx);
+                store_arg(interp, st, idx);
 
                 check_for_opt_flag(interp, st, 0);
 
@@ -1718,7 +1724,7 @@
         /* actually store the argument */
         idx = st->dest.u.op.pc[st->dest.i];
         PARROT_ASSERT(idx >= 0);
-        store_arg(st, idx);
+        store_arg(interp, st, idx);
 
         /* if we're at an :optional argument, check for an :opt_flag */
         if (dest->sig & PARROT_ARG_OPTIONAL)
@@ -1843,9 +1849,8 @@
 
 /*
 
-=item C<void parrot_pass_args(PARROT_INTERP, Parrot_Context *src_ctx,
-Parrot_Context *dest_ctx, opcode_t *src_indexes, opcode_t *dest_indexes,
-arg_pass_t param_or_result)>
+=item C<void parrot_pass_args(PARROT_INTERP, PMC *src_ctx, PMC *dest_ctx,
+opcode_t *src_indexes, opcode_t *dest_indexes, arg_pass_t param_or_result)>
 
 Main argument passing routine.
 
@@ -1865,7 +1870,7 @@
 PARROT_EXPORT
 void
 parrot_pass_args(PARROT_INTERP,
-        ARGMOD(Parrot_Context *src_ctx), ARGMOD(Parrot_Context *dest_ctx),
+        ARGMOD(PMC *src_ctx), ARGMOD(PMC *dest_ctx),
         ARGMOD_NULLOK(opcode_t *src_indexes), ARGMOD_NULLOK(opcode_t *dest_indexes),
         arg_pass_t param_or_result)
 {
@@ -1881,9 +1886,9 @@
     }
     else /* (param_or_result == PARROT_PASS_RESULTS) */ {
         src_signature               = interp->returns_signature;
-        dest_signature              = dest_ctx->results_signature;
+        dest_signature              = Parrot_pcc_get_results_signature(interp, dest_ctx);
         interp->returns_signature   = NULL;
-        dest_ctx->results_signature = NULL;
+        Parrot_pcc_set_results_signature(interp, dest_ctx, NULL);
     }
 
     memset(&st, 0, sizeof st);
@@ -1904,7 +1909,7 @@
 /*
 
 =item C<opcode_t * parrot_pass_args_fromc(PARROT_INTERP, const char *sig,
-opcode_t *dest, Parrot_Context *old_ctxp, va_list ap)>
+opcode_t *dest, PMC *old_ctxp, va_list ap)>
 
 Passes arguments from C code with given signature to a Parrot Sub.
 Prerequisites are like above.
@@ -1917,12 +1922,12 @@
 PARROT_WARN_UNUSED_RESULT
 opcode_t *
 parrot_pass_args_fromc(PARROT_INTERP, ARGIN(const char *sig),
-        ARGMOD(opcode_t *dest), ARGIN(Parrot_Context *old_ctxp), va_list ap)
+        ARGMOD(opcode_t *dest), ARGIN(PMC *old_ctxp), va_list ap)
 {
     ASSERT_ARGS(parrot_pass_args_fromc)
     call_state st;
 
-    Parrot_init_arg_op(interp, CONTEXT(interp), dest, &st.dest);
+    Parrot_init_arg_op(interp, CURRENT_CONTEXT(interp), dest, &st.dest);
     Parrot_init_arg_sig(interp, old_ctxp, sig, PARROT_VA_TO_VAPTR(ap), &st.src);
     Parrot_process_args(interp, &st, PARROT_PASS_PARAMS);
     return dest + st.dest.n + 2;
@@ -1931,8 +1936,8 @@
 
 /*
 
-=item C<static int set_retval_util(PARROT_INTERP, const char *sig,
-Parrot_Context *ctx, call_state *st)>
+=item C<static int set_retval_util(PARROT_INTERP, const char *sig, PMC *ctx,
+call_state *st)>
 
 Adds the current return parameter to the current context, and fetches
 the next return parameter from the call state object.
@@ -1943,7 +1948,7 @@
 
 static int
 set_retval_util(PARROT_INTERP, ARGIN(const char *sig),
-    ARGIN(Parrot_Context *ctx), ARGMOD(call_state *st))
+    ARGIN(PMC *ctx), ARGMOD(call_state *st))
 {
     ASSERT_ARGS(set_retval_util)
     opcode_t * const src_pc = interp->current_returns;
@@ -1952,7 +1957,7 @@
     interp->current_returns = NULL;
 
     if (todo) {
-        todo = Parrot_init_arg_sig(interp, CONTEXT(interp), sig, NULL,
+        todo = Parrot_init_arg_sig(interp, CURRENT_CONTEXT(interp), sig, NULL,
             &st->dest);
 
         if (todo) {
@@ -1968,7 +1973,7 @@
 
 /*
 
-=item C<void * set_retval(PARROT_INTERP, int sig_ret, Parrot_Context *ctx)>
+=item C<void * set_retval(PARROT_INTERP, int sig_ret, PMC *ctx)>
 
 Handles void and pointer (PMC *, STRING *) return values.  Returns a PMC,
 STRING, or NULL pointer as appropriate.
@@ -1980,7 +1985,7 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 void *
-set_retval(PARROT_INTERP, int sig_ret, ARGIN(Parrot_Context *ctx))
+set_retval(PARROT_INTERP, int sig_ret, ARGIN(PMC *ctx))
 {
     ASSERT_ARGS(set_retval)
     call_state st;
@@ -2005,7 +2010,7 @@
 
 /*
 
-=item C<INTVAL set_retval_i(PARROT_INTERP, int sig_ret, Parrot_Context *ctx)>
+=item C<INTVAL set_retval_i(PARROT_INTERP, int sig_ret, PMC *ctx)>
 
 Handles an INTVAL return value, returning its value if present and 0 otherwise.
 
@@ -2014,7 +2019,7 @@
 */
 
 INTVAL
-set_retval_i(PARROT_INTERP, int sig_ret, ARGIN(Parrot_Context *ctx))
+set_retval_i(PARROT_INTERP, int sig_ret, ARGIN(PMC *ctx))
 {
     ASSERT_ARGS(set_retval_i)
     call_state st;
@@ -2032,7 +2037,7 @@
 
 /*
 
-=item C<FLOATVAL set_retval_f(PARROT_INTERP, int sig_ret, Parrot_Context *ctx)>
+=item C<FLOATVAL set_retval_f(PARROT_INTERP, int sig_ret, PMC *ctx)>
 
 Handles a FLOATVAL return value, returning its value if present and 0.0
 otherwise.
@@ -2042,7 +2047,7 @@
 */
 
 FLOATVAL
-set_retval_f(PARROT_INTERP, int sig_ret, ARGIN(Parrot_Context *ctx))
+set_retval_f(PARROT_INTERP, int sig_ret, ARGIN(PMC *ctx))
 {
     ASSERT_ARGS(set_retval_f)
     call_state st;
@@ -2060,7 +2065,7 @@
 
 /*
 
-=item C<STRING* set_retval_s(PARROT_INTERP, int sig_ret, Parrot_Context *ctx)>
+=item C<STRING* set_retval_s(PARROT_INTERP, int sig_ret, PMC *ctx)>
 
 Handles a STRING return value, returning its pointer if present and NULL
 otherwise.
@@ -2072,7 +2077,7 @@
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 STRING*
-set_retval_s(PARROT_INTERP, int sig_ret, ARGIN(Parrot_Context *ctx))
+set_retval_s(PARROT_INTERP, int sig_ret, ARGIN(PMC *ctx))
 {
     ASSERT_ARGS(set_retval_s)
     call_state st;
@@ -2090,7 +2095,7 @@
 
 /*
 
-=item C<PMC* set_retval_p(PARROT_INTERP, int sig_ret, Parrot_Context *ctx)>
+=item C<PMC* set_retval_p(PARROT_INTERP, int sig_ret, PMC *ctx)>
 
 Handles a PMC return value, returning the PMC pointer if present and NULL
 otherwise.
@@ -2102,7 +2107,7 @@
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 PMC*
-set_retval_p(PARROT_INTERP, int sig_ret, ARGIN(Parrot_Context *ctx))
+set_retval_p(PARROT_INTERP, int sig_ret, ARGIN(PMC *ctx))
 {
     ASSERT_ARGS(set_retval_p)
     call_state st;
@@ -2121,8 +2126,8 @@
 /*
 
 =item C<static void commit_last_arg(PARROT_INTERP, int index, int cur, opcode_t
-*n_regs_used, int seen_arrow, PMC * const *sigs, opcode_t **indexes,
-Parrot_Context *ctx, PMC *pmc, va_list *list)>
+*n_regs_used, int seen_arrow, PMC * const *sigs, opcode_t **indexes, PMC *ctx,
+PMC *pmc, va_list *list)>
 
 Called by C<Parrot_PCCINVOKE> when it reaches the end of each arg in the arg
 signature.  See C<Parrot_PCCINVOKE> for signature syntax.
@@ -2134,7 +2139,7 @@
 static void
 commit_last_arg(PARROT_INTERP, int index, int cur,
     ARGMOD(opcode_t *n_regs_used), int seen_arrow, ARGIN(PMC * const *sigs),
-    ARGMOD(opcode_t **indexes), ARGMOD(Parrot_Context *ctx),
+    ARGMOD(opcode_t **indexes), ARGMOD(PMC *ctx),
     ARGIN_NULLOK(PMC *pmc), ARGIN(va_list *list))
 {
     ASSERT_ARGS(commit_last_arg)
@@ -2187,8 +2192,8 @@
 
 /*
 
-=item C<static Parrot_Context * count_signature_elements(PARROT_INTERP, const
-char *signature, PMC *args_sig, PMC *results_sig, int flag)>
+=item C<static PMC * count_signature_elements(PARROT_INTERP, const char
+*signature, PMC *args_sig, PMC *results_sig, int flag)>
 
 Counts the number of each type of register in a signature object. Returns
 the total number of parameter arguments, the total number of result
@@ -2200,7 +2205,7 @@
 */
 
 PARROT_CANNOT_RETURN_NULL
-static Parrot_Context *
+static PMC *
 count_signature_elements(PARROT_INTERP, ARGIN(const char *signature),
     ARGMOD(PMC *args_sig), ARGMOD(PMC *results_sig), int flag)
 {
@@ -2300,7 +2305,7 @@
 
 =item C<static void commit_last_arg_sig_object(PARROT_INTERP, int index, int
 cur, opcode_t *n_regs_used, int seen_arrow, PMC * const *sigs, opcode_t
-**indexes, Parrot_Context *ctx, PMC *sig_obj)>
+**indexes, PMC *ctx, PMC *sig_obj)>
 
 Called by Parrot_pcc_invoke_from_sig_object when it reaches the end of each
 arg in the arg signature.  See C<Parrot_pcc_invoke_from_sig_object> for
@@ -2313,7 +2318,7 @@
 static void
 commit_last_arg_sig_object(PARROT_INTERP, int index, int cur,
     ARGMOD(opcode_t *n_regs_used), int seen_arrow, ARGIN(PMC * const *sigs),
-    ARGMOD(opcode_t **indexes), ARGMOD(Parrot_Context *ctx),
+    ARGMOD(opcode_t **indexes), ARGMOD(PMC *ctx),
     ARGIN(PMC *sig_obj))
 {
     ASSERT_ARGS(commit_last_arg_sig_object)
@@ -2384,8 +2389,8 @@
 
 /*
 
-=item C<static void set_context_sig_returns(PARROT_INTERP, Parrot_Context *ctx,
-opcode_t **indexes, const char *ret_x, PMC *result_list)>
+=item C<static void set_context_sig_returns(PARROT_INTERP, PMC *ctx, opcode_t
+**indexes, const char *ret_x, PMC *result_list)>
 
 Sets the subroutine return arguments in the context C<ctx>. Takes a C string
 for the return signature C<ret_x> and a list of return parameters C<result_list>.
@@ -2396,7 +2401,7 @@
 
 static void
 set_context_sig_returns(PARROT_INTERP,
-    ARGMOD(Parrot_Context *ctx), ARGMOD(opcode_t **indexes),
+    ARGMOD(PMC *ctx), ARGMOD(opcode_t **indexes),
     ARGIN_NULLOK(const char *ret_x), ARGMOD(PMC *result_list))
 {
     ASSERT_ARGS(set_context_sig_returns)
@@ -2453,8 +2458,8 @@
 
 /*
 
-=item C<static void set_context_sig_returns_varargs(PARROT_INTERP,
-Parrot_Context *ctx, opcode_t **indexes, const char *ret_x, va_list returns)>
+=item C<static void set_context_sig_returns_varargs(PARROT_INTERP, PMC *ctx,
+opcode_t **indexes, const char *ret_x, va_list returns)>
 
 Sets the subroutine return arguments in the context C<ctx>. Takes a C string
 for the return signature C<ret_x> and a varargs list of return parameters C<returns>.
@@ -2469,7 +2474,7 @@
 */
 
 static void
-set_context_sig_returns_varargs(PARROT_INTERP, ARGMOD(Parrot_Context *ctx),
+set_context_sig_returns_varargs(PARROT_INTERP, ARGMOD(PMC *ctx),
     ARGMOD(opcode_t **indexes), ARGIN(const char *ret_x), va_list returns)
 {
     ASSERT_ARGS(set_context_sig_returns_varargs)
@@ -2519,8 +2524,8 @@
 /*
 
 =item C<static const char * set_context_sig_params(PARROT_INTERP, const char
-*signature, INTVAL *n_regs_used, PMC **sigs, opcode_t **indexes, Parrot_Context
-*ctx, PMC *sig_obj)>
+*signature, INTVAL *n_regs_used, PMC **sigs, opcode_t **indexes, PMC *ctx, PMC
+*sig_obj)>
 
 Sets the subroutine arguments in the C<ctx> context, according to the
 signature string C<signature>. Currently this function is only called
@@ -2537,7 +2542,7 @@
 static const char *
 set_context_sig_params(PARROT_INTERP, ARGIN(const char *signature),
     ARGMOD(INTVAL *n_regs_used), ARGMOD(PMC **sigs),
-    ARGMOD(opcode_t **indexes), ARGMOD(Parrot_Context *ctx),
+    ARGMOD(opcode_t **indexes), ARGMOD(PMC *ctx),
     ARGMOD(PMC *sig_obj))
 {
     ASSERT_ARGS(set_context_sig_params)
@@ -2621,8 +2626,8 @@
 
     interp->current_args   = indexes[0];
     interp->args_signature = sigs[0];
-    ctx->current_results   = indexes[1];
-    ctx->results_signature = sigs[1];
+    Parrot_pcc_set_results(interp, ctx, indexes[1]);
+    Parrot_pcc_set_results_signature(interp, ctx, sigs[1]);
     return ret_x;
 }
 
@@ -2731,12 +2736,12 @@
     PMC * const results_sig = pmc_new(interp, enum_class_FixedIntegerArray);
     PMC * const ret_cont    = new_ret_continuation_pmc(interp, NULL);
 
-    Parrot_Context *ctx;              /* The newly created context */
-    PMC              *pccinvoke_meth;
+    PMC         *ctx;              /* The newly created context */
+    PMC         *pccinvoke_meth;
 
-    opcode_t         *save_current_args;
-    PMC              *save_args_signature;
-    PMC              *save_current_object;
+    opcode_t    *save_current_args;
+    PMC         *save_args_signature;
+    PMC         *save_current_object;
 
     /* temporary state vars for building PCC index and PCC signature arrays. */
 
@@ -2856,15 +2861,15 @@
 
     interp->current_args   = arg_indexes;
     interp->args_signature = args_sig;
-    ctx->current_results   = result_indexes;
-    ctx->results_signature = results_sig;
+    Parrot_pcc_set_results(interp, ctx, result_indexes);
+    Parrot_pcc_set_results_signature(interp, ctx, results_sig);
 
     /* arg_accessors assigned in loop above */
 
     interp->current_object       = pmc;
     interp->current_cont         = NEED_CONTINUATION;
-    ctx->current_cont            = ret_cont;
-    PMC_cont(ret_cont)->from_ctx = Parrot_context_ref(interp, ctx);
+    Parrot_pcc_set_continuation(interp, ctx, ret_cont);
+    PMC_cont(ret_cont)->from_ctx = ctx;
     pccinvoke_meth               = VTABLE_find_method(interp, pmc, method_name);
 
     if (PMC_IS_NULL(pccinvoke_meth))
@@ -2961,11 +2966,11 @@
     PMC * const ret_cont    = new_ret_continuation_pmc(interp, NULL);
     PMC * const result_list = VTABLE_get_attr_str(interp, sig_obj, CONST_STRING(interp, "returns"));
 
-    Parrot_Context *ctx;
-    opcode_t         *dest;
-    opcode_t         *save_current_args;
-    PMC              *save_args_signature;
-    PMC              *save_current_object;
+    PMC         *ctx;
+    opcode_t    *dest;
+    opcode_t    *save_current_args;
+    PMC         *save_args_signature;
+    PMC         *save_current_object;
 
     /* temporary state vars for building PCC index and PCC signature arrays. */
 
@@ -3005,9 +3010,9 @@
     else {
         interp->current_object       = PMCNULL;
     }
-    interp->current_cont         = NEED_CONTINUATION;
-    ctx->current_cont            = ret_cont;
-    PMC_cont(ret_cont)->from_ctx = Parrot_context_ref(interp, ctx);
+    interp->current_cont             = NEED_CONTINUATION;
+    Parrot_pcc_set_continuation(interp, ctx, ret_cont);
+    PMC_cont(ret_cont)->from_ctx     = ctx;
 
     /* Invoke the function */
     dest = VTABLE_invoke(interp, sub_obj, NULL);

Modified: trunk/src/debug.c
==============================================================================
--- trunk/src/debug.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/debug.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -2211,7 +2211,7 @@
 PDB_check_condition(PARROT_INTERP, ARGIN(const PDB_condition_t *condition))
 {
     ASSERT_ARGS(PDB_check_condition)
-    Parrot_Context *ctx = CONTEXT(interp);
+    PMC *ctx = CURRENT_CONTEXT(interp);
 
     TRACEDEB_MSG("PDB_check_condition");
 
@@ -2219,7 +2219,7 @@
 
     if (condition->type & PDB_cond_int) {
         INTVAL   i,  j;
-        if (condition->reg >= ctx->n_regs_used[REGNO_INT])
+        if (condition->reg >= Parrot_pcc_get_regs_used(interp, ctx, REGNO_INT))
             return 0;
         i = CTX_REG_INT(ctx, condition->reg);
 
@@ -2241,7 +2241,7 @@
     else if (condition->type & PDB_cond_num) {
         FLOATVAL k,  l;
 
-        if (condition->reg >= ctx->n_regs_used[REGNO_NUM])
+        if (condition->reg >= Parrot_pcc_get_regs_used(interp, ctx, REGNO_NUM))
             return 0;
         k = CTX_REG_NUM(ctx, condition->reg);
 
@@ -2263,7 +2263,7 @@
     else if (condition->type & PDB_cond_str) {
         STRING  *m, *n;
 
-        if (condition->reg >= ctx->n_regs_used[REGNO_STR])
+        if (condition->reg >= Parrot_pcc_get_regs_used(interp, ctx, REGNO_STR))
             return 0;
         m = CTX_REG_STR(ctx, condition->reg);
 
@@ -2294,7 +2294,7 @@
     else if (condition->type & PDB_cond_pmc) {
         PMC *m;
 
-        if (condition->reg >= ctx->n_regs_used[REGNO_PMC])
+        if (condition->reg >= Parrot_pcc_get_regs_used(interp, ctx, REGNO_PMC))
             return 0;
         m = CTX_REG_PMC(ctx, condition->reg);
 
@@ -3511,8 +3511,8 @@
     int               rec_level = 0;
 
     /* information about the current sub */
-    PMC              *sub = interpinfo_p(interp, CURRENT_SUB);
-    Parrot_Context   *ctx = CONTEXT(interp);
+    PMC *sub = interpinfo_p(interp, CURRENT_SUB);
+    PMC *ctx = CURRENT_CONTEXT(interp);
 
     if (!PMC_IS_NULL(sub)) {
         str = Parrot_Context_infostr(interp, ctx);
@@ -3520,7 +3520,7 @@
             Parrot_io_eprintf(interp, "%Ss", str);
             if (interp->code->annotations) {
                 PMC *annot = PackFile_Annotations_lookup(interp, interp->code->annotations,
-                        ctx->current_pc - interp->code->base.data + 1, NULL);
+                        Parrot_pcc_get_pc(interp, ctx) - interp->code->base.data + 1, NULL);
                 if (!PMC_IS_NULL(annot)) {
                     PMC *pfile = VTABLE_get_pmc_keyed_str(interp, annot,
                             Parrot_str_new_constant(interp, "file"));
@@ -3540,9 +3540,9 @@
     /* backtrace: follow the continuation chain */
     while (1) {
         Parrot_cont *sub_cont;
-        sub = ctx->current_cont;
+        sub = Parrot_pcc_get_continuation(interp, ctx);
 
-        if (!sub)
+        if (PMC_IS_NULL(sub))
             break;
 
         sub_cont = PMC_cont(sub);
@@ -3557,10 +3557,10 @@
 
         /* recursion detection */
         if (!PMC_IS_NULL(old) && PMC_cont(old) &&
-            PMC_cont(old)->to_ctx->current_pc ==
-            PMC_cont(sub)->to_ctx->current_pc &&
-            PMC_cont(old)->to_ctx->current_sub ==
-            PMC_cont(sub)->to_ctx->current_sub) {
+            Parrot_pcc_get_pc(interp, PMC_cont(old)->to_ctx) ==
+            Parrot_pcc_get_pc(interp, PMC_cont(sub)->to_ctx) &&
+            Parrot_pcc_get_sub(interp, PMC_cont(old)->to_ctx) ==
+            Parrot_pcc_get_sub(interp, PMC_cont(sub)->to_ctx)) {
                 ++rec_level;
         }
         else if (rec_level != 0) {
@@ -3573,7 +3573,9 @@
             Parrot_io_eprintf(interp, "%Ss", str);
             if (interp->code->annotations) {
                 PMC *annot = PackFile_Annotations_lookup(interp, interp->code->annotations,
-                        sub_cont->to_ctx->current_pc - interp->code->base.data + 1, NULL);
+                        Parrot_pcc_get_pc(interp, sub_cont->to_ctx) - interp->code->base.data + 1,
+                        NULL);
+
                 if (!PMC_IS_NULL(annot)) {
                     PMC *pfile = VTABLE_get_pmc_keyed_str(interp, annot,
                             Parrot_str_new_constant(interp, "file"));
@@ -3632,7 +3634,7 @@
     ASSERT_ARGS(GDB_print_reg)
     char * string;
 
-    if (n >= 0 && n < CONTEXT(interp)->n_regs_used[t]) {
+    if (n >= 0 && n < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), t)) {
         switch (t) {
             case REGNO_INT:
                 return Parrot_str_from_int(interp, IREG(n))->strstart;
@@ -3697,7 +3699,7 @@
     }
     if (! s[1]) {
         /* Print all registers of this type. */
-        const int max_reg = CONTEXT(interp)->n_regs_used[t];
+        const int max_reg = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), t);
         int n;
 
         for (n = 0; n < max_reg; n++) {

Modified: trunk/src/embed.c
==============================================================================
--- trunk/src/embed.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/embed.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -234,7 +234,7 @@
 void
 Parrot_set_trace(PARROT_INTERP, UINTVAL flag)
 {
-    CONTEXT(interp)->trace_flags |= flag;
+    Parrot_pcc_trace_flags_on(interp, interp->ctx, flag);
     Interp_core_SET(interp, PARROT_SLOW_CORE);
 }
 
@@ -289,7 +289,7 @@
 void
 Parrot_clear_trace(PARROT_INTERP, UINTVAL flag)
 {
-    CONTEXT(interp)->trace_flags &= ~flag;
+    Parrot_pcc_trace_flags_off(interp, interp->ctx, flag);
 }
 
 
@@ -343,7 +343,7 @@
 UINTVAL
 Parrot_test_trace(PARROT_INTERP, UINTVAL flag)
 {
-    return CONTEXT(interp)->trace_flags & flag;
+    return Parrot_pcc_trace_flags_test(interp, interp->ctx, flag);
 }
 
 
@@ -910,8 +910,8 @@
                 const size_t offs = sub->start_offs;
 
                 if (offs == interp->resume_offset) {
-                    CONTEXT(interp)->current_sub = sub_pmc;
-                    CONTEXT(interp)->current_HLL = sub->HLL_id;
+                    Parrot_pcc_set_sub(interp, CURRENT_CONTEXT(interp), sub_pmc);
+                    Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), sub->HLL_id);
                     return sub_pmc;
                 }
 
@@ -925,7 +925,7 @@
     sub_pmc                      = pmc_new(interp, enum_class_Sub);
     PMC_get_sub(interp, sub_pmc, sub_pmc_sub);
     sub_pmc_sub->start_offs      = 0;
-    CONTEXT(interp)->current_sub = sub_pmc;
+    Parrot_pcc_set_sub(interp, CURRENT_CONTEXT(interp), sub_pmc);
 
     return sub_pmc;
 }
@@ -970,15 +970,15 @@
     Parrot_on_exit(interp, print_profile, NULL);
 
     /* Let's kick the tires and light the fires--call interpreter.c:runops. */
-    main_sub = CONTEXT(interp)->current_sub;
+    main_sub = Parrot_pcc_get_sub(interp, CURRENT_CONTEXT(interp));
 
     /* if no sub was marked being :main, we create a dummy sub with offset 0 */
 
     if (!main_sub)
         main_sub = set_current_sub(interp);
 
-    CONTEXT(interp)->current_sub = NULL;
-    CONTEXT(interp)->constants   = interp->code->const_table->constants;
+    Parrot_pcc_set_sub(interp, CURRENT_CONTEXT(interp), NULL);
+    Parrot_pcc_set_constants(interp, interp->ctx, interp->code->const_table->constants);
 
     Parrot_runops_fromc_args(interp, main_sub, "vP", userargv);
 }
@@ -1247,7 +1247,7 @@
     run_native = func;
 
     if (interp->code && interp->code->const_table)
-        CONTEXT(interp)->constants = interp->code->const_table->constants;
+        Parrot_pcc_set_constants(interp, interp->ctx, interp->code->const_table->constants);
 
     runops(interp, interp->resume_offset);
 }

Modified: trunk/src/exceptions.c
==============================================================================
--- trunk/src/exceptions.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/exceptions.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -41,7 +41,7 @@
 static opcode_t * pass_exception_args(PARROT_INTERP,
     ARGIN(const char *sig),
     ARGIN(opcode_t *dest),
-    ARGIN(Parrot_Context * old_ctx),
+    ARGIN(PMC * old_ctx),
     ...)
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -253,7 +253,7 @@
     /* Set up the continuation context of the handler in the interpreter. */
     else if (PMC_cont(handler)->current_results)
         address = pass_exception_args(interp, "P", address,
-                CONTEXT(interp), exception);
+                CURRENT_CONTEXT(interp), exception);
 
     if (PObj_get_FLAGS(handler) & SUB_FLAG_C_HANDLER) {
         /* it's a C exception handler */
@@ -268,7 +268,7 @@
 /*
 
 =item C<static opcode_t * pass_exception_args(PARROT_INTERP, const char *sig,
-opcode_t *dest, Parrot_Context * old_ctx, ...)>
+opcode_t *dest, PMC * old_ctx, ...)>
 
 Passes arguments to the exception handler routine. These are retrieved with
 the .get_results() directive in PIR code.
@@ -280,7 +280,7 @@
 PARROT_CAN_RETURN_NULL
 static opcode_t *
 pass_exception_args(PARROT_INTERP, ARGIN(const char *sig),
-        ARGIN(opcode_t *dest), ARGIN(Parrot_Context * old_ctx), ...)
+        ARGIN(opcode_t *dest), ARGIN(PMC * old_ctx), ...)
 {
     ASSERT_ARGS(pass_exception_args)
     va_list   ap;
@@ -389,7 +389,8 @@
 
     /* Note the thrower.
      * XXX TT#596 - pass in current context instead when we have context PMCs. */
-    VTABLE_set_attr_str(interp, exception, CONST_STRING(interp, "thrower"), CONTEXT(interp)->current_cont);
+    /* Don't split line. It will break CONST_STRING handling */
+    VTABLE_set_attr_str(interp, exception, CONST_STRING(interp, "thrower"), Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp)));
 
     /* it's a C exception handler */
     if (PObj_get_FLAGS(handler) & SUB_FLAG_C_HANDLER) {
@@ -402,7 +403,7 @@
     address = VTABLE_invoke(interp, handler, NULL);
     if (PMC_cont(handler)->current_results)
         address = pass_exception_args(interp, "P", address,
-                CONTEXT(interp), exception);
+                CURRENT_CONTEXT(interp), exception);
     PARROT_ASSERT(return_point->handler_start == NULL);
     return_point->handler_start = address;
     longjmp(return_point->resume, 2);

Modified: trunk/src/extend.c
==============================================================================
--- trunk/src/extend.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/extend.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -1046,7 +1046,7 @@
 
     va_start(ap, signature);
     PMC_get_sub(interp, sub_pmc, sub);
-    CONTEXT(interp)->constants = sub->seg->const_table->constants;
+    Parrot_pcc_set_constants(interp, CURRENT_CONTEXT(interp), sub->seg->const_table->constants);
     result = Parrot_runops_fromc_arglist(interp, sub_pmc, signature, ap);
     va_end(ap);
 
@@ -1079,7 +1079,7 @@
 
     va_start(ap, signature);
     PMC_get_sub(interp, sub_pmc, sub);
-    CONTEXT(interp)->constants = sub->seg->const_table->constants;
+    Parrot_pcc_set_constants(interp, CURRENT_CONTEXT(interp), sub->seg->const_table->constants);
     result = Parrot_runops_fromc_arglist_reti(interp, sub_pmc, signature, ap);
     va_end(ap);
 
@@ -1112,7 +1112,7 @@
 
     va_start(ap, signature);
     PMC_get_sub(interp, sub_pmc, sub);
-    CONTEXT(interp)->constants = sub->seg->const_table->constants;
+    Parrot_pcc_set_constants(interp, CURRENT_CONTEXT(interp), sub->seg->const_table->constants);
     result = Parrot_runops_fromc_arglist_retf(interp, sub_pmc, signature, ap);
     va_end(ap);
 

Modified: trunk/src/gc/alloc_register.c
==============================================================================
--- trunk/src/gc/alloc_register.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/gc/alloc_register.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -37,24 +37,24 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void clear_regs(PARROT_INTERP, ARGMOD(Parrot_Context *ctx))
+static void clear_regs(PARROT_INTERP, ARGMOD(PMC *pmcctx))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        FUNC_MODIFIES(*ctx);
+        FUNC_MODIFIES(*pmcctx);
 
 static void init_context(PARROT_INTERP,
-    ARGMOD(Parrot_Context *ctx),
-    ARGIN_NULLOK(const Parrot_Context *old))
+    ARGMOD(PMC *pmcctx),
+    ARGIN_NULLOK(PMC *pmcold))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        FUNC_MODIFIES(*ctx);
+        FUNC_MODIFIES(*pmcctx);
 
 #define ASSERT_ARGS_clear_regs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(ctx)
+    || PARROT_ASSERT_ARG(pmcctx)
 #define ASSERT_ARGS_init_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(ctx)
+    || PARROT_ASSERT_ARG(pmcctx)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
@@ -144,48 +144,6 @@
 
 */
 
-/*
-
-=item C<void destroy_context(PARROT_INTERP)>
-
-Frees allocated context memory.
-
-=cut
-
-*/
-
-void
-destroy_context(PARROT_INTERP)
-{
-    ASSERT_ARGS(destroy_context)
-    Parrot_Context *context = CONTEXT(interp);
-    int             slot;
-
-    while (context) {
-        Parrot_Context * const prev = context->caller_ctx;
-
-        /* always collect the parentmost context in the parentmost interp*/
-        if (!prev && !interp->parent_interpreter)
-            context->ref_count = 1;
-
-        Parrot_free_context(interp, context, 1);
-
-        context = prev;
-    }
-
-    /* clear freed contexts */
-    for (slot = 0; slot < interp->ctx_mem.n_free_slots; ++slot) {
-        void *ptr = interp->ctx_mem.free_list[slot];
-        while (ptr) {
-            void * const next = *(void **) ptr;
-            mem_sys_free(ptr);
-            ptr = next;
-        }
-        interp->ctx_mem.free_list[slot] = NULL;
-    }
-    mem_sys_free(interp->ctx_mem.free_list);
-}
-
 
 /*
 
@@ -202,14 +160,11 @@
 {
     ASSERT_ARGS(create_initial_context)
     static INTVAL   num_regs[] = {32, 32, 32, 32};
-    Parrot_Context *ignored;
+    PMC *ignored;
 
     /* Create some initial free_list slots. */
 
 #define INITIAL_FREE_SLOTS 8
-    interp->ctx_mem.n_free_slots = INITIAL_FREE_SLOTS;
-    interp->ctx_mem.free_list    = mem_allocate_n_zeroed_typed(INITIAL_FREE_SLOTS, void *);
-
     /* For now create context with 32 regs each. Some src tests (and maybe
      * other extenders) assume the presence of these registers */
     ignored = Parrot_set_new_context(interp, num_regs);
@@ -249,7 +204,7 @@
 
 /*
 
-=item C<static void clear_regs(PARROT_INTERP, Parrot_Context *ctx)>
+=item C<static void clear_regs(PARROT_INTERP, PMC *pmcctx)>
 
 Clears all registers in a context.  PMC and STRING registers contain PMCNULL
 and NULL, respectively.  Integer and float registers contain negative flag
@@ -260,10 +215,11 @@
 */
 
 static void
-clear_regs(PARROT_INTERP, ARGMOD(Parrot_Context *ctx))
+clear_regs(PARROT_INTERP, ARGMOD(PMC *pmcctx))
 {
     ASSERT_ARGS(clear_regs)
     int i;
+    Parrot_Context *ctx = Parrot_pcc_get_context_struct(interp, pmcctx);
 
     /* NULL out registers - P/S have to be NULL for GC
      *
@@ -271,20 +227,20 @@
      */
 
     for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; i++) {
-        CTX_REG_PMC(ctx, i) = PMCNULL;
+        CTX_REG_PMC(pmcctx, i) = PMCNULL;
     }
 
     for (i = 0; i < ctx->n_regs_used[REGNO_STR]; i++) {
-        CTX_REG_STR(ctx, i) = NULL;
+        CTX_REG_STR(pmcctx, i) = NULL;
     }
 
     if (Interp_debug_TEST(interp, PARROT_REG_DEBUG_FLAG)) {
         /* depending on -D40 we set int and num to be identifiable garbage values */
         for (i = 0; i < ctx->n_regs_used[REGNO_INT]; i++) {
-            CTX_REG_INT(ctx, i) = -999;
+            CTX_REG_INT(pmcctx, i) = -999;
         }
         for (i = 0; i < ctx->n_regs_used[REGNO_NUM]; i++) {
-            CTX_REG_NUM(ctx, i) = -99.9;
+            CTX_REG_NUM(pmcctx, i) = -99.9;
         }
     }
 }
@@ -292,8 +248,7 @@
 
 /*
 
-=item C<static void init_context(PARROT_INTERP, Parrot_Context *ctx, const
-Parrot_Context *old)>
+=item C<static void init_context(PARROT_INTERP, PMC *pmcctx, PMC *pmcold)>
 
 Initializes a freshly allocated or recycled context.
 
@@ -302,12 +257,13 @@
 */
 
 static void
-init_context(PARROT_INTERP, ARGMOD(Parrot_Context *ctx),
-        ARGIN_NULLOK(const Parrot_Context *old))
+init_context(PARROT_INTERP, ARGMOD(PMC *pmcctx),
+        ARGIN_NULLOK(PMC *pmcold))
 {
     ASSERT_ARGS(init_context)
-    ctx->ref_count         = 0;
-    ctx->gc_mark           = 0;
+    Parrot_Context *ctx = Parrot_pcc_get_context_struct(interp, pmcctx);
+    Parrot_Context *old = Parrot_pcc_get_context_struct(interp, pmcold);
+
     ctx->current_results   = NULL;
     ctx->results_signature = NULL;
     ctx->lex_pad           = PMCNULL;
@@ -341,14 +297,13 @@
     }
 
     /* other stuff is set inside Sub.invoke */
-    clear_regs(interp, ctx);
+    clear_regs(interp, pmcctx);
 }
 
 
 /*
 
-=item C<Parrot_Context * Parrot_push_context(PARROT_INTERP, const INTVAL
-*n_regs_used)>
+=item C<PMC * Parrot_push_context(PARROT_INTERP, const INTVAL *n_regs_used)>
 
 Creates and sets the current context to a new context, remembering the old
 context in C<caller_ctx>.  Suitable to use with C<Parrot_pop_context>.
@@ -360,17 +315,17 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-Parrot_Context *
+PMC *
 Parrot_push_context(PARROT_INTERP, ARGIN(const INTVAL *n_regs_used))
 {
     ASSERT_ARGS(Parrot_push_context)
-    Parrot_Context * const old = CONTEXT(interp);
-    Parrot_Context * const ctx = Parrot_set_new_context(interp, n_regs_used);
+    PMC * const old = CURRENT_CONTEXT(interp);
+    PMC * const ctx = Parrot_set_new_context(interp, n_regs_used);
 
-    ctx->caller_ctx  = old;
+    Parrot_pcc_set_caller_ctx(interp, ctx, old);
 
     /* doesn't change */
-    ctx->current_sub = old->current_sub;
+    Parrot_pcc_set_sub(interp, ctx, Parrot_pcc_get_sub(interp, old));
 
     /* copy more ? */
     return ctx;
@@ -393,30 +348,18 @@
 Parrot_pop_context(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_pop_context)
-    Parrot_Context * const ctx = CONTEXT(interp);
-    Parrot_Context * const old = ctx->caller_ctx;
-
-#if CTX_LEAK_DEBUG
-    if (ctx->ref_count > 0 &&
-            Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
-        fprintf(stderr, "[force recycle of context %p (%d refs)]\n",
-            (void *)ctx, ctx->ref_count);
-    }
-#endif
-    ctx->ref_count = 0;
-    Parrot_free_context(interp, ctx, 0);
+    PMC * const ctx = CURRENT_CONTEXT(interp);
+    PMC * const old = Parrot_pcc_get_caller_ctx(interp, ctx);
 
     /* restore old, set cached interpreter base pointers */
-    CONTEXT(interp)      = old;
-    interp->ctx.bp       = old->bp;
-    interp->ctx.bp_ps    = old->bp_ps;
+    CURRENT_CONTEXT(interp) = old;
 }
 
 
 /*
 
-=item C<Parrot_Context * Parrot_alloc_context(PARROT_INTERP, const INTVAL
-*number_regs_used, Parrot_Context *old)>
+=item C<PMC * Parrot_alloc_context(PARROT_INTERP, const INTVAL
+*number_regs_used, PMC *old)>
 
 Allocates and returns a new context.  Does not set this new context as the
 current context. Note that the register usage C<n_regs_used> is copied.  Use
@@ -429,11 +372,12 @@
 
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-Parrot_Context *
+PMC *
 Parrot_alloc_context(PARROT_INTERP, ARGIN(const INTVAL *number_regs_used),
-    ARGIN_NULLOK(Parrot_Context *old))
+    ARGIN_NULLOK(PMC *old))
 {
     ASSERT_ARGS(Parrot_alloc_context)
+    PMC            *pmcctx;
     Parrot_Context *ctx;
     void *p;
 
@@ -445,57 +389,15 @@
     const size_t size_nip      = size_n + size_i + size_p;
     const size_t all_regs_size = size_n + size_i + size_p + size_s;
     const size_t reg_alloc     = ROUND_ALLOC_SIZE(all_regs_size);
-    const int    slot          = CALCULATE_SLOT_NUM(reg_alloc);
 
-    /*
-     * If slot is beyond the end of the allocated list, extend the list to
-     * allocate more slots.
-     */
-    if (slot >= interp->ctx_mem.n_free_slots) {
-        const int extend_size = slot + 1;
-        int i;
-
-        mem_realloc_n_typed(interp->ctx_mem.free_list, extend_size, void *);
-        for (i = interp->ctx_mem.n_free_slots; i < extend_size; ++i)
-            interp->ctx_mem.free_list[i] = NULL;
-        interp->ctx_mem.n_free_slots = extend_size;
-    }
-
-    /*
-     * The free_list contains a linked list of pointers for each size (slot
-     * index). Pop off an available context of the desired size from free_list.
-     * If no contexts of the desired size are available, allocate a new one.
-     */
-    ctx = (Parrot_Context *)interp->ctx_mem.free_list[slot];
-
-    if (ctx) {
-        /*
-         * Store the next pointer from the linked list for this size (slot
-         * index) in free_list. On "*(void **) ctx", C won't dereference a void
-         * * pointer (untyped), so type cast ctx to void ** (a dereference-able
-         * type) then dereference it to get a void *. Store the dereferenced
-         * value (the next pointer in the linked list) in free_list.
-         */
-        interp->ctx_mem.free_list[slot] = *(void **)ctx;
-    }
-    else {
-        const size_t to_alloc = reg_alloc + ALIGNED_CTX_SIZE;
-        ctx                   = (Parrot_Context *)mem_sys_allocate(to_alloc);
-    }
+    const size_t to_alloc = reg_alloc + ALIGNED_CTX_SIZE;
+    ctx                   = (Parrot_Context *)mem_sys_allocate(to_alloc);
 
     ctx->n_regs_used[REGNO_INT] = number_regs_used[REGNO_INT];
     ctx->n_regs_used[REGNO_NUM] = number_regs_used[REGNO_NUM];
     ctx->n_regs_used[REGNO_STR] = number_regs_used[REGNO_STR];
     ctx->n_regs_used[REGNO_PMC] = number_regs_used[REGNO_PMC];
 
-#if CTX_LEAK_DEBUG
-    if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
-        fprintf(stderr, "[alloc ctx %p]\n", ctx);
-    }
-#endif
-
-    ctx->regs_mem_size = reg_alloc;
-
     /* regs start past the context */
     p   = (void *) ((char *)ctx + ALIGNED_CTX_SIZE);
 
@@ -505,15 +407,18 @@
     /* ctx.bp_ps points to S0, which has Px on the left */
     ctx->bp_ps.regs_s = (STRING **)((char *)p + size_nip);
 
-    init_context(interp, ctx, old);
+    pmcctx = pmc_new(interp, enum_class_Context);
+    VTABLE_set_pointer(interp, pmcctx, ctx);
 
-    return ctx;
+    init_context(interp, pmcctx, old);
+
+    return pmcctx;
 }
 
 
 /*
 
-=item C<Parrot_Context * Parrot_set_new_context(PARROT_INTERP, const INTVAL
+=item C<PMC * Parrot_set_new_context(PARROT_INTERP, const INTVAL
 *number_regs_used)>
 
 Allocates and returns a new context as the current context.  Note that the
@@ -525,16 +430,14 @@
 
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-Parrot_Context *
+PMC *
 Parrot_set_new_context(PARROT_INTERP, ARGIN(const INTVAL *number_regs_used))
 {
     ASSERT_ARGS(Parrot_set_new_context)
-    Parrot_Context *old = CONTEXT(interp);
-    Parrot_Context *ctx = Parrot_alloc_context(interp, number_regs_used, old);
+    PMC *old = CURRENT_CONTEXT(interp);
+    PMC *ctx = Parrot_alloc_context(interp, number_regs_used, old);
 
-    CONTEXT(interp)          = ctx;
-    interp->ctx.bp.regs_i    = ctx->bp.regs_i;
-    interp->ctx.bp_ps.regs_s = ctx->bp_ps.regs_s;
+    CURRENT_CONTEXT(interp) = ctx;
 
     return ctx;
 }
@@ -542,11 +445,17 @@
 
 /*
 
-=item C<void Parrot_free_context(PARROT_INTERP, Parrot_Context *ctx, int deref)>
+=back
+
+=head2 Register Stack Functions
+
+=over 4
+
+=cut
 
-Frees the context if its reference count is zero.  If C<deref>
-is true, then reduce the reference count prior to determining
-if the context should be freed.
+=item C<void Parrot_clear_i(PARROT_INTERP)>
+
+Sets all integer registers in the current context to 0.
 
 =cut
 
@@ -554,141 +463,62 @@
 
 PARROT_EXPORT
 void
-Parrot_free_context(PARROT_INTERP, ARGMOD(Parrot_Context *ctx), int deref)
+Parrot_clear_i(PARROT_INTERP)
 {
-    ASSERT_ARGS(Parrot_free_context)
-    /*
-     * The context structure has a reference count, initially 0.
-     * This field is incremented when something outside of the normal
-     * calling chain (such as a continuation or outer scope) wants to
-     * preserve the context.  The field is decremented when
-     * Parrot_free_context is called with the C<deref> flag set true.
-     * To trace context handling and check for leaks,
-     * (a) disable NDEBUG, (b) enable CTX_LEAK_DEBUG in interpreter.h,
-     * and (c) execute "debug 0x80" in a (preferably small) test case.
-     *
-     */
-    if (deref) {
-#if CTX_LEAK_DEBUG
-        if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
-            fprintf(stderr, "[reference to context %p released]\n", (void*)ctx);
-        }
-#endif
-        ctx->ref_count--;
-    }
+    ASSERT_ARGS(Parrot_clear_i)
+    int i;
+    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT); ++i)
+        REG_INT(interp, i) = 0;
+}
 
-    if (ctx->ref_count <= 0) {
-        void *ptr;
-        int slot;
-
-#ifndef NDEBUG
-        if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)
-            && ctx->current_sub) {
-            /* can't probably Parrot_io_eprintf here */
-            Parrot_Sub_attributes *doomed;
-            PMC_get_sub(interp, ctx->current_sub, doomed);
-
-            if (doomed) {
-                fprintf(stderr, "[free  ctx %p of sub '%s']\n",
-                        (void *)ctx,
-                        (doomed->name == (void*)0xdeadbeef
-                        ? "???"
-                        : (char*)doomed->name->strstart));
-            }
-            else {
-                Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                        "NULL doomed sub detected in Parrot_free_context");
-            }
-        }
-#endif
 
-        if (ctx->outer_ctx)
-            Parrot_free_context(interp, ctx->outer_ctx, 1);
+/*
 
-        ctx->n_regs_used[REGNO_INT] = 0;
-        ctx->n_regs_used[REGNO_NUM] = 0;
-        ctx->n_regs_used[REGNO_STR] = 0;
-        ctx->n_regs_used[REGNO_PMC] = 0;
-
-#if CTX_LEAK_DEBUG_FULL
-        /* for debugging, poison the freed context in case anything
-         * tries to use it later. */
-        ctx->current_results   = (opcode_t *)0xbeefcafe;
-        ctx->results_signature = (PMC *)0xbeefcafe;
-        ctx->lex_pad           = (PMC *)0xbeefcafe;
-        ctx->outer_ctx         = (Parrot_Context *)0xbeefcafe;
-        ctx->current_cont      = (PMC *)0xbeefcafe;
-        ctx->current_object    = (PMC *)0xbeefcafe;
-        ctx->current_HLL       = -1;
-        ctx->handlers          = (PMC *)0xbeefcafe;
-        ctx->constants         = (struct PackFile_Constant **)0xbeefcafe;
-        ctx->current_namespace = (PMC *)0xbeefcafe;
-#endif
+=item C<void Parrot_clear_s(PARROT_INTERP)>
 
-        /* don't put the same context on the free list multiple times; we don't
-         * have the re-use versus multiple ref count semantics right yet */
-        if (ctx->ref_count < 0)
-            return;
-
-        /* force the reference count negative to indicate a dead context
-         * so mark_context (src/sub.c) can report it */
-        ctx->ref_count--;
+Sets all STRING registers in the current context to NULL.
 
-        ptr             = ctx;
-        slot            = CALCULATE_SLOT_NUM(ctx->regs_mem_size);
+=cut
 
-#if CTX_LEAK_DEBUG_FULL
-        slot = 0;
-#endif
+*/
 
-        PARROT_ASSERT(slot < interp->ctx_mem.n_free_slots);
-        *(void **)ptr                   = interp->ctx_mem.free_list[slot];
-        interp->ctx_mem.free_list[slot] = ptr;
-    }
+PARROT_EXPORT
+void
+Parrot_clear_s(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_clear_s)
+    int i;
+    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_STR); ++i)
+        REG_STR(interp, i) = NULL;
 }
 
 
 /*
 
-=item C<Parrot_Context * Parrot_context_ref_trace(PARROT_INTERP, Parrot_Context
-*ctx, const char *file, int line)>
+=item C<void Parrot_clear_p(PARROT_INTERP)>
 
-Helper function to trace references when CTX_LEAK_DEBUG is set.
+Sets all PMC registers in the current context to NULL.
 
 =cut
 
 */
 
 PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-Parrot_Context *
-Parrot_context_ref_trace(PARROT_INTERP, ARGMOD(Parrot_Context *ctx),
-        ARGIN(const char *file), int line)
+void
+Parrot_clear_p(PARROT_INTERP)
 {
-    ASSERT_ARGS(Parrot_context_ref_trace)
-    if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
-        const char *name = "unknown";
-
-        if (ctx->current_sub) {
-            Parrot_Sub_attributes *sub;
-            PMC_get_sub(interp, ctx->current_sub, sub);
-            name = (char *)(sub->name->strstart);
-        }
-
-        fprintf(stderr, "[reference to context %p ('%s') taken at %s:%d]\n",
-                (void *)ctx, name, file, line);
-    }
-
-    ctx->ref_count++;
-    return ctx;
+    ASSERT_ARGS(Parrot_clear_p)
+    int i;
+    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_PMC); ++i)
+        REG_PMC(interp, i) = PMCNULL;
 }
 
 
 /*
 
-=item C<void Parrot_set_context_threshold(PARROT_INTERP, Parrot_Context *ctx)>
+=item C<void Parrot_clear_n(PARROT_INTERP)>
 
-Marks the context as possible threshold.
+Sets all number registers in the current context to 0.0.
 
 =cut
 
@@ -696,104 +526,198 @@
 
 PARROT_EXPORT
 void
-Parrot_set_context_threshold(SHIM_INTERP, SHIM(Parrot_Context *ctx))
+Parrot_clear_n(PARROT_INTERP)
 {
-    ASSERT_ARGS(Parrot_set_context_threshold)
-    /* nothing to do */
+    ASSERT_ARGS(Parrot_clear_n)
+    int i;
+    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_NUM); ++i)
+        REG_NUM(interp, i) = 0.0;
 }
 
 /*
 
-=back
-
-=head2 Register Stack Functions
+=item C<INTVAL * Parrot_pcc_get_INTVAL_reg(PARROT_INTERP, PMC *ctx, INTVAL idx)>
 
-=over 4
+Get pointer to INTVAL register.
 
 =cut
 
-=item C<void Parrot_clear_i(PARROT_INTERP)>
+*/
 
-Sets all integer registers in the current context to 0.
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+INTVAL *
+Parrot_pcc_get_INTVAL_reg(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_INTVAL_reg)
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp.regs_i[idx]);
+}
+
+/*
+
+=item C<FLOATVAL * Parrot_pcc_get_FLOATVAL_reg(PARROT_INTERP, PMC *ctx, INTVAL
+idx)>
+
+Get pointer to FLOATVAL register.
 
 =cut
 
 */
 
 PARROT_EXPORT
-void
-Parrot_clear_i(PARROT_INTERP)
+PARROT_CANNOT_RETURN_NULL
+FLOATVAL *
+Parrot_pcc_get_FLOATVAL_reg(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
 {
-    ASSERT_ARGS(Parrot_clear_i)
-    int i;
-    for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_INT]; ++i)
-        REG_INT(interp, i) = 0;
+    ASSERT_ARGS(Parrot_pcc_get_FLOATVAL_reg)
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp.regs_n[-1L - idx]);
 }
 
-
 /*
 
-=item C<void Parrot_clear_s(PARROT_INTERP)>
+=item C<STRING ** Parrot_pcc_get_STRING_reg(PARROT_INTERP, PMC *ctx, INTVAL
+idx)>
 
-Sets all STRING registers in the current context to NULL.
+Get pointer to STRING register.
 
 =cut
 
 */
 
 PARROT_EXPORT
-void
-Parrot_clear_s(PARROT_INTERP)
+PARROT_CANNOT_RETURN_NULL
+STRING **
+Parrot_pcc_get_STRING_reg(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
 {
-    ASSERT_ARGS(Parrot_clear_s)
-    int i;
-    for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_STR]; ++i)
-        REG_STR(interp, i) = NULL;
+    ASSERT_ARGS(Parrot_pcc_get_STRING_reg)
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp_ps.regs_s[idx]);
 }
 
+/*
+
+=item C<PMC ** Parrot_pcc_get_PMC_reg(PARROT_INTERP, PMC *ctx, INTVAL idx)>
+
+Get pointer to PMC register.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC **
+Parrot_pcc_get_PMC_reg(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_PMC_reg)
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp_ps.regs_p[-1L - idx]);
+}
 
 /*
 
-=item C<void Parrot_clear_p(PARROT_INTERP)>
+=item C<int Parrot_pcc_get_regs_used(PARROT_INTERP, PMC *ctx, int type)>
 
-Sets all PMC registers in the current context to NULL.
+Return number of used registers of particular type.
 
 =cut
 
 */
+PARROT_EXPORT
+int
+Parrot_pcc_get_regs_used(PARROT_INTERP, ARGIN(PMC *ctx), int type)
+{
+    ASSERT_ARGS(Parrot_pcc_get_regs_used)
+    return Parrot_pcc_get_context_struct(interp, ctx)->n_regs_used[type];
+}
+
+/*
+
+=item C<void Parrot_pcc_set_regs_used(PARROT_INTERP, PMC *ctx, int type, INTVAL
+num)>
+
+Set number of used registers of particular type.
 
+=cut
+
+*/
 PARROT_EXPORT
 void
-Parrot_clear_p(PARROT_INTERP)
+Parrot_pcc_set_regs_used(PARROT_INTERP, ARGIN(PMC *ctx), int type, INTVAL num)
 {
-    ASSERT_ARGS(Parrot_clear_p)
-    int i;
-    for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_PMC]; ++i)
-        REG_PMC(interp, i) = PMCNULL;
+    ASSERT_ARGS(Parrot_pcc_set_regs_used)
+    Parrot_pcc_get_context_struct(interp, ctx)->n_regs_used[type] = num;
 }
 
-
 /*
 
-=item C<void Parrot_clear_n(PARROT_INTERP)>
+=item C<Regs_ni* Parrot_pcc_get_regs_ni(PARROT_INTERP, PMC *ctx)>
 
-Sets all number registers in the current context to 0.0.
+Get pointer to FLOANFAL and INTVAL registers.
 
 =cut
 
 */
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+Regs_ni*
+Parrot_pcc_get_regs_ni(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_regs_ni)
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp);
+}
+
+/*
+
+=item C<void Parrot_pcc_set_regs_ni(PARROT_INTERP, PMC *ctx, Regs_ni *bp)>
+
+Copy Regs_ni into Context.
+
+=cut
 
+*/
 PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
 void
-Parrot_clear_n(PARROT_INTERP)
+Parrot_pcc_set_regs_ni(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(Regs_ni *bp))
 {
-    ASSERT_ARGS(Parrot_clear_n)
-    int i;
-    for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_NUM]; ++i)
-        REG_NUM(interp, i) = 0.0;
+    ASSERT_ARGS(Parrot_pcc_set_regs_ni)
+    Parrot_pcc_get_context_struct(interp, ctx)->bp = *bp;
+}
+
+/*
+
+=item C<Regs_ps* Parrot_pcc_get_regs_ps(PARROT_INTERP, PMC *ctx)>
+
+Get pointer to PMC and STRING registers.
+
+=cut
+
+*/
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+Regs_ps*
+Parrot_pcc_get_regs_ps(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_regs_ps)
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp_ps);
 }
 
+/*
+
+=item C<void Parrot_pcc_set_regs_ps(PARROT_INTERP, PMC *ctx, Regs_ps *bp_ps)>
+
+Copy Regs_ps into Context.
+
+=cut
 
+*/
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+void
+Parrot_pcc_set_regs_ps(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(Regs_ps *bp_ps))
+{
+    ASSERT_ARGS(Parrot_pcc_set_regs_ps)
+    Parrot_pcc_get_context_struct(interp, ctx)->bp_ps = *bp_ps;
+}
 /*
 
 =back

Modified: trunk/src/gc/mark_sweep.c
==============================================================================
--- trunk/src/gc/mark_sweep.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/gc/mark_sweep.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -169,9 +169,8 @@
 Parrot_gc_trace_root(PARROT_INTERP, Parrot_gc_trace_type trace)
 {
     ASSERT_ARGS(Parrot_gc_trace_root)
-    Arenas           * const arena_base = interp->arena_base;
-    Parrot_Context   *ctx;
-    PObj             *obj;
+    Arenas  * const arena_base = interp->arena_base;
+    PObj    *obj;
 
     /* note: adding locals here did cause increased GC runs */
     mark_context_start();
@@ -200,8 +199,7 @@
         Parrot_gc_mark_PObj_alive(interp, obj);
 
     /* mark the current context. */
-    ctx = CONTEXT(interp);
-    mark_context(interp, ctx);
+    Parrot_gc_mark_PObj_alive(interp, (PObj*)CURRENT_CONTEXT(interp));
 
     /* mark the dynamic environment. */
     Parrot_gc_mark_PObj_alive(interp, (PObj*)interp->dynamic_env);

Modified: trunk/src/global.c
==============================================================================
--- trunk/src/global.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/global.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -375,10 +375,10 @@
     ASSERT_ARGS(Parrot_make_namespace_autobase)
     PMC *base_ns;
     if (VTABLE_isa(interp, key, CONST_STRING(interp, "String")))
-        base_ns = CONTEXT(interp)->current_namespace;
+        base_ns = Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp));
     else
         base_ns = VTABLE_get_pmc_keyed_int(interp, interp->HLL_namespace,
-            CONTEXT(interp)->current_HLL);
+            Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp)));
     return Parrot_make_namespace_keyed(interp, base_ns, key);
 }
 
@@ -531,7 +531,7 @@
 Parrot_find_global_cur(PARROT_INTERP, ARGIN_NULLOK(STRING *globalname))
 {
     ASSERT_ARGS(Parrot_find_global_cur)
-    PMC * const ns = CONTEXT(interp)->current_namespace;
+    PMC * const ns = Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp));
     return Parrot_find_global_n(interp, ns, globalname);
 }
 
@@ -678,7 +678,7 @@
 Parrot_find_name_op(PARROT_INTERP, ARGIN(STRING *name), SHIM(void *next))
 {
     ASSERT_ARGS(Parrot_find_name_op)
-    Parrot_Context * const ctx = CONTEXT(interp);
+    PMC * const ctx     = CURRENT_CONTEXT(interp);
     PMC * const lex_pad = Parrot_find_pad(interp, name, ctx);
     PMC *g;
 
@@ -788,7 +788,7 @@
 Parrot_store_sub_in_namespace(PARROT_INTERP, ARGIN(PMC *sub_pmc))
 {
     ASSERT_ARGS(Parrot_store_sub_in_namespace)
-    const INTVAL cur_id = CONTEXT(interp)->current_HLL;
+    const INTVAL cur_id = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp));
 
     PMC        *ns;
     Parrot_Sub_attributes *sub;
@@ -798,7 +798,7 @@
 
     /* store relative to HLL namespace */
     PMC_get_sub(interp, sub_pmc, sub);
-    CONTEXT(interp)->current_HLL = sub->HLL_id;
+    Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), sub->HLL_id);
 
     ns = get_namespace_pmc(interp, sub_pmc);
 
@@ -824,7 +824,7 @@
     }
 
     /* restore HLL_id */
-    CONTEXT(interp)->current_HLL = cur_id;
+    Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), cur_id);
     Parrot_unblock_GC_mark(interp);
 }
 

Modified: trunk/src/global_setup.c
==============================================================================
--- trunk/src/global_setup.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/global_setup.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -209,12 +209,14 @@
     PMC *classname_hash, *iglobals;
     int  i;
 
+    create_initial_context(interp);
+
     /* create the namespace root stash */
     interp->root_namespace = pmc_new(interp, enum_class_NameSpace);
     Parrot_init_HLL(interp);
 
-    CONTEXT(interp)->current_namespace =
-        VTABLE_get_pmc_keyed_int(interp, interp->HLL_namespace, 0);
+    Parrot_pcc_set_namespace(interp, CURRENT_CONTEXT(interp),
+        VTABLE_get_pmc_keyed_int(interp, interp->HLL_namespace, 0));
 
     /* We need a class hash */
     interp->class_hash = classname_hash = pmc_new(interp, enum_class_NameSpace);

Modified: trunk/src/hll.c
==============================================================================
--- trunk/src/hll.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/hll.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -446,7 +446,7 @@
 Parrot_get_ctx_HLL_type(PARROT_INTERP, INTVAL core_type)
 {
     ASSERT_ARGS(Parrot_get_ctx_HLL_type)
-    const INTVAL hll_id = CONTEXT(interp)->current_HLL;
+    const INTVAL hll_id = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp));
 
     return Parrot_get_HLL_type(interp, hll_id, core_type);
 }
@@ -468,7 +468,7 @@
 Parrot_get_ctx_HLL_namespace(PARROT_INTERP)
 {
     ASSERT_ARGS(Parrot_get_ctx_HLL_namespace)
-    return Parrot_get_HLL_namespace(interp, CONTEXT(interp)->current_HLL);
+    return Parrot_get_HLL_namespace(interp, Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp)));
 }
 
 /*

Modified: trunk/src/interp/inter_create.c
==============================================================================
--- trunk/src/interp/inter_create.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/interp/inter_create.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -152,11 +152,9 @@
     Parrot_block_GC_mark(interp);
     Parrot_block_GC_sweep(interp);
 
-    create_initial_context(interp);
+    interp->ctx         = PMCNULL;
     interp->resume_flag = RESUME_INITIAL;
 
-    /* main is called as a Sub too - this will get depth 0 then */
-    CONTEXT(interp)->recursion_depth = (UINTVAL)-1;
     interp->recursion_limit = RECURSION_LIMIT;
 
     /* PANIC will fail until this is done */
@@ -211,10 +209,12 @@
     PARROT_ERRORS_on(interp, PARROT_ERRORS_RESULT_COUNT_FLAG);
 #endif
 
+    create_initial_context(interp);
+
     /* clear context introspection vars */
-    CONTEXT(interp)->current_sub    = NULL;
-    CONTEXT(interp)->current_cont   = NULL;
-    CONTEXT(interp)->current_object = NULL;
+    Parrot_pcc_set_sub(interp, CURRENT_CONTEXT(interp), NULL);
+    Parrot_pcc_set_continuation(interp, CURRENT_CONTEXT(interp), NULL); /* TODO Use PMCNULL */
+    Parrot_pcc_set_object(interp, CURRENT_CONTEXT(interp), NULL);
 
     /* Load the core op func and info tables */
     interp->op_lib          = PARROT_CORE_OPLIB_INIT(1);
@@ -418,7 +418,6 @@
         interp->profile = NULL;
     }
 
-    destroy_context(interp);
     destroy_runloop_jump_points(interp);
 
     if (interp->evc_func_table) {

Modified: trunk/src/interp/inter_misc.c
==============================================================================
--- trunk/src/interp/inter_misc.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/interp/inter_misc.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -282,19 +282,19 @@
     ASSERT_ARGS(interpinfo_p)
     switch (what) {
         case CURRENT_SUB:
-            return CONTEXT(interp)->current_sub;
+            return Parrot_pcc_get_sub(interp, CURRENT_CONTEXT(interp));
         case CURRENT_CONT:
             {
-            PMC * const cont = CONTEXT(interp)->current_cont;
+            PMC * const cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
             if (!PMC_IS_NULL(cont) && cont->vtable->base_type ==
                     enum_class_RetContinuation)
                 return VTABLE_clone(interp, cont);
             return cont;
             }
         case CURRENT_OBJECT:
-            return CONTEXT(interp)->current_object;
+            return Parrot_pcc_get_object(interp, CURRENT_CONTEXT(interp));
         case CURRENT_LEXPAD:
-            return CONTEXT(interp)->lex_pad;
+            return Parrot_pcc_get_lex_pad(interp, CURRENT_CONTEXT(interp));
         default:        /* or a warning only? */
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNIMPLEMENTED,
                 "illegal argument in interpinfo");

Modified: trunk/src/jit.c
==============================================================================
--- trunk/src/jit.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/jit.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -287,7 +287,7 @@
         int arg_type;
         PMC *sig;
         if (argn >= args) {
-            sig = CONTEXT(interp)->constants[cur_op[1]]->u.key;
+            sig = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), cur_op[1]);
             arg_type = VTABLE_get_integer_keyed_int(interp,
                     sig, argn - args);
             arg_type &= (PARROT_ARG_TYPE_MASK | PARROT_ARG_CONSTANT);
@@ -396,8 +396,10 @@
 {
     int typ;
 
-    cur_section->ru[0].registers_used = CONTEXT(interp)->n_regs_used[REGNO_INT];
-    cur_section->ru[3].registers_used = CONTEXT(interp)->n_regs_used[REGNO_NUM];
+    cur_section->ru[0].registers_used = Parrot_pcc_get_regs_used(interp,
+                                            CURRENT_CONTEXT(interp), REGNO_INT);
+    cur_section->ru[3].registers_used = Parrot_pcc_get_regs_used(interp,
+                                            CURRENT_CONTEXT(interp), REGNO_NUM);
     cur_section->ru[1].registers_used = cur_section->ru[2].registers_used = 0;
 
     for (typ = 0; typ < 4; typ++) {
@@ -1304,7 +1306,8 @@
 
             if (offs >= sub->start_offs && offs < sub->end_offs) {
                 for (i = 0; i < 4; i++)
-                    CONTEXT(interp)->n_regs_used[i] = sub->n_regs_used[i];
+                    Parrot_pcc_set_regs_used(interp, CURRENT_CONTEXT(interp),
+                            i, sub->n_regs_used[i]);
 
                 return;
             }
@@ -1425,7 +1428,7 @@
 
     /* remember register usage */
     for (i = 0; i < 4; i++)
-        n_regs_used[i] = CONTEXT(interp)->n_regs_used[i];
+        n_regs_used[i] = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), i);
 
     set_reg_usage(interp, code_start);
 
@@ -1679,7 +1682,7 @@
 
     /* restore register usage */
     for (i = 0; i < 4; i++)
-        CONTEXT(interp)->n_regs_used[i] = n_regs_used[i];
+        Parrot_pcc_set_regs_used(interp, CURRENT_CONTEXT(interp), i, n_regs_used[i]);
 
     /* Do fixups before converting offsets */
     (arch_info->jit_dofixup)(jit_info, interp);

Modified: trunk/src/jit/amd64/jit_defs.c
==============================================================================
--- trunk/src/jit/amd64/jit_defs.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/jit/amd64/jit_defs.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -153,7 +153,9 @@
 #endif
     }
     /* Base pointer */
-    emit_mov_r_mr(jit_info->native_ptr, RBX, INTERP, (long)offsetof(Interp, ctx.bp));
+    emit_mov_r_mr(jit_info->native_ptr, RBX, INTERP, (long)offsetof(Interp, ctx));
+    emit_mov_r_mr(jit_info->native_ptr, RBX, RBX, (long)offsetof(PMC, data));
+    emit_mov_r_mr(jit_info->native_ptr, RBX, RBX, (long)offsetof(Parrot_Context, bp));
 
 #ifdef USE_OP_MAP_AND_CODE_START
     emit_jmp_r_r(jit_info->native_ptr, RAX, OP_MAP);

Modified: trunk/src/jit/i386/core.jit
==============================================================================
--- trunk/src/jit/i386/core.jit	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/jit/i386/core.jit	Thu Sep  3 11:56:50 2009	(r40958)
@@ -1453,21 +1453,18 @@
 
 Parrot_pic_callr___pc {
     int offset, here, op_i;
-    PackFile_Constant ** constants;
     PMC *sig_params, *sig_result;
     opcode_t *params;
     int skip;
 
-    constants = CONTEXT(interp)->constants;
     params = jit_info->optimizer->sections->begin;
-    sig_params = constants[params[1]]->u.key;
+    sig_params = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), params[1]);
     op_i = 2 + VTABLE_elements(interp, sig_params);
 
     offset = jit_info->arena.op_map[op_i].offset;
     /* TODO preserve necessary regs */
     assert(*CUR_OPCODE == PARROT_OP_get_results_pc);
-    constants = CONTEXT(interp)->constants;
-    sig_result = constants[CUR_OPCODE[1]]->u.key;
+    sig_result = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), CUR_OPCODE[1]);
     if (!VTABLE_elements(interp, sig_result))
         skip = -1;
     else
@@ -1492,16 +1489,16 @@
     if (jit_info->code_type == JIT_CODE_FILE) {
         Parrot_jit_emit_get_INTERP(interp, jit_info->native_ptr, emit_EAX);
         emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_EAX, emit_None, 1,
-                offsetof(Interp, ctx.state));
+                offsetof(Interp, ctx));
+        emitm_movl_m_r(interp, NATIVECODE, emit_EAX, emit_EAX, emit_None, 1,
+                offsetof(PMC, data));
         emitm_movl_i_m(NATIVECODE, jit_info->cur_op, emit_EAX, emit_None, 1,
                 offsetof(Parrot_Context, current_results));
     }
     else {
-        PackFile_Constant ** constants;
-        PMC *sig_result;
+        PMC *sig_result = Parrot_pcc_get_pmc_constant(interp,
+                                CURRENT_CONTEXT(interp), CUR_OPCODE[1]);
 
-        constants = CONTEXT(interp)->constants;
-        sig_result = constants[CUR_OPCODE[1]]->u.key;
         if (!VTABLE_elements(interp, sig_result))
             return;
         if (VTABLE_get_integer_keyed_int(interp, sig_result, 0) ==

Modified: trunk/src/jit/i386/jit_defs.c
==============================================================================
--- trunk/src/jit/i386/jit_defs.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/jit/i386/jit_defs.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -872,7 +872,11 @@
 #endif
     /* get base pointer */
     emitm_movl_m_r(interp, jit_info->native_ptr, emit_EBX, emit_EBX, 0, 1,
-            offsetof(Interp, ctx.bp));
+            offsetof(Interp, ctx));
+    emitm_movl_m_r(interp, jit_info->native_ptr, emit_EBX, emit_EBX, 0, 1,
+            offsetof(PMC, data));
+    emitm_movl_m_r(interp, jit_info->native_ptr, emit_EBX, emit_EBX, 0, 1,
+            offsetof(Parrot_Context, bp));
 
     /* This jumps to the address in op_map[EDX + sizeof (void *) * INDEX] */
     emitm_jumpm(jit_info->native_ptr, emit_EDX, emit_EAX,
@@ -1231,7 +1235,7 @@
     PMC *sig_pmc;
     INTVAL *sig_bits, i, n;
 
-    sig_pmc = CONTEXT(interp)->constants[CUR_OPCODE[1]]->u.key;
+    sig_pmc = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), CUR_OPCODE[1]);
     GETATTR_FixedIntegerArray_int_array(interp, sig_pmc, sig_bits);
     n = VTABLE_elements(interp, sig_pmc);
     jit_info->n_args = n;
@@ -1267,7 +1271,7 @@
     int i, used_i, save_i;
     const jit_arch_regs *reg_info;
 
-    used_i = CONTEXT(interp)->n_regs_used[REGNO_INT];
+    used_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
     reg_info = &jit_info->arch_info->regs[jit_info->code_type];
     save_i = reg_info->n_preserved_I;
     for (i = save_i; i < used_i; ++i) {
@@ -1283,7 +1287,7 @@
     int i, used_i, save_i;
     const jit_arch_regs *reg_info;
 
-    used_i = CONTEXT(interp)->n_regs_used[REGNO_INT];
+    used_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
     reg_info = &jit_info->arch_info->regs[jit_info->code_type];
     save_i = reg_info->n_preserved_I;
     /* note - reversed order of jit_save_regs  */
@@ -1307,8 +1311,8 @@
     int i, used_i, used_n;
     const jit_arch_regs *reg_info;
 
-    used_i = CONTEXT(interp)->n_regs_used[REGNO_INT];
-    used_n = CONTEXT(interp)->n_regs_used[REGNO_NUM];
+    used_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
+    used_n = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_NUM);
     jit_emit_sub_ri_i(interp, jit_info->native_ptr, emit_ESP,
             (used_i * sizeof (INTVAL) + used_n * sizeof (FLOATVAL)));
     reg_info = &jit_info->arch_info->regs[jit_info->code_type];
@@ -1338,8 +1342,8 @@
     int i, used_i, used_n;
     const jit_arch_regs *reg_info;
 
-    used_i = CONTEXT(interp)->n_regs_used[REGNO_INT];
-    used_n = CONTEXT(interp)->n_regs_used[REGNO_NUM];
+    used_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
+    used_n = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_NUM);
     reg_info = &jit_info->arch_info->regs[jit_info->code_type];
 
     for (i = 0; i < used_i; ++i) {
@@ -1368,7 +1372,7 @@
     PMC *sig_pmc;
     INTVAL *sig_bits, sig;
 
-    sig_pmc = CONTEXT(interp)->constants[CUR_OPCODE[1]]->u.key;
+    sig_pmc = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), CUR_OPCODE[1]);
     if (!VTABLE_elements(interp, sig_pmc))
         return;
     GETATTR_FixedIntegerArray_int_array(interp, sig_pmc, sig_bits);
@@ -1428,7 +1432,6 @@
 {
     PMC *sig_args, *sig_params, *sig_result;
     INTVAL *sig_bits, sig, i, n;
-    PackFile_Constant ** constants;
     opcode_t *params, *result;
     char params_map;
     int skip, used_n;
@@ -1442,13 +1445,12 @@
         Parrot_ex_throw_from_c_args(interp, NULL, 1,
             "set_args_jit - can't do that yet ");
 
-    constants = CONTEXT(interp)->constants;
-    sig_args  = constants[CUR_OPCODE[1]]->u.key;
+    sig_args  = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), CUR_OPCODE[1]);
 
     if (!VTABLE_elements(interp, sig_args))
         return;
     params = jit_info->optimizer->sections->begin;
-    sig_params = constants[params[1]]->u.key;
+    sig_params = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), params[1]);
     ASSERT_SIG_PMC(sig_params);
     GETATTR_FixedIntegerArray_int_array(interp, sig_args, sig_bits);
     n = VTABLE_elements(interp, sig_args);
@@ -1458,7 +1460,7 @@
      */
     result = CUR_OPCODE + 2 + n + 3; /* set_args, set_p_pc */
     PARROT_ASSERT(*result == PARROT_OP_get_results_pc);
-    sig_result = constants[result[1]]->u.key;
+    sig_result = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), result[1]);
     ASSERT_SIG_PMC(sig_result);
 
     if (!VTABLE_elements(interp, sig_result))
@@ -1738,7 +1740,6 @@
      */
     if (jit_info->flags & JIT_CODE_RECURSIVE) {
         char * L1;
-        PackFile_Constant ** constants;
         PMC *sig_result;
         opcode_t *result;
 
@@ -1747,9 +1748,8 @@
         L1 = NATIVECODE;
         emitm_calll(NATIVECODE, 0);
         /* check type of return value */
-        constants = CONTEXT(interp)->constants;
-        result = CONTEXT(interp)->current_results;
-        sig_result = constants[result[1]]->u.key;
+        result      = Parrot_pcc_get_results(interp, CURRENT_CONTEXT(interp));
+        sig_result  = Parrot_pcc_get_pmc_constant(interp, CURRENT_CONTEXT(interp), result[1]);
         if (!VTABLE_elements(interp, sig_result))
             goto no_result;
         /* fetch args to %edx */

Modified: trunk/src/jit/ppc/core.jit
==============================================================================
--- trunk/src/jit/ppc/core.jit	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/jit/ppc/core.jit	Thu Sep  3 11:56:50 2009	(r40958)
@@ -1223,8 +1223,8 @@
 ; or just JIT (TODO)  the 2 easy ones
 Parrot_set_args_pc {
     if (jit_info->code_type == JIT_CODE_FILE) {
-    jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
-    jit_emit_stw(NATIVECODE, ISR1, offsetof(Interp, current_args), r16);
+        jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
+        jit_emit_stw(NATIVECODE, ISR1, offsetof(Interp, current_args), r16);
     }
     else  {
         jit_set_args_pc(jit_info, interp,
@@ -1294,10 +1294,12 @@
 
 Parrot_get_results_pc {
     if (jit_info->code_type == JIT_CODE_FILE) {
-    jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
-    jit_emit_lwz(NATIVECODE, ISR2, offsetof(Interp, ctx.state), r16);
-    jit_emit_stw(NATIVECODE, ISR1,
-        offsetof(Parrot_Context, current_results), ISR2);
+        jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
+        jit_emit_lwz(NATIVECODE, ISR2, offsetof(Interp, ctx), r16);
+        jit_emit_lwz(NATIVECODE, ISR2, offsetof(PMC, data), ISR2);
+        jit_emit_lwz(NATIVECODE, ISR2, offsetof(Parrot_Context, state), ISR2);
+        jit_emit_stw(NATIVECODE, ISR1,
+            offsetof(Parrot_Context, current_results), ISR2);
     }
     else {
     PackFile_Constant **constants  = CONTEXT(interp)->constants;

Modified: trunk/src/jit/ppc/jit_emit.h
==============================================================================
--- trunk/src/jit/ppc/jit_emit.h	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/jit/ppc/jit_emit.h	Thu Sep  3 11:56:50 2009	(r40958)
@@ -675,7 +675,9 @@
     jit_emit_lwz((pc), r15,  offsetof(PackFile_Segment, data), ISR1)
 
 #  define jit_emit_branch_to_opcode(pc, D) \
-    jit_emit_lwz((pc), r13, offsetof(Interp, ctx.bp), r16); \
+    jit_emit_lwz((pc), r13, offsetof(Interp, ctx), r16); \
+    jit_emit_lwz((pc), r13, offsetof(PMC, data), r13); \
+    jit_emit_lwz((pc), r13, offsetof(Parrot_Context, bp), r13); \
     jit_emit_sub_rrr(jit_info->native_ptr, ISR1, (D), r15); \
     jit_emit_lwzx(jit_info->native_ptr, ISR1, ISR1, r14); \
     jit_emit_mtctr(jit_info->native_ptr, ISR1); \

Modified: trunk/src/jit/sun4/jit_emit.h
==============================================================================
--- trunk/src/jit/sun4/jit_emit.h	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/jit/sun4/jit_emit.h	Thu Sep  3 11:56:50 2009	(r40958)
@@ -413,8 +413,12 @@
     emitm_jumpl_i(jit_info->native_ptr, XSR1, 0, XSR1);
 
     /* fixup where we have the Parrot registers - context switches */
-    emitm_ld_i(jit_info->native_ptr, Parrot_jit_intrp, offsetof(Interp, ctx.bp),
-        Parrot_jit_regbase);
+    emitm_ld_i(jit_info->native_ptr, Parrot_jit_intrp, offsetof(Interp, ctx),
+        Parrot_jit_intrp);
+    emitm_ld_i(jit_info->native_ptr, Parrot_jit_intrp, offsetof(PMC, data),
+        Parrot_jit_intrp);
+    emitm_ld_i(jit_info->native_ptr, Parrot_jit_intrp,
+        offsetof(Parrot_Context, bp), Parrot_jit_intrp);
 }
 
 /* Generate conditional branch to offset from current parrot op */

Modified: trunk/src/multidispatch.c
==============================================================================
--- trunk/src/multidispatch.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/multidispatch.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -1229,7 +1229,8 @@
 {
     ASSERT_ARGS(mmd_add_multi_to_namespace)
     PMC * const hll_ns = VTABLE_get_pmc_keyed_int(interp,
-                        interp->HLL_namespace, CONTEXT(interp)->current_HLL);
+                        interp->HLL_namespace,
+                        Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp)));
     PMC * const ns     = Parrot_make_namespace_keyed_str(interp, hll_ns, ns_name);
     PMC        *multi_sub = Parrot_get_global(interp, ns, sub_name);
 

Modified: trunk/src/oo.c
==============================================================================
--- trunk/src/oo.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/oo.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -209,7 +209,7 @@
                 {
                 PMC * const hll_ns = VTABLE_get_pmc_keyed_int(interp,
                                         interp->HLL_namespace,
-                                        CONTEXT(interp)->current_HLL);
+                                        Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp)));
                 PMC * const ns     = Parrot_get_namespace_keyed(interp,
                                         hll_ns, key);
 
@@ -421,7 +421,7 @@
 
     /* First check in current HLL namespace */
     PMC * const hll_ns = VTABLE_get_pmc_keyed_int(interp, interp->HLL_namespace,
-                           CONTEXT(interp)->current_HLL);
+                           Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp)));
     PMC * const ns     = Parrot_get_namespace_keyed_str(interp, hll_ns, name);
     PMC * const _class = PMC_IS_NULL(ns)
                        ? PMCNULL : VTABLE_get_class(interp, ns);

Modified: trunk/src/ops/core.ops
==============================================================================
--- trunk/src/ops/core.ops	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/ops/core.ops	Thu Sep  3 11:56:50 2009	(r40958)
@@ -447,7 +447,7 @@
 
 inline op yield() :flow {
     opcode_t *dest = expr NEXT();
-    PMC * const p = CONTEXT(interp)->current_sub;
+    PMC * const p = Parrot_pcc_get_sub(interp, CURRENT_CONTEXT(interp));
     dest = (opcode_t *)p->vtable->invoke(interp, p, dest);
     goto ADDRESS(dest);
 }
@@ -456,14 +456,14 @@
     opcode_t *dest;
     PMC * const p = $1;
     dest = expr NEXT();
-    interp->current_cont = CONTEXT(interp)->current_cont;
+    interp->current_cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
     PObj_get_FLAGS(interp->current_cont) |= SUB_FLAG_TAILCALL;
     dest = (opcode_t *)p->vtable->invoke(interp, p, dest);
     goto ADDRESS(dest);
 }
 
 inline op returncc() :flow {
-    PMC * const p = CONTEXT(interp)->current_cont;
+    PMC * const p = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
     opcode_t * const dest = (opcode_t *)p->vtable->invoke(interp,
             p, expr NEXT());
     goto ADDRESS(dest);
@@ -527,24 +527,24 @@
     PMC * const signature = $1;
     INTVAL argc;
 
-    CONTEXT(interp)->current_results = _this;
+    Parrot_pcc_set_results(interp, CURRENT_CONTEXT(interp), _this);
     argc = VTABLE_elements(interp, signature);
     goto OFFSET(argc + 2);
 }
 
 op get_params(inconst PMC) :flow {
     opcode_t * const _this = CUR_OPCODE;
-    Parrot_Context *caller_ctx, *ctx;
+    PMC *caller_ctx, *ctx;
     PMC * ccont;
     PMC * const signature = $1;
     INTVAL argc;
     opcode_t *src_indexes, *dst_indexes;
 
     interp->current_params = _this;
-    ctx = CONTEXT(interp);
-    ccont = ctx->current_cont;
+    ctx     = CURRENT_CONTEXT(interp);
+    ccont   = Parrot_pcc_get_continuation(interp, ctx);
 
-    caller_ctx = ctx->caller_ctx;
+    caller_ctx  = Parrot_pcc_get_caller_ctx(interp, ctx);
 
     src_indexes = interp->current_args;
     dst_indexes = interp->current_params;
@@ -553,13 +553,11 @@
     interp->current_params = NULL;
 
     parrot_pass_args(interp, caller_ctx, ctx, src_indexes, dst_indexes, PARROT_PASS_PARAMS);
+    /* TODO Factor out with Sub.invoke */
     if (PObj_get_FLAGS(ccont) & SUB_FLAG_TAILCALL) {
         PObj_get_FLAGS(ccont) &= ~SUB_FLAG_TAILCALL;
-        --ctx->recursion_depth;
-        ctx->caller_ctx = caller_ctx->caller_ctx;
-        /* ordinarily, this will free the context immediately, but not if the
-           sub created a closure (or continuation, or . . .).  */
-        Parrot_free_context(interp, caller_ctx, 1);
+        Parrot_pcc_dec_recursion_depth(interp, ctx);
+        Parrot_pcc_set_caller_ctx(interp, ctx, Parrot_pcc_get_caller_ctx(interp, caller_ctx));
         interp->current_args = NULL;
     }
     argc = VTABLE_elements(interp, signature);
@@ -568,37 +566,38 @@
 
 op set_returns(inconst PMC) :flow {
     opcode_t * const _this = CUR_OPCODE;
-    Parrot_Context *ctx;
+    PMC *ctx, *caller_ctx;
     PMC *ccont;
     PMC *signature = $1;
     INTVAL argc;
     opcode_t *src_indexes, *dest_indexes;
 
     interp->current_returns = _this;
-    ctx = CONTEXT(interp);
-    ccont = ctx->current_cont;
+    ctx                     = CURRENT_CONTEXT(interp);
+    caller_ctx              = Parrot_pcc_get_caller_ctx(interp, ctx);
+    ccont                   = Parrot_pcc_get_continuation(interp, ctx);
 
     if (PMC_cont(ccont)->address) {
         /* Call is from runops_fromc */
-        Parrot_Context * const caller_ctx = PMC_cont(ccont)->to_ctx;
-        if (! caller_ctx) {
+        caller_ctx = PMC_cont(ccont)->to_ctx;
+        if (PMC_IS_NULL(caller_ctx)) {
             /* there is no point calling Parrot_ex_throw_..., because
                PDB_backtrace can't deal with a missing to_ctx either. */
             exit_fatal(1, "No caller_ctx for continuation %p.", ccont);
         }
 
-        src_indexes = interp->current_returns;
-        dest_indexes = caller_ctx->current_results;
+        src_indexes             = interp->current_returns;
+        dest_indexes            = Parrot_pcc_get_results(interp, caller_ctx);
         interp->current_returns = NULL;
         /* does this need to be here */
         interp->current_args = NULL;
 
         parrot_pass_args(interp, ctx, caller_ctx, src_indexes, dest_indexes, PARROT_PASS_RESULTS);
     }
-    else if (ctx->caller_ctx->results_signature) {
+    else if (Parrot_pcc_get_results_signature(interp, caller_ctx)) {
     /* We have a dynamic result signature, from pcc_invoke */
-        parrot_pass_args(interp, ctx, ctx->caller_ctx, interp->current_returns,
-                ctx->caller_ctx->current_results, PARROT_PASS_RESULTS);
+        parrot_pass_args(interp, ctx, caller_ctx, interp->current_returns,
+                Parrot_pcc_get_results(interp, caller_ctx), PARROT_PASS_RESULTS);
     }
     argc = VTABLE_elements(interp, signature);
     goto OFFSET(argc + 2);
@@ -615,11 +614,11 @@
 
 inline op result_info(out PMC) {
     /* Get context of callee from return continuation. */
-    PMC * const cc = CONTEXT(interp)->current_cont;
+    PMC * const cc = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
     PMC *sig = NULL;
     if (cc && PMC_cont(cc)->to_ctx) {
         /* caller context has results */
-        opcode_t * const results = PMC_cont(cc)->to_ctx->current_results;
+        opcode_t * const results = Parrot_pcc_get_results(interp, PMC_cont(cc)->to_ctx);
         if (results) {
             /* get results PMC index and get PMC. */
             sig = PF_CONST(PMC_cont(cc)->seg, results[1])->u.key;
@@ -803,11 +802,7 @@
         except = Parrot_ex_build_exception(interp, EXCEPT_fatal,
                 EXCEPTION_UNIMPLEMENTED,
                 Parrot_str_new_constant(interp, "Not a throwable object"));
-    /*
-     * We might return here after handling the exception, so mark the
-     * current context appropriately.
-     */
-    Parrot_context_ref(interp, CONTEXT(interp));
+
     VTABLE_set_attr_str(interp, except, Parrot_str_new_constant(interp, "resume"), resume);
     dest = Parrot_ex_throw_from_op(interp, except, ret);
     goto ADDRESS(dest);
@@ -1471,3 +1466,5 @@
  * End:
  * vim: expandtab shiftwidth=4:
  */
+
+

Modified: trunk/src/ops/debug.ops
==============================================================================
--- trunk/src/ops/debug.ops	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/ops/debug.ops	Thu Sep  3 11:56:50 2009	(r40958)
@@ -121,7 +121,7 @@
 
 inline op getline(out INT) {
   Parrot_Context_info info;
-  Parrot_Context_get_info(interp, CONTEXT(interp), &info);
+  Parrot_Context_get_info(interp, CURRENT_CONTEXT(interp), &info);
   $1 = info.line;
 }
 
@@ -133,7 +133,7 @@
 
 inline op getfile(out STR) {
   Parrot_Context_info info;
-  Parrot_Context_get_info(interp, CONTEXT(interp), &info);
+  Parrot_Context_get_info(interp, CURRENT_CONTEXT(interp), &info);
   $1 = info.file;
 }
 

Modified: trunk/src/ops/object.ops
==============================================================================
--- trunk/src/ops/object.ops	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/ops/object.ops	Thu Sep  3 11:56:50 2009	(r40958)
@@ -142,7 +142,7 @@
         VTABLE_get_string(interp, VTABLE_get_class(interp, object)));
   }
   else {
-    interp->current_cont = CONTEXT(interp)->current_cont;
+    interp->current_cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
     PObj_get_FLAGS(interp->current_cont) |= SUB_FLAG_TAILCALL;
     interp->current_object = object;
     dest = (opcode_t *)VTABLE_invoke(interp, method_pmc, next);
@@ -157,7 +157,7 @@
 
   opcode_t *dest;
 
-  interp->current_cont = CONTEXT(interp)->current_cont;
+  interp->current_cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
   PObj_get_FLAGS(interp->current_cont) |= SUB_FLAG_TAILCALL;
   interp->current_object = object;
   dest = (opcode_t *)VTABLE_invoke(interp, method_pmc, next);

Modified: trunk/src/ops/pic.ops
==============================================================================
--- trunk/src/ops/pic.ops	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/ops/pic.ops	Thu Sep  3 11:56:50 2009	(r40958)
@@ -132,18 +132,18 @@
     PMC *sig, *ccont;
     opcode_t *src_pc;
     void **src_pred;
-    Parrot_Context *caller_ctx, *ctx;
+    PMC *caller_ctx, *ctx;
     int n;
 
     /* avoid load dependencies - intermix derefs
      * - yes, confusing but faster
      */
-    ctx = CONTEXT(interp);
-    src_pc = interp->current_args;
-    mic = (Parrot_MIC *) cur_opcode[1];
-    caller_ctx = ctx->caller_ctx;
+    ctx         = CURRENT_CONTEXT(interp);
+    src_pc      = interp->current_args;
+    mic         = (Parrot_MIC *) cur_opcode[1];
+    caller_ctx  = Parrot_pcc_get_caller_ctx(interp, ctx);
     if (src_pc) {
-        src_pred = (void**) src_pc - caller_ctx->pred_offset;
+        src_pred = (void**) src_pc - Parrot_pcc_get_pred_offset(interp, caller_ctx);
         sig = (PMC*)(src_pred[1]);
     }
     else {
@@ -154,17 +154,17 @@
     if (lru->u.signature == sig) {
         if (sig) {
             n = ((arg_pass_f)lru->f.real_function)(interp, sig,
-                    (char*)caller_ctx->bp.regs_i, src_pred,
+                    (char*)Parrot_pcc_get_regs_ni(interp, caller_ctx)->regs_i, src_pred,
                     _reg_base, (void**)cur_opcode);
         }
         else
             n = 2;
-        ccont = ctx->current_cont;
+        ccont = Parrot_pcc_get_continuation(interp, ctx);
         if (PObj_get_FLAGS(ccont) & SUB_FLAG_TAILCALL) {
             PObj_get_FLAGS(ccont) &= ~SUB_FLAG_TAILCALL;
-            --ctx->recursion_depth;
-            ctx->caller_ctx = caller_ctx->caller_ctx;
-            Parrot_free_context(interp, caller_ctx, 1);
+            Parrot_pcc_dec_recursion_depth(interp, ctx);
+            Parrot_pcc_set_caller_ctx(interp, ctx,
+                    Parrot_pcc_get_caller_ctx(interp, caller_ctx));
             interp->current_args = NULL;
         }
 
@@ -183,14 +183,14 @@
     PMC *sig, *ccont;
     opcode_t *dest_pc;
     void **dest_pred;
-    Parrot_Context *caller_ctx, *ctx;
+    PMC *caller_ctx, *ctx;
     Parrot_cont *cc;
     int n;
 
-    ctx = CONTEXT(interp);
-    mic = (Parrot_MIC *) cur_opcode[1];
-    ccont = ctx->current_cont;
-    cc = PMC_cont(ccont);
+    ctx     = CURRENT_CONTEXT(interp);
+    mic     = (Parrot_MIC *) cur_opcode[1];
+    ccont   = Parrot_pcc_get_continuation(interp, ctx);
+    cc      = PMC_cont(ccont);
     if (!cc->address) {
         interp->current_returns = CUR_OPCODE;
         n = VTABLE_get_integer(interp, mic->m.sig);
@@ -198,9 +198,9 @@
     }
     caller_ctx = cc->to_ctx;
     interp->current_args = NULL;
-    dest_pc = caller_ctx->current_results;
+    dest_pc = Parrot_pcc_get_results(interp, caller_ctx);
     if (dest_pc) {
-        dest_pred = (void**) dest_pc - caller_ctx->pred_offset;
+        dest_pred = (void**) dest_pc - Parrot_pcc_get_pred_offset(interp, caller_ctx);
         sig = (PMC*)(dest_pred[1]);
     }
     else {
@@ -212,7 +212,7 @@
         if (sig) {
             n = ((arg_pass_f)lru->f.real_function)(interp, mic->m.sig,
                     _reg_base, (void**)cur_opcode,
-                    (char*)caller_ctx->bp.regs_i, dest_pred);
+                    (char*)Parrot_pcc_get_regs_ni(interp, caller_ctx)->regs_i, dest_pred);
         }
         else
             n = 2;
@@ -239,18 +239,18 @@
     Parrot_MIC *mic;
     Parrot_PIC_lru *lru;
     void *args[6];      /* RT#42355 ARG_MAX */
-    Parrot_Context *ctx;
+    PMC *ctx;
     opcode_t *pc;
     void **pred_pc;
     INTVAL i, n_args, *sig_bits;
     PMC *sig;
 
-    ctx = CONTEXT(interp);
+    ctx = CURRENT_CONTEXT(interp);
     mic = (Parrot_MIC *) cur_opcode[1];
     /* get_results */
-    pc = ctx->current_results;
+    pc = Parrot_pcc_get_results(interp, ctx);
     if (pc) {
-        pred_pc = (void**) pc - ctx->pred_offset;
+        pred_pc = (void**) pc - Parrot_pcc_get_pred_offset(interp, ctx);
         sig = (PMC*)(pred_pc[1]);
         ASSERT_SIG_PMC(sig);
         PARROT_ASSERT(VTABLE_elements(interp, sig) <= 1);

Modified: trunk/src/ops/var.ops
==============================================================================
--- trunk/src/ops/var.ops	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/ops/var.ops	Thu Sep  3 11:56:50 2009	(r40958)
@@ -37,9 +37,9 @@
 =cut
 
 op store_lex(in STR, invar PMC) {
-    Parrot_Context   * const ctx      = CONTEXT(interp);
-    STRING           * const lex_name = $1;
-    PMC              * const lex_pad  = Parrot_find_pad(interp, lex_name, ctx);
+    PMC     * const ctx      = CURRENT_CONTEXT(interp);
+    STRING  * const lex_name = $1;
+    PMC     * const lex_pad  = Parrot_find_pad(interp, lex_name, ctx);
 
     if (PMC_IS_NULL(lex_pad)) {
         opcode_t * const handler = Parrot_ex_throw_from_op_args(interp, NULL,
@@ -62,9 +62,9 @@
 =cut
 
 op find_lex(out PMC, in STR) {
-    Parrot_Context   * const ctx      = CONTEXT(interp);
-    STRING           * const lex_name = $2;
-    PMC              * const lex_pad  = Parrot_find_pad(interp, lex_name, ctx);
+    PMC     * const ctx      = CURRENT_CONTEXT(interp);
+    STRING  * const lex_name = $2;
+    PMC     * const lex_pad  = Parrot_find_pad(interp, lex_name, ctx);
 
     PMC * const result =
         PMC_IS_NULL(lex_pad)
@@ -91,11 +91,14 @@
 =cut
 
 op find_caller_lex(out PMC, in STR) {
-    STRING         * const lex_name = $2;
-    Parrot_Context * ctx            = CONTEXT(interp);
-    PMC            * result         = PMCNULL;
-
-    for (ctx = ctx->caller_ctx; ctx && PMC_IS_NULL(result); ctx = ctx->caller_ctx) {
+    STRING  * const lex_name = $2;
+    PMC     * ctx            = CURRENT_CONTEXT(interp);
+    PMC     * result         = PMCNULL;
+
+    for (ctx = Parrot_pcc_get_caller_ctx(interp, ctx);
+            !PMC_IS_NULL(ctx) && PMC_IS_NULL(result);
+            ctx = Parrot_pcc_get_caller_ctx(interp, ctx))
+    {
         PMC * const lex_pad = Parrot_find_pad(interp, lex_name, ctx);
         if (!PMC_IS_NULL(lex_pad)) {
             result = VTABLE_get_pmc_keyed_str(interp, lex_pad, lex_name);
@@ -127,12 +130,12 @@
 =cut
 
 op get_namespace(out PMC) {
-    PMC * const cur_ns = CONTEXT(interp)->current_namespace;
+    PMC * const cur_ns = Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp));
     $1 = cur_ns;
 }
 
 op get_namespace(out PMC, in PMC) {
-    PMC * const cur_ns = CONTEXT(interp)->current_namespace;
+    PMC * const cur_ns = Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp));
     PMC * const ns     = Parrot_get_namespace_keyed(interp, cur_ns, $2);
 
     $1 = PMC_IS_NULL(ns) ? PMCNULL : ns;
@@ -215,12 +218,12 @@
 =cut
 
 op get_global(out PMC, in STR) {
-    PMC * const cur_ns = CONTEXT(interp)->current_namespace;
+    PMC * const cur_ns = Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp));
     $1 = Parrot_find_global_op(interp, cur_ns, $2, expr NEXT());
 }
 
 op get_global(out PMC, in PMC, in STR) {
-    PMC * const cur_ns = CONTEXT(interp)->current_namespace;
+    PMC * const cur_ns = Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp));
     if (PMC_IS_NULL(cur_ns)) {
         $1 = PMCNULL;
     }
@@ -319,12 +322,12 @@
 =cut
 
 op set_global(in STR, invar PMC) {
-    PMC * const cur_ns = CONTEXT(interp)->current_namespace;
+    PMC * const cur_ns = Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp));
     Parrot_set_global(interp, cur_ns, $1, $2);
 }
 
 op set_global(in PMC, in STR, invar PMC) {
-    PMC * const cur_ns = CONTEXT(interp)->current_namespace;
+    PMC * const cur_ns = Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp));
     PMC * const ns     = Parrot_make_namespace_keyed(interp, cur_ns, $1);
 
     Parrot_set_global(interp, ns, $2, $3);

Modified: trunk/src/packfile.c
==============================================================================
--- trunk/src/packfile.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/packfile.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -682,7 +682,8 @@
     &&  interp->run_core != PARROT_FAST_CORE)
             interp->run_core = PARROT_FAST_CORE;
 
-    CONTEXT(interp)->constants = interp->code->const_table->constants;
+    Parrot_pcc_set_constants(interp, CURRENT_CONTEXT(interp),
+            interp->code->const_table->constants);
 
     retval           = (PMC *)Parrot_runops_fromc_args(interp, sub_pmc, "P");
     interp->run_core = old;
@@ -760,7 +761,7 @@
                                           / sizeof (opcode_t *);
 
                     PObj_get_FLAGS(sub_pmc)      &= ~SUB_FLAG_PF_MAIN;
-                    CONTEXT(interp)->current_sub  = sub_pmc;
+                    Parrot_pcc_set_sub(interp, CURRENT_CONTEXT(interp), sub_pmc);
                 }
                 else {
                     Parrot_warn(interp, PARROT_WARNINGS_ALL_FLAG,
@@ -3084,13 +3085,13 @@
     }
 
     interp->code               = new_cs;
-    CONTEXT(interp)->constants = really
+    Parrot_pcc_set_constants(interp, CURRENT_CONTEXT(interp), really
                                ? find_constants(interp, new_cs->const_table)
-                               : new_cs->const_table->constants;
+                               : new_cs->const_table->constants);
 
     /* new_cs->const_table->constants; */
-    CONTEXT(interp)->pred_offset =
-        new_cs->base.data - (opcode_t*) new_cs->prederef.code;
+    Parrot_pcc_set_pred_offset(interp, CURRENT_CONTEXT(interp),
+        new_cs->base.data - (opcode_t*) new_cs->prederef.code);
 
     if (really)
         prepare_for_run(interp);

Modified: trunk/src/pic.c
==============================================================================
--- trunk/src/pic.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pic.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -694,24 +694,24 @@
 is_pic_param(PARROT_INTERP, ARGIN(void **pc), ARGOUT(Parrot_MIC *mic), opcode_t op)
 {
     ASSERT_ARGS(is_pic_param)
-    PMC                           *sig2;
-    Parrot_Context                *caller_ctx;
-    opcode_t                      *args;
-    PMC                    * const sig1 = (PMC *)(pc[1]);
-    const Parrot_Context   * const ctx  = CONTEXT(interp);
-    int                            type = 0;
+    PMC                *sig2;
+    PMC                *caller_ctx;
+    opcode_t           *args;
+    PMC         * const sig1 = (PMC *)(pc[1]);
+    PMC                *ctx  = CURRENT_CONTEXT(interp);
+    int                 type = 0;
 
     /* check params */
 
     if (op == PARROT_OP_set_returns_pc) {
-        PMC * const ccont = ctx->current_cont;
+        PMC * const ccont = Parrot_pcc_get_continuation(interp, ctx);
         if (!PMC_cont(ccont)->address)
             return 0;
         caller_ctx = PMC_cont(ccont)->to_ctx;
-        args       = caller_ctx->current_results;
+        args       = Parrot_pcc_get_results(interp, caller_ctx);
     }
     else {
-        caller_ctx = ctx->caller_ctx;
+        caller_ctx = Parrot_pcc_get_caller_ctx(interp, ctx);
         args       = interp->current_args;
     }
 
@@ -720,7 +720,7 @@
         int          n;
 
         /* check current_args signature */
-        sig2 = caller_ctx->constants[const_nr]->u.key;
+        sig2 = Parrot_pcc_get_pmc_constant(interp, caller_ctx, const_nr);
         n    = parrot_pic_check_sig(interp, sig1, sig2, &type);
 
         if (n == -1)
@@ -799,14 +799,14 @@
     opcode_t *op, n;
     int flags;
 
-    Parrot_Context * const ctx      = CONTEXT(interp);
-    PMC            * const sig_args = (PMC *)(pc[1]);
+    PMC * const ctx      = CURRENT_CONTEXT(interp);
+    PMC * const sig_args = (PMC *)(pc[1]);
 
     ASSERT_SIG_PMC(sig_args);
     n                    = VTABLE_elements(interp, sig_args);
-    interp->current_args = (opcode_t*)pc + ctx->pred_offset;
+    interp->current_args = (opcode_t*)pc + Parrot_pcc_get_pred_offset(interp, ctx);
     pc                  += 2 + n;
-    op                   = (opcode_t*)pc + ctx->pred_offset;
+    op                   = (opcode_t*)pc + Parrot_pcc_get_pred_offset(interp, ctx);
 
     if (*op != PARROT_OP_set_p_pc)
         return 0;
@@ -820,7 +820,7 @@
         return 0;
 
     pc += 3;    /* results */
-    op  = (opcode_t *)pc + ctx->pred_offset;
+    op  = (opcode_t *)pc + Parrot_pcc_get_pred_offset(interp, ctx);
 
     if (*op != PARROT_OP_get_results_pc)
         return 0;
@@ -829,7 +829,7 @@
     sig_results = (PMC *)(pc[1]);
     ASSERT_SIG_PMC(sig_results);
 
-    ctx->current_results = (opcode_t *)pc + ctx->pred_offset;
+    Parrot_pcc_set_results(interp, ctx, (opcode_t *)pc + Parrot_pcc_get_pred_offset(interp, ctx));
     if (!parrot_pic_is_safe_to_jit(interp, sub, sig_args, sig_results, &flags))
         return 0;
 

Modified: trunk/src/pmc.c
==============================================================================
--- trunk/src/pmc.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -894,7 +894,7 @@
 
             /* anchor at parent, aka current_namespace, that is 'parrot' */
             VTABLE_set_pmc_keyed_str(interp,
-                    CONTEXT(interp)->current_namespace, class_name, ns);
+                    Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp)), class_name, ns);
         }
 
         _class = vtable->pmc_class;

Modified: trunk/src/pmc/class.pmc
==============================================================================
--- trunk/src/pmc/class.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/class.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -197,7 +197,7 @@
         }
         else {
             PMC * const hll_ns = VTABLE_get_pmc_keyed_int(interp,
-                    interp->HLL_namespace, CONTEXT(interp)->current_HLL);
+                    interp->HLL_namespace, Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp)));
             new_namespace = Parrot_make_namespace_keyed(interp, hll_ns, name_arg);
         }
 
@@ -1168,13 +1168,13 @@
             /* Check that we have all methods listed in resolve list. */
             const int resolve_count  = VTABLE_elements(interp,
                                                        _class->resolve_method);
-            const INTVAL cur_hll     = CONTEXT(interp)->current_HLL;
+            const INTVAL cur_hll     = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp));
             const INTVAL num_parents = VTABLE_elements(interp, _class->parents);
             INTVAL       mro_length;
             int          i;
 
             /* don't use HLL mappings for internal-only data */
-            CONTEXT(interp)->current_HLL = 0;
+            Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), 0);
 
             for (i = 0; i < resolve_count; i++) {
                 STRING * const check_meth =
@@ -1211,7 +1211,7 @@
                 }
             }
 
-            CONTEXT(interp)->current_HLL = cur_hll;
+            Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), cur_hll);
         }
 
         /* Set instantiated flag. */

Added: trunk/src/pmc/context.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/src/pmc/context.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -0,0 +1,165 @@
+/*
+Copyright (C) 2001-2009, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/context.pmc - Interpreter Context.
+
+=head1 DESCRIPTION
+
+Stores context of execution. Currently we store pointer to Parrot_Context
+structure in PMC_data.
+
+=head2 Vtable Functions
+
+=over 4
+
+=cut
+
+*/
+
+
+#include "parrot/packfile.h"
+
+pmclass Context {
+
+/*
+
+=item C<void init()>
+
+Initialize new Context. See C<Parrot_alloc_context>.
+
+=cut
+
+*/
+
+    VTABLE void init() {
+        PMC_data(SELF) = NULL;
+        PObj_custom_mark_destroy_SETALL(SELF);
+    }
+
+
+/*
+
+=item C<void mark()>
+
+Mark Context as alive.
+
+=cut
+
+*/
+
+    VTABLE void mark()
+    {
+        Parrot_Context * const ctx = PMC_data_typed(SELF, Parrot_Context*);
+        PObj *obj;
+        int   i;
+
+        /* If Context wasn't initialised just return */
+        if (!ctx)
+            return;
+
+        obj = (PObj *)ctx->caller_ctx;
+        if (obj)
+            Parrot_gc_mark_PObj_alive(interp, obj);
+
+        obj = (PObj *)ctx->lex_pad;
+        if (obj)
+            Parrot_gc_mark_PObj_alive(interp, obj);
+
+        obj = (PObj *)ctx->outer_ctx;
+        if (obj)
+            Parrot_gc_mark_PObj_alive(interp, obj);
+
+        obj = (PObj *)ctx->current_sub;
+        if (obj)
+            Parrot_gc_mark_PObj_alive(interp, obj);
+
+        obj = (PObj *)ctx->handlers;
+        if (obj)
+            Parrot_gc_mark_PObj_alive(interp, obj);
+
+        obj = (PObj *)ctx->current_cont;
+        if (obj && !PObj_live_TEST(obj))
+            Parrot_gc_mark_PObj_alive(interp, obj);
+
+        obj = (PObj *)ctx->current_object;
+        if (obj)
+            Parrot_gc_mark_PObj_alive(interp, obj);
+
+        obj = (PObj *)ctx->current_namespace;
+        if (obj)
+            Parrot_gc_mark_PObj_alive(interp, obj);
+
+        obj = (PObj *)ctx->results_signature;
+        if (obj)
+            Parrot_gc_mark_PObj_alive(interp, obj);
+
+        if (!ctx->n_regs_used)
+            return;
+
+        for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; ++i) {
+            /* Original code from CTX_REG_PMC */
+            obj = (PObj *)ctx->bp_ps.regs_p[-1L-(i)];
+            if (obj)
+                Parrot_gc_mark_PObj_alive(interp, obj);
+        }
+
+        for (i = 0; i < ctx->n_regs_used[REGNO_STR]; ++i) {
+            obj = (PObj *) ctx->bp_ps.regs_s[i];
+            if (obj)
+                Parrot_gc_mark_PObj_alive(interp, obj);
+        }
+    }
+
+/*
+
+=item C<void destroy()>
+
+Destroy Context and memory allocated by C<Parrot_alloc_context>.
+
+=cut
+
+*/
+
+    VTABLE void destroy() {
+        /* We own this pointer */
+        Parrot_Context * const ctx = PMC_data_typed(SELF, Parrot_Context*);
+        mem_sys_free(ctx);
+    }
+
+/*
+
+=item C<void *get_pointer()>
+
+Return pointer to underlying Parrot_Context structure.
+
+=cut
+
+*/
+
+    VTABLE void *get_pointer() {
+        return PMC_data(SELF);
+    }
+
+/*
+
+=item C<void set_pointer(void *)>
+
+Set new Parrot_Context structure.
+
+=cut
+
+*/
+    VTABLE void set_pointer(void *context) {
+        PMC_data(SELF) = context;
+    }
+}
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Modified: trunk/src/pmc/continuation.pmc
==============================================================================
--- trunk/src/pmc/continuation.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/continuation.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -88,9 +88,9 @@
         Parrot_cont *cc = PMC_cont(SELF);
 
         if (cc->to_ctx)
-            mark_context(INTERP, cc->to_ctx);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) cc->to_ctx);
         if (cc->from_ctx)
-            mark_context(INTERP, cc->from_ctx);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) cc->from_ctx);
     }
 
 /*
@@ -105,20 +105,8 @@
 
     VTABLE void destroy() {
         Parrot_cont * const cc = PMC_cont(SELF);
-        if (cc) {
-#if CTX_LEAK_DEBUG
-            if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
-                fprintf(stderr,
-                        "[destroy cont    %p, to_ctx %p, from_ctx %p]\n",
-                        (void *)SELF, (void *)cc->to_ctx, (void *)cc->from_ctx);
-            }
-
-#endif
-            if (cc->from_ctx)
-                Parrot_free_context(interp, cc->from_ctx, 1);
-
+        if (cc)
             mem_sys_free(cc);
-        }
     }
 /*
 
@@ -139,7 +127,7 @@
         PObj_custom_mark_destroy_SETALL(ret);
 
         /* free ret's PMC_cont */
-        Parrot_free_context(interp, ret_cont->from_ctx, 1);
+        /* XXX Looks very suspicious... Why? */
         mem_sys_free(ret_cont);
 
         cc->runloop_id = cc_self->runloop_id;
@@ -232,10 +220,10 @@
 */
 
     VTABLE opcode_t *invoke(void *next) {
-        Parrot_cont      *cc           = PMC_cont(SELF);
-        Parrot_Context   *from_ctx     = CONTEXT(interp);
-        Parrot_Context   *to_ctx       = cc->to_ctx;
-        opcode_t         *pc           = cc->address;
+        Parrot_cont *cc           = PMC_cont(SELF);
+        PMC         *from_ctx     = CURRENT_CONTEXT(interp);
+        PMC         *to_ctx       = cc->to_ctx;
+        opcode_t    *pc           = cc->address;
         UNUSED(next)
 
         Parrot_continuation_check(interp, SELF, cc);
@@ -243,9 +231,9 @@
 
         /* pass args to where caller wants result */
         if (cc->current_results)
-            to_ctx->current_results = cc->current_results;
+            Parrot_pcc_set_results(interp, to_ctx, cc->current_results);
 
-        if (to_ctx->current_results && INTERP->current_args) {
+        if (Parrot_pcc_get_results(interp, to_ctx) && INTERP->current_args) {
             /*
              * the register pointer is already switched back
              * to the caller, therefore the registers of the
@@ -254,7 +242,7 @@
              * therefore we have to block GC
              */
             opcode_t *src_indexes  = interp->current_args;
-            opcode_t *dest_indexes = to_ctx->current_results;
+            opcode_t *dest_indexes = Parrot_pcc_get_results(interp, to_ctx);
             interp->current_args   = NULL;
 
             Parrot_block_GC_mark(INTERP);
@@ -298,7 +286,7 @@
 
     METHOD caller() {
         Parrot_cont *cc     = PMC_cont(SELF);
-        PMC         *caller = cc->to_ctx->current_sub;
+        PMC         *caller = Parrot_pcc_get_sub(interp, cc->to_ctx);
         Parrot_Sub_attributes  *sub;
 
         if (!caller)
@@ -324,7 +312,7 @@
 
     METHOD continuation() {
         Parrot_cont *cc   = PMC_cont(SELF);
-        PMC         *cont = cc->to_ctx->current_cont;
+        PMC         *cont = Parrot_pcc_get_continuation(interp, cc->to_ctx);
 
         if (cont)
             RETURN(PMC *cont);

Modified: trunk/src/pmc/coroutine.pmc
==============================================================================
--- trunk/src/pmc/coroutine.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/coroutine.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -49,7 +49,7 @@
     if (co->ctx && (PObj_get_FLAGS(sub_pmc) & SUB_FLAG_CORO_FF)) {
         Parrot_io_eprintf(tracer, " to '%Ss'",
                 Parrot_full_sub_name(interp,
-                    co->ctx->caller_ctx->current_sub));
+                    Parrot_pcc_get_sub(interp, Parrot_pcc_get_caller_ctx(interp, co->ctx))));
     }
 
     Parrot_io_eprintf(tracer, "\n# ");
@@ -128,8 +128,8 @@
             print_sub_name(INTERP, SELF);
 
         if (!co->ctx) {
-            Parrot_Context *caller_ctx;
-            Parrot_Context *ctx;
+            PMC *caller_ctx;
+            PMC *ctx;
             PMC *ccont;
 
             ccont = INTERP->current_cont;
@@ -143,27 +143,27 @@
                         "tail call to coro not allowed");
 
             /* first time set current sub, cont, object */
-            caller_ctx = CONTEXT(interp);
+            caller_ctx = CURRENT_CONTEXT(interp);
             ctx        = Parrot_set_new_context(INTERP, co->n_regs_used);
 
-            co->ctx                   = Parrot_context_ref(interp, ctx);
+            co->ctx                   = ctx;
 
-            ctx->caller_ctx           = caller_ctx;
-            PMC_cont(ccont)->from_ctx = ctx;
-            ctx->current_sub          = SELF;
-            ctx->current_HLL          = co->HLL_id;
-            ctx->current_namespace    = co->namespace_stash;
-            ctx->current_cont         = ccont;
-            ctx->current_object       = NULL;
-            INTERP->current_object    = NULL;
-            INTERP->current_cont      = NULL;
+            Parrot_pcc_set_caller_ctx(INTERP, ctx, caller_ctx);
+            PMC_cont(ccont)->from_ctx                       = ctx;
+            Parrot_pcc_set_sub(INTERP, ctx, SELF);
+            Parrot_pcc_set_HLL(interp, ctx, co->HLL_id);
+            Parrot_pcc_set_namespace(INTERP, ctx, co->namespace_stash);
+            Parrot_pcc_set_continuation(INTERP, ctx, ccont);
+            Parrot_pcc_set_object(interp, ctx, NULL);
+            INTERP->current_object                  = NULL;
+            INTERP->current_cont                    = NULL;
 
             /* create pad if needed */
             if (!PMC_IS_NULL(co->lex_info)) {
-                ctx->lex_pad = pmc_new_init(INTERP,
+                Parrot_pcc_set_lex_pad(INTERP, ctx, pmc_new_init(INTERP,
                         Parrot_get_ctx_HLL_type(interp, enum_class_LexPad),
-                        co->lex_info);
-                VTABLE_set_pointer(INTERP, ctx->lex_pad, ctx);
+                        co->lex_info));
+                VTABLE_set_pointer(INTERP, Parrot_pcc_get_lex_pad(INTERP, ctx), ctx);
             }
 
             PObj_get_FLAGS(SELF) |= SUB_FLAG_CORO_FF;
@@ -175,7 +175,7 @@
         /* if calling the Coro we need the segment of the Coro */
         else if (!(PObj_get_FLAGS(SELF) & SUB_FLAG_CORO_FF)) {
             PMC *ccont;
-            Parrot_Context   *ctx;
+            PMC *ctx;
 
             PObj_get_FLAGS(SELF) |= SUB_FLAG_CORO_FF;
             wanted_seg            = co->seg;
@@ -185,24 +185,22 @@
             ctx                   = co->ctx;
 
             /* and the recent call context */
-            ccont                 = ctx->current_cont;
-            ctx->caller_ctx       = PMC_cont(ccont)->to_ctx
-                                  = CONTEXT(interp);
+            ccont                   = Parrot_pcc_get_continuation(INTERP, ctx);
+            PMC_cont(ccont)->to_ctx = CURRENT_CONTEXT(interp);
+            Parrot_pcc_set_caller_ctx(interp, ctx, CURRENT_CONTEXT(interp));
 
             /* set context to coro context */
-            CONTEXT(interp)       = ctx;
-            INTERP->ctx.bp        = ctx->bp;
-            INTERP->ctx.bp_ps     = ctx->bp_ps;
+            CURRENT_CONTEXT(interp) = ctx;
         }
         else {
             PMC *ccont;
-            Parrot_Context   *ctx;
+            PMC *ctx;
 
             PObj_get_FLAGS(SELF) &= ~SUB_FLAG_CORO_FF;
             /* switch back to last remembered code seg and context */
 
             wanted_seg            = co->caller_seg;
-            ccont                 = co->ctx->current_cont;
+            ccont                 = Parrot_pcc_get_continuation(INTERP, co->ctx);
             ctx                   = PMC_cont(ccont)->to_ctx;
 
             if (! ctx) {
@@ -215,9 +213,7 @@
                                "Cannot resume dead coroutine.");
             }
 
-            CONTEXT(interp)      = ctx;
-            INTERP->ctx.bp       = ctx->bp;
-            INTERP->ctx.bp_ps    = ctx->bp_ps;
+            CURRENT_CONTEXT(interp) = ctx;
         }
 
         /* toggle address */

Modified: trunk/src/pmc/exception.pmc
==============================================================================
--- trunk/src/pmc/exception.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/exception.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -65,8 +65,8 @@
     ATTR PMC            *backtrace;    /* The backtrace of an exception. */
     ATTR INTVAL          handled;      /* Whether the exception has been handled. */
     ATTR PMC            *handler_iter; /* An iterator of handlers (for rethrow). */
-    ATTR Parrot_Context *handler_ctx;  /* A stored context for handler iterator. */
-    ATTR Parrot_Context *thrower;      /* The position we were at when thrown. */
+    ATTR PMC            *handler_ctx;  /* A stored context for handler iterator. */
+    ATTR PMC            *thrower;      /* The position we were at when thrown. */
 
 /*
 
@@ -161,22 +161,10 @@
             Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->backtrace);
         if (core_struct->handler_iter)
             Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->handler_iter);
-    }
-
-/*
-
-=item C<void destroy()>
-
-Destroys the exception.
-
-=cut
-
-*/
-
-    VTABLE void destroy() {
-        Parrot_Exception_attributes * const core_struct = PARROT_EXCEPTION(SELF);
-        if (core_struct && core_struct->thrower)
-            Parrot_free_context(interp, core_struct->thrower, 1);
+        if (core_struct->handler_ctx)
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->handler_ctx);
+        if (core_struct->thrower)
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->thrower);
     }
 
 /*
@@ -495,11 +483,7 @@
     VTABLE void set_pointer(void *context) {
         Parrot_Exception_attributes * const core_struct = PARROT_EXCEPTION(SELF);
 
-        /* contexts are refcounted; increment and decrement appropriately */
-        if (core_struct->handler_ctx)
-            Parrot_free_context(interp, core_struct->handler_ctx, 1);
-        core_struct->handler_ctx = Parrot_context_ref(interp,
-                                       (Parrot_Context *)context);
+        core_struct->handler_ctx = (PMC*)context;
     }
 
 /*
@@ -659,11 +643,9 @@
         else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "thrower"))) {
             /* Ensure it's a ret cont, and extract the from_ctx.
              * XXX TT#596 - when we have Context PMCs, just take and set that. */
-
             if (!PMC_IS_NULL(value) && VTABLE_isa(interp, value, CONST_STRING(interp, "Continuation"))) {
-                Parrot_Context *ctx = PMC_cont(value)->from_ctx;
-                if (ctx) {
-                    Parrot_context_ref(interp, ctx);
+                PMC *ctx = PMC_cont(value)->from_ctx;
+                if (!PMC_IS_NULL(ctx)) {
                     SET_ATTR_thrower(interp, SELF, ctx);
                 }
             }
@@ -761,7 +743,7 @@
     METHOD backtrace() {
         PMC *result = pmc_new(interp, enum_class_ResizablePMCArray);
         PMC *resume;
-        Parrot_Context *cur_ctx;
+        PMC *cur_ctx;
         Parrot_cont    *cont;
 
         /* Get starting context, then loop over them. */
@@ -785,7 +767,7 @@
                 Parrot_Sub_attributes *sub;
 
                 /* Get sub and put it in the hash. */
-                PMC *sub_pmc = cur_ctx->current_sub;
+                PMC *sub_pmc = Parrot_pcc_get_sub(interp, cur_ctx);
 
                 if (!sub_pmc)
                     sub_pmc = PMCNULL;
@@ -800,7 +782,7 @@
                         PackFile_ByteCode *seg = sub->seg;
                         opcode_t          *pc  = cont && cur_ctx == cont->to_ctx
                                                ? cont->address
-                                               : cur_ctx->current_pc;
+                                               : Parrot_pcc_get_pc(interp, cur_ctx);
 
                         annotations = PackFile_Annotations_lookup(interp,
                                         seg->annotations, pc - seg->base.data,
@@ -815,7 +797,7 @@
 
                 /* Push frame and go to next caller. */
                 VTABLE_push_pmc(interp, result, frame);
-                cur_ctx = cur_ctx->caller_ctx;
+                cur_ctx = Parrot_pcc_get_caller_ctx(interp, cur_ctx);
             }
         }
 

Modified: trunk/src/pmc/exporter.pmc
==============================================================================
--- trunk/src/pmc/exporter.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/exporter.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -109,7 +109,7 @@
     VTABLE void init() {
         /* Set up the object. */
         SET_ATTR_ns_src(INTERP, SELF, PMCNULL);
-        SET_ATTR_ns_dest(INTERP, SELF, CONTEXT(interp)->current_namespace);
+        SET_ATTR_ns_dest(INTERP, SELF, Parrot_pcc_get_namespace(INTERP, CURRENT_CONTEXT(INTERP)));
         SET_ATTR_globals(INTERP, SELF, PMCNULL);
 
         /* Set flags for custom GC mark and destroy. */

Modified: trunk/src/pmc/lexpad.pmc
==============================================================================
--- trunk/src/pmc/lexpad.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/lexpad.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -22,13 +22,13 @@
  * LexPad provides a Hash interface for lexical fetch/store
  * needed
  *
- * struct_val ... Parrot_Context *ctx
+ * struct_val ... Context *ctx
  * pmc_val    ... LexInfo
  */
 
 pmclass LexPad provides hash no_ro auto_attrs {
-    ATTR PMC                   *lexinfo;
-    ATTR struct Parrot_Context *ctx;
+    ATTR PMC *lexinfo;
+    ATTR PMC *ctx;
 
     VTABLE void init() {
         Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
@@ -82,7 +82,7 @@
     }
 
     VTABLE void set_pointer(void *ctx) {
-        SET_ATTR_ctx(INTERP, SELF, (struct Parrot_Context *)ctx);
+        SET_ATTR_ctx(INTERP, SELF, (PMC *)ctx);
     }
 
     VTABLE INTVAL elements() {
@@ -107,7 +107,7 @@
     VTABLE PMC *get_pmc_keyed_str(STRING *name) {
         PMC              * info;
         Hash             * hash;
-        Parrot_Context   * ctx;
+        PMC              * ctx;
         HashBucket       * b;
         INTVAL            regno;
 
@@ -132,7 +132,7 @@
     VTABLE void set_pmc_keyed_str(STRING *name, PMC *value) {
         PMC              * info;
         Hash             * hash;
-        Parrot_Context   * ctx;
+        PMC              * ctx;
         HashBucket       * b;
         INTVAL             regno;
 

Modified: trunk/src/pmc/nci.pmc
==============================================================================
--- trunk/src/pmc/nci.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/nci.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -348,7 +348,7 @@
          */
         if (cont && cont != NEED_CONTINUATION
         && (PObj_get_FLAGS(cont) & SUB_FLAG_TAILCALL)) {
-            cont = CONTEXT(interp)->current_cont;
+            cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
             next = VTABLE_invoke(INTERP, cont, next);
         }
 

Modified: trunk/src/pmc/object.pmc
==============================================================================
--- trunk/src/pmc/object.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/object.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -27,11 +27,11 @@
 get_attrib_index(PARROT_INTERP, PMC *self, STRING *name)
 {
     Parrot_Class_attributes * const _class  = PARROT_CLASS(self);
-    const INTVAL                    cur_hll = CONTEXT(interp)->current_HLL;
+    const INTVAL                    cur_hll = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp));
     int                             num_classes, i;
     INTVAL                          retval;
 
-    CONTEXT(interp)->current_HLL = 0;
+    Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), 0);
 
     /* First see if we can find it in the cache. */
     retval                       = VTABLE_get_integer_keyed_str(interp,
@@ -40,7 +40,7 @@
     /* there's a semi-predicate problem with a retval of 0 */
     if (retval
     || VTABLE_exists_keyed_str(interp, _class->attrib_cache, name)) {
-        CONTEXT(interp)->current_HLL = cur_hll;
+        Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), cur_hll);
         return retval;
     }
 
@@ -65,12 +65,12 @@
             VTABLE_set_integer_keyed_str(interp, _class->attrib_cache, name,
                 index);
 
-            CONTEXT(interp)->current_HLL = cur_hll;
+            Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), cur_hll);
             return index;
         }
     }
 
-    CONTEXT(interp)->current_HLL = cur_hll;
+    Parrot_pcc_set_HLL(interp, CURRENT_CONTEXT(interp), cur_hll);
     return -1;
 }
 

Modified: trunk/src/pmc/parrotinterpreter.pmc
==============================================================================
--- trunk/src/pmc/parrotinterpreter.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/parrotinterpreter.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -450,7 +450,7 @@
         STRING *s     = CONST_STRING(interp, "globals");
         int     level = 0;
 
-        Parrot_Context *ctx;
+        PMC *ctx;
 
         if (Parrot_str_equal(interp, item, s))
             return interp->root_namespace;
@@ -478,19 +478,19 @@
             Parrot_ex_throw_from_c_args(interp, NULL, CONTROL_ERROR,
                 "No such caller depth");
 
-        ctx = CONTEXT(interp);
+        ctx = CURRENT_CONTEXT(interp);
 
         if (outer) {
             for (; level; --level) {
-                ctx = ctx->outer_ctx;
-                if (!ctx)
+                ctx = Parrot_pcc_get_outer_ctx(interp, ctx);
+                if (PMC_IS_NULL(ctx))
                     Parrot_ex_throw_from_c_args(interp, NULL,
                         CONTROL_ERROR, "No such outer depth");
             }
         }
         else {
             for (; level; --level) {
-                cont = ctx->current_cont;
+                cont = Parrot_pcc_get_continuation(interp, ctx);
 
                 if (PMC_IS_NULL(cont) || !PMC_cont(cont)->seg)
                     Parrot_ex_throw_from_c_args(interp, NULL,
@@ -498,51 +498,50 @@
 
                 ctx = PMC_cont(cont)->to_ctx;
 
-                if (!ctx->current_sub)
+                if (PMC_IS_NULL(Parrot_pcc_get_sub(interp, ctx)))
                     Parrot_ex_throw_from_c_args(interp, NULL,
                         CONTROL_ERROR, "No such caller depth");
             }
         }
 
         if (item == outer)
-            return ctx->current_sub;
+            return Parrot_pcc_get_sub(interp, ctx);
 
         s = CONST_STRING(interp, "sub");
 
         if (Parrot_str_equal(interp, item, s))
-            return ctx->current_sub;
+            return Parrot_pcc_get_sub(interp, ctx);
 
         s = CONST_STRING(interp, "lexpad");
 
         if (Parrot_str_equal(interp, item, s))
-            return ctx->lex_pad;
+            return Parrot_pcc_get_lex_pad(interp, ctx);
 
         s = CONST_STRING(interp, "namespace");
 
         if (Parrot_str_equal(interp, item, s))
-            return ctx->current_namespace;
+            return Parrot_pcc_get_namespace(interp, ctx);
 
         s = CONST_STRING(interp, "continuation");
 
         if (Parrot_str_equal(interp, item, s))
-            return VTABLE_clone(interp, ctx->current_cont);
+            return VTABLE_clone(interp, Parrot_pcc_get_continuation(interp, ctx));
 
         s = CONST_STRING(interp, "annotations");
 
         if (Parrot_str_equal(interp, item, s)) {
-            PMC        *sub_pmc = ctx->current_sub;
-            if (ctx == CONTEXT(interp)) {
+            PMC        *sub_pmc = Parrot_pcc_get_sub(interp, ctx);
+            if (ctx == CURRENT_CONTEXT(interp)) {
                 /* We can't know the current program counter for the currently
                  * executing sub, so can't return annotations for that. */
-                if (ctx == CONTEXT(interp))
-                    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-                            "Cannot get annotations at depth 0; use annotations op instead.");
+                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                        "Cannot get annotations at depth 0; use annotations op instead.");
             }
             if (!PMC_IS_NULL(sub_pmc)
             &&   sub_pmc->vtable->base_type == enum_class_Sub) {
                 Parrot_Sub_attributes *sub;
                 PackFile_ByteCode     *seg;
-                opcode_t              *pc  = ctx->current_pc;
+                opcode_t              *pc  = Parrot_pcc_get_pc(interp, ctx);
 
                 PMC_get_sub(interp, sub_pmc, sub);
                 seg = sub->seg;
@@ -803,7 +802,7 @@
     METHOD hll_map(PMC *core_type, PMC *hll_type) {
         INTVAL core_type_id = VTABLE_type(INTERP, core_type);
         INTVAL hll_type_id  = VTABLE_type(INTERP, hll_type);
-        INTVAL hll_id       = CONTEXT(interp)->current_HLL;
+        INTVAL hll_id       = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp));
         Parrot_register_HLL_type(INTERP, hll_id, core_type_id, hll_type_id);
     }
 
@@ -845,3 +844,5 @@
  * End:
  * vim: expandtab shiftwidth=4:
  */
+
+

Modified: trunk/src/pmc/retcontinuation.pmc
==============================================================================
--- trunk/src/pmc/retcontinuation.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/retcontinuation.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -82,14 +82,13 @@
 
     VTABLE opcode_t *invoke(void *in_next) {
         Parrot_cont       *cc         = PMC_cont(SELF);
-        Parrot_Context    *from_ctx   = cc->from_ctx;
+        PMC               *from_ctx   = cc->from_ctx;
         PackFile_ByteCode * const seg = cc->seg;
         opcode_t          *next       = cc->address;
         UNUSED(in_next)
 
         Parrot_continuation_check(interp, SELF, cc);
         Parrot_continuation_rewind_environment(interp, SELF, cc);
-        Parrot_free_context(INTERP, from_ctx, 1);
 
         /* the continuation is dead - delete and destroy it */
         /* This line causes a failure in t/pmc/packfiledirectory.t. No idea

Modified: trunk/src/pmc/role.pmc
==============================================================================
--- trunk/src/pmc/role.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/role.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -102,7 +102,7 @@
         /* Namespace is nested in the current namespace and with the name of
          * the role. */
         role->_namespace = Parrot_make_namespace_keyed_str(interp,
-            CONTEXT(interp)->current_namespace, role->name);
+            Parrot_pcc_get_namespace(interp, CURRENT_CONTEXT(interp)), role->name);
     }
 
     /* Otherwise, we may just have a namespace. */

Modified: trunk/src/pmc/scheduler.pmc
==============================================================================
--- trunk/src/pmc/scheduler.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/scheduler.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -246,7 +246,10 @@
 */
     VTABLE void destroy() {
         Parrot_Scheduler_attributes * const core_struct = PARROT_SCHEDULER(SELF);
-        MUTEX_DESTROY(core_struct->msg_lock);
+        /* TT #946: this line is causing an order-of-destruction error
+           because the scheduler is being freed before it's tasks.
+           Commenting this out till we get a real fix (although it's a hack) */
+        /* MUTEX_DESTROY(core_struct->msg_lock); */
     }
 
 

Modified: trunk/src/pmc/sub.pmc
==============================================================================
--- trunk/src/pmc/sub.pmc	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/pmc/sub.pmc	Thu Sep  3 11:56:50 2009	(r40958)
@@ -57,12 +57,12 @@
     ATTR PMC      *lex_info;          /* LexInfo PMC */
     ATTR PMC      *outer_sub;         /* :outer for closures */
     ATTR PMC      *eval_pmc;          /* eval container / NULL */
-    ATTR Parrot_Context *ctx;         /* the context this sub is in */
+    ATTR PMC      *ctx;               /* the context this sub is in */
     ATTR UINTVAL  comp_flags;         /* compile time and additional flags */
     ATTR Parrot_sub_arginfo *arg_info;/* Argument counts and flags. */
 
     /* - end common */
-    ATTR Parrot_Context *outer_ctx;   /* outer context, if a closure */
+    ATTR PMC      *outer_ctx;         /* outer context, if a closure */
 
 /*
 
@@ -113,10 +113,6 @@
         if (sub) {
             if (sub->arg_info)
                 mem_sys_free(sub->arg_info);
-            if (sub->ctx)
-                Parrot_free_context(INTERP, sub->ctx, 1);
-            if (sub->outer_ctx)
-                Parrot_free_context(INTERP, sub->outer_ctx, 1);
         }
     }
 
@@ -237,10 +233,10 @@
 
     VTABLE opcode_t *invoke(void *next) {
         Parrot_Sub_attributes *sub;
-        Parrot_Context *caller_ctx;
-        Parrot_Context *context;
-        PMC            *ccont;
-        opcode_t       *pc;
+        PMC                   *caller_ctx;
+        PMC                   *context;
+        PMC                   *ccont;
+        opcode_t              *pc;
 
         PMC_get_sub(INTERP, SELF, sub);
         if (Interp_trace_TEST(INTERP, PARROT_TRACE_SUB_CALL_FLAG))
@@ -269,7 +265,7 @@
          *
          */
         pc                   = sub->seg->base.data + sub->start_offs;
-        caller_ctx           = CONTEXT(interp);
+        caller_ctx           = CURRENT_CONTEXT(interp);
         ccont                = INTERP->current_cont;
         INTERP->current_cont = NULL;
 
@@ -281,13 +277,13 @@
         /* plain subroutine call
          * create new context, place it in interpreter */
         context               = Parrot_set_new_context(INTERP, sub->n_regs_used);
-        context->current_sub  = SELF;
-        context->caller_ctx   = caller_ctx;
-        context->current_pc   = pc;
-        context->current_cont = ccont;
+        Parrot_pcc_set_sub(interp, context, SELF);
+        Parrot_pcc_set_caller_ctx(interp, context, caller_ctx);
+        Parrot_pcc_set_pc(interp, context, pc);
+        Parrot_pcc_set_continuation(interp, context, ccont);
 
         /* check recursion/call depth */
-        if (++context->recursion_depth > INTERP->recursion_limit)
+        if (Parrot_pcc_inc_recursion_depth(INTERP, context) > INTERP->recursion_limit)
             Parrot_ex_throw_from_c_args(INTERP, next, CONTROL_ERROR,
                     "maximum recursion depth exceeded");
 
@@ -298,49 +294,45 @@
          * to the new context (refcounted) and convert the
          * retcontinuation to a normal continuation.  */
         if (PObj_get_FLAGS(SELF) & SUB_FLAG_IS_OUTER) {
-            /* release any previously held context */
-            if (sub->ctx)
-                Parrot_free_context(interp, sub->ctx, 1);
-            sub->ctx = Parrot_context_ref(interp, context);
+            sub->ctx = context;
             /* convert retcontinuation to a continuation */
             ccont->vtable = interp->vtables[enum_class_Continuation];
         }
 
-        /* reference counting should work */
-        Parrot_context_ref(interp, context);
-
         if (!PMC_IS_NULL(INTERP->current_object)) {
-            context->current_object = INTERP->current_object;
+            Parrot_pcc_set_object(interp, context, INTERP->current_object);
             INTERP->current_object  = NULL;
         }
 
-        context->current_HLL       = sub->HLL_id;
-        context->current_namespace = sub->namespace_stash;
+        Parrot_pcc_set_HLL(interp, context, sub->HLL_id);
+        Parrot_pcc_set_namespace(interp, context, sub->namespace_stash);
 
         /* create pad if needed
          * TODO move this up in front of argument passing
          *      and factor out common code with coroutine pmc
          */
         if (!PMC_IS_NULL(sub->lex_info)) {
-            context->lex_pad = pmc_new_init(INTERP,
+            Parrot_pcc_set_lex_pad(interp, context, pmc_new_init(INTERP,
                     Parrot_get_ctx_HLL_type(interp, enum_class_LexPad),
-                    sub->lex_info);
-            VTABLE_set_pointer(INTERP, context->lex_pad, context);
+                    sub->lex_info));
+            VTABLE_set_pointer(INTERP, Parrot_pcc_get_lex_pad(interp, context), context);
         }
 
         if (sub->outer_ctx) {
             /* set outer context */
-            context->outer_ctx = Parrot_context_ref(interp, sub->outer_ctx);
+            Parrot_pcc_set_outer_ctx(interp, context, sub->outer_ctx);
         }
         else {
             /* autoclose */
-            Parrot_Context *c;
-            for (c = context; !c->outer_ctx; c = c->outer_ctx) {
+            PMC *c;
+            for (c = context;
+                 PMC_IS_NULL(Parrot_pcc_get_outer_ctx(interp, c));
+                 c = Parrot_pcc_get_outer_ctx(interp, c)) {
 
                 PMC         *outer_pmc;
                 Parrot_Sub_attributes *current_sub, *outer_sub;
 
-                PMC_get_sub(INTERP, c->current_sub, current_sub);
+                PMC_get_sub(INTERP, Parrot_pcc_get_sub(interp, c), current_sub);
                 outer_pmc   = current_sub->outer_sub;
 
                 if (PMC_IS_NULL(outer_pmc))
@@ -349,25 +341,23 @@
                 PMC_get_sub(INTERP, outer_pmc, outer_sub);
 
                 if (!outer_sub->ctx) {
-                    Parrot_Context * const dummy = Parrot_alloc_context(INTERP,
+                    PMC * const dummy = Parrot_alloc_context(INTERP,
                                                 outer_sub->n_regs_used, NULL);
-                    dummy->current_sub    = outer_pmc;
+                    Parrot_pcc_set_sub(interp, dummy, outer_pmc);
 
                     if (!PMC_IS_NULL(outer_sub->lex_info)) {
-                        dummy->lex_pad = pmc_new_init(INTERP,
+                        Parrot_pcc_set_lex_pad(interp, dummy, pmc_new_init(INTERP,
                                Parrot_get_ctx_HLL_type(interp, enum_class_LexPad),
-                               outer_sub->lex_info);
-                        VTABLE_set_pointer(INTERP, dummy->lex_pad, dummy);
+                               outer_sub->lex_info));
+                        VTABLE_set_pointer(INTERP, Parrot_pcc_get_lex_pad(interp, dummy), dummy);
                     }
 
-                    if (outer_sub->outer_ctx) {
-                        dummy->outer_ctx = Parrot_context_ref(interp,
-                                               outer_sub->outer_ctx);
-                    }
-                    outer_sub->ctx = Parrot_context_ref(interp, dummy);
+                    if (!PMC_IS_NULL(outer_sub->outer_ctx))
+                        Parrot_pcc_set_outer_ctx(interp, dummy, outer_sub->outer_ctx);
+                    outer_sub->ctx = dummy;
                 }
 
-                c->outer_ctx = Parrot_context_ref(interp, outer_sub->ctx);
+                Parrot_pcc_set_outer_ctx(interp, c, outer_sub->ctx);
             }
         }
 
@@ -381,12 +371,11 @@
             &&     pc[2] == PARROT_OP_get_params_pc))) {
 
                 /* TODO keep it or resize it */
-                --context->recursion_depth;
+                Parrot_pcc_dec_recursion_depth(INTERP, context);
 
                 PObj_get_FLAGS(ccont) &= ~SUB_FLAG_TAILCALL;
-                context->caller_ctx    = caller_ctx->caller_ctx;
-
-                Parrot_free_context(INTERP, caller_ctx, 1);
+                Parrot_pcc_set_caller_ctx(interp, context,
+                        Parrot_pcc_get_caller_ctx(interp, caller_ctx));
             }
         }
 
@@ -415,12 +404,6 @@
         PMC_get_sub(INTERP, SELF, dest_sub);
         PMC_get_sub(INTERP, ret, sub);
 
-        /* release any previously held contexts */
-        if (sub->ctx)
-            Parrot_free_context(INTERP, sub->ctx, 1);
-        if (sub->outer_ctx)
-            Parrot_free_context(INTERP, sub->outer_ctx, 1);
-
         /* first set the sub struct, Parrot_str_copy may cause GC */
         *sub = *dest_sub;
 
@@ -430,12 +413,6 @@
         /* Be sure not to share arg_info. */
         dest_sub->arg_info = NULL;
 
-        /* mark any newly held contexts */
-        if (sub->ctx)
-            Parrot_context_ref(INTERP, sub->ctx);
-        if (sub->outer_ctx)
-            Parrot_context_ref(INTERP, sub->outer_ctx);
-
         return ret;
     }
 
@@ -462,15 +439,6 @@
             PMC_get_sub(INTERP, SELF, my_sub);
             PMC_get_sub(INTERP, other, other_sub);
 
-            /* Increase reference count of destination before
-             * freeing the one in self, to avoid problems in
-             * case of self assignment */
-            if (other_sub->ctx)
-                Parrot_context_ref(interp, other_sub->ctx);
-            /* get rid of this context, if attached */
-            if (my_sub->ctx)
-                Parrot_free_context(INTERP, my_sub->ctx, 1);
-
             /* copy the sub struct */
             memmove(my_sub, other_sub, sizeof (Parrot_Sub_attributes));
 
@@ -521,9 +489,9 @@
         if (sub->subid)
             Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->subid);
         if (sub->ctx)
-            mark_context(interp, sub->ctx);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *) sub->ctx);
         if (sub->outer_ctx)
-            mark_context(interp, sub->outer_ctx);
+            Parrot_gc_mark_PObj_alive(interp, (PObj *) sub->outer_ctx);
     }
 
 /*
@@ -974,6 +942,7 @@
     METHOD set_outer(PMC *outer) {
         /* Set outer sub. */
         Parrot_Sub_attributes *sub;
+        PMC *tmp1, *tmp2;
         PMC_get_sub(INTERP, SELF, sub);
 
         sub->outer_sub = outer;
@@ -990,10 +959,16 @@
 
         /* If we've got a context around for the outer sub, set it as the
          * outer context. */
-        if (CONTEXT(interp)->caller_ctx->caller_ctx->current_sub == outer)
-            sub->outer_ctx = Parrot_context_ref(interp, CONTEXT(interp)->caller_ctx->caller_ctx);
-        else if (CONTEXT(interp)->caller_ctx->current_sub == outer)
-            sub->outer_ctx = Parrot_context_ref(interp, CONTEXT(interp)->caller_ctx);
+
+        /* XXX This code looks very suspicious. */
+        /* (CONTEXT(interp)->caller_ctx->caller_ctx->current_sub */
+        tmp1 = Parrot_pcc_get_caller_ctx(interp, CURRENT_CONTEXT(interp));
+        tmp2 = Parrot_pcc_get_caller_ctx(interp, tmp1);
+        if (Parrot_pcc_get_sub(interp, tmp2) == outer)
+            sub->outer_ctx = tmp2;
+        /* else if (CONTEXT(interp)->caller_ctx->current_sub == outer) */
+        else if (Parrot_pcc_get_sub(interp, tmp1) == outer)
+            sub->outer_ctx = tmp1;
     }
 
     METHOD get_multisig() {

Modified: trunk/src/runcore/cores.c
==============================================================================
--- trunk/src/runcore/cores.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/runcore/cores.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -263,6 +263,16 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
+#ifdef code_start
+#  undef code_start
+#endif
+#ifdef code_end
+#  undef code_end
+#endif
+
+#define  code_start interp->code->base.data
+#define  code_end (interp->code->base.data + interp->code->base.size)
+
 /*
 
 =item C<opcode_t * runops_fast_core(PARROT_INTERP, opcode_t *pc)>
@@ -282,9 +292,16 @@
     ASSERT_ARGS(runops_fast_core)
 
     /* disable pc */
-    CONTEXT(interp)->current_pc = NULL;
+    Parrot_pcc_set_pc(interp, CURRENT_CONTEXT(interp), NULL);
 
     while (pc) {
+        /* TODO
+         * Decide do we need check here.
+         * Fast-core cause segfaults even on test suite
+        if (pc < code_start || pc >= code_end)
+            Parrot_ex_throw_from_c_args(interp, NULL, 1,
+                "attempt to access code outside of current code segment");
+        */
         DO_OP(pc, interp);
     }
 
@@ -314,7 +331,7 @@
     ASSERT_ARGS(runops_cgoto_core)
 
     /* disable pc */
-    CONTEXT(interp)->current_pc = NULL;
+    Parrot_pcc_set_pc(interp, CURRENT_CONTEXT(interp), NULL);
 
 #ifdef HAVE_COMPUTED_GOTO
     pc = cg_core(pc, interp);
@@ -327,16 +344,6 @@
 #endif
 }
 
-#ifdef code_start
-#  undef code_start
-#endif
-#ifdef code_end
-#  undef code_end
-#endif
-
-#define  code_start interp->code->base.data
-#define  code_end (interp->code->base.data + interp->code->base.size)
-
 
 /*
 
@@ -403,7 +410,7 @@
             Parrot_ex_throw_from_c_args(interp, NULL, 1,
                 "attempt to access code outside of current code segment");
 
-        CONTEXT(interp)->current_pc = pc;
+        Parrot_pcc_set_pc(interp, CURRENT_CONTEXT(interp), pc);
 
         DO_OP(pc, interp);
         trace_op(interp, code_start, code_end, pc);
@@ -457,7 +464,7 @@
             Parrot_ex_throw_from_c_args(interp, NULL, 1,
                 "attempt to access code outside of current code segment");
 
-        CONTEXT(interp)->current_pc = pc;
+        Parrot_pcc_set_pc(interp, CURRENT_CONTEXT(interp), pc);
 
         DO_OP(pc, interp);
     }
@@ -490,7 +497,7 @@
                 "attempt to access code outside of current code segment");
 
         Parrot_gc_mark_and_sweep(interp, GC_TRACE_FULL);
-        CONTEXT(interp)->current_pc = pc;
+        Parrot_pcc_set_pc(interp, CURRENT_CONTEXT(interp), pc);
 
         DO_OP(pc, interp);
     }
@@ -530,9 +537,9 @@
     while (pc) {/* && pc >= code_start && pc < code_end) */
         opcode_t cur_op;
 
-        CONTEXT(interp)->current_pc      = pc;
-        profile->cur_op                  = cur_op = *pc + PARROT_PROF_EXTRA;
-        profile->starttime               = Parrot_floatval_time();
+        Parrot_pcc_set_pc(interp, CURRENT_CONTEXT(interp), pc);
+        profile->cur_op                   = cur_op = *pc + PARROT_PROF_EXTRA;
+        profile->starttime                = Parrot_floatval_time();
         profile->data[cur_op].numcalls++;
 
         DO_OP(pc, interp);
@@ -591,7 +598,7 @@
                     pc);
         }
 
-        CONTEXT(interp)->current_pc = pc;
+        Parrot_pcc_set_pc(interp, CURRENT_CONTEXT(interp), pc);
         DO_OP(pc, interp);
 
         if (interp->pdb->state & PDB_STOPPED) {

Modified: trunk/src/runcore/main.c
==============================================================================
--- trunk/src/runcore/main.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/runcore/main.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -188,10 +188,10 @@
     ASSERT_ARGS(prederef_args)
     const PackFile_ConstTable * const const_table = interp->code->const_table;
 
-    const int regs_n = CONTEXT(interp)->n_regs_used[REGNO_NUM];
-    const int regs_i = CONTEXT(interp)->n_regs_used[REGNO_INT];
-    const int regs_p = CONTEXT(interp)->n_regs_used[REGNO_PMC];
-    const int regs_s = CONTEXT(interp)->n_regs_used[REGNO_STR];
+    const int regs_n = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_NUM);
+    const int regs_i = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_INT);
+    const int regs_p = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_PMC);
+    const int regs_s = Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_STR);
 
     /* prederef var part too */
     const int m = opinfo->op_count;
@@ -312,11 +312,6 @@
 
     opinfo = &interp->op_info_table[*pc];
 
-    /* first arguments - PIC needs it */
-
-    /* check for RT#58044 */
-    PARROT_ASSERT(CONTEXT(interp)->n_regs_used);
-
     prederef_args(pc_prederef, interp, pc, opinfo);
 
     switch (type) {
@@ -541,7 +536,7 @@
                 N * sizeof (void *));
 #endif
         /* calc and remember pred_offset */
-        CONTEXT(interp)->pred_offset = pc - (opcode_t *)temp;
+        Parrot_pcc_set_pred_offset(interp, CURRENT_CONTEXT(interp), pc - (opcode_t *)temp);
 
         /* fill with the prederef__ opcode function */
         if (which == PARROT_SWITCH_CORE || which == PARROT_SWITCH_JIT_CORE)

Modified: trunk/src/scheduler.c
==============================================================================
--- trunk/src/scheduler.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/scheduler.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -482,10 +482,10 @@
 Parrot_cx_add_handler_local(PARROT_INTERP, ARGIN(PMC *handler))
 {
     ASSERT_ARGS(Parrot_cx_add_handler_local)
-    if (PMC_IS_NULL(CONTEXT(interp)->handlers))
-        CONTEXT(interp)->handlers = pmc_new(interp, enum_class_ResizablePMCArray);
+    if (PMC_IS_NULL(Parrot_pcc_get_handlers(interp, interp->ctx)))
+        Parrot_pcc_set_handers(interp, interp->ctx, pmc_new(interp, enum_class_ResizablePMCArray));
 
-    VTABLE_unshift_pmc(interp, CONTEXT(interp)->handlers, handler);
+    VTABLE_unshift_pmc(interp, Parrot_pcc_get_handlers(interp, interp->ctx), handler);
 
 }
 
@@ -506,7 +506,7 @@
 Parrot_cx_delete_handler_local(PARROT_INTERP, ARGIN(STRING *handler_type))
 {
     ASSERT_ARGS(Parrot_cx_delete_handler_local)
-    PMC *handlers  = CONTEXT(interp)->handlers;
+    PMC *handlers  = Parrot_pcc_get_handlers(interp, interp->ctx);
 
     if (PMC_IS_NULL(handlers))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
@@ -577,7 +577,7 @@
 Parrot_cx_count_handlers_local(PARROT_INTERP, ARGIN(STRING *handler_type))
 {
     ASSERT_ARGS(Parrot_cx_count_handlers_local)
-    PMC *handlers = CONTEXT(interp)->handlers;
+    PMC *handlers = Parrot_pcc_get_handlers(interp, interp->ctx);
     INTVAL elements;
 
     if (PMC_IS_NULL(handlers))
@@ -849,9 +849,9 @@
      * for a handler
      */
     static int already_doing = 0;
-    static Parrot_Context * keep_context = NULL;
+    static PMC * keep_context = NULL;
 
-    Parrot_Context *context;
+    PMC            *context;
     PMC            *iter        = PMCNULL;
     STRING * const  handled_str = CONST_STRING(interp, "handled");
     STRING * const  iter_str    = CONST_STRING(interp, "handler_iter");
@@ -865,30 +865,28 @@
          * Note that we are now trying to handle the new exception,
          * not the initial task argument (exception or whatever).
          */
-        context = keep_context->caller_ctx;
+        context = Parrot_pcc_get_caller_ctx(interp, keep_context);
         keep_context = NULL;
-        if (context && !PMC_IS_NULL(context->handlers))
-            iter = VTABLE_get_iter(interp, context->handlers);
+        if (context && !PMC_IS_NULL(Parrot_pcc_get_handlers(interp, context)))
+            iter = VTABLE_get_iter(interp, Parrot_pcc_get_handlers(interp, context));
         else
             iter = PMCNULL;
     }
     else {
+        ++already_doing;
 
-    ++already_doing;
-
-    /* Exceptions store the handler iterator for rethrow, other kinds of
-     * tasks don't (though they could). */
-    if (task->vtable->base_type == enum_class_Exception
-    && VTABLE_get_integer_keyed_str(interp, task, handled_str) == -1) {
-        iter    = VTABLE_get_attr_str(interp, task, iter_str);
-        context = (Parrot_Context *)VTABLE_get_pointer(interp, task);
-    }
-    else {
-        context = CONTEXT(interp);
-        if (!PMC_IS_NULL(context->handlers))
-            iter = VTABLE_get_iter(interp, context->handlers);
-    }
-
+        /* Exceptions store the handler iterator for rethrow, other kinds of
+         * tasks don't (though they could). */
+        if (task->vtable->base_type == enum_class_Exception
+        && VTABLE_get_integer_keyed_str(interp, task, handled_str) == -1) {
+            iter    = VTABLE_get_attr_str(interp, task, iter_str);
+            context = (PMC *)VTABLE_get_pointer(interp, task);
+        }
+        else {
+            context = CURRENT_CONTEXT(interp);
+            if (!PMC_IS_NULL(Parrot_pcc_get_handlers(interp, context)))
+                iter = VTABLE_get_iter(interp, Parrot_pcc_get_handlers(interp, context));
+        }
     }
 
     while (context) {
@@ -899,7 +897,11 @@
 
             if (!PMC_IS_NULL(handler)) {
                 INTVAL valid_handler = 0;
-                Parrot_PCCINVOKE(interp, handler, CONST_STRING(interp, "can_handle"),
+                if (handler->vtable->base_type == enum_class_Object)
+                    Parrot_pcc_invoke_method_from_c_args(interp, handler, CONST_STRING(interp, "can_handle"),
+                        "P->I", task, &valid_handler);
+                else
+                    Parrot_PCCINVOKE(interp, handler, CONST_STRING(interp, "can_handle"),
                         "P->I", task, &valid_handler);
 
                 if (valid_handler) {
@@ -916,9 +918,9 @@
         }
 
         /* Continue the search in the next context up the chain. */
-        context = context->caller_ctx;
-        if (context && !PMC_IS_NULL(context->handlers))
-            iter = VTABLE_get_iter(interp, context->handlers);
+        context = Parrot_pcc_get_caller_ctx(interp, context);
+        if (context && !PMC_IS_NULL(Parrot_pcc_get_handlers(interp, context)))
+            iter = VTABLE_get_iter(interp, Parrot_pcc_get_handlers(interp, context));
         else
             iter = PMCNULL;
     }

Modified: trunk/src/sub.c
==============================================================================
--- trunk/src/sub.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/sub.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -49,84 +49,6 @@
 
 /*
 
-=item C<void mark_context(PARROT_INTERP, Parrot_Context* ctx)>
-
-Marks the context C<*ctx>.
-
-=cut
-
-*/
-
-void
-mark_context(PARROT_INTERP, ARGMOD(Parrot_Context* ctx))
-{
-    ASSERT_ARGS(mark_context)
-    PObj *obj;
-    int   i;
-
-    if (ctx->gc_mark == context_gc_mark)
-        return;
-    ctx->gc_mark = context_gc_mark;
-
-    /* don't mark the context if it's actually dead */
-    if (ctx->ref_count < 0) {
-        /* report it, though */
-        if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
-            fprintf(stderr, "[attempt to mark dead context %p]\n",
-                (void *)ctx);
-        }
-        return;
-    }
-
-    obj = (PObj *)ctx->current_sub;
-    if (obj)
-        Parrot_gc_mark_PObj_alive(interp, obj);
-
-    obj = (PObj *)ctx->current_object;
-    if (obj)
-        Parrot_gc_mark_PObj_alive(interp, obj);
-
-    obj = (PObj *)ctx->current_cont;
-    if (obj && !PObj_live_TEST(obj))
-        Parrot_gc_mark_PObj_alive(interp, obj);
-
-    if (ctx->caller_ctx)
-        mark_context(interp, ctx->caller_ctx);
-
-    if (ctx->outer_ctx)
-        mark_context(interp, ctx->outer_ctx);
-
-    obj = (PObj *)ctx->current_namespace;
-    if (obj)
-        Parrot_gc_mark_PObj_alive(interp, obj);
-
-    obj = (PObj *)ctx->lex_pad;
-    if (obj)
-        Parrot_gc_mark_PObj_alive(interp, obj);
-
-    obj = (PObj *)ctx->handlers;
-    if (obj)
-        Parrot_gc_mark_PObj_alive(interp, obj);
-
-
-    if (!ctx->n_regs_used)
-        return;
-
-    for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; ++i) {
-        obj = (PObj *)CTX_REG_PMC(ctx, i);
-        if (obj)
-            Parrot_gc_mark_PObj_alive(interp, obj);
-    }
-
-    for (i = 0; i < ctx->n_regs_used[REGNO_STR]; ++i) {
-        obj = (PObj *)CTX_REG_STR(ctx, i);
-        if (obj)
-            Parrot_gc_mark_PObj_alive(interp, obj);
-    }
-}
-
-/*
-
 =item C<Parrot_cont * new_continuation(PARROT_INTERP, const Parrot_cont *to)>
 
 Returns a new C<Parrot_cont> to the context of C<to> with its own copy of the
@@ -144,10 +66,10 @@
 {
     ASSERT_ARGS(new_continuation)
     Parrot_cont    * const cc     = mem_allocate_typed(Parrot_cont);
-    Parrot_Context * const to_ctx = to ? to->to_ctx : CONTEXT(interp);
+    PMC            * const to_ctx = to ? to->to_ctx : CURRENT_CONTEXT(interp);
 
     cc->to_ctx        = to_ctx;
-    cc->from_ctx      = Parrot_context_ref(interp, CONTEXT(interp));
+    cc->from_ctx      = CURRENT_CONTEXT(interp);
     cc->runloop_id    = 0;
     if (to) {
         cc->seg       = to->seg;
@@ -158,7 +80,7 @@
         cc->address   = NULL;
     }
 
-    cc->current_results = to_ctx->current_results;
+    cc->current_results = Parrot_pcc_get_results(interp, to_ctx);
     return cc;
 }
 
@@ -180,8 +102,8 @@
     ASSERT_ARGS(new_ret_continuation)
     Parrot_cont * const cc = mem_allocate_typed(Parrot_cont);
 
-    cc->to_ctx          = CONTEXT(interp);
-    cc->from_ctx        = CONTEXT(interp);    /* filled in during a call */
+    cc->to_ctx          = CURRENT_CONTEXT(interp);
+    cc->from_ctx        = CURRENT_CONTEXT(interp);    /* filled in during a call */
     cc->runloop_id      = 0;
     cc->seg             = interp->code;
     cc->current_results = NULL;
@@ -226,10 +148,9 @@
 invalidate_retc_context(PARROT_INTERP, ARGMOD(PMC *cont))
 {
     ASSERT_ARGS(invalidate_retc_context)
-    Parrot_Context *ctx = PMC_cont(cont)->from_ctx;
-    cont = ctx->current_cont;
+    PMC *ctx = PMC_cont(cont)->from_ctx;
+    cont = Parrot_pcc_get_continuation(interp, ctx);
 
-    Parrot_set_context_threshold(interp, ctx);
     while (1) {
         /*
          * We  stop if we encounter a true continuation, because
@@ -239,9 +160,8 @@
         if (!cont || cont->vtable != interp->vtables[enum_class_RetContinuation])
             break;
         cont->vtable = interp->vtables[enum_class_Continuation];
-        Parrot_context_ref(interp, ctx);
-        ctx  = ctx->caller_ctx;
-        cont = ctx->current_cont;
+        ctx  = Parrot_pcc_get_caller_ctx(interp, ctx);
+        cont = Parrot_pcc_get_continuation(interp, ctx);
     }
 
 }
@@ -316,8 +236,8 @@
 
 /*
 
-=item C<int Parrot_Context_get_info(PARROT_INTERP, const Parrot_Context *ctx,
-Parrot_Context_info *info)>
+=item C<int Parrot_Context_get_info(PARROT_INTERP, PMC *ctx, Parrot_Context_info
+*info)>
 
 Takes pointers to a context and its information table.
 Populates the table and returns 0 or 1. XXX needs explanation
@@ -329,7 +249,7 @@
 
 PARROT_EXPORT
 int
-Parrot_Context_get_info(PARROT_INTERP, ARGIN(const Parrot_Context *ctx),
+Parrot_Context_get_info(PARROT_INTERP, ARGIN(PMC *ctx),
                     ARGOUT(Parrot_Context_info *info))
 {
     ASSERT_ARGS(Parrot_Context_get_info)
@@ -344,7 +264,7 @@
     info->fullname = NULL;
 
     /* is the current sub of the specified context valid? */
-    if (PMC_IS_NULL(ctx->current_sub)) {
+    if (PMC_IS_NULL(Parrot_pcc_get_sub(interp, ctx))) {
         info->subname  = Parrot_str_new(interp, "???", 3);
         info->nsname   = info->subname;
         info->fullname = Parrot_str_new(interp, "??? :: ???", 10);
@@ -353,10 +273,10 @@
     }
 
     /* fetch Parrot_sub of the current sub in the given context */
-    if (!VTABLE_isa(interp, ctx->current_sub, CONST_STRING(interp, "Sub")))
+    if (!VTABLE_isa(interp, Parrot_pcc_get_sub(interp, ctx), CONST_STRING(interp, "Sub")))
         return 1;
 
-    PMC_get_sub(interp, ctx->current_sub, sub);
+    PMC_get_sub(interp, Parrot_pcc_get_sub(interp, ctx), sub);
     /* set the sub name */
     info->subname = sub->name;
 
@@ -367,18 +287,18 @@
     }
     else {
         info->nsname   = VTABLE_get_string(interp, sub->namespace_name);
-        info->fullname = Parrot_full_sub_name(interp, ctx->current_sub);
+        info->fullname = Parrot_full_sub_name(interp, Parrot_pcc_get_sub(interp, ctx));
     }
 
     /* return here if there is no current pc */
-    if (ctx->current_pc == NULL)
+    if (Parrot_pcc_get_pc(interp, ctx) == NULL)
         return 1;
 
     /* calculate the current pc */
-    info->pc = ctx->current_pc - sub->seg->base.data;
+    info->pc = Parrot_pcc_get_pc(interp, ctx) - sub->seg->base.data;
 
     /* determine the current source file/line */
-    if (ctx->current_pc) {
+    if (Parrot_pcc_get_pc(interp, ctx)) {
         const size_t offs = info->pc;
         size_t i, n;
         opcode_t *pc = sub->seg->base.data;
@@ -408,8 +328,7 @@
 
 /*
 
-=item C<STRING* Parrot_Context_infostr(PARROT_INTERP, const Parrot_Context
-*ctx)>
+=item C<STRING* Parrot_Context_infostr(PARROT_INTERP, PMC *ctx)>
 
 Formats context information for display.  Takes a context pointer and
 returns a pointer to the text.  Used in debug.c and warnings.c
@@ -422,12 +341,12 @@
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 STRING*
-Parrot_Context_infostr(PARROT_INTERP, ARGIN(const Parrot_Context *ctx))
+Parrot_Context_infostr(PARROT_INTERP, ARGIN(PMC *ctx))
 {
     ASSERT_ARGS(Parrot_Context_infostr)
     Parrot_Context_info info;
     STRING             *res = NULL;
-    const char * const  msg = (CONTEXT(interp) == ctx)
+    const char * const  msg = (CURRENT_CONTEXT(interp) == ctx)
         ? "current instr.:"
         : "called from Sub";
 
@@ -445,8 +364,7 @@
 
 /*
 
-=item C<PMC* Parrot_find_pad(PARROT_INTERP, STRING *lex_name, const
-Parrot_Context *ctx)>
+=item C<PMC* Parrot_find_pad(PARROT_INTERP, STRING *lex_name, PMC *ctx)>
 
 Locate the LexPad containing the given name. Return NULL on failure.
 
@@ -457,12 +375,12 @@
 PARROT_CAN_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 PMC*
-Parrot_find_pad(PARROT_INTERP, ARGIN(STRING *lex_name), ARGIN(const Parrot_Context *ctx))
+Parrot_find_pad(PARROT_INTERP, ARGIN(STRING *lex_name), ARGIN(PMC *ctx))
 {
     ASSERT_ARGS(Parrot_find_pad)
     while (1) {
-        PMC                    * const lex_pad = ctx->lex_pad;
-        const Parrot_Context   * const outer   = ctx->outer_ctx;
+        PMC * const lex_pad = Parrot_pcc_get_lex_pad(interp, ctx);
+        PMC        *outer   = Parrot_pcc_get_outer_ctx(interp, ctx);
 
         if (!outer)
             return lex_pad;
@@ -471,17 +389,6 @@
             if (VTABLE_exists_keyed_str(interp, lex_pad, lex_name))
                 return lex_pad;
 
-#if CTX_LEAK_DEBUG
-        if (outer == ctx) {
-            /* This is a bug; a context can never be its own :outer context.
-             * Detecting it avoids an unbounded loop, which is difficult to
-             * debug, though we'd rather not pay the cost of detection in a
-             * production release.
-             */
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-                "Bug:  Context %p :outer points back to itself.", ctx);
-        }
-#endif
         ctx = outer;
     }
 }
@@ -501,12 +408,11 @@
 Parrot_capture_lex(PARROT_INTERP, ARGMOD(PMC *sub_pmc))
 {
     ASSERT_ARGS(Parrot_capture_lex)
-    Parrot_Context * const ctx          = CONTEXT(interp);
+    PMC            * const ctx          = CURRENT_CONTEXT(interp);
     Parrot_Sub_attributes *current_sub;
     Parrot_Sub_attributes *sub;
-    Parrot_Context        *old;
 
-    PMC_get_sub(interp, ctx->current_sub, current_sub);
+    PMC_get_sub(interp, Parrot_pcc_get_sub(interp, ctx), current_sub);
 
     /* MultiSub gets special treatment */
     if (VTABLE_isa(interp, sub_pmc, CONST_STRING(interp, "MultiSub"))) {
@@ -524,10 +430,7 @@
                 PMC_get_sub(interp, child_sub->outer_sub, child_outer_sub);
                 if (Parrot_str_equal(interp, current_sub->subid,
                                       child_outer_sub->subid)) {
-                    old = child_sub->outer_ctx;
-                    child_sub->outer_ctx = Parrot_context_ref(interp, ctx);
-                    if (old)
-                        Parrot_free_context(interp, old, 1);
+                    child_sub->outer_ctx = ctx;
                 }
             }
         }
@@ -552,10 +455,7 @@
 #endif
 
     /* set the sub's outer context to the current context */
-    old = sub->outer_ctx;
-    sub->outer_ctx = Parrot_context_ref(interp, ctx);
-    if (old)
-        Parrot_free_context(interp, old, 1);
+    sub->outer_ctx = ctx;
 }
 
 
@@ -603,16 +503,10 @@
     ARGIN(const Parrot_cont *cc))
 {
     ASSERT_ARGS(Parrot_continuation_check)
-    Parrot_Context *to_ctx       = cc->to_ctx;
-    Parrot_Context *from_ctx     = CONTEXT(interp);
+    PMC *to_ctx       = cc->to_ctx;
+    PMC *from_ctx     = CURRENT_CONTEXT(interp);
 
-#if CTX_LEAK_DEBUG
-    if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG))
-        fprintf(stderr,
-                "[invoke cont    %p, to_ctx %p, from_ctx %p (refs %d)]\n",
-                (const void *)pmc, (void *)to_ctx, (void *)from_ctx, (int)from_ctx->ref_count);
-#endif
-    if (!to_ctx)
+    if (PMC_IS_NULL(to_ctx))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                        "Continuation invoked after deactivation.");
 }
@@ -634,11 +528,11 @@
         ARGIN(Parrot_cont *cc))
 {
     ASSERT_ARGS(Parrot_continuation_rewind_environment)
-    Parrot_Context * const to_ctx = cc->to_ctx;
+    PMC * const to_ctx = cc->to_ctx;
 
     /* debug print before context is switched */
     if (Interp_trace_TEST(interp, PARROT_TRACE_SUB_CALL_FLAG)) {
-        PMC * const sub = to_ctx->current_sub;
+        PMC * const sub = Parrot_pcc_get_sub(interp, to_ctx);
 
         Parrot_io_eprintf(interp, "# Back in sub '%Ss', env %p\n",
                     Parrot_full_sub_name(interp, sub),
@@ -646,9 +540,7 @@
     }
 
     /* set context */
-    CONTEXT(interp)      = to_ctx;
-    interp->ctx.bp       = to_ctx->bp;
-    interp->ctx.bp_ps    = to_ctx->bp_ps;
+    CURRENT_CONTEXT(interp) = to_ctx;
 }
 
 

Modified: trunk/src/warnings.c
==============================================================================
--- trunk/src/warnings.c	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/src/warnings.c	Thu Sep  3 11:56:50 2009	(r40958)
@@ -53,8 +53,7 @@
         interp->pdb->debugger :
         interp;
     Parrot_io_eprintf(tracer, "%Ss\n",
-            Parrot_Context_infostr(interp,
-                CONTEXT(interp)));
+            Parrot_Context_infostr(interp, CURRENT_CONTEXT(interp)));
 }
 
 /*

Modified: trunk/t/compilers/pge/06-grammar.t
==============================================================================
--- trunk/t/compilers/pge/06-grammar.t	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/t/compilers/pge/06-grammar.t	Thu Sep  3 11:56:50 2009	(r40958)
@@ -180,6 +180,7 @@
     load_bytecode 'PGE.pbc'
     load_bytecode 'PGE/Perl6Grammar.pbc'
 
+    ok        = 1
     match     = parser(expr)
     result    = match
 

Modified: trunk/t/native_pbc/annotations.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/integer_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/number_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/string_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/op/annotate.t
==============================================================================
--- trunk/t/op/annotate.t	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/t/op/annotate.t	Thu Sep  3 11:56:50 2009	(r40958)
@@ -37,6 +37,7 @@
   failed:
     .local pmc exception
     .get_results (exception)
+    pop_eh
     $P0 = exception.'annotations'()
     isa_ok ($P0, 'Hash', 'annotations gives back hash')
     $I0 = elements $P0
@@ -59,6 +60,7 @@
   failed:
     .local pmc exception
     .get_results (exception)
+    pop_eh
 
     $P0 = exception.'annotations'('file')
     is ($P0, 'foo.p6', "file annotation got OK")
@@ -107,6 +109,7 @@
   failed:
     .local pmc exception, bt, frame, ann
     .get_results (exception)
+    pop_eh
     bt = exception.'backtrace'()
     $I0 = elements bt
     $I0 = $I0 > 3

Added: trunk/t/pmc/context.t
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/t/pmc/context.t	Thu Sep  3 11:56:50 2009	(r40958)
@@ -0,0 +1,35 @@
+#! parrot
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+t/pmc/context.t - test Context PMC
+
+=head1 SYNOPSIS
+
+    % prove t/pmc/context.t
+
+=head1 DESCRIPTION
+
+Tests the Context PMC.
+
+TODO: Implement real tests when Context PMC will be migrated to use ATTRibutes.
+
+=cut
+
+.sub main :main
+    .include 'test_more.pir'
+
+    plan(1)
+
+    $P0 = new ['Context']
+    sweep 1
+    ok(1, 'Instantiated .Context')
+.end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: trunk/t/pmc/exceptionhandler.t
==============================================================================
--- trunk/t/pmc/exceptionhandler.t	Thu Sep  3 10:58:58 2009	(r40957)
+++ trunk/t/pmc/exceptionhandler.t	Thu Sep  3 11:56:50 2009	(r40958)
@@ -22,7 +22,8 @@
 .sub main :main
     .include 'test_more.pir'
 
-    plan(8)
+    # If test exited with "bad plan" MyHandlerCan.can_handle wasn't invoked.
+    plan(9)
 
     .local pmc eh
     eh = new ['ExceptionHandler']
@@ -213,6 +214,7 @@
 
 .sub can_handle :method
     .param pmc ex
+    ok(1, 'MyHandlerCan.can_handle invoked')
     .return(1)
 .end
 


More information about the parrot-commits mailing list