Object* BlockEnvironment::invoke(STATE, CallFrame* previous, BlockEnvironment* env, Arguments& args, BlockInvocation& invocation) { MachineCode* mcode = env->compiled_code_->machine_code(); if(!mcode) { OnStack<3> os(state, env, args.recv_location(), args.block_location()); OnStack<3> iv(state, invocation.self, invocation.constant_scope, invocation.module); VariableRootBuffer vrb(state->vm()->current_root_buffers(), &args.arguments_location(), args.total()); GCTokenImpl gct; mcode = env->machine_code(state, gct, previous); if(!mcode) { Exception::internal_error(state, previous, "invalid bytecode method"); return 0; } } state->vm()->metrics().machine.blocks_invoked++; #ifdef ENABLE_LLVM if(executor ptr = mcode->unspecialized) { return (*((BlockExecutor)ptr))(state, previous, env, args, invocation); } #endif return execute_interpreter(state, previous, env, args, invocation); }
Object* CompiledCode::default_executor(STATE, CallFrame* call_frame, Executable* exec, Module* mod, Arguments& args) { LockableScopedLock lg(state, &state->shared(), __FILE__, __LINE__); CompiledCode* code = as<CompiledCode>(exec); if(code->execute == default_executor) { const char* reason = 0; int ip = -1; OnStack<5> os(state, code, exec, mod, args.recv_location(), args.block_location()); VariableRootBuffer vrb(state->vm()->current_root_buffers(), &args.arguments_location(), args.total()); GCTokenImpl gct; if(!code->internalize(state, gct, call_frame, &reason, &ip)) { Exception::bytecode_error(state, call_frame, code, ip, reason); return 0; } } lg.unlock(); return code->execute(state, call_frame, exec, mod, args); }
int dorun(ub4 fln,enum Runlvl stage,bool silent) { int run; vrb(0,"dorun stage %u stopat %u",stage, globs.stopat); if (stage >= globs.stopat) run = 0; else if (stage >= Runcnt) run = 1; else run = globs.doruns[stage]; if (silent) return run; info0(User,""); infofln(fln,0,"--- %s stage %u %s ---",run ? "run" : "skip",stage,runlvlnames(stage)); return run; }
//*create Circle from 3 points //Author: Dongxu Li bool RS_Circle::createFrom3P(const RS_VectorSolutions& sol) { if(sol.getNumber() < 2) return false; if(sol.getNumber() == 2) return createFrom2P(sol.get(0),sol.get(1)); if((sol.get(1)-sol.get(2)).squared() < RS_TOLERANCE*RS_TOLERANCE) return createFrom2P(sol.get(0),sol.get(1)); RS_Vector vra(sol.get(1) - sol.get(0)); RS_Vector vrb(sol.get(2) - sol.get(0)); double ra2=vra.squared()*0.5; double rb2=vrb.squared()*0.5; double crossp=vra.x * vrb.y - vra.y * vrb.x; if (fabs(crossp)< RS_TOLERANCE*RS_TOLERANCE) { RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Circle::createFrom3P(): " "Cannot create a circle with radius 0.0."); return false; } crossp=1./crossp; data.center.set((ra2*vrb.y - rb2*vra.y)*crossp,(rb2*vra.x - ra2*vrb.x)*crossp); data.radius=data.center.magnitude(); data.center += sol.get(0); return true; }
int prepnet(netbase *basenet) { struct gnetwork *gnet = getgnet(); struct portbase *bports,*bpp; struct subportbase *bsports,*bspp; struct hopbase *bhops,*bhp; struct sidbase *bsids,*bsp; struct chainbase *bchains,*bcp; struct routebase *broutes,*brp; ub8 *bchip,*bchainidxs; struct chainhopbase *bchp,*bchainhops; struct port *ports,*pdep,*parr,*pp; struct sport *sports,*spp; struct hop *hops,*hp; struct sidtable *sids,*sp; struct chain *chains,*cp; struct route *routes,*rp; struct timepatbase *btp; struct timepat *tp; ub4 bportcnt,portcnt; ub4 bsportcnt,sportcnt; ub4 bhopcnt,hopcnt; ub4 dep,arr; ub4 bsidcnt,sidcnt,bchaincnt,chaincnt,chainhopcnt; ub4 bridcnt,ridcnt; ub4 nlen,cnt,acnt,dcnt,sid,rid,rrid; enum txkind kind; ub4 hop,port,sport,chain; ub4 *rrid2rid = basenet->rrid2rid; ub4 hirrid = basenet->hirrid; bhopcnt = basenet->hopcnt; bportcnt = basenet->portcnt; bsportcnt = basenet->subportcnt; bsidcnt = basenet->sidcnt; bridcnt = basenet->ridcnt; bchaincnt = basenet->rawchaincnt; if (bportcnt == 0 || bhopcnt == 0) return error(0,"prepnet: %u ports, %u hops",bportcnt,bhopcnt); // filter but leave placeholder in gnet to make refs match ports = alloc(bportcnt,struct port,0,"ports",bportcnt); portcnt = 0; bports = basenet->ports; for (port = 0; port < bportcnt; port++) { bpp = bports + port; pp = ports + port; nlen = bpp->namelen; if (bpp->ndep == 0 && bpp->narr == 0) { info(0,"skip unconnected port %u %s",port,bpp->name); if (nlen) memcpy(pp->name,bpp->name,nlen); pp->namelen = nlen; continue; } // new ndep,narr filled lateron pp->valid = 1; pp->id = pp->allid = pp->gid = portcnt; pp->cid = bpp->cid; nlen = bpp->namelen; if (nlen) { memcpy(pp->name,bpp->name,nlen); pp->namelen = nlen; } else info(0,"port %u has no name", port); pp->lat = bpp->lat; // error_z(pp->lat,port); pp->lon = bpp->lon; pp->rlat = bpp->rlat; pp->rlon = bpp->rlon; pp->utcofs = bpp->utcofs; pp->modes = bpp->modes; pp->subcnt = bpp->subcnt; pp->subofs = bpp->subofs; portcnt++; } info(0,"%u from %u ports",portcnt,bportcnt); portcnt = bportcnt; sports = alloc(bsportcnt,struct sport,0,"sports",bsportcnt); sportcnt = 0; bsports = basenet->subports; for (sport = 0; sport < bsportcnt; sport++) { bspp = bsports + sport; spp = sports + sport; nlen = bspp->namelen; if (nlen) memcpy(spp->name,bspp->name,nlen); else info(0,"sport %u has no name", sport); spp->namelen = nlen; if (bspp->ndep == 0 && bspp->narr == 0) { vrb0(Notty,"unconnected subport %u %s",sport,bspp->name); // continue; } spp->valid = 1; spp->id = sportcnt; spp->cid = bspp->cid; spp->parent = bspp->parent; spp->lat = bspp->lat; error_z(spp->lat,sport); spp->lon = bspp->lon; spp->rlat = bspp->rlat; spp->rlon = bspp->rlon; spp->modes = bspp->modes; spp->seq = bspp->seq; sportcnt++; } info(0,"%u from %u sports",sportcnt,bsportcnt); sportcnt = bsportcnt; sidcnt = bsidcnt; sids = alloc(sidcnt,struct sidtable,0,"sids",sidcnt); bsids = basenet->sids; for (sid = 0; sid < bsidcnt; sid++) { bsp = bsids + sid; sp = sids + sid; sp->sid = bsp->sid; sp->t0 = bsp->t0; sp->t1 = bsp->t1; nlen = bsp->namelen; if (nlen) { memcpy(sp->name,bsp->name,nlen); sp->namelen = nlen; } } info(0,"%u sids",sidcnt); ub4 cumrhops = 0,cumrhops2 = 0; ub4 ofs = 0; ridcnt = bridcnt; routes = alloc(ridcnt,struct route,0,"routes",ridcnt); broutes = basenet->routes; for (rid = 0; rid < ridcnt; rid++) { brp = broutes + rid; rp = routes + rid; rp->rrid = brp->rrid; rp->kind = brp->kind; rp->reserve = brp->reserve; rp->chainofs = brp->chainofs; rp->chaincnt = brp->chaincnt; cnt = rp->hopcnt = brp->hopcnt; rp->hichainlen = brp->hichainlen; nlen = brp->namelen; if (nlen) { memcpy(rp->name,brp->name,nlen); rp->namelen = nlen; } rp->hop2pos = ofs; ofs += cnt * cnt; } info(0,"%u routes",ridcnt); cumrhops = ofs; block *ridhopmem = &gnet->ridhopmem; gnet->ridhopbase = mkblock(ridhopmem,cumrhops + cumrhops2,ub4,Init1,"net"); ub4 *gportsbyhop = alloc(bhopcnt * 2, ub4,0xff,"net portsbyhop",bhopcnt); ub4 dist,*hopdist = alloc(bhopcnt,ub4,0,"net hopdist",bhopcnt); ub4 midur,*hopdur = alloc(bhopcnt,ub4,0,"net hopdur",bhopcnt); ub4 *drids,*arids,*deps,*arrs; ub4 t0,t1,tdep,prvtdep,evcnt; hops = alloc(bhopcnt,struct hop,0,"hops",bhopcnt); hopcnt = 0; bhops = basenet->hops; for (hop = 0; hop < bhopcnt; hop++) { bhp = bhops + hop; dep = bhp->dep; arr = bhp->arr; error_ge(dep,portcnt); error_ge(arr,portcnt); if (dep == arr) { bpp = bports + dep; warning(0,"nil hop %u %s at %u",dep,bpp->name,bhp->cid); continue; } else if (bhp->valid == 0) { bpp = bports + dep; warning(0,"invalid hop %u %s at %u",dep,bpp->name,bhp->cid); continue; } pdep = ports + dep; parr = ports + arr; error_z(pdep->valid,hop); error_z(parr->valid,hop); gportsbyhop[hop * 2] = dep; gportsbyhop[hop * 2 + 1] = arr; hp = hops + hop; hp->gid = hop; nlen = bhp->namelen; if (nlen) { memcpy(hp->name,bhp->name,nlen); hp->namelen = nlen; } rrid = bhp->rrid; error_gt(rrid,hirrid,hop); hp->rrid = rrid; rid = rrid2rid[rrid]; hp->rid = rid; if (rid != hi32) { rp = routes + rid; hp->reserve = rp->reserve; } else { rp = NULL; hp->reserve = 0; } hp->rhop = bhp->rhop; tp = &hp->tp; btp = &bhp->tp; t0 = btp->t0; t1 = btp->t1; evcnt = btp->evcnt; tp->utcofs = btp->utcofs; tp->tdays = btp->tdays; tp->gt0 = btp->gt0; tp->t0 = t0; tp->t1 = t1; tp->evcnt = evcnt; tp->genevcnt = btp->genevcnt; noexit error_ne(tp->genevcnt,evcnt); // todo tp->genevcnt = min(tp->genevcnt,evcnt); tp->evofs = btp->evofs; tp->dayofs = btp->dayofs; tp->lodur = btp->lodur; tp->hidur = btp->hidur; midur = tp->midur = btp->midur; hopdur[hop] = midur; tp->avgdur = btp->avgdur; tp->duracc = btp->duracc; // mark local links pdep = ports + dep; parr = ports + arr; dcnt = pdep->ndep; deps = pdep->deps; drids = pdep->drids; if (dcnt == 0) { deps[0] = hop; drids[0] = rid; pdep->ndep = 1; } else if (dcnt == 1) { if (deps[0] != hop || drids[0] != rid) { deps[1] = hop; drids[1] = rid; pdep->ndep = 2; } } else if ( (deps[0] == hop && drids[0] == rid) || (deps[1] == hop && drids[1] == rid) ) ; else pdep->ndep = dcnt + 1; acnt = parr->narr; arrs = parr->arrs; arids = parr->arids; if (acnt == 0) { arrs[0] = hop; arids[0] = rid; parr->narr = 1; } else if (acnt == 1) { if (arrs[0] != hop || arids[0] != rid) { arrs[1] = hop; arids[1] = rid; parr->narr = 2; } } else if ( (arrs[0] == hop && arids[0] == rid) || (arrs[1] == hop && arids[1] == rid) ) ; else parr->narr = acnt + 1; kind = bhp->kind; hp->kind = kind; dist = hp->dist = bhp->dist; hopdist[hop] = dist; error_z(dist,hop); hp->dep = dep; hp->arr = arr; hopcnt++; } if (hopcnt == 0) return error(0,"nil hops out of %u",bhopcnt); info(0,"%u from %u hops",hopcnt,bhopcnt); hopcnt = bhopcnt; // prepare <rid,dep,arr> to hop lookup ub4 rhop,rhopovf = 0; for (hop = 0; hop < hopcnt; hop++) { hp = hops + hop; rid = hp->rid; if (rid == hi32) continue; error_ge(rid,ridcnt); rp = routes + rid; rhop = hp->rhop; if (rhop < Chainlen) rp->hops[rhop] = hop; else rhopovf++; } warncc(rhopovf,0,"%u of %u hops exceeding %u chain limit",rhopovf,hopcnt,Chainlen); ub4 *bbox = gnet->bbox; // bbox of connected ports for (port = 0; port < portcnt; port++) { pp = ports + port; if (pp->ndep == 0 && pp->narr == 0) continue; updbbox(pp->lat,pp->lon,bbox,Elemcnt(gnet->bbox)); } info(0,"bbox lat %u - %u = %u",bbox[Minlat],bbox[Maxlat],bbox[Latrng]); info(0,"bbox lon %u - %u = %u",bbox[Minlon],bbox[Maxlon],bbox[Lonrng]); ub4 oneridcnt = 0; ub4 onerid; bool oneroute; ub4 ndep,narr; // mark single-route only ports for (port = 0; port < portcnt; port++) { pp = ports + port; ndep = pp->ndep; narr = pp->narr; drids = pp->drids; arids = pp->arids; arrs = pp->arrs; deps = pp->deps; oneroute = 0; onerid = 0; if (ndep == 0 && narr == 0) continue; else if (ndep > 2 || narr > 2) continue; else if (ndep == 0 && narr == 1 && arids[0] != hi32) { oneroute = 1; pp->onerid = arids[0]; } else if (ndep == 1 && narr == 0 && drids[0] != hi32) { oneroute = 1; pp->onerid = drids[0]; } else if (ndep == 1 && narr == 1 && drids[0] == arids[0] && drids[0] != hi32) { oneroute = 1; pp->onerid = arids[0]; } else if (ndep == 2 && narr == 2 && drids[0] != hi32 && drids[1] != hi32) { if (drids[0] == drids[1] && arids[0] == arids[1] && drids[0] == arids[0]) { oneroute = 1; pp->onerid = arids[0]; } else if (drids[0] == arids[0] && drids[1] == arids[1]) { if (sameroute2a(hops,port,drids,deps,arrs)) { oneroute = 1; pp->onerid = arids[0]; } } else if (drids[0] == arids[1] && drids[1] == arids[0]) { if (sameroute2b(hops,port,drids,deps,arrs)) { oneroute = 1; pp->onerid = arids[0]; } } } if (oneroute) { pp->oneroute = 1; pp->onerid = onerid; oneridcnt++; } } info0(0,"global connectivity"); showconn(ports,portcnt,0); ub4 i,idx,bofs,seq,prvseq,rtid; chains = alloc(bchaincnt,struct chain,0,"chains",bchaincnt); bchains = basenet->chains; bchainhops = basenet->chainhops; bchainidxs = basenet->chainidxs; chaincnt = chainhopcnt = ofs = 0; for (chain = 0; chain < bchaincnt; chain++) { bcp = bchains + chain; cp = chains + chain; cp->rid = bcp->rid; cp->tripno = bcp->tripno; cnt = bcp->hopcnt; if (cnt < 3) { vrb(0,"skip dummy chain %u with %u hop\as",chain,cnt); continue; } cp->hopcnt = cnt; cp->rhopcnt = bcp->rhopcnt; cp->rrid = bcp->rrid; cp->rid = bcp->rid; cp->tid = chain; cp->rtid = bcp->rtid; cp->hopofs = ofs; ofs += cnt; chaincnt++; } chainhopcnt = ofs; info(0,"%u from %u chains with %u hops",chaincnt,bchaincnt,chainhopcnt); chaincnt = bchaincnt; ub4 *tid2rtid = alloc(chaincnt,ub4,0,"chain tid2rtid",chaincnt); struct chainhop *chp,*chainhops = alloc(chainhopcnt,struct chainhop,0,"chain hops",chainhopcnt); // write in sorted order for (chain = 0; chain < chaincnt; chain++) { cp = chains + chain; bcp = bchains + chain; cnt = cp->hopcnt; rtid = cp->rtid; tid2rtid[chain] = rtid; if (cnt < 3) continue; ofs = cp->hopofs; bofs = bcp->hopofs; bchip = bchainidxs + bofs; cp->rhopcnt = bcp->rhopcnt; cp->rhopofs = bcp->rhopofs; seq = prvtdep = 0; for (i = 0; i < cnt; i++) { chp = chainhops + ofs + i; idx = bchip[i] & hi32; error_ge(idx,cnt); bchp = bchainhops + bofs + idx; prvseq = seq; seq = (ub4)(bchip[i] >> 32); hop = bchp->hop; tdep = bchp->tdep; error_le(seq,prvseq); chp->hop = hop; chp->tdep = tdep; noexit error_lt(tdep,prvtdep); // todo day wrap ? prvtdep = tdep; chp->tarr = bchp->tarr; error_lt(chp->tarr,chp->tdep); chp->midur = bchp->midur; } } gnet->portcnt = portcnt; gnet->sportcnt = sportcnt; gnet->hopcnt = hopcnt; gnet->sidcnt = sidcnt; gnet->chaincnt = chaincnt; gnet->ridcnt = ridcnt; gnet->ports = ports; gnet->sports = sports; gnet->hops = hops; gnet->sids = sids; gnet->chains = chains; gnet->routes = routes; gnet->portsbyhop = gportsbyhop; gnet->hopdist = hopdist; gnet->hopdur = hopdur; gnet->chainhops = chainhops; gnet->chainrhops = basenet->chainrhops; gnet->chainrphops = basenet->chainrphops; gnet->chainhopcnt = chainhopcnt; gnet->hirrid = hirrid; gnet->rrid2rid = rrid2rid; gnet->tid2rtid = tid2rtid; gnet->hichainlen = basenet->hichainlen; gnet->eventmem = &basenet->eventmem; gnet->evmapmem = &basenet->evmapmem; gnet->events = basenet->events; gnet->evmaps = basenet->evmaps; gnet->t0 = basenet->t0; gnet->t1 = basenet->t1; gnet->walklimit = m2geo(globs.walklimit); gnet->sumwalklimit = m2geo(globs.sumwalklimit); gnet->walkspeed = m2geo(globs.walkspeed); info(0,"precomputed walk limit set to %u m, summed %u",globs.walklimit,globs.sumwalklimit); // write reference for name lookup if (wrportrefs(basenet)) return 1; // if (condense(gnet)) return 1; not (yet?) return 0; }
Object* System::vm_find_object(STATE, GCToken gct, Array* arg, Object* callable, CallFrame* calling_environment) { ObjectMemory::GCInhibit inhibitor(state->memory()); // Support an aux mode, where callable is an array and we just append // objects to it rather than #call it. Array* ary = try_as<Array>(callable); if(!ary) ary = nil<Array>(); Array* args = Array::create(state, 1); int total = 0; QueryCondition* condition = create_condition(state, arg); if(!condition) return Fixnum::from(0); Object* ret = cNil; // Special case for looking for an immediate if(Object* obj = condition->immediate()) { if(Symbol* sym = try_as<Symbol>(obj)) { // Check whether this is actually a valid symbol, not // some random non existing symbol. if(!state->shared().symbols.lookup_string(state, sym)) { delete condition; std::ostringstream msg; msg << "Invalid symbol 0x" << std::hex << reinterpret_cast<uintptr_t>(sym); Exception::range_error(state, msg.str().c_str()); return 0; } } if(!ary->nil_p()) { ary->append(state, obj); } else { args->set(state, 0, obj); ret = callable->send(state, calling_environment, G(sym_call), args, cNil, false); } delete condition; if(!ret) return 0; return Fixnum::from(1); } OnStack<2> os(state, ary, args); state->set_call_frame(calling_environment); ObjectWalker walker(state->memory()); GCData gc_data(state->vm()); { StopTheWorld stw(state, gct, calling_environment); // Seed it with the root objects. walker.seed(gc_data); } Object* obj = walker.next(); while(obj) { if(condition->perform(state, obj)) { total++; if(!ary->nil_p()) { ary->append(state, obj); } else { // We call back into Ruby land here, so that might trigger a GC // This ensures we mark all the locations of the current search // queue for the walker, so we update these object references // properly. Object** stack_buf = walker.stack_buf(); size_t stack_size = walker.stack_size(); Object** variable_buffer[stack_size]; for(size_t i = 0; i < stack_size; ++i) { variable_buffer[i] = &stack_buf[i]; } VariableRootBuffer vrb(state->vm()->current_root_buffers(), variable_buffer, stack_size); args->set(state, 0, obj); ret = callable->send(state, calling_environment, G(sym_call), args, cNil, false); if(!ret) break; } } obj = walker.next(); } delete condition; if(!ret) return 0; return Integer::from(state, total); }