Index: parrot/classes/sub.pmc =================================================================== --- parrot.orig/classes/sub.pmc +++ parrot/classes/sub.pmc @@ -321,6 +321,7 @@ * - private5 ... @LOAD * - private6 ... @IMMEDIATE * - private7 ... @POSTCOMP + * - private8 ... fasttailcall invoked this Sub * * see also the enum in include/parrot/sub.h * @@ -525,9 +526,13 @@ if (PObj_get_FLAGS(ccont) & SUB_FLAG_TAILCALL) { PObj_get_FLAGS(ccont) &= ~SUB_FLAG_TAILCALL; assert(ccont == REG_PMC(1)); - if (INTERP->current_args) { - pc = parrot_pass_args(INTERP, sub, caller_regs, - PARROT_OP_get_params_pc); + if (PObj_get_FLAGS(ccont) & SUB_FLAG_FASTTAILCALL) { + PObj_get_FLAGS(ccont) &= ~SUB_FLAG_FASTTAILCALL; + } else { + if (INTERP->current_args) { + pc = parrot_pass_args(INTERP, sub, caller_regs, + PARROT_OP_get_params_pc); + } } goto is_tail_call; } Index: parrot/include/parrot/sub.h =================================================================== --- parrot.orig/include/parrot/sub.h +++ parrot/include/parrot/sub.h @@ -35,6 +35,8 @@ SUB_FLAG_PF_IMMEDIATE = PObj_private6_FLAG, SUB_FLAG_PF_POSTCOMP = PObj_private7_FLAG, + SUB_FLAG_FASTTAILCALL = PObj_private8_FLAG, + SUB_FLAG_PF_MASK = 0xf8 /* anon ... postcomp */ } sub_flags_enum; Index: parrot/ops/experimental.ops =================================================================== --- parrot.orig/ops/experimental.ops +++ parrot/ops/experimental.ops @@ -302,6 +302,21 @@ =back +=item B(in PMC) + +=cut + +inline op fasttailcall(in PMC) { + opcode_t *dest; + PMC * p = $1; + + dest = expr NEXT(); + REG_PMC(1) = interpreter->ctx.current_cont; + PObj_get_FLAGS(REG_PMC(1)) |= (SUB_FLAG_TAILCALL | SUB_FLAG_FASTTAILCALL); + dest = (opcode_t *)p->vtable->invoke(interpreter, p, dest); + goto ADDRESS(dest); +} + ############################################################################### =head2 Function argument opcode