Ticket #1396: tt1396.patch

File tt1396.patch, 18.2 KB (added by jimmy, 12 years ago)
  • src/pmc/continuation.pmc

     
    6464*/ 
    6565 
    6666    VTABLE void init() { 
    67         Parrot_Continuation_attributes * const attrs = PARROT_CONTINUATION(SELF); 
     67        PMC * const to_ctx = CURRENT_CONTEXT(INTERP); 
    6868 
    69         attrs->to_ctx           = CURRENT_CONTEXT(interp); 
    70         attrs->to_call_object   = Parrot_pcc_get_signature(INTERP, attrs->to_ctx); 
    71         attrs->from_ctx         = CURRENT_CONTEXT(interp); 
    72         attrs->runloop_id       = 0; 
    73         attrs->seg              = interp->code; 
    74         attrs->address          = NULL; 
     69        SET_ATTR_to_ctx(INTERP, SELF, to_ctx); 
     70        SET_ATTR_to_call_object(INTERP, SELF, Parrot_pcc_get_signature(INTERP, to_ctx)); 
     71        SET_ATTR_from_ctx(INTERP, SELF, CURRENT_CONTEXT(INTERP)); 
     72        SET_ATTR_runloop_id(INTERP, SELF, 0); 
     73        SET_ATTR_seg(INTERP, SELF, INTERP->code); 
     74        SET_ATTR_address(INTERP, SELF, NULL); 
    7575 
    7676        PObj_custom_mark_SET(SELF); 
    7777 
     
    8787 
    8888    /*if they pass in a PMC to initialize with*/ 
    8989    VTABLE void init_pmc(PMC *values) { 
    90         Parrot_Continuation_attributes * const attrs  = PARROT_CONTINUATION(SELF); 
    91         Parrot_Continuation_attributes * const theirs = PARROT_CONTINUATION(values); 
     90        PMC               *to_ctx; 
     91        opcode_t          *address; 
     92        PackFile_ByteCode *seg; 
    9293 
    93         attrs->to_ctx           = theirs->to_ctx; 
    94         attrs->to_call_object   = Parrot_pcc_get_signature(INTERP, attrs->to_ctx); 
    95         attrs->from_ctx         = CURRENT_CONTEXT(interp); 
    96         attrs->runloop_id       = 0; 
    97         attrs->seg              = theirs->seg; 
    98         attrs->address          = theirs->address; 
     94        GET_ATTR_to_ctx(INTERP, values, to_ctx); 
     95        SET_ATTR_to_ctx(INTERP, SELF, to_ctx); 
     96        SET_ATTR_to_call_object(INTERP, SELF, Parrot_pcc_get_signature(INTERP, to_ctx)); 
    9997 
     98        SET_ATTR_from_ctx(INTERP, SELF, CURRENT_CONTEXT(INTERP)); 
     99        SET_ATTR_runloop_id(INTERP, SELF, 0); 
     100 
     101        GET_ATTR_seg(INTERP, values, seg); 
     102        SET_ATTR_seg(INTERP, SELF, seg); 
     103 
     104        GET_ATTR_address(INTERP, values, address); 
     105        SET_ATTR_address(INTERP, SELF, address); 
     106 
    100107        PObj_custom_mark_SET(SELF); 
    101108 
    102109        /* PANIC("don't do that"); */ 
     
    122129*/ 
    123130 
    124131    VTABLE void mark() { 
    125         Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(SELF); 
     132        PMC *tmp; 
    126133 
    127134        /* If Continuation wasn't fully constructed yet */ 
    128         if (!cc) 
     135        if (!PMC_data(SELF)) 
    129136            return; 
    130137 
    131         Parrot_gc_mark_PMC_alive(INTERP, cc->to_ctx); 
    132         Parrot_gc_mark_PMC_alive(INTERP, cc->to_call_object); 
    133         Parrot_gc_mark_PMC_alive(INTERP, cc->from_ctx); 
     138        GET_ATTR_to_ctx(INTERP, SELF, tmp); 
     139        Parrot_gc_mark_PMC_alive(INTERP, tmp); 
     140 
     141        GET_ATTR_to_call_object(INTERP, SELF, tmp); 
     142        Parrot_gc_mark_PMC_alive(INTERP, tmp); 
     143 
     144        GET_ATTR_from_ctx(INTERP, SELF, tmp); 
     145        Parrot_gc_mark_PMC_alive(INTERP, tmp); 
    134146    } 
    135147 
    136148/* 
     
    145157 
    146158    VTABLE PMC *clone() { 
    147159        /* Start to prepare for subclassable continuations */ 
    148         INTVAL type = SELF->vtable->base_type; 
    149         PMC * ret = pmc_new_init(interp, type, SELF); 
    150         return ret; 
     160        return pmc_new_init(INTERP, SELF->vtable->base_type, SELF); 
    151161    } 
    152162 
    153163/* 
     
    160170 
    161171*/ 
    162172    VTABLE void set_pmc(PMC *src) { 
    163         Parrot_Continuation_attributes * const cc_self = PARROT_CONTINUATION(SELF); 
    164         Parrot_Continuation_attributes * const cc_src  = PARROT_CONTINUATION(src); 
    165  
    166         STRUCT_COPY(cc_self, cc_src); 
     173        STRUCT_COPY((Parrot_Continuation_attributes *)PMC_data(SELF), 
     174                (Parrot_Continuation_attributes *)PMC_data(src)); 
    167175    } 
    168176/* 
    169177 
     
    177185*/ 
    178186 
    179187    VTABLE void set_pointer(void *value) { 
    180         opcode_t                       * const pos = (opcode_t *)value; 
    181         Parrot_Continuation_attributes * const cc  = PARROT_CONTINUATION(SELF); 
    182  
    183         cc->address    = pos; 
    184         cc->runloop_id = INTERP->current_runloop_id; 
     188        SET_ATTR_address(INTERP, SELF, (opcode_t *)value); 
     189        SET_ATTR_runloop_id(INTERP, SELF, INTERP->current_runloop_id); 
    185190    } 
    186191 
    187192/* 
     
    195200*/ 
    196201 
    197202    VTABLE void *get_pointer() { 
    198         return PARROT_CONTINUATION(SELF)->address; 
     203        opcode_t          *address; 
     204 
     205        GET_ATTR_address(INTERP, SELF, address); 
     206 
     207        return address; 
    199208    } 
    200209 
    201210/* 
     
    211220*/ 
    212221 
    213222    VTABLE INTVAL defined() { 
    214         return PARROT_CONTINUATION(SELF)->address != NULL; 
     223        opcode_t          *address; 
     224 
     225        GET_ATTR_address(INTERP, SELF, address); 
     226 
     227        return address != NULL; 
    215228    } 
    216229 
    217230    VTABLE INTVAL get_bool() { 
    218         return PARROT_CONTINUATION(SELF)->address != NULL; 
     231        opcode_t          *address; 
     232 
     233        GET_ATTR_address(INTERP, SELF, address); 
     234 
     235        return address != NULL; 
    219236    } 
    220237 
    221238/* 
     
    230247*/ 
    231248 
    232249    VTABLE opcode_t *invoke(void *next) { 
    233         Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(SELF); 
    234         PMC      *from_ctx = CURRENT_CONTEXT(interp); 
    235         PMC      *to_ctx   = cc->to_ctx; 
    236         opcode_t *pc       = cc->address; 
    237         PMC      *call_obj = cc->to_call_object; 
    238         PMC      *from_obj = Parrot_pcc_get_signature(interp, from_ctx); 
     250        PMC * const        from_obj = Parrot_pcc_get_signature(INTERP, CURRENT_CONTEXT(INTERP)); 
     251        PMC               *to_ctx, *call_obj; 
     252        opcode_t          *pc; 
     253        PackFile_ByteCode *seg; 
    239254        UNUSED(next) 
    240255 
    241         Parrot_continuation_check(interp, SELF); 
    242         Parrot_continuation_rewind_environment(interp, SELF); 
     256        GET_ATTR_seg(INTERP, SELF, seg); 
     257        GET_ATTR_address(INTERP, SELF, pc); 
     258        GET_ATTR_to_ctx(INTERP, SELF, to_ctx); 
     259        GET_ATTR_to_call_object(INTERP, SELF, call_obj); 
    243260 
     261        Parrot_continuation_check(INTERP, SELF); 
     262        Parrot_continuation_rewind_environment(INTERP, SELF); 
     263 
    244264        if (!PMC_IS_NULL(from_obj)) { 
    245             STRING *string_sig = VTABLE_get_string(INTERP, from_obj); 
     265            STRING * const string_sig = VTABLE_get_string(INTERP, from_obj); 
    246266            /* If there is no string - there is no args */ 
    247267            if (string_sig) { 
    248268                PMC *raw_sig, *invalid_sig; 
     
    253273                    call_obj = Parrot_pcc_build_sig_object_returns_from_op(INTERP, call_obj, 
    254274                        Parrot_pcc_get_pmc_constant(INTERP, to_ctx, pc[1]), pc); 
    255275 
    256                 Parrot_pcc_fill_returns_from_continuation(interp, call_obj, raw_sig, from_obj); 
     276                Parrot_pcc_fill_returns_from_continuation(INTERP, call_obj, raw_sig, from_obj); 
    257277            } 
    258278        } 
    259279 
    260280        /* switch segment */ 
    261         if (INTERP->code != cc->seg) 
    262             Parrot_switch_to_cs(INTERP, cc->seg, 1); 
     281        if (INTERP->code != seg) 
     282            Parrot_switch_to_cs(INTERP, seg, 1); 
    263283 
    264284        return pc; 
    265285    } 
     
    275295*/ 
    276296 
    277297    VTABLE STRING *get_string() { 
    278         return Parrot_Context_infostr(INTERP, PARROT_CONTINUATION(SELF)->to_ctx); 
     298        PMC *to_ctx; 
     299 
     300        GET_ATTR_to_ctx(INTERP, SELF, to_ctx); 
     301 
     302        return Parrot_Context_infostr(INTERP, to_ctx); 
    279303    } 
    280304 
    281305/* 
     
    289313*/ 
    290314 
    291315    METHOD caller() { 
    292         Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(SELF); 
    293         PMC *caller = Parrot_pcc_get_sub(interp, cc->to_ctx); 
     316        PMC *to_ctx, *caller; 
    294317 
     318        GET_ATTR_to_ctx(INTERP, SELF, to_ctx); 
     319 
     320        caller = Parrot_pcc_get_sub(INTERP, to_ctx); 
     321 
    295322        if (!caller) 
    296323            caller = PMCNULL; 
    297324        else { 
     
    315342*/ 
    316343 
    317344    METHOD continuation() { 
    318         Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(SELF); 
    319         PMC * const cont = Parrot_pcc_get_continuation(interp, cc->to_ctx); 
     345        PMC *to_ctx, *cont; 
    320346 
     347        GET_ATTR_to_ctx(INTERP, SELF, to_ctx); 
     348 
     349        cont = Parrot_pcc_get_continuation(INTERP, to_ctx); 
     350 
    321351        if (cont) 
    322352            RETURN(PMC *cont); 
    323353 
  • src/pmc/coroutine.pmc

     
    3535static void 
    3636print_sub_name(PARROT_INTERP, PMC *sub_pmc) 
    3737{ 
    38     /* It's actually a Parrot_coro, but this avoids casting warnings. */ 
    39     Parrot_Sub_attributes *co = PARROT_SUB(sub_pmc); 
    40     Interp      * const tracer = (interp->pdb && interp->pdb->debugger) ? 
    41         interp->pdb->debugger : 
    42         interp; 
     38    /* It's actually a Parrot_coroutine, but this avoids casting warnings. */ 
     39    PMC           *ctx; 
     40    Interp * const tracer = (interp->pdb && interp->pdb->debugger) ? 
     41            interp->pdb->debugger : 
     42            interp; 
    4343 
    44     Parrot_io_eprintf(tracer, "# %s coro '%Ss'", 
     44    GETATTR_Coroutine_ctx(interp, sub_pmc, ctx); 
     45 
     46    Parrot_io_eprintf(tracer, "# %s coroutine '%Ss'", 
    4547        !(PObj_get_FLAGS(sub_pmc) & SUB_FLAG_CORO_FF) ? 
    4648        "Calling" : "yielding from", 
    4749        Parrot_full_sub_name(interp, sub_pmc)); 
    4850 
    49     if (co->ctx && (PObj_get_FLAGS(sub_pmc) & SUB_FLAG_CORO_FF)) { 
     51    if (ctx && (PObj_get_FLAGS(sub_pmc) & SUB_FLAG_CORO_FF)) { 
    5052        Parrot_io_eprintf(tracer, " to '%Ss'", 
    5153                Parrot_full_sub_name(interp, 
    52                     Parrot_pcc_get_sub(interp, Parrot_pcc_get_caller_ctx(interp, co->ctx)))); 
     54                    Parrot_pcc_get_sub(interp, Parrot_pcc_get_caller_ctx(interp, ctx)))); 
    5355    } 
    5456 
    5557    Parrot_io_eprintf(tracer, "\n# "); 
     
    5759} 
    5860 
    5961pmclass Coroutine extends Sub auto_attrs { 
     62    ATTR INTVAL             yield;      /* yield in process */ 
     63    ATTR opcode_t          *address;    /* next address to run - toggled each time */ 
    6064    ATTR PackFile_ByteCode *caller_seg; /* bytecode segment */ 
    61     ATTR opcode_t *address;             /* next address to run - toggled each time */ 
    62     ATTR INTVAL yield;                  /* yield in process */ 
    6365 
    6466/* 
    6567 
     
    7678*/ 
    7779 
    7880    VTABLE void init() { 
    79         Parrot_Coroutine_attributes *attrs = PARROT_COROUTINE(SELF); 
     81        SET_ATTR_seg(INTERP, SELF, INTERP->code); 
     82        SET_ATTR_ctx(INTERP, SELF, PMCNULL); 
    8083 
    81         attrs->seg = INTERP->code; 
    82         attrs->ctx = PMCNULL; 
    83  
    8484        PObj_custom_mark_destroy_SETALL(SELF); 
    8585    } 
    8686 
     
    9696*/ 
    9797 
    9898    VTABLE PMC *clone() { 
     99        STRING     *name; 
    99100        PMC * const ret = pmc_new(INTERP, SELF->vtable->base_type); 
    100         Parrot_Coroutine_attributes * const sub      = PARROT_COROUTINE(SELF); 
    101         Parrot_Coroutine_attributes * const coro_sub = PARROT_COROUTINE(ret); 
    102101 
    103102        PObj_custom_mark_destroy_SETALL(ret); 
    104103 
    105         memcpy(coro_sub, sub, sizeof (Parrot_Coroutine_attributes)); 
     104        memcpy((Parrot_Coroutine_attributes *)PMC_data(ret), 
     105                (Parrot_Coroutine_attributes *)PMC_data(SELF), 
     106                sizeof (Parrot_Coroutine_attributes)); 
    106107 
    107         coro_sub->name = Parrot_str_copy(INTERP, coro_sub->name); 
     108        GET_ATTR_name(INTERP, ret, name); 
     109        SET_ATTR_name(INTERP, ret, Parrot_str_copy(INTERP, name)); 
    108110 
    109111        return ret; 
    110112    } 
     
    134136*/ 
    135137 
    136138    VTABLE opcode_t *invoke(void *next) { 
     139        PMC               *ctx; 
     140        opcode_t          *dest; 
    137141        PackFile_ByteCode *wanted_seg; 
    138         Parrot_Coroutine_attributes * const co = PARROT_COROUTINE(SELF); 
    139         opcode_t * dest = co->address; 
    140         opcode_t * const next_op = (opcode_t *)next; 
    141  
     142        opcode_t * const   next_op = (opcode_t *)next; 
     143         
    142144        if (Interp_trace_TEST(INTERP, PARROT_TRACE_SUB_CALL_FLAG)) 
    143145            print_sub_name(INTERP, SELF); 
    144146 
    145         if (PMC_IS_NULL(co->ctx)) { 
    146             PMC * const caller_ctx = CURRENT_CONTEXT(interp); 
    147             PMC *ctx; 
    148             PMC *ccont = INTERP->current_cont; 
     147        GET_ATTR_ctx(INTERP, SELF, ctx); 
    149148 
     149        if (PMC_IS_NULL(ctx)) { 
     150            PackFile_ByteCode *seg; 
     151            size_t             start_offs; 
     152            const INTVAL      *n_regs_used; 
     153            PMC               *lex_info; 
     154            PMC * const        caller_ctx = CURRENT_CONTEXT(INTERP); 
     155            PMC               *ctx        = Parrot_pcc_get_signature(INTERP, caller_ctx); 
     156            PMC               *ccont      = INTERP->current_cont; 
     157 
    150158            if (ccont == NEED_CONTINUATION) 
    151                 ccont = (PMC *)new_ret_continuation_pmc(interp, next_op); 
     159                ccont = (PMC *)new_ret_continuation_pmc(INTERP, next_op); 
    152160 
    153161            if (PObj_get_FLAGS(ccont) & SUB_FLAG_TAILCALL) 
    154162                Parrot_ex_throw_from_c_args(INTERP, NULL, CONTROL_ERROR, 
    155                         "tail call to coro not allowed"); 
     163                        "tail call to coroutine not allowed"); 
    156164 
    157165            /* first time set current sub, cont, object */ 
    158             ctx = Parrot_pcc_get_signature(INTERP, caller_ctx); 
    159166            if (PMC_IS_NULL(ctx)) 
    160167                ctx = pmc_new(INTERP, enum_class_CallContext); 
     168 
    161169            CURRENT_CONTEXT(INTERP) = ctx; 
    162             Parrot_pcc_allocate_registers(INTERP, ctx, co->n_regs_used); 
     170 
     171            GET_ATTR_n_regs_used(INTERP, SELF, n_regs_used); 
     172            Parrot_pcc_allocate_registers(INTERP, ctx, n_regs_used); 
    163173            Parrot_pcc_set_caller_ctx(INTERP, ctx, caller_ctx); 
    164174            Parrot_pcc_init_context(INTERP, ctx, caller_ctx); 
    165175 
    166             co->ctx = ctx; 
     176            SET_ATTR_ctx(INTERP, SELF, ctx); 
    167177 
    168             PARROT_CONTINUATION(ccont)->from_ctx = ctx; 
     178            SETATTR_Continuation_from_ctx(INTERP, ccont, ctx); 
     179 
    169180            Parrot_pcc_set_sub(INTERP, ctx, SELF); 
    170181            Parrot_pcc_set_continuation(INTERP, ctx, ccont); 
    171             Parrot_pcc_set_object(interp, ctx, PMCNULL); 
     182            Parrot_pcc_set_object(INTERP, ctx, PMCNULL); 
     183 
    172184            INTERP->current_object = PMCNULL; 
    173185            INTERP->current_cont   = PMCNULL; 
    174186 
     187            GET_ATTR_lex_info(INTERP, SELF, lex_info); 
     188 
    175189            /* create pad if needed */ 
    176             if (!PMC_IS_NULL(co->lex_info)) { 
    177                 const INTVAL hlltype = Parrot_get_ctx_HLL_type(interp, enum_class_LexPad); 
    178                 PMC * const lexpad = pmc_new_init(INTERP, hlltype, co->lex_info); 
     190            if (!PMC_IS_NULL(lex_info)) { 
     191                const INTVAL hlltype = Parrot_get_ctx_HLL_type(INTERP, enum_class_LexPad); 
     192                PMC * const lexpad = pmc_new_init(INTERP, hlltype, lex_info); 
    179193                Parrot_pcc_set_lex_pad(INTERP, ctx, lexpad); 
    180194                VTABLE_set_pointer(INTERP, lexpad, ctx); 
    181195            } 
    182196 
     197            GET_ATTR_seg(INTERP, SELF, seg); 
    183198            PObj_get_FLAGS(SELF) |= SUB_FLAG_CORO_FF; 
    184             wanted_seg            = co->seg; 
    185             co->caller_seg        = INTERP->code; 
    186             co->address           = co->seg->base.data + co->start_offs; 
     199            wanted_seg            = seg; 
     200 
     201            GET_ATTR_start_offs(INTERP, SELF, start_offs); 
     202            SET_ATTR_caller_seg(INTERP, SELF, INTERP->code); 
     203            SET_ATTR_address(INTERP, SELF, seg->base.data + start_offs); 
    187204        } 
    188205 
    189206        /* if calling the Coro we need the segment of the Coro */ 
    190207        else if (!(PObj_get_FLAGS(SELF) & SUB_FLAG_CORO_FF)) { 
    191             PMC * const ctx   = co->ctx; 
    192             PMC * const ccont = Parrot_pcc_get_continuation(INTERP, ctx); 
     208            PackFile_ByteCode *seg; 
     209            PMC               *ctx; 
     210            PMC               *ccont; 
    193211 
     212            GET_ATTR_ctx(INTERP, SELF, ctx); 
     213            ccont = Parrot_pcc_get_continuation(INTERP, ctx); 
     214 
    194215            PObj_get_FLAGS(SELF) |= SUB_FLAG_CORO_FF; 
    195             wanted_seg            = co->seg; 
    196216 
     217            GET_ATTR_seg(INTERP, SELF, seg); 
     218            wanted_seg            = seg; 
     219 
    197220            /* remember segment of caller */ 
    198             co->caller_seg        = INTERP->code; 
     221            SET_ATTR_caller_seg(INTERP, SELF, INTERP->code); 
    199222 
     223 
     224 
    200225            /* and the recent call context */ 
    201             PARROT_CONTINUATION(ccont)->to_ctx = CURRENT_CONTEXT(interp); 
    202             Parrot_pcc_set_caller_ctx(interp, ctx, CURRENT_CONTEXT(interp)); 
     226            SETATTR_Continuation_to_ctx(INTERP, ccont, CURRENT_CONTEXT(INTERP)); 
     227            Parrot_pcc_set_caller_ctx(INTERP, ctx, CURRENT_CONTEXT(INTERP)); 
    203228 
    204             /* set context to coro context */ 
    205             CURRENT_CONTEXT(interp) = ctx; 
     229            /* set context to coroutine context */ 
     230            CURRENT_CONTEXT(INTERP) = ctx; 
    206231        } 
    207232        else { 
    208             PMC * const ccont = Parrot_pcc_get_continuation(INTERP, co->ctx); 
    209             PMC * const ctx   = PARROT_CONTINUATION(ccont)->to_ctx; 
    210             INTVAL yield; 
     233            INTVAL             yield; 
     234            PMC               *ccont, *ctx, *to_ctx; 
     235            PackFile_ByteCode *caller_seg; 
     236 
    211237            GET_ATTR_yield(INTERP, SELF, yield); 
    212             if (! yield) 
     238 
     239            if (!yield) 
    213240                Parrot_ex_throw_from_c_args(INTERP, NULL, CONTROL_ERROR, 
    214241                               "Cannot resume dead coroutine."); 
     242 
    215243            SET_ATTR_yield(INTERP, SELF, 0); 
    216244 
     245            GET_ATTR_ctx(INTERP, SELF, ctx); 
     246            ccont = Parrot_pcc_get_continuation(INTERP, ctx); 
     247 
     248            GETATTR_Continuation_to_ctx(INTERP, ccont, to_ctx); 
     249 
    217250            PObj_get_FLAGS(SELF) &= ~SUB_FLAG_CORO_FF; 
     251            GET_ATTR_caller_seg(INTERP, SELF, caller_seg); 
     252 
    218253            /* switch back to last remembered code seg and context */ 
     254            wanted_seg = caller_seg; 
    219255 
    220             wanted_seg            = co->caller_seg; 
    221  
    222             if (PMC_IS_NULL(ctx)) { 
     256            if (PMC_IS_NULL(to_ctx)) { 
    223257                /* This still isn't quite right, but it beats segfaulting.  See 
    224258                   the "Call an exited coroutine" case in t/pmc/coroutine.t; the 
    225259                   problem is that the defunct coroutine yields up one more 
     
    230264                               "Cannot resume dead coroutine."); 
    231265            } 
    232266 
    233             CURRENT_CONTEXT(interp) = ctx; 
     267            CURRENT_CONTEXT(INTERP) = to_ctx; 
    234268        } 
    235269 
    236270        /* toggle address */ 
    237         dest        = co->address; 
    238         co->address = (opcode_t *)next; 
     271        GET_ATTR_address(INTERP, SELF, dest); 
     272        SET_ATTR_address(INTERP, SELF, (opcode_t *)next); 
    239273 
    240274        if (INTERP->code != wanted_seg) 
    241275            Parrot_switch_to_cs(INTERP, wanted_seg, 1);