void WorkerPersistentArrayManager::save_marked_arrays(Interpreter* runner) { ArrayIdLabelMap::iterator it; for (it = persistent_array_map_.begin(); it != persistent_array_map_.end(); ++it) { int array_id = it->first; int string_slot = it->second; //DEBUG SIP_LOG(std::cout << "\nsave marked: array= " << runner->array_name(array_id) << ", label=" << runner->string_literal(string_slot) << std::endl); const std::string label = runner->sip_tables().string_literal(string_slot); if (runner->sip_tables().is_scalar(array_id)) { double value = runner->scalar_value(array_id); SIP_LOG(std::cout << "saving scalar with label " << label << " value is " << value << std::endl); save_scalar(label, value); } else if (runner->sip_tables().is_contiguous(array_id)) { Block* contiguous_array = runner->get_and_remove_contiguous_array(array_id); SIP_LOG(std::cout << "saving contiguous array with label "<< label << " with contents "<< std::endl << *contiguous_array << std::endl); save_contiguous(label, contiguous_array); } else { //in parallel implementation, there won't be any of these on worker. IdBlockMap<Block>::PerArrayMap* per_array_map = runner->get_and_remove_per_array_map(array_id); SIP_LOG(std::cout << " saving distributed array with label " << label << " and map with " << per_array_map->size() << " blocks" << std::endl); save_distributed(label, per_array_map); } } persistent_array_map_.clear(); }
/* The "gv" parameter should be the glob known to Perl code as *! * The scalar must already have been magicalized. */ STATIC void S_require_errno(pTHX_ GV *gv) { HV* stash = gv_stashpvn("Errno",5,FALSE); if (!stash || !(gv_fetchmethod(stash, "TIEHASH"))) { dSP; PUTBACK; ENTER; save_scalar(gv); /* keep the value of $! */ Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, newSVpvn("Errno",5), Nullsv); LEAVE; SPAGAIN; stash = gv_stashpvn("Errno",5,FALSE); if (!stash || !(gv_fetchmethod(stash, "TIEHASH"))) Perl_croak(aTHX_ "Can't use %%! because Errno.pm is not available"); } }
PJS_EXTERN SV * PJS_CallPerlMethod( pTHX_ JSContext *cx, const char *method, ... ) { dSP; va_list ap; SV *arg, *ret; PJS_Context *pcx = PJS_GET_CONTEXT(cx); ENTER; SAVETMPS; PUSHMARK(SP); sv_setiv(save_scalar(PJS_Context_SV), PTR2IV(pcx)); va_start(ap, method); while( (arg = va_arg(ap, SV*)) ) XPUSHs(arg); va_end(ap); PUTBACK; call_method(method, G_SCALAR | G_EVAL); ret = newSVsv(*PL_stack_sp--); FREETMPS; LEAVE; if (SvTRUE(ERRSV)) { sv_free(ret); // Don't want leaks propagate2JS(aTHX_ pcx, NULL); return NULL; } return sv_2mortal(ret); }
PJS_EXTERN JSBool PJS_Call_sv_with_jsvals_rsv( pTHX_ JSContext *cx, JSObject *obj, SV *code, SV *caller, /* Will be disposed inside */ uintN argc, jsval *argv, SV **rsv, I32 flag ) { dSP; JSBool ok = JS_TRUE; uintN arg; I32 rcount = caller ? 1 : 0; PJS_Context *pcx = PJS_GET_CONTEXT(cx); if(SvROK(code) && SvTYPE(SvRV(code)) == SVt_PVCV) { ENTER; SAVETMPS; PUSHMARK(SP) ; sv_setiv(save_scalar(PJS_Context_SV), PTR2IV(pcx)); EXTEND(SP, argc + rcount); PUTBACK; /* From here we are working with the global stack, * a) at PUSH time we can fail, so we need to abort the call * b) Want to avoid copying local <=> global SP at every single PUSH * * Before 'call_sv', rcount is the number of SVs pushed so far */ if(caller) *++PL_stack_sp = sv_2mortal(caller); if(argv && !(flag & G_NOARGS)) { /* HACK: We use G_NOARGS as a guard against use argv[-1] to get This. * Needed for the use in PJS_invoke_perl_property_setter where given * argc is faked */ SV *This; ok = PJS_ReflectJS2Perl(aTHX_ cx, argv[-1], &This, 0); if(ok) sv_setsv(save_scalar(PJS_This), sv_2mortal(This)); else goto forget; } else flag &= ~G_NOARGS; for(arg = 0; arg < argc; arg++) { SV *sv; ok = PJS_ReflectJS2Perl(aTHX_ cx, argv[arg], &sv, 1); if(!ok) { rcount += arg; goto forget; } *++PL_stack_sp = sv_2mortal(sv); } rcount = call_sv(code, flag | G_EVAL); if(rsv) { if(flag == G_SCALAR || rcount == 1) *rsv = SvREFCNT_inc_simple_NN(*PL_stack_sp); else *rsv = newRV((SV *)av_make(rcount, PL_stack_sp-rcount+1)); SAVEMORTALIZESV(*rsv); } forget: PL_stack_sp -= rcount; FREETMPS; LEAVE; if(ok && SvTRUE(ERRSV)) { propagate2JS(aTHX_ pcx, obj); ok = JS_FALSE; } } else croak("Not a coderef"); return ok; }