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);
  }
Exemple #2
0
  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);
  }
Exemple #3
0
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;
}
Exemple #5
0
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;
}
Exemple #6
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);
  }