# New Ticket Created by "Alek Storm" # Please include the string: [perl #42155] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=42155 >
This patch moves args_signature, params_signature, returns_signature, current_args, current_params, and current_returns from Parrot_Interp to Parrot_Context. This makes the interpreter more reentrant, which is always a good thing. Since these variables are no longer global, we need to keep track of who belongs to whom. In a sub call, current_args and current_results are set for the caller, while current_params and current_returns are set for the callee. The same goes for *_signature, mutatis mutandis (an excuse to use Latin! yes!). This patch seems to break some tests in t/dynoplibs, and I have no idea why. It also *looks* like it breaks t/examples/shootout.t, but if the examples are run manually, they work fine. I am completely baffled. If anyone can solve these, they get a hug. Thanks, Alek Storm
Index: src/ops/core.ops =================================================================== --- src/ops/core.ops (revision 17785) +++ src/ops/core.ops (working copy) @@ -503,7 +503,7 @@ INTVAL argc; /* for now just point to the opcode */ - interp->current_args = this; + CONTEXT(interp->ctx)->current_args = this; argc = SIG_ELEMS(signature); goto OFFSET(argc + 2); } @@ -526,17 +526,16 @@ INTVAL argc; opcode_t *src_indexes, *dst_indexes; - interp->current_params = this; ctx = CONTEXT(interp->ctx); + ctx->current_params = this; ccont = ctx->current_cont; caller_ctx = ctx->caller_ctx; - src_indexes = interp->current_args; - dst_indexes = interp->current_params; - /* the args and params are now 'used.' */ - interp->current_args = NULL; - interp->current_params = NULL; + src_indexes = caller_ctx->current_args; + dst_indexes = ctx->current_params; + caller_ctx->current_args = NULL; + ctx->current_params = NULL; parrot_pass_args(interp, caller_ctx, ctx, src_indexes, dst_indexes, PARROT_PASS_PARAMS); if (PObj_get_FLAGS(ccont) & SUB_FLAG_TAILCALL) { @@ -546,7 +545,6 @@ /* ordinarily, this will free the context immediately, but not if the sub created a closure (or continuation, or . . .). */ Parrot_free_context(interp, caller_ctx, 0); - interp->current_args = NULL; } argc = SIG_ELEMS(signature); goto OFFSET(argc + 2); @@ -560,8 +558,8 @@ INTVAL argc; opcode_t *src_indexes, *dest_indexes; - interp->current_returns = this; ctx = CONTEXT(interp->ctx); + ctx->current_returns = this; ccont = ctx->current_cont; if (PMC_cont(ccont)->address) { @@ -573,11 +571,10 @@ internal_exception(1, "No caller_ctx for continuation %p.", ccont); } - src_indexes = interp->current_returns; + src_indexes = ctx->current_returns; dest_indexes = caller_ctx->current_results; - interp->current_returns = NULL; - /* does this need to be here */ - interp->current_args = NULL; + ctx->current_returns = NULL; + caller_ctx->current_results = NULL; parrot_pass_args(interp, ctx, caller_ctx, src_indexes, dest_indexes, PARROT_PASS_RESULTS); } Index: src/ops/experimental.ops =================================================================== --- src/ops/experimental.ops (revision 17785) +++ src/ops/experimental.ops (working copy) @@ -394,13 +394,14 @@ opcode_t* arg_op; PMC *sig, *class; int typ; + parrot_context_t *ctx = CONTEXT(interp->ctx); - arg_op = interp->current_args; + arg_op = ctx->current_args; if (!arg_op) { real_exception(interp, NULL, NULL_REG_ACCESS, "No set_args with instantiate"); } - sig = CONTEXT(interp->ctx)->constants[arg_op[1]]->u.key; + sig = ctx->constants[arg_op[1]]->u.key; ASSERT_SIG_PMC(sig); if (!SIG_ELEMS(sig)) { real_exception(interp, NULL, E_ValueError, @@ -425,7 +426,7 @@ break; } $1 = VTABLE_instantiate(interp, class, sig); - interp->current_args = NULL; + ctx->current_args = NULL; goto NEXT(); } Index: src/ops/pic.ops =================================================================== --- src/ops/pic.ops (revision 17785) +++ src/ops/pic.ops (working copy) @@ -147,7 +147,7 @@ * - yes, confusing but faster */ ctx = CONTEXT(interp->ctx); - src_pc = interp->current_args; + src_pc = ctx->current_args; mic = (Parrot_MIC *) cur_opcode[1]; caller_ctx = ctx->caller_ctx; if (src_pc) { @@ -173,7 +173,7 @@ --ctx->recursion_depth; ctx->caller_ctx = caller_ctx->caller_ctx; Parrot_free_context(interp, caller_ctx, 0); - interp->current_args = NULL; + ctx->current_args = NULL; } goto OFFSET(n); @@ -200,12 +200,12 @@ ccont = ctx->current_cont; cc = PMC_cont(ccont); if (!cc->address) { - interp->current_returns = CUR_OPCODE; + ctx->current_returns = CUR_OPCODE; n = PMC_int_val(mic->m.sig); goto OFFSET(n + 2); } caller_ctx = cc->to_ctx; - interp->current_args = NULL; + ctx->current_args = NULL; dest_pc = caller_ctx->current_results; if (dest_pc) { dest_pred = (void**) dest_pc - caller_ctx->pred_offset; Index: src/gc/register.c =================================================================== --- src/gc/register.c (revision 17785) +++ src/gc/register.c (working copy) @@ -230,27 +230,33 @@ static void init_context(Interp *interp, parrot_context_t *ctx, parrot_context_t *old) { - ctx->ref_count = 0; /* TODO 1 - Exceptions !!! */ - ctx->current_results = NULL; + ctx->ref_count = 0; /* TODO 1 - Exceptions !!! */ + ctx->current_results = NULL; + ctx->current_args = NULL; + ctx->current_params = NULL; + ctx->current_returns = NULL; ctx->results_signature = NULL; - ctx->lex_pad = PMCNULL; - ctx->outer_ctx = NULL; - ctx->current_cont = NULL; - ctx->current_object = NULL; /* XXX who clears it? */ + ctx->args_signature = NULL; + ctx->params_signature = NULL; + ctx->returns_signature = NULL; + ctx->lex_pad = PMCNULL; + ctx->outer_ctx = NULL; + ctx->current_cont = NULL; + ctx->current_object = NULL; /* XXX who clears it? */ ctx->current_HLL = 0; if (old) { /* some items should better be COW copied */ - ctx->constants = old->constants; - ctx->reg_stack = old->reg_stack; /* XXX move into interpreter? */ - ctx->user_stack = old->user_stack; /* XXX move into interpreter? */ - 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->constants = old->constants; + ctx->reg_stack = old->reg_stack; /* XXX move into interpreter? */ + ctx->user_stack = old->user_stack; /* XXX move into interpreter? */ + 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; + ctx->recursion_depth = old->recursion_depth; } /* other stuff is set inside Sub.invoke */ clear_regs(interp, ctx); Index: src/pic.c =================================================================== --- src/pic.c (revision 17785) +++ src/pic.c (working copy) @@ -436,7 +436,7 @@ } else { caller_ctx = ctx->caller_ctx; - args = interp->current_args; + args = ctx->current_args; } if (args) { const_nr = args[1]; @@ -510,7 +510,7 @@ sig_args = (PMC*)(pc[1]); ASSERT_SIG_PMC(sig_args); n = SIG_ELEMS(sig_args); - interp->current_args = (opcode_t*)pc + ctx->pred_offset; + ctx->current_args = (opcode_t*)pc + ctx->pred_offset; pc += 2 + n; op = (opcode_t*)pc + ctx->pred_offset; if (*op != PARROT_OP_set_p_pc) Index: src/inter_call.c =================================================================== --- src/inter_call.c (revision 17785) +++ src/inter_call.c (working copy) @@ -59,8 +59,9 @@ int Parrot_init_arg_nci(Interp *interp, struct call_state *st, const char *sig) { - Parrot_init_arg_op(interp, CONTEXT(interp->ctx), interp->current_args, &st->src); - Parrot_init_arg_sig(interp, CONTEXT(interp->ctx), sig, NULL, &st->dest); + parrot_context_t *ctx = CONTEXT(interp->ctx); + Parrot_init_arg_op(interp, ctx, ctx->current_args, &st->src); + Parrot_init_arg_sig(interp, ctx, sig, NULL, &st->dest); return 1; } @@ -1072,15 +1073,15 @@ PMC* dest_signature; if (param_or_result == PARROT_PASS_PARAMS) { - src_signature = interp->args_signature; - dest_signature = interp->params_signature; - interp->args_signature = NULL; - interp->params_signature = NULL; + src_signature = src_ctx->args_signature; + dest_signature = dest_ctx->params_signature; + src_ctx->args_signature = NULL; + dest_ctx->params_signature = NULL; } else /* (param_or_result == PARROT_PASS_RESULTS) */ { - src_signature = interp->returns_signature; + src_signature = src_ctx->returns_signature; dest_signature = dest_ctx->results_signature; - interp->returns_signature = NULL; + src_ctx->returns_signature = NULL; dest_ctx->results_signature = NULL; } @@ -1119,13 +1120,11 @@ int set_retval_util(Parrot_Interp interp, const char *sig, parrot_context_t *ctx, struct call_state *st) { - opcode_t *src_pc = interp->current_returns; + opcode_t *src_pc = ctx->current_returns; int todo = Parrot_init_arg_op(interp, ctx, src_pc, &st->src); - interp->current_returns = NULL; - if (todo) { - todo = Parrot_init_arg_sig(interp, CONTEXT(interp->ctx), sig, NULL, &st->dest); + todo = Parrot_init_arg_sig(interp, ctx, sig, NULL, &st->dest); if (todo) { Parrot_fetch_arg(interp, st); Parrot_convert_arg(interp, st); @@ -1448,13 +1447,13 @@ } /* code from PCCINVOKE impl in PCCMETHOD.pm */ - save_current_args = interp->current_args; - save_args_signature = interp->args_signature; + save_current_args = ctx->current_args; + save_args_signature = ctx->args_signature; save_current_object = interp->current_object; - interp->current_args = arg_indexes; - interp->args_signature = args_sig; - ctx->current_results = result_indexes; + ctx->current_args = arg_indexes; + ctx->args_signature = args_sig; + ctx->current_results = result_indexes; ctx->results_signature = results_sig; @@ -1508,8 +1507,8 @@ PObj_live_CLEAR(args_sig); PObj_live_CLEAR(results_sig); Parrot_pop_context(interp); - interp->current_args = save_current_args; - interp->args_signature = save_args_signature; + CONTEXT(interp->ctx)->current_args = save_current_args; + ctx->args_signature = save_args_signature; interp->current_object = save_current_object; } Index: src/inter_run.c =================================================================== --- src/inter_run.c (revision 17785) +++ src/inter_run.c (working copy) @@ -163,7 +163,7 @@ const char *sig_p; old_ctx = CONTEXT(interp->ctx); - interp->current_cont = new_ret_continuation_pmc(interp, NULL); + interp->current_cont = new_ret_continuation_pmc(interp, NULL); interp->current_object = obj; dest = VTABLE_invoke(interp, sub, NULL); if (!dest) @@ -319,9 +319,6 @@ * running code from event handlers isn't fully reentrant due to * these interpreter variables - mainly related to calls */ - cargs = interp->current_args; - params = interp->current_params; - returns = interp->current_returns; cont = interp->current_cont; /* what else ? */ @@ -330,9 +327,6 @@ va_end(args); retval = set_retval(interp, *sig, ctx); - interp->current_args = cargs; - interp->current_params = params; - interp->current_returns = returns; interp->current_cont = cont; return retval; } Index: src/pmc/continuation.pmc =================================================================== --- src/pmc/continuation.pmc (revision 17785) +++ src/pmc/continuation.pmc (working copy) @@ -356,7 +356,7 @@ /* where caller wants result */ to_ctx->current_results = cc->current_results; } - if (to_ctx->current_results && INTERP->current_args) { + if (to_ctx->current_results && from_ctx->current_args) { opcode_t *src_indexes, *dest_indexes; /* * the register pointer is already switched back @@ -365,9 +365,10 @@ * inside argument passing a DOD run is triggered * therefore we have to block DOD */ - src_indexes = interp->current_args; - interp->current_args = NULL; + src_indexes = from_ctx->current_args; dest_indexes = to_ctx->current_results; + from_ctx->current_args = NULL; + to_ctx->current_results = NULL; Parrot_block_DOD(INTERP); parrot_pass_args(INTERP, from_ctx, to_ctx, src_indexes, dest_indexes, @@ -376,7 +377,7 @@ } /* switch segment */ - INTERP->current_args = NULL; + from_ctx->current_args = NULL; if (INTERP->code != cc->seg) { Parrot_switch_to_cs(INTERP, cc->seg, 1); } Index: src/pmc/integer.pmc =================================================================== --- src/pmc/integer.pmc (revision 17785) +++ src/pmc/integer.pmc (working copy) @@ -90,7 +90,7 @@ INTVAL init = 0; ret->vtable = INTERP->vtables[SELF->vtable->base_type]; - arg_op = interp->current_args; + arg_op = CONTEXT(INTERP->ctx)->current_args; if (SIG_ELEMS(sig) == 2) { switch (SIG_ITEM(sig, 1)) { case PARROT_ARG_I: Index: src/jit/i386/core.jit =================================================================== --- src/jit/i386/core.jit (revision 17785) +++ src/jit/i386/core.jit (working copy) @@ -1427,7 +1427,7 @@ if (jit_info->code_type == JIT_CODE_FILE) { Parrot_jit_emit_get_INTERP(jit_info->native_ptr, emit_EAX); emitm_movl_i_m(NATIVECODE, jit_info->cur_op, emit_EAX, emit_None, 1, - offsetof(Interp, current_args)); + offsetof(parrot_context_t, current_args)); } else { jit_set_args_pc(jit_info, interp, Index: src/mmd.c =================================================================== --- src/mmd.c (revision 17785) +++ src/mmd.c (working copy) @@ -988,7 +988,7 @@ */ arg_tuple = pmc_new(interp, enum_class_ResizableIntegerArray); - args_op = interp->current_args; + args_op = CONTEXT(interp->ctx)->current_args; if (!args_op) return arg_tuple; assert(*args_op == PARROT_OP_set_args_pc); Index: lib/Parrot/Pmc2c/PCCMETHOD.pm =================================================================== --- lib/Parrot/Pmc2c/PCCMETHOD.pm (revision 17785) +++ lib/Parrot/Pmc2c/PCCMETHOD.pm (working copy) @@ -381,12 +381,12 @@ ctx->current_cont = ret_cont; - current_args = interp->current_args; - interp->current_args = NULL; + current_args = caller_ctx->current_args; + caller_ctx->current_args = NULL; $named_names - interp->params_signature = param_sig; + ctx->params_signature = param_sig; parrot_pass_args(interp, caller_ctx, ctx, current_args, param_indexes, PARROT_PASS_PARAMS); if (PObj_get_FLAGS(ccont) & SUB_FLAG_TAILCALL) { @@ -394,7 +394,6 @@ --ctx->recursion_depth; ctx->caller_ctx = caller_ctx->caller_ctx; Parrot_free_context(interp, caller_ctx, 0); - interp->current_args = NULL; } /* BEGIN PARMS SCOPE */ { @@ -422,7 +421,7 @@ internal_exception(1, "No caller_ctx for continuation \%p.", ccont); } - interp->returns_signature = return_sig; + ctx->returns_signature = return_sig; parrot_pass_args(interp, ctx, caller_ctx, return_indexes, caller_ctx->current_results, PARROT_PASS_RESULTS); } @@ -502,12 +501,12 @@ parrot_context_t *ctx = Parrot_push_context(interp, n_regs_used); PMC* pccinvoke_meth; - opcode_t* save_current_args = interp->current_args; - PMC* save_args_signature = interp->args_signature; + opcode_t* save_current_args = ctx->current_args; + PMC* save_args_signature = ctx->args_signature; PMC* save_current_object = interp->current_object; - interp->current_args = arg_indexes; - interp->args_signature = args_sig; + ctx->current_args = arg_indexes; + ctx->args_signature = args_sig; ctx->current_results = result_indexes; ctx->results_signature = results_sig; @@ -532,8 +531,8 @@ PObj_live_CLEAR(args_sig); PObj_live_CLEAR(results_sig); Parrot_pop_context(interp); - interp->current_args = save_current_args; - interp->args_signature = save_args_signature; + CONTEXT(interp->ctx)->current_args = save_current_args; + ctx->args_signature = save_args_signature; interp->current_object = save_current_object; } /*END PCCONVOKE $method_name */ Index: include/parrot/interpreter.h =================================================================== --- include/parrot/interpreter.h (revision 17785) +++ include/parrot/interpreter.h (working copy) @@ -225,8 +225,14 @@ opcode_t *current_pc; /* program counter of Sub invocation */ PMC *current_namespace; /* The namespace we're currently in */ INTVAL current_HLL; /* see also src/hll.c */ + opcode_t *current_args; /* ptr into code with set_args opcode */ + opcode_t *current_params; /* ptr into code with get_params opcode */ opcode_t *current_results; /* ptr into code with get_results opcode */ + opcode_t *current_returns; /* ptr into code with set_returns opcode */ PMC *results_signature; /* results signature pmc if it is non-const */ + PMC *args_signature; /* args signature pmc if it is non-const */ + PMC *params_signature; /* params signature pmc if it is non-const */ + PMC *returns_signature; /* returns signature pmc if it is non-const */ /* deref the constants - we need it all the time */ struct PackFile_Constant ** constants; /* code->prederefed.code - code->base.data in opcodes @@ -391,12 +397,6 @@ UINTVAL gc_generation; /* GC generation number */ - opcode_t *current_args; /* ptr into code with set_args opcode */ - opcode_t *current_params; /* ptr into code with get_params opcode */ - opcode_t *current_returns; /* ptr into code with get_returns opcode */ - PMC *args_signature; /* args signature pmc if it is non-const */ - PMC *params_signature; /* params signature pmc if it is non-const */ - PMC *returns_signature; /* returns signature pmc if it is non-const */ /* during a call sequencer the caller fills these objects * inside the invoke these get moved to the context structure */