Ticket #1427: retcon.diff
File retcon.diff, 15.9 KB (added by coke, 12 years ago) |
---|
-
src/ops/core.ops
746 746 PMC * except = $1; 747 747 opcode_t *dest; 748 748 opcode_t * const ret = expr NEXT(); 749 PMC * const resume = new_ret_continuation_pmc(interp, ret);749 PMC * const resume = pmc_new(interp, enum_class_Continuation); 750 750 751 VTABLE_set_pointer(interp, resume, ret); 752 751 753 if (PMC_IS_NULL(except) || except->vtable->base_type != enum_class_Exception) 752 754 except = Parrot_ex_build_exception(interp, EXCEPT_fatal, 753 755 EXCEPTION_UNIMPLEMENTED, … … 792 794 inline op die(in STR) :flow { 793 795 opcode_t *dest; 794 796 opcode_t * const ret = expr NEXT(); 795 PMC * const resume = new_ret_continuation_pmc(interp, ret);797 PMC * const resume = pmc_new(interp, enum_class_Continuation); 796 798 PMC * const exception = Parrot_ex_build_exception(interp, EXCEPT_error, 797 799 CONTROL_ERROR, $1); 798 800 801 VTABLE_set_pointer(interp, resume, ret); 802 799 803 VTABLE_set_attr_str(interp, exception, 800 804 Parrot_str_new_constant(interp, "resume"), resume); 801 805 dest = Parrot_ex_throw_from_op(interp, exception, ret); … … 805 809 inline op die(in PMC) :flow { 806 810 opcode_t *dest; 807 811 opcode_t * const ret = expr NEXT(); 808 PMC * const resume = new_ret_continuation_pmc(interp, ret);812 PMC * const resume = pmc_new(interp, enum_class_Continuation); 809 813 STRING * const msg = PMC_IS_NULL($1) ? NULL : VTABLE_get_string(interp, $1); 810 814 PMC * const exception = 811 815 Parrot_ex_build_exception(interp, EXCEPT_error, CONTROL_ERROR, msg); 812 816 817 VTABLE_set_pointer(interp, resume, ret); 818 813 819 VTABLE_set_attr_str(interp, exception, 814 820 Parrot_str_new_constant(interp, "resume"), resume); 815 821 dest = Parrot_ex_throw_from_op(interp, exception, ret); … … 831 837 inline op exit(in INT) :flow { 832 838 opcode_t *dest; 833 839 opcode_t * const ret = expr NEXT(); 834 PMC * const resume = new_ret_continuation_pmc(interp, ret);840 PMC * const resume = pmc_new(interp, enum_class_Continuation); 835 841 PMC * const exception = Parrot_ex_build_exception(interp, EXCEPT_exit, $1, NULL); 836 842 843 VTABLE_set_pointer(interp, resume, ret); 844 837 845 VTABLE_set_attr_str(interp, exception, 838 846 Parrot_str_new_constant(interp, "resume"), resume); 839 847 VTABLE_set_integer_keyed_str(interp, exception, -
src/pmc/retcontinuation.pmc
1 /*2 Copyright (C) 2001-2008, Parrot Foundation.3 $Id$4 5 =head1 NAME6 7 src/pmc/retcontinuation.pmc - Return Continuation8 9 =head1 DESCRIPTION10 11 C<RetContinuation> extends C<Continuation>.12 13 A return continuation is a one shot Continuation. It gets recycled immediately14 after invocation.15 16 =head2 Methods17 18 =over 419 20 =cut21 22 */23 24 #include "parrot/oplib/ops.h"25 26 /* HEADERIZER HFILE: none */27 /* HEADERIZER BEGIN: static */28 /* HEADERIZER END: static */29 30 pmclass RetContinuation extends Continuation auto_attrs {31 32 /*33 34 =item C<void init()>35 36 Initializes the continuation.37 38 =cut39 40 */41 42 VTABLE void init() {43 Parrot_RetContinuation_attributes * const attrs = PARROT_RETCONTINUATION(SELF);44 45 attrs->to_ctx = CURRENT_CONTEXT(interp);46 attrs->from_ctx = PMCNULL; /* filled in during a call */47 attrs->runloop_id = 0;48 attrs->seg = interp->code;49 attrs->address = NULL;50 }51 52 53 /*54 55 =item C<PMC *clone>56 57 Return a new Continuation PMC with the context of SELF. Note: the returned58 object is not a RetContinuation and creating a real Continuation invalidates59 all RetContinuation all the way up the call chain. That is, these can't be60 recycled; they persist until the GC gets at them.61 62 =cut63 64 */65 VTABLE PMC *clone() {66 invalidate_retc_context(INTERP, SELF);67 return SUPER();68 }69 /*70 71 =item C<opcode_t *invoke(void *next)>72 73 Transfers control to the calling context and frees the current context.74 75 =cut76 77 */78 79 VTABLE opcode_t *invoke(void *in_next) {80 Parrot_Continuation_attributes *data = PARROT_CONTINUATION(SELF);81 PMC *from_ctx = data->from_ctx;82 PackFile_ByteCode * const seg = data->seg;83 opcode_t *next = data->address;84 UNUSED(in_next)85 86 Parrot_continuation_check(interp, SELF);87 Parrot_continuation_rewind_environment(interp, SELF);88 89 /* recycle this PMC and make sure it doesn't get marked */90 if (!PMC_IS_NULL(from_ctx))91 Parrot_pcc_set_continuation(interp, from_ctx, NULL);92 93 if (INTERP->code != seg)94 Parrot_switch_to_cs(INTERP, seg, 1);95 96 return next;97 }98 }99 100 101 /*102 103 =back104 105 =head1 HISTORY106 107 Initial revision by sean 2002/08/04.108 109 =cut110 111 */112 113 /*114 * Local variables:115 * c-file-style: "parrot"116 * End:117 * vim: expandtab shiftwidth=4:118 */ -
src/pmc/coroutine.pmc
172 172 PMC *ctx = Parrot_pcc_get_signature(INTERP, caller_ctx); 173 173 PMC *ccont = INTERP->current_cont; 174 174 175 if (ccont == NEED_CONTINUATION) 176 ccont = (PMC *)new_ret_continuation_pmc(INTERP, next_op); 175 if (ccont == NEED_CONTINUATION) { 176 ccont = pmc_new(interp, enum_class_Continuation); 177 VTABLE_set_pointer(interp, ccont, next_op); 178 } 177 179 178 180 if (PObj_get_FLAGS(ccont) & SUB_FLAG_TAILCALL) 179 181 Parrot_ex_throw_from_c_args(INTERP, NULL, CONTROL_ERROR, -
src/pmc/continuation.pmc
78 78 SET_ATTR_address(INTERP, SELF, NULL); 79 79 80 80 PObj_custom_mark_SET(SELF); 81 82 /* PANIC("don't do that"); */83 /*84 * Whenever we create a continuation, all return continuations85 * up the call chain may be reused due to invoking the86 * continuation. To avoid that all return continuations are87 * converted to true continuations.88 */89 invalidate_retc_context(INTERP, SELF);90 81 } 91 82 92 83 /*if they pass in a PMC to initialize with*/ … … 109 100 SET_ATTR_address(INTERP, SELF, address); 110 101 111 102 PObj_custom_mark_SET(SELF); 112 113 /* PANIC("don't do that"); */114 /*115 * Whenever we create a continuation, all return continuations116 * up the call chain may be reused due to invoking the117 * continuation. To avoid that all return continuations are118 * converted to true continuations.119 */120 invalidate_retc_context(INTERP, SELF);121 103 } 122 104 123 105 -
src/pmc/sub.pmc
398 398 pc = sub->seg->base.data + sub->start_offs; 399 399 INTERP->current_cont = NULL; 400 400 401 if (ccont == NEED_CONTINUATION) 402 ccont = new_ret_continuation_pmc(interp, (opcode_t *)next); 401 if (ccont == NEED_CONTINUATION) { 402 ccont = pmc_new(interp, enum_class_Continuation); 403 VTABLE_set_pointer(interp, ccont, next); 404 } 403 405 404 406 PARROT_ASSERT(!PMC_IS_NULL(ccont)); 405 407 … … 427 429 PARROT_CONTINUATION(ccont)->from_ctx = context; 428 430 429 431 /* if this is an outer sub, then we need to set sub->ctx 430 * to the new context (refcounted) and convert the 431 * retcontinuation to a normal continuation. */ 432 * to the new context (refcounted) */ 432 433 if (PObj_get_FLAGS(SELF) & SUB_FLAG_IS_OUTER) { 433 434 sub->ctx = context; 434 /* convert retcontinuation to a continuation */435 ccont->vtable = interp->vtables[enum_class_Continuation];436 435 } 437 436 438 437 /* create pad if needed -
src/interp/inter_misc.c
283 283 case CURRENT_CONT: 284 284 { 285 285 PMC * const cont = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp)); 286 if (!PMC_IS_NULL(cont) && cont->vtable->base_type ==287 enum_class_RetContinuation)288 return VTABLE_clone(interp, cont);289 286 return cont; 290 287 } 291 288 case CURRENT_OBJECT: -
src/sub.c
49 49 50 50 /* 51 51 52 =item C<PMC * new_ret_continuation_pmc(PARROT_INTERP, opcode_t *address)>53 54 Returns a new C<RetContinuation> PMC, and sets address field to C<address>55 56 =cut57 58 */59 60 PARROT_EXPORT61 PARROT_MALLOC62 PARROT_CANNOT_RETURN_NULL63 PMC *64 new_ret_continuation_pmc(PARROT_INTERP, ARGIN_NULLOK(opcode_t *address))65 {66 ASSERT_ARGS(new_ret_continuation_pmc)67 PMC* const continuation = Parrot_pmc_new(interp, enum_class_RetContinuation);68 VTABLE_set_pointer(interp, continuation, address);69 return continuation;70 }71 72 /*73 74 =item C<void invalidate_retc_context(PARROT_INTERP, PMC *cont)>75 76 Make true Continuations from all RetContinuations up the call chain.77 78 =cut79 80 */81 82 void83 invalidate_retc_context(PARROT_INTERP, ARGMOD(PMC *cont))84 {85 ASSERT_ARGS(invalidate_retc_context)86 87 PMC *ctx = PARROT_CONTINUATION(cont)->from_ctx;88 cont = Parrot_pcc_get_continuation(interp, ctx);89 90 while (1) {91 /*92 * We stop if we encounter a true continuation, because93 * if one were created, everything up the chain would have been94 * invalidated earlier.95 */96 if (!cont || cont->vtable != interp->vtables[enum_class_RetContinuation])97 break;98 cont->vtable = interp->vtables[enum_class_Continuation];99 ctx = Parrot_pcc_get_caller_ctx(interp, ctx);100 cont = Parrot_pcc_get_continuation(interp, ctx);101 }102 }103 104 /*105 106 52 =item C<STRING* Parrot_full_sub_name(PARROT_INTERP, PMC* sub_pmc)> 107 53 108 54 Return namespace, name, and location of subroutine. -
src/call/pcc.c
340 340 opcode_t *dest; 341 341 UINTVAL n_regs_used[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 342 342 PMC *ctx = Parrot_push_context(interp, n_regs_used); 343 PMC * const ret_cont = new_ret_continuation_pmc(interp, NULL);343 PMC * const ret_cont = pmc_new(interp, enum_class_Continuation); 344 344 345 345 Parrot_pcc_set_signature(interp, ctx, call_object); 346 346 Parrot_pcc_set_continuation(interp, ctx, ret_cont); -
MANIFEST
1 1 # ex: set ro: 2 2 # $Id$ 3 3 # 4 # generated by tools/dev/mk_manifest_and_skip.pl Tue Apr 20 2 0:11:262010 UT4 # generated by tools/dev/mk_manifest_and_skip.pl Tue Apr 20 23:21:11 2010 UT 5 5 # 6 6 # See below for documentation on the format of this file. 7 7 # … … 1465 1465 src/pmc/resizableintegerarray.pmc [] 1466 1466 src/pmc/resizablepmcarray.pmc [] 1467 1467 src/pmc/resizablestringarray.pmc [] 1468 src/pmc/retcontinuation.pmc []1469 1468 src/pmc/role.pmc [] 1470 1469 src/pmc/scalar.pmc [] 1471 1470 src/pmc/scheduler.pmc [] … … 1948 1947 t/pmc/resizableintegerarray.t [test] 1949 1948 t/pmc/resizablepmcarray.t [test] 1950 1949 t/pmc/resizablestringarray.t [test] 1951 t/pmc/retcontinuation.t [test]1952 1950 t/pmc/ro.t [test] 1953 1951 t/pmc/role.t [test] 1954 1952 t/pmc/scalar.t [test] -
include/parrot/sub.h
172 172 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 173 173 174 174 PARROT_EXPORT 175 PARROT_MALLOC176 PARROT_CANNOT_RETURN_NULL177 PMC * new_ret_continuation_pmc(PARROT_INTERP,178 ARGIN_NULLOK(opcode_t *address))179 __attribute__nonnull__(1);180 181 PARROT_EXPORT182 175 void Parrot_capture_lex(PARROT_INTERP, ARGMOD(PMC *sub_pmc)) 183 176 __attribute__nonnull__(1) 184 177 __attribute__nonnull__(2) … … 219 212 __attribute__nonnull__(1) 220 213 __attribute__nonnull__(2); 221 214 222 void invalidate_retc_context(PARROT_INTERP, ARGMOD(PMC *cont))223 __attribute__nonnull__(1)224 __attribute__nonnull__(2)225 FUNC_MODIFIES(*cont);226 227 215 void mark_context_start(void); 228 216 void Parrot_continuation_check(PARROT_INTERP, ARGIN(const PMC *pmc)) 229 217 __attribute__nonnull__(1) … … 262 250 ARGIN_NULLOK(opcode_t *pc)) 263 251 __attribute__nonnull__(1); 264 252 265 #define ASSERT_ARGS_new_ret_continuation_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\266 PARROT_ASSERT_ARG(interp))267 253 #define ASSERT_ARGS_Parrot_capture_lex __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 268 254 PARROT_ASSERT_ARG(interp) \ 269 255 , PARROT_ASSERT_ARG(sub_pmc)) … … 283 269 #define ASSERT_ARGS_parrot_new_closure __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 284 270 PARROT_ASSERT_ARG(interp) \ 285 271 , PARROT_ASSERT_ARG(sub_pmc)) 286 #define ASSERT_ARGS_invalidate_retc_context __attribute__unused__ int _ASSERT_ARGS_CHECK = (\287 PARROT_ASSERT_ARG(interp) \288 , PARROT_ASSERT_ARG(cont))289 272 #define ASSERT_ARGS_mark_context_start __attribute__unused__ int _ASSERT_ARGS_CHECK = (0) 290 273 #define ASSERT_ARGS_Parrot_continuation_check __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 291 274 PARROT_ASSERT_ARG(interp) \ -
t/pmc/retcontinuation.t
1 #! parrot2 # Copyright (C) 2006-2008, Parrot Foundation.3 # $Id$4 5 =head1 NAME6 7 t/pmc/retcontinuation.t - test the RetContinuation PMC8 9 =head1 SYNOPSIS10 11 % prove t/pmc/retcontinuation.t12 13 =head1 DESCRIPTION14 15 Tests the RetContinuation PMC.16 17 =cut18 19 .sub main :main20 .include 'test_more.pir'21 22 plan(1)23 24 new $P0, ['RetContinuation']25 ok(1, 'Instantiated a RetContinuation PMC')26 .end27 28 # Local Variables:29 # mode: pir30 # fill-column: 10031 # End:32 # vim: expandtab shiftwidth=4 ft=pir: -
t/op/gc.t
508 508 509 509 # coro context and invalid return continuations 510 510 # this is a stripped down version of imcc/t/syn/pcc_16 511 # s. also src/pmc/retcontinuation.pmc512 511 513 512 .sub coro_context_ret_continuation 514 513 .const 'Sub' $P0 = "co1" -
PBC_COMPAT
27 27 28 28 # please insert tab separated entries at the top of the list 29 29 30 6.6 2010.04.20 coke remove retcontinuation PMC 30 31 6.5 2010.03.09 cotto remove cpu_ret op 31 32 6.4 2010.03.02 cotto remove prederef__ and reserved 32 33 6.3 2010.02.16 whiteknight Add OpLib and Opcode PMCs