[svn:parrot] r39810 - in branches/context_pmc: include/parrot lib/Parrot/Pmc2c src src/gc src/ops src/pmc
whiteknight at svn.parrot.org
whiteknight at svn.parrot.org
Sat Jun 27 19:39:11 UTC 2009
Author: whiteknight
Date: Sat Jun 27 19:39:09 2009
New Revision: 39810
URL: https://trac.parrot.org/parrot/changeset/39810
Log:
[context_pmc] flesh out the new PMC type a little bit more, and start making the switch. Obviously haven't gotten very far
Modified:
branches/context_pmc/include/parrot/interpreter.h
branches/context_pmc/lib/Parrot/Pmc2c/PCCMETHOD.pm
branches/context_pmc/src/debug.c
branches/context_pmc/src/gc/alloc_register.c
branches/context_pmc/src/gc/alloc_resources.c
branches/context_pmc/src/gc/mark_sweep.c
branches/context_pmc/src/global.c
branches/context_pmc/src/ops/core.ops
branches/context_pmc/src/ops/pic.ops
branches/context_pmc/src/ops/var.ops
branches/context_pmc/src/pmc/context.pmc
branches/context_pmc/src/pmc/continuation.pmc
branches/context_pmc/src/pmc/exception.pmc
branches/context_pmc/src/pmc/lexpad.pmc
branches/context_pmc/src/pmc/parrotinterpreter.pmc
branches/context_pmc/src/pmc/sub.pmc
branches/context_pmc/src/scheduler.c
Modified: branches/context_pmc/include/parrot/interpreter.h
==============================================================================
--- branches/context_pmc/include/parrot/interpreter.h Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/include/parrot/interpreter.h Sat Jun 27 19:39:09 2009 (r39810)
@@ -186,48 +186,6 @@
INTVAL *regs_i;
} Regs_ni;
-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 */
@@ -243,21 +201,7 @@
size_t n_allocated; /* allocated size of it */
} Prederef;
-
-/*
- * 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
- */
-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 CONTEXT(interp) ((interp)->ctx.state)
+#define CONTEXT(interp) ((interp)->ctx)
#define CHUNKED_CTX_MEM 0 /* no longer works, but will be reinstated
* some day; see src/register.c for details.
@@ -294,7 +238,7 @@
/* The actual interpreter structure */
struct parrot_interp_t {
- struct Interp_Context ctx;
+ PMC * ctx;
context_mem ctx_mem; /* ctx memory managment */
struct Arenas *arena_base; /* Pointer to this interpreter's
Modified: branches/context_pmc/lib/Parrot/Pmc2c/PCCMETHOD.pm
==============================================================================
--- branches/context_pmc/lib/Parrot/Pmc2c/PCCMETHOD.pm Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/lib/Parrot/Pmc2c/PCCMETHOD.pm Sat Jun 27 19:39:09 2009 (r39810)
@@ -394,16 +394,17 @@
PMC * const _param_sig = pmc_new(interp, enum_class_FixedIntegerArray);
PMC *_return_sig = PMCNULL;
- Parrot_Context *_caller_ctx = CONTEXT(interp);
+ PMC *_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 *_ctx = pmc_new_init(interp, enum_class_Context, CONTEXT(interp));
PMC *_ccont = PMCNULL;
+ VTABLE_set_pointer(inter, _ctx, _n_regs_used);
$set_params
UNUSED(_return_indexes);
- if (_caller_ctx) {
- _ccont = _caller_ctx->current_cont;
+ if (!PMC_IS_NULL(_caller_ctx)) {
+ _ccont = PARROT_CONTEXT(_caller_ctx)->current_cont;
}
else {
/* there is no point calling Parrot_ex_throw_from_c_args here, because
@@ -411,8 +412,8 @@
exit_fatal(1, "No caller_ctx for continuation \%p.", _ccont);
}
- _ctx->current_cont = _ret_cont;
- PMC_cont(_ret_cont)->from_ctx = _ctx;
+ PARROT_CONTEXT(_ctx)->current_cont = _ret_cont;
+ PMC_cont(_ret_cont)->from_ctx = _ctx;
_current_args = interp->current_args;
interp->current_args = NULL;
@@ -429,9 +430,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_CONTEXT(_ctx)->recursion_depth;
+ PARROT_CONTEXT(_ctx)->caller_ctx = PARROT_CONTEXT(_caller_ctx)->caller_ctx;
interp->current_args = NULL;
}
/* BEGIN PARMS SCOPE */
@@ -458,7 +458,7 @@
$e_post->emit( <<"END", __FILE__, __LINE__ + 1 );
$method_returns
- if (! _caller_ctx) {
+ if (PMC_IS_NULL(_caller_ctx)) {
/* there is no point calling Parrot_ex_throw_from_c_args here, because
PDB_backtrace can't deal with a missing to_ctx either. */
exit_fatal(1, "No caller_ctx for continuation \%p.", _ccont);
@@ -466,7 +466,7 @@
interp->returns_signature = _return_sig;
parrot_pass_args(interp, _ctx, _caller_ctx, _return_indexes,
- _caller_ctx->current_results, PARROT_PASS_RESULTS);
+ PARROT_CONTEXT(_caller_ctx)->current_results, PARROT_PASS_RESULTS);
END
}
$e_post->emit( <<"END", __FILE__, __LINE__ + 1 );
@@ -476,7 +476,7 @@
no_return:
PObj_live_CLEAR(_param_sig);
PObj_live_CLEAR(_return_sig);
- Parrot_pop_context(interp);
+ VTABLE_pop_pmc(interp, CONTEXT(interp));
END
$self->return_type('void');
$self->parameters('');
Modified: branches/context_pmc/src/debug.c
==============================================================================
--- branches/context_pmc/src/debug.c Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/debug.c Sat Jun 27 19:39:09 2009 (r39810)
@@ -2176,7 +2176,7 @@
PDB_check_condition(PARROT_INTERP, ARGIN(const PDB_condition_t *condition))
{
ASSERT_ARGS(PDB_check_condition)
- Parrot_Context *ctx = CONTEXT(interp);
+ PMC *ctx = CONTEXT(interp);
TRACEDEB_MSG("PDB_check_condition");
@@ -3441,7 +3441,7 @@
/* information about the current sub */
PMC *sub = interpinfo_p(interp, CURRENT_SUB);
- Parrot_Context *ctx = CONTEXT(interp);
+ PMC *ctx = CONTEXT(interp);
if (!PMC_IS_NULL(sub)) {
str = Parrot_Context_infostr(interp, ctx);
Modified: branches/context_pmc/src/gc/alloc_register.c
==============================================================================
--- branches/context_pmc/src/gc/alloc_register.c Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/gc/alloc_register.c Sat Jun 27 19:39:09 2009 (r39810)
@@ -17,87 +17,8 @@
*/
-#include "parrot/parrot.h"
-#include "parrot/register.h"
-#include "../pmc/pmc_sub.h"
-
-/* HEADERIZER HFILE: include/parrot/register.h */
-
-/* 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))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- FUNC_MODIFIES(*ctx);
-
-static void init_context(PARROT_INTERP,
- ARGMOD(Parrot_Context *ctx),
- ARGIN_NULLOK(const Parrot_Context *old))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- FUNC_MODIFIES(*ctx);
-
-#define ASSERT_ARGS_clear_regs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
- PARROT_ASSERT_ARG(interp) \
- || PARROT_ASSERT_ARG(ctx)
-#define ASSERT_ARGS_init_context __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: static */
-/*
-=head2 Context and register frame layout
-
- +----------++----+------+------------+----+
- | context || N | I | P | S +
- +----------++----+------+------------+----+
- ^ ^ ^ ^
- | | ctx.bp ctx.bp_ps
- ctx.state opt
- padding
-
-Registers are addressed as usual via the register base pointer ctx.bp.
-
-The macro CONTEXT() hides these details
-
-=cut
-
-*/
-
-/*
-=head2 Context and register frame allocation
-
-There are two allocation strategies: chunked memory and malloced with a free
-list.
-
- CHUNKED_CTX_MEM = 1
-
-C<ctx_mem.data> is a pointer to an allocated chunk of memory. The pointer
-C<ctx_mem.free> holds the next usable location. With (full) continuations the
-C<ctx_mem.free> pointer can't be moved below the C<ctx_mem.threshold>, which is
-the highest context pointer of all active continuations.
-
-[the code for this is incomplete; it had suffered some bit-rot and was
-getting in the way of maintaining the other case. -- rgr, 4-Feb-06.]
-
-RT #46177 GC has to lower this threshold when collecting continuations.
-
- CHUNKED_CTX_MEM = 0
-
-Context/register memory is malloced. C<ctx_mem.free> is used as a free list of
-reusable items.
-
-=cut
-
-*/
-
-#define CTX_ALLOC_SIZE 0x20000
-
-#define ALIGNED_CTX_SIZE (((sizeof (Parrot_Context) + NUMVAL_SIZE - 1) \
- / NUMVAL_SIZE) * NUMVAL_SIZE)
/*
@@ -113,15 +34,7 @@
*/
-#define SLOT_CHUNK_SIZE 8
-#define ROUND_ALLOC_SIZE(size) ((((size) + SLOT_CHUNK_SIZE - 1) \
- / SLOT_CHUNK_SIZE) * SLOT_CHUNK_SIZE)
-#define CALCULATE_SLOT_NUM(size) ((size) / SLOT_CHUNK_SIZE)
-
-#if CHUNKED_CTX_MEM
- # error "Non-working code removed."
-#endif
/*
@@ -133,47 +46,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);
-}
/*
@@ -191,305 +63,17 @@
{
ASSERT_ARGS(create_initial_context)
static INTVAL num_regs[] = {32, 32, 32, 32};
- Parrot_Context *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);
- UNUSED(ignored);
-}
-
-
-/*
-
-=item C<void parrot_gc_context(PARROT_INTERP)>
-
-Cleans up dead context memory; called by the garbage collector. This only
-applies in the chunked context memory scheme.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-parrot_gc_context(PARROT_INTERP)
-{
- ASSERT_ARGS(parrot_gc_context)
-#if CHUNKED_CTX_MEM
- Parrot_Context ctx;
- ASSERT_ARGS(parrot_gc_context)
-
- if (!interp->ctx_mem.threshold)
- return;
- LVALUE_CAST(char *, ctx.bp) = interp->ctx_mem.threshold
- - sizeof (parrot_regs_t);
-#else
- UNUSED(interp);
-#endif
-}
-
-
-/*
-
-=item C<static void clear_regs(PARROT_INTERP, Parrot_Context *ctx)>
-
-Clears all registers in a context. PMC and STRING registers contain PMCNULL
-and NULL, respectively. Integer and float registers contain negative flag
-values, for debugging purposes.
-
-=cut
-
-*/
-
-static void
-clear_regs(PARROT_INTERP, ARGMOD(Parrot_Context *ctx))
-{
- ASSERT_ARGS(clear_regs)
- int i;
-
- /* NULL out registers - P/S have to be NULL for GC
- *
- * if the architecture has 0x := NULL and 0.0 we could memset too
- */
-
- for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; i++) {
- CTX_REG_PMC(ctx, i) = PMCNULL;
- }
-
- for (i = 0; i < ctx->n_regs_used[REGNO_STR]; i++) {
- CTX_REG_STR(ctx, 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;
- }
- for (i = 0; i < ctx->n_regs_used[REGNO_NUM]; i++) {
- CTX_REG_NUM(ctx, i) = -99.9;
- }
- }
-}
-
-
-/*
-
-=item C<static void init_context(PARROT_INTERP, Parrot_Context *ctx, const
-Parrot_Context *old)>
-
-Initializes a freshly allocated or recycled context.
-
-=cut
-
-*/
-
-static void
-init_context(PARROT_INTERP, ARGMOD(Parrot_Context *ctx),
- ARGIN_NULLOK(const Parrot_Context *old))
-{
- ASSERT_ARGS(init_context)
- ctx->ref_count = 0;
- ctx->gc_mark = 0;
- ctx->current_results = NULL;
- ctx->results_signature = NULL;
- ctx->lex_pad = PMCNULL;
- ctx->outer_ctx = NULL;
- ctx->current_cont = NULL;
- ctx->current_object = NULL;
- ctx->handlers = PMCNULL;
- ctx->caller_ctx = NULL;
-
- if (old) {
- /* some items should better be COW copied */
- ctx->constants = old->constants;
- ctx->warns = old->warns;
- ctx->errors = old->errors;
- ctx->trace_flags = old->trace_flags;
- ctx->pred_offset = old->pred_offset;
- ctx->current_HLL = old->current_HLL;
- ctx->current_namespace = old->current_namespace;
- /* end COW */
- ctx->recursion_depth = old->recursion_depth;
- }
- else {
- ctx->constants = NULL;
- ctx->warns = 0;
- ctx->errors = 0;
- ctx->trace_flags = 0;
- ctx->pred_offset = 0;
- ctx->current_HLL = 0;
- ctx->current_namespace = PMCNULL;
- ctx->recursion_depth = 0;
- }
-
- /* other stuff is set inside Sub.invoke */
- clear_regs(interp, ctx);
-}
-
-
-/*
-
-=item C<Parrot_Context * 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>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-Parrot_Context *
-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);
-
- ctx->caller_ctx = old;
-
- /* doesn't change */
- ctx->current_sub = old->current_sub;
-
- /* copy more ? */
- return ctx;
-}
-
-
-/*
-
-=item C<void Parrot_pop_context(PARROT_INTERP)>
-
-Frees the context created with C<Parrot_push_context> and restores the previous
-context (the caller context).
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_pop_context(PARROT_INTERP)
-{
- ASSERT_ARGS(Parrot_pop_context)
- Parrot_Context * const ctx = CONTEXT(interp);
- Parrot_Context * const old = ctx->caller_ctx;
-
- ctx->ref_count = 0;
- Parrot_free_context(interp, ctx, 0);
-
- /* restore old, set cached interpreter base pointers */
- CONTEXT(interp) = old;
- interp->ctx.bp = old->bp;
- interp->ctx.bp_ps = old->bp_ps;
+ CONTEXT(interp) = pmc_new(interp, enum_class_Context);
+ VTABLE_set_pointer(interp, CONTEXT(interp));
}
/*
-=item C<Parrot_Context * Parrot_alloc_context(PARROT_INTERP, const INTVAL
-*number_regs_used, Parrot_Context *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
-the init flag to indicate whether you want to initialize the new context
-(setting its default values and clearing its registers).
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-Parrot_Context *
-Parrot_alloc_context(PARROT_INTERP, ARGIN(const INTVAL *number_regs_used),
- ARGIN_NULLOK(Parrot_Context *old))
-{
- ASSERT_ARGS(Parrot_alloc_context)
- Parrot_Context *ctx;
- void *p;
-
- const size_t size_i = sizeof (INTVAL) * number_regs_used[REGNO_INT];
- const size_t size_n = sizeof (FLOATVAL) * number_regs_used[REGNO_NUM];
- const size_t size_s = sizeof (STRING *) * number_regs_used[REGNO_STR];
- const size_t size_p = sizeof (PMC *) * number_regs_used[REGNO_PMC];
-
- 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);
- }
-
- 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];
-
- ctx->regs_mem_size = reg_alloc;
-
- /* regs start past the context */
- p = (void *) ((char *)ctx + ALIGNED_CTX_SIZE);
-
- /* ctx.bp points to I0, which has Nx on the left */
- ctx->bp.regs_i = (INTVAL *)((char *)p + size_n);
-
- /* 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);
-
- return ctx;
-}
-
-
-/*
-
-=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
@@ -501,210 +85,18 @@
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);
-
- CONTEXT(interp) = ctx;
- interp->ctx.bp.regs_i = ctx->bp.regs_i;
- interp->ctx.bp_ps.regs_s = ctx->bp_ps.regs_s;
-
+ PMC *old = CONTEXT(interp);
+ PMC *ctx = pmc_new(interp, enum_class_Context);
+ VTABLE_set_pointer(interp, ctx, number_regs_used);
+ VTABLE_push_pmc(interp, CONTEXT(interp), ctx);
return ctx;
}
-/*
-
-=item C<void Parrot_free_context(PARROT_INTERP, Parrot_Context *ctx, int deref)>
-
-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.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_free_context(PARROT_INTERP, ARGMOD(Parrot_Context *ctx), int deref)
-{
- 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.
- */
- if (deref) {
- ctx->ref_count--;
- }
-
- 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 *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;
-
- /* 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--;
-
- ptr = ctx;
- slot = CALCULATE_SLOT_NUM(ctx->regs_mem_size);
-
- PARROT_ASSERT(slot < interp->ctx_mem.n_free_slots);
- *(void **)ptr = interp->ctx_mem.free_list[slot];
- interp->ctx_mem.free_list[slot] = ptr;
- }
-}
-
-
-/*
-
-=item C<void Parrot_set_context_threshold(PARROT_INTERP, Parrot_Context *ctx)>
-
-Marks the context as possible threshold.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_set_context_threshold(SHIM_INTERP, SHIM(Parrot_Context *ctx))
-{
- ASSERT_ARGS(Parrot_set_context_threshold)
- /* nothing to do */
-}
-
-/*
-
-=back
-
-=head2 Register Stack Functions
-
-=over 4
-
-=cut
-
-=item C<void Parrot_clear_i(PARROT_INTERP)>
-
-Sets all integer registers in the current context to 0.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_clear_i(PARROT_INTERP)
-{
- ASSERT_ARGS(Parrot_clear_i)
- int i;
- for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_INT]; ++i)
- REG_INT(interp, i) = 0;
-}
-
-
-/*
-
-=item C<void Parrot_clear_s(PARROT_INTERP)>
-
-Sets all STRING registers in the current context to NULL.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_clear_s(PARROT_INTERP)
-{
- ASSERT_ARGS(Parrot_clear_s)
- int i;
- for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_STR]; ++i)
- REG_STR(interp, i) = NULL;
-}
-
-
-/*
-
-=item C<void Parrot_clear_p(PARROT_INTERP)>
-
-Sets all PMC registers in the current context to NULL.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_clear_p(PARROT_INTERP)
-{
- ASSERT_ARGS(Parrot_clear_p)
- int i;
- for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_PMC]; ++i)
- REG_PMC(interp, i) = PMCNULL;
-}
-
-
-/*
-
-=item C<void Parrot_clear_n(PARROT_INTERP)>
-
-Sets all number registers in the current context to 0.0.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_clear_n(PARROT_INTERP)
-{
- 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;
-}
-
/*
Modified: branches/context_pmc/src/gc/alloc_resources.c
==============================================================================
--- branches/context_pmc/src/gc/alloc_resources.c Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/gc/alloc_resources.c Sat Jun 27 19:39:09 2009 (r39810)
@@ -21,6 +21,7 @@
#include "parrot/parrot.h"
#include "gc_private.h"
+#include "../pmc/pmc_context.h"
#define RECLAMATION_FACTOR 0.20
@@ -262,7 +263,7 @@
int i;
static char reg[10];
- Parrot_Context* const ctx = CONTEXT(interp);
+ Parrot_Context_attributes * const ctx = PARROT_CONTEXT(CONTEXT(interp));
for (i = 0; i < ctx->n_regs_used[REGNO_STR]; ++i) {
PObj * const obj = (PObj *) CTX_REG_STR(interp, ctx, i);
Modified: branches/context_pmc/src/gc/mark_sweep.c
==============================================================================
--- branches/context_pmc/src/gc/mark_sweep.c Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/gc/mark_sweep.c Sat Jun 27 19:39:09 2009 (r39810)
@@ -161,7 +161,7 @@
{
ASSERT_ARGS(Parrot_gc_trace_root)
Arenas * const arena_base = interp->arena_base;
- Parrot_Context *ctx;
+ PMC *ctx;
PObj *obj;
/* note: adding locals here did cause increased GC runs */
@@ -191,8 +191,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, CONTEXT(interp));
/* mark the dynamic environment. */
mark_stack(interp, interp->dynamic_env);
Modified: branches/context_pmc/src/global.c
==============================================================================
--- branches/context_pmc/src/global.c Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/global.c Sat Jun 27 19:39:09 2009 (r39810)
@@ -742,7 +742,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 = CONTEXT(interp);
PMC * const lex_pad = Parrot_find_pad(interp, name, ctx);
PMC *g;
Modified: branches/context_pmc/src/ops/core.ops
==============================================================================
--- branches/context_pmc/src/ops/core.ops Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/ops/core.ops Sat Jun 27 19:39:09 2009 (r39810)
@@ -605,7 +605,7 @@
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;
@@ -613,9 +613,9 @@
interp->current_params = _this;
ctx = CONTEXT(interp);
- ccont = ctx->current_cont;
+ ccont = PARROT_CONTEXT(ctx)->current_cont;
- caller_ctx = ctx->caller_ctx;
+ caller_ctx = PARROT_CONTEXT(ctx)->caller_ctx;
src_indexes = interp->current_args;
dst_indexes = interp->current_params;
@@ -639,7 +639,7 @@
op set_returns(inconst PMC) :flow {
opcode_t * const _this = CUR_OPCODE;
- Parrot_Context *ctx;
+ PMC *ctx;
PMC *ccont;
PMC *signature = $1;
INTVAL argc;
@@ -647,12 +647,12 @@
interp->current_returns = _this;
ctx = CONTEXT(interp);
- ccont = ctx->current_cont;
+ ccont = PARROT_CONTEXT(ctx)->current_cont;
if (PMC_cont(ccont)->address) {
/* Call is from runops_fromc */
- Parrot_Context * const caller_ctx = PMC_cont(ccont)->to_ctx;
- if (! caller_ctx) {
+ PMC * const 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);
@@ -666,10 +666,10 @@
parrot_pass_args(interp, ctx, caller_ctx, src_indexes, dest_indexes, PARROT_PASS_RESULTS);
}
- else if (ctx->caller_ctx->results_signature) {
- /* 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);
+ else if (PARROT_CONTEXT(PARROT_CONTEXT(ctx)->caller_ctx)->results_signature) {
+ /* We have a dynamic result signature, from pcc_invoke */
+ parrot_pass_args(interp, ctx, PARROT_CONTEXT(ctx)->caller_ctx, interp->current_returns,
+ PARROT_CONTEXT(PARROT_CONTEXT(ctx)->caller_ctx)->current_results, PARROT_PASS_RESULTS);
}
argc = VTABLE_elements(interp, signature);
goto OFFSET(argc + 2);
Modified: branches/context_pmc/src/ops/pic.ops
==============================================================================
--- branches/context_pmc/src/ops/pic.ops Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/ops/pic.ops Sat Jun 27 19:39:09 2009 (r39810)
@@ -132,7 +132,7 @@
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
@@ -183,13 +183,13 @@
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;
+ ccont = PARROT_CONTEXT(ctx)->current_cont;
cc = PMC_cont(ccont);
if (!cc->address) {
interp->current_returns = CUR_OPCODE;
@@ -239,7 +239,7 @@
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;
@@ -248,9 +248,9 @@
ctx = CONTEXT(interp);
mic = (Parrot_MIC *) cur_opcode[1];
/* get_results */
- pc = ctx->current_results;
+ pc = PARROT_CONTEXT(ctx)->current_results;
if (pc) {
- pred_pc = (void**) pc - ctx->pred_offset;
+ pred_pc = (void**) pc - PARROT_CONTEXT(ctx)->pred_offset;
sig = (PMC*)(pred_pc[1]);
ASSERT_SIG_PMC(sig);
PARROT_ASSERT(VTABLE_elements(interp, sig) <= 1);
Modified: branches/context_pmc/src/ops/var.ops
==============================================================================
--- branches/context_pmc/src/ops/var.ops Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/ops/var.ops Sat Jun 27 19:39:09 2009 (r39810)
@@ -39,7 +39,7 @@
=cut
op store_lex(in STR, invar PMC) {
- Parrot_Context * const ctx = CONTEXT(interp);
+ PMC * const ctx = CONTEXT(interp);
STRING * const lex_name = $1;
PMC * const lex_pad = Parrot_find_pad(interp, lex_name, ctx);
@@ -64,7 +64,7 @@
=cut
op find_lex(out PMC, in STR) {
- Parrot_Context * const ctx = CONTEXT(interp);
+ PMC * const ctx = CONTEXT(interp);
STRING * const lex_name = $2;
PMC * const lex_pad = Parrot_find_pad(interp, lex_name, ctx);
@@ -94,10 +94,12 @@
op find_caller_lex(out PMC, in STR) {
STRING * const lex_name = $2;
- Parrot_Context * ctx = CONTEXT(interp);
+ PMC * ctx = CONTEXT(interp);
PMC * result = PMCNULL;
- for (ctx = ctx->caller_ctx; ctx && PMC_IS_NULL(result); ctx = ctx->caller_ctx) {
+ for (ctx = PARROT_CONTEXT(ctx)->caller_ctx;
+ !PMC_IS_NULL(ctx) && PMC_IS_NULL(result);
+ ctx = PARROT_CONTEXT(ctx)->caller_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);
Modified: branches/context_pmc/src/pmc/context.pmc
==============================================================================
--- branches/context_pmc/src/pmc/context.pmc Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/pmc/context.pmc Sat Jun 27 19:39:09 2009 (r39810)
@@ -18,46 +18,342 @@
*/
-pmclass Context {
+/*
+=head2 Context and register frame layout
+
+ +----------++----+------+------------+----+
+ | context || N | I | P | S +
+ +----------++----+------+------------+----+
+ ^ ^ ^ ^
+ | | ctx.bp ctx.bp_ps
+ ctx.state opt
+ padding
+
+Registers are addressed as usual via the register base pointer ctx.bp.
+
+The macro CONTEXT() hides these details
+
+=cut
+
+*/
+
+/*
+=head2 Context and register frame allocation
+
+There are two allocation strategies: chunked memory and malloced with a free
+list.
+
+ CHUNKED_CTX_MEM = 1
+
+C<ctx_mem.data> is a pointer to an allocated chunk of memory. The pointer
+C<ctx_mem.free> holds the next usable location. With (full) continuations the
+C<ctx_mem.free> pointer can't be moved below the C<ctx_mem.threshold>, which is
+the highest context pointer of all active continuations.
+
+[the code for this is incomplete; it had suffered some bit-rot and was
+getting in the way of maintaining the other case. -- rgr, 4-Feb-06.]
+
+RT #46177 GC has to lower this threshold when collecting continuations.
- ATTR PMC caller_ctx /* caller context */
- ATTR Regs_ni bp; /* pointers to FLOATVAL & INTVAL */
- ATTR Regs_ps bp_ps; /* pointers to PMC & STR */
+ CHUNKED_CTX_MEM = 0
+
+Context/register memory is malloced. C<ctx_mem.free> is used as a free list of
+reusable items.
+
+=cut
+
+*/
+
+
+#include "parrot/parrot.h"
+#include "parrot/register.h"
+#include "pmc_sub.h"
+
+#define SLOT_CHUNK_SIZE 8
+
+#define ROUND_ALLOC_SIZE(size) ((((size) + SLOT_CHUNK_SIZE - 1) \
+ / SLOT_CHUNK_SIZE) * SLOT_CHUNK_SIZE)
+#define CALCULATE_SLOT_NUM(size) ((size) / SLOT_CHUNK_SIZE)
+
+#if CHUNKED_CTX_MEM
+ # error "Non-working code removed."
+#endif
+
+#define CTX_ALLOC_SIZE 0x20000
+
+#define ALIGNED_CTX_SIZE (((sizeof (Parrot_Context) + NUMVAL_SIZE - 1) \
+ / NUMVAL_SIZE) * NUMVAL_SIZE)
+
+
+/*
+
+=item C<static void clear_regs(PARROT_INTERP, Parrot_Context *ctx)>
+
+Clears all registers in a context. PMC and STRING registers contain PMCNULL
+and NULL, respectively. Integer and float registers contain negative flag
+values, for debugging purposes.
+
+=cut
+
+*/
+
+static void
+clear_regs(PARROT_INTERP, ARGMOD(Parrot_Context *ctx))
+{
+ ASSERT_ARGS(clear_regs)
+ int i;
+
+ /* NULL out registers - P/S have to be NULL for GC
+ *
+ * if the architecture has 0x := NULL and 0.0 we could memset too
+ */
+
+ for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; i++) {
+ CTX_REG_PMC(ctx, i) = PMCNULL;
+ }
+
+ for (i = 0; i < ctx->n_regs_used[REGNO_STR]; i++) {
+ CTX_REG_STR(ctx, 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;
+ }
+ for (i = 0; i < ctx->n_regs_used[REGNO_NUM]; i++) {
+ CTX_REG_NUM(ctx, i) = -99.9;
+ }
+ }
+}
+
+
+pmclass Context {
+ ATTR PMC *caller_ctx /* caller context */
+ ATTR Regs_ni bp; /* pointers to FLOATVAL & INTVAL */
+ ATTR Regs_ps bp_ps; /* pointers to PMC & STR */
+ ATTR void * regs; /* register storage */
/* end common header */
- ATTR INTVAL n_regs_used[4]; /* INSP in PBC points to Sub */
- ATTR PMC lex_pad; /* LexPad PMC */
- ATTR PMC outer_ctx; /* outer context, if a closure */
+ ATTR INTVAL n_regs_used[4]; /* INSP in PBC points to Sub */
+ ATTR PMC *lex_pad; /* LexPad PMC */
+ ATTR PMC *outer_ctx; /* outer context, if a closure */
/* new call scheme and introspective variables */
- ATTR PMC current_sub; /* the Sub we are executing */
+ ATTR PMC *current_sub; /* the Sub we are executing */
/* for now use a return continuation PMC */
- ATTR PMC handlers; /* local handlers for the context */
- ATTR PMC current_cont; /* the return continuation PMC */
- ATTR PMC current_object; /* current object if a method call */
- ATTR PMC current_namespace; /* The namespace we're currently in */
- ATTR PMC results_signature; /* non-const results signature PMC */
+ ATTR PMC *handlers; /* local handlers for the context */
+ ATTR PMC *current_cont; /* the return continuation PMC */
+ ATTR PMC *current_object; /* current object if a method call */
+ ATTR PMC *current_namespace; /* The namespace we're currently in */
+ ATTR PMC *results_signature; /* non-const results signature PMC */
ATTR opcode_t *current_pc; /* program counter of Sub invocation */
ATTR opcode_t *current_results; /* ptr into code with get_results opcode */
/* deref the constants - we need it all the time */
- ATTR struct PackFile_Constant **constants;
+ ATTR struct PackFile_Constant **constants;
- ATTR INTVAL current_HLL; /* see also src/hll.c */
- ATTR size_t regs_mem_size; /* memory occupied by registers */
- ATTR int ref_count; /* how often refered to */
- ATTR int gc_mark; /* marked in gc run */
+ ATTR INTVAL current_HLL; /* see also src/hll.c */
+ ATTR size_t regs_mem_size; /* memory occupied by registers */
+ ATTR int ref_count; /* how often refered to */
+ ATTR int gc_mark; /* marked in gc run */
- ATTR UINTVAL warns; /* Keeps track of what warnings
+ ATTR UINTVAL warns; /* Keeps track of what warnings
* have been activated */
- ATTR UINTVAL errors; /* fatals that can be turned off */
- ATTR UINTVAL trace_flags;
- ATTR UINTVAL recursion_depth; /* Sub call recursion depth */
+ ATTR UINTVAL errors; /* fatals that can be turned off */
+ ATTR UINTVAL trace_flags;
+ ATTR 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 */
- ATTR size_t pred_offset;
+ ATTR size_t pred_offset;
+
+ VTABLE void init() {
+ Parrot_Context_attributes * const ctx =
+ mem_alloc_typed(Parrot_Context_attributes);
+ ctx->current_results = NULL;
+ ctx->results_signature = PMCNULL;
+ ctx->lex_pad = PMCNULL;
+ ctx->outer_ctx = PMCNULL;
+ ctx->current_cont = PMCNULL;
+ ctx->current_object = PMCNULL;
+ ctx->handlers = PMCNULL;
+ ctx->caller_ctx = PMCNULL;
+ ctx->current_pc = PMCNULL;
+ PMC_data(SELF) = ctx;
+ PObj_active_destroy_SET(SELF);
+ PObj_custom_mark_SET(SELF);
+ }
+
+ VTABLE void init_pmc(PMC *old_ctx) {
+ Parrot_Context_attributes * const ctx =
+ mem_alloc_typed(Parrot_Context_attributes);
+ ctx->current_results = NULL;
+ ctx->results_signature = PMCNULL;
+ ctx->lex_pad = PMCNULL;
+ ctx->outer_ctx = PMCNULL;
+ ctx->current_cont = PMCNULL;
+ ctx->current_object = PMCNULL;
+ ctx->handlers = PMCNULL;
+ ctx->caller_ctx = PMCNULL;
+ ctx->current_pc = PMCNULL;
+ ctx->current_namespace = PMCNULL;
+ PMC_data(SELF) = ctx;
+ PObj_active_destroy_SET(SELF);
+ PObj_custom_mark_SET(SELF);
+
+ if (!PMC_IS_NULL(old_ctx)) {
+ Parrot_Context_attributes * const old = PARROT_CONTEXT(old_ctx);
+ /* some items should better be COW copied */
+ ctx->constants = old->constants;
+ ctx->warns = old->warns;
+ ctx->errors = old->errors;
+ ctx->trace_flags = old->trace_flags;
+ ctx->pred_offset = old->pred_offset;
+ ctx->current_HLL = old->current_HLL;
+ ctx->current_namespace = old->current_namespace;
+ /* end COW */
+ ctx->recursion_depth = old->recursion_depth;
+ }
+ else {
+ ctx->constants = NULL;
+ ctx->warns = 0;
+ ctx->errors = 0;
+ ctx->trace_flags = 0;
+ ctx->pred_offset = 0;
+ ctx->current_HLL = 0;
+ ctx->recursion_depth = 0;
+ }
+ clear_regs(interp, ctx);
+ }
+
+ VTABLE void mark() {
+ Parrot_Context_attributes * const data = PARROT_CONTEXT(SELF);
+ if (data) {
+ if (data->caller_ctx)
+ Parrot_gc_mark_PObj_alive(interp, data->caller_ctx);
+ if (data->lex_pad)
+ Parrot_gc_mark_PObj_alive(interp, data->lex_pad);
+ if (data->outer_ctx)
+ Parrot_gc_mark_PObj_alive(interp, data->outer_ctx);
+ if (data->handlers)
+ Parrot_gc_mark_PObj_alive(interp, data->handlers);
+ if (data->current_sub)
+ Parrot_gc_mark_PObj_alive(interp, data->current_sub);
+ if (data->current_cont)
+ Parrot_gc_mark_PObj_alive(interp, data->current_cont);
+ if (data->current_object)
+ Parrot_gc_mark_PObj_alive(interp, data->current_object);
+ if (data->current_namespace)
+ Parrot_gc_mark_PObj_alive(interp, data->current_namespace);
+ if (data->results_signature)
+ Parrot_gc_mark_PObj_alive(interp, data->results_signature);
+ }
+ }
+
+/*
+
+=item C<void push_pmc(PMC *new)>
+
+Pushes the new context, and sets it as the current context
+
+=cut
+
+*/
+
+ VTABLE void push_pmc(PMC * new) {
+ PMC * const old = CONTEXT(interp);
+
+ PARROT_CONTEXT(SELF)->caller_ctx = old;
+
+ /* doesn't change */
+ PARROT_CONTEXT(SELF)->current_sub = PARROT_CONTEXT(old)->current_sub;
+ }
+
+/*
+
+=item C<PMC * pop_pmc()>
+
+Pops SELF off the context list, and sets it's immediate parent as the
+current context
+
+*/
+
+ VTABLE PMC * pop_pmc() {
+ PMC * const ctx = CONTEXT(interp);
+ PMC * const old = ctx->caller_ctx;
+
+ /* restore old, set cached interpreter base pointers */
+ CONTEXT(interp) = old;
+ interp->ctx.bp = old->bp;
+ interp->ctx.bp_ps = old->bp_ps;
+ }
+
+ VTABLE void set_integer_native(INTVAL val) {
+ INTVAL i;
+ INTVAL num_ints = PARROT_CONTEXT(SELF)->n_regs_used[REGNO_INT];
+ for (i = 0; i < num_ints; ++i)
+ VTABLE_set_integer_keyed_int(INTERP, SELF, i, val);
+ }
+
+ VTABLE void set_number_native(FLOATVAL val) {
+ INTVAL i;
+ INTVAL num_nums = PARROT_CONTEXT(SELF)->n_regs_used[REGNO_NUM];
+ for (i = 0; i < num_nums; ++i)
+ VTABLE_set_number_keyed_int(INTERP, SELF, i, val);
+ }
+
+ VTABLE void set_pmc(PMC * val) {
+ INTVAL i;
+ INTVAL num_pmcs = PARROT_CONTEXT(SELF)->n_regs_used[REGNO_PMC];
+ for (i = 0; i < num_nums; ++i)
+ VTABLE_set_pmc_keyed_int(INTERP, SELF, i, val);
+ }
+
+ VTABLE void set_string_native(STRING * val) {
+ INTVAL i;
+ INTVAL num_strs = PARROT_CONTEXT(SELF)->n_regs_used[REGNO_STR];
+ for (i = 0; i < num_strs; ++i)
+ VTABLE_set_string_keyed_int(INTERP, SELF, i, val);
+ }
+
+
+
+ VTABLE void set_pointer(void *number_regs_used) {
+ Parrot_Context_attributes * const ctx = PARROT_CONTEXT(SELF);
+ const size_t size_i = sizeof (INTVAL) * number_regs_used[REGNO_INT];
+ const size_t size_n = sizeof (FLOATVAL) * number_regs_used[REGNO_NUM];
+ const size_t size_s = sizeof (STRING *) * number_regs_used[REGNO_STR];
+ const size_t size_p = sizeof (PMC *) * number_regs_used[REGNO_PMC];
+
+ 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);
+
+ 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];
+
+ ctx->regs_mem_size = reg_alloc;
+ ctx->regs = (void *)mem_sys_allocate(reg_alloc);
+
+ /* ctx.bp points to I0, which has Nx on the left */
+ ctx->bp.regs_i = (INTVAL *)((char *)ctx->regs + size_n);
+ /* ctx.bp_ps points to S0, which has Px on the left */
+ ctx->bp_ps.regs_s = (STRING **)((char *)ctx_regs + size_nip);
+ }
+
+ VTABLE void destroy() {
+ Parrot_Context_attributes * const data = PARROT_CONTEXT(SELF);
+ if (data) {
+ if (data->regs)
+ mem_sys_free(data->regs);
+ mem_sys_free(data);
+ }
+ }
}
/*
Modified: branches/context_pmc/src/pmc/continuation.pmc
==============================================================================
--- branches/context_pmc/src/pmc/continuation.pmc Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/pmc/continuation.pmc Sat Jun 27 19:39:09 2009 (r39810)
@@ -23,6 +23,7 @@
#include "parrot/oplib/ops.h"
#include "pmc_sub.h"
+#include "pmc_context.h"
/*
@@ -228,8 +229,8 @@
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;
+ PMC *from_ctx = CONTEXT(interp);
+ PMC *to_ctx = cc->to_ctx;
opcode_t *pc = cc->address;
UNUSED(next)
@@ -249,7 +250,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_CONTEXT(to_ctx)->current_results;
interp->current_args = NULL;
Parrot_block_GC_mark(INTERP);
@@ -293,7 +294,7 @@
METHOD caller() {
Parrot_cont *cc = PMC_cont(SELF);
- PMC *caller = cc->to_ctx->current_sub;
+ PMC *caller = PARROT_CONTEXT(cc->to_ctx)->current_sub;
Parrot_sub *sub;
PMC_get_sub(INTERP, caller, sub);
@@ -315,7 +316,7 @@
METHOD continuation() {
Parrot_cont *cc = PMC_cont(SELF);
- PMC *cont = cc->to_ctx->current_cont;
+ PMC *cont = PARROT_CONTEXT(cc->to_ctx)->current_cont;
if (cont)
RETURN(PMC *cont);
Modified: branches/context_pmc/src/pmc/exception.pmc
==============================================================================
--- branches/context_pmc/src/pmc/exception.pmc Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/pmc/exception.pmc Sat Jun 27 19:39:09 2009 (r39810)
@@ -51,6 +51,7 @@
#include "parrot/exceptions.h"
#include "pmc_sub.h"
+#include "pmc_context.h"
pmclass Exception {
@@ -65,8 +66,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. */
/*
@@ -99,6 +100,8 @@
core_struct->resume = PMCNULL;
core_struct->backtrace = PMCNULL;
core_struct->handler_iter = PMCNULL;
+ core_struct->handler_ctx = PMCNULL;
+ core_struct->thrower = PMCNULL;
}
/*
@@ -161,6 +164,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);
+ 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);
}
/*
@@ -175,8 +182,6 @@
VTABLE void destroy() {
Parrot_Exception_attributes * const core_struct = PARROT_EXCEPTION(SELF);
- if (core_struct->thrower)
- Parrot_free_context(interp, core_struct->thrower, 1);
if (core_struct)
mem_sys_free(core_struct);
}
@@ -495,11 +500,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;
}
/*
@@ -661,11 +662,9 @@
/* 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 (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);
- }
}
}
else {
@@ -761,7 +760,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. */
@@ -800,7 +799,7 @@
PackFile_ByteCode *seg = sub->seg;
opcode_t *pc = cont && cur_ctx == cont->to_ctx
? cont->address
- : cur_ctx->current_pc;
+ : PARROT_CONTEXT(cur_ctx)->current_pc;
annotations = PackFile_Annotations_lookup(interp,
seg->annotations, pc - seg->base.data,
@@ -815,7 +814,7 @@
/* Push frame and go to next caller. */
VTABLE_push_pmc(interp, result, frame);
- cur_ctx = cur_ctx->caller_ctx;
+ cur_ctx = PARROT_CONTEXT(cur_ctx)->caller_ctx;
}
}
Modified: branches/context_pmc/src/pmc/lexpad.pmc
==============================================================================
--- branches/context_pmc/src/pmc/lexpad.pmc Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/pmc/lexpad.pmc Sat Jun 27 19:39:09 2009 (r39810)
@@ -27,8 +27,8 @@
*/
pmclass LexPad provides hash no_ro {
- 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,8 @@
mem_allocate_zeroed_typed(Parrot_LexPad_attributes);
PObj_active_destroy_SET(SELF);
-
+ PObj_custom_mark_SET(SELF);
+ attrs->ctx = PMCNULL;
attrs->lexinfo = lexinfo;
PMC_data(SELF) = attrs;
}
@@ -91,8 +92,16 @@
mem_sys_free(PMC_data(SELF));
}
+ VTABLE void mark() {
+ Parrot_LexPad_attributes * const data = PARROT_LEXPAD(SELF);
+ if (data) {
+ if (data->ctx)
+ Parrot_gc_mark_PObj_alive(INTERP, (PObj *)data->ctx);
+ }
+ }
+
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() {
@@ -117,7 +126,7 @@
VTABLE PMC *get_pmc_keyed_str(STRING *name) {
PMC * info;
Hash * hash;
- Parrot_Context * ctx;
+ PMC * ctx;
HashBucket * b;
INTVAL regno;
@@ -142,7 +151,7 @@
VTABLE void set_pmc_keyed_str(STRING *name, PMC *value) {
PMC * info;
Hash * hash;
- Parrot_Context * ctx;
+ PMC * ctx;
HashBucket * b;
INTVAL regno;
@@ -169,6 +178,12 @@
GET_ATTR_lexinfo(INTERP, SELF, lexinfo);
RETURN(PMC *lexinfo);
}
+
+ METHOD get_context() {
+ PMC * ctx;
+ GET_ATTR_ctx(INTERP, SELF, ctx);
+ RETURN(PMC *ctx);
+ }
}
Modified: branches/context_pmc/src/pmc/parrotinterpreter.pmc
==============================================================================
--- branches/context_pmc/src/pmc/parrotinterpreter.pmc Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/pmc/parrotinterpreter.pmc Sat Jun 27 19:39:09 2009 (r39810)
@@ -442,7 +442,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;
@@ -474,15 +474,15 @@
if (outer) {
for (; level; --level) {
- ctx = ctx->outer_ctx;
- if (!ctx)
+ ctx = PARROT_CONTEXT(ctx)->outer_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_CONTEXT(ctx)->current_cont;
if (PMC_IS_NULL(cont) || !PMC_cont(cont)->seg)
Parrot_ex_throw_from_c_args(interp, NULL,
@@ -497,45 +497,44 @@
}
if (item == outer)
- return ctx->current_sub;
+ return PARROT_CONTEXT(ctx)->current_sub;
s = CONST_STRING(interp, "sub");
if (Parrot_str_equal(interp, item, s))
- return ctx->current_sub;
+ return PARROT_CONTEXT(ctx)->current_sub;
s = CONST_STRING(interp, "lexpad");
if (Parrot_str_equal(interp, item, s))
- return ctx->lex_pad;
+ return PARROT_CONTEXT(ctx)->lex_pad;
s = CONST_STRING(interp, "namespace");
if (Parrot_str_equal(interp, item, s))
- return ctx->current_namespace;
+ return PARROT_CONTEXT(ctx)->current_namespace;
s = CONST_STRING(interp, "continuation");
if (Parrot_str_equal(interp, item, s))
- return VTABLE_clone(interp, ctx->current_cont);
+ return VTABLE_clone(interp, PARROT_CONTEXT(ctx)->current_cont);
s = CONST_STRING(interp, "annotations");
if (Parrot_str_equal(interp, item, s)) {
Parrot_sub *sub;
- PMC *sub_pmc = ctx->current_sub;
+ PMC *sub_pmc = PARROT_CONTEXT(ctx)->current_sub;
PMC_get_sub(interp, sub_pmc, sub);
if (ctx == 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 &&
sub->seg->annotations) {
PackFile_ByteCode *seg = sub->seg;
- opcode_t *pc = ctx->current_pc;
+ opcode_t *pc = PARROT_CONTEXT(ctx)->current_pc;
return PackFile_Annotations_lookup(interp, seg->annotations,
pc - seg->base.data, NULL);
}
Modified: branches/context_pmc/src/pmc/sub.pmc
==============================================================================
--- branches/context_pmc/src/pmc/sub.pmc Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/pmc/sub.pmc Sat Jun 27 19:39:09 2009 (r39810)
@@ -92,11 +92,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);
-
mem_sys_free(sub);
}
@@ -220,9 +215,9 @@
VTABLE opcode_t *invoke(void *next) {
Parrot_sub *sub;
- Parrot_Context *caller_ctx;
- Parrot_Context *context;
- Parrot_Context *c;
+ PMC *caller_ctx;
+ PMC *context;
+ PMC *c;
PMC *ccont;
opcode_t *pc;
@@ -264,14 +259,15 @@
/* 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;
+ context = pmc_new(INTERP, enum_class_Context);
+ VTABLE_set_pointer(INTERP, context, sub->n_regs_used);
+ PARROT_CONTEXT(context)->current_sub = SELF;
+ PARROT_CONTEXT(context)->caller_ctx = caller_ctx;
+ PARROT_CONTEXT(context)->current_pc = pc;
+ PARROT_CONTEXT(context)->current_cont = ccont;
/* check recursion/call depth */
- if (++context->recursion_depth > INTERP->recursion_limit)
+ if (++PARROT_CONTEXT(context)->recursion_depth > INTERP->recursion_limit)
Parrot_ex_throw_from_c_args(INTERP, next, CONTROL_ERROR,
"maximum recursion depth exceeded");
@@ -283,9 +279,7 @@
* 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];
}
@@ -314,7 +308,7 @@
if (sub->outer_ctx) {
/* set outer context */
- context->outer_ctx = Parrot_context_ref(interp, sub->outer_ctx);
+ context->outer_ctx = sub->outer_ctx;
}
else {
/* autoclose */
@@ -332,25 +326,24 @@
PMC_get_sub(INTERP, outer_pmc, outer_sub);
if (!outer_sub->ctx) {
- Parrot_Context * const dummy = Parrot_alloc_context(INTERP,
- outer_sub->n_regs_used, NULL);
- dummy->current_sub = outer_pmc;
+ PMC * const dummy = pmc_new(INTERP, enum_class_Context);
+ VTABLE_set_pointer(INTERP, dummy, outer_sub->n_regs_used);
+ PARROT_CONTEXT(dummy)->current_sub = outer_pmc;
if (!PMC_IS_NULL(outer_sub->lex_info)) {
- dummy->lex_pad = pmc_new_init(INTERP,
+ PARROT_CONTEXT(dummy)->lex_pad = 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);
+ VTABLE_set_pointer(INTERP, PARROT_CONTEXT(dummy)->lex_pad, dummy);
}
if (outer_sub->outer_ctx) {
- dummy->outer_ctx = Parrot_context_ref(interp,
- outer_sub->outer_ctx);
+ dummy->outer_ctx = outer_sub->outer_ctx);
}
- outer_sub->ctx = Parrot_context_ref(interp, dummy);
+ outer_sub->ctx = dummy;
}
- c->outer_ctx = Parrot_context_ref(interp, outer_sub->ctx);
+ c->outer_ctx = outer_sub->ctx;
}
}
@@ -367,9 +360,7 @@
--context->recursion_depth;
PObj_get_FLAGS(ccont) &= ~SUB_FLAG_TAILCALL;
- context->caller_ctx = caller_ctx->caller_ctx;
-
- Parrot_free_context(INTERP, caller_ctx, 1);
+ context->caller_ctx = PARROT_CONTEXT(caller_ctx)->caller_ctx;
}
}
@@ -395,13 +386,6 @@
PObj_custom_mark_destroy_SETALL(ret);
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);
-
PMC_get_sub(INTERP, SELF, dest_sub);
/* first set the sub struct, Parrot_str_copy may cause GC */
@@ -413,12 +397,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;
}
@@ -444,15 +422,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));
@@ -502,9 +471,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);
}
/*
Modified: branches/context_pmc/src/scheduler.c
==============================================================================
--- branches/context_pmc/src/scheduler.c Sat Jun 27 19:09:28 2009 (r39809)
+++ branches/context_pmc/src/scheduler.c Sat Jun 27 19:39:09 2009 (r39810)
@@ -22,6 +22,7 @@
#include "pmc/pmc_scheduler.h"
#include "pmc/pmc_task.h"
#include "pmc/pmc_timer.h"
+#include "pmc/pmc_context.h"
#include "scheduler.str"
@@ -849,9 +850,9 @@
* for a handler
*/
static int already_doing = 0;
- static Parrot_Context * keep_context = NULL;
+ 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");
@@ -859,16 +860,16 @@
if (already_doing) {
Parrot_io_eprintf(interp,
"** Exception caught while looking for a handler, trying next **\n");
- if (! keep_context)
+ if (PMC_IS_NULL(keep_context))
return NULL;
/*
* Note that we are now trying to handle the new exception,
* not the initial task argument (exception or whatever).
*/
- context = keep_context->caller_ctx;
- keep_context = NULL;
- if (context && !PMC_IS_NULL(context->handlers))
- iter = VTABLE_get_iter(interp, context->handlers);
+ context = PARROT_CONTEXT(keep_context)->caller_ctx;
+ keep_context = PMCNULL;
+ if (!PMC_IS_NULL(context) && !PMC_IS_NULL(PARROT_CONTEXT(context)->handlers))
+ iter = VTABLE_get_iter(interp, PARROT_CONTEXT(context)->handlers);
else
iter = PMCNULL;
}
@@ -881,12 +882,12 @@
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);
+ context = VTABLE_get_pointer(interp, task);
}
else {
context = CONTEXT(interp);
- if (!PMC_IS_NULL(context->handlers))
- iter = VTABLE_get_iter(interp, context->handlers);
+ if (!PMC_IS_NULL(PARROT_CONTEXT(context)->handlers))
+ iter = VTABLE_get_iter(interp, PARROT_CONTEXT(context)->handlers);
}
}
@@ -916,9 +917,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_CONTEXT(context)->caller_ctx;
+ if (context && !PMC_IS_NULL(PARROT_CONTEXT(context)->handlers))
+ iter = VTABLE_get_iter(interp, PARROT_CONTEXT(context)->handlers);
else
iter = PMCNULL;
}
More information about the parrot-commits
mailing list