# 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
*/