示例#1
0
void emitUnbox(HTS& env) {
  auto const exit = makeExit(env);
  auto const srcBox = popV(env);
  auto const unboxed = unbox(env, srcBox, exit);
  pushIncRef(env, unboxed);
  gen(env, DecRef, srcBox);
}
示例#2
0
void emitCGetL(HTS& env, int32_t id) {
  auto const ldrefExit = makeExit(env);
  auto const ldPMExit = makePseudoMainExit(env);
  // Mimic hhbc guard relaxation for now.
  auto cat = curSrcKey(env).op() == OpFPassL ? DataTypeSpecific
                                             : DataTypeCountnessInit;
  pushIncRef(env, ldLocInnerWarn(env, id, ldrefExit, ldPMExit, cat));
}
示例#3
0
void emitContCurrent(HTS& env) {
  assert(curClass(env));
  auto const cont = ldThis(env);
  gen(env, ContStartedCheck, makeExitSlow(env), cont);
  auto const offset = cns(env, offsetof(c_Generator, m_value));
  auto const value = gen(env, LdContField, Type::Cell, cont, offset);
  pushIncRef(env, value);
}
示例#4
0
void emitContCurrent(IRGS& env) {
  assertx(curClass(env));
  auto const cont = ldThis(env);
  gen(env, ContStartedCheck, IsAsyncData(false), makeExitSlow(env), cont);
  auto const offset = cns(env,
    offsetof(Generator, m_value) - Generator::objectOff());
  auto const value = gen(env, LdContField, TCell, cont, offset);
  pushIncRef(env, value);
}
示例#5
0
void emitVGetG(IRGS& env) {
  auto const name = topC(env);
  if (!name->isA(TStr)) PUNT(VGetG-NonStrName);
  auto const ptr = gen(env, LdGblAddrDef, name);
  destroyName(env, name);
  pushIncRef(
    env,
    gen(env, LdMem, TBoxedInitCell, gen(env, BoxPtr, ptr))
  );
}
示例#6
0
void emitCGetG(IRGS& env) {
  auto const exit = makeExitSlow(env);
  auto const name = topC(env);
  if (!name->isA(TStr)) PUNT(CGetG-NonStrName);
  auto const ptr = gen(env, LdGblAddr, exit, name);
  destroyName(env, name);
  pushIncRef(
    env,
    gen(env, LdMem, TCell, gen(env, UnboxPtr, ptr))
  );
}
示例#7
0
void emitBareThis(HTS& env, BareThisOp subop) {
  if (!curClass(env)) {
    interpOne(env, Type::InitNull, 0); // will raise notice and push null
    return;
  }
  auto const ctx = gen(env, LdCtx, fp(env));
  if (subop == BareThisOp::NeverNull) {
    env.irb->setThisAvailable();
  } else {
    gen(env, CheckCtxThis, makeExitSlow(env), ctx);
  }
  pushIncRef(env, gen(env, CastCtxThis, ctx));
}
示例#8
0
void emitCGetL2(HTS& env, int32_t id) {
  auto const ldrefExit = makeExit(env);
  auto const ldPMExit = makePseudoMainExit(env);
  auto const oldTop = pop(env, Type::StkElem);
  auto const val = ldLocInnerWarn(
    env,
    id,
    ldrefExit,
    ldPMExit,
    DataTypeCountnessInit
  );
  pushIncRef(env, val);
  push(env, oldTop);
}
示例#9
0
void emitVGetL(HTS& env, int32_t id) {
  auto value = ldLoc(env, id, makeExit(env), DataTypeCountnessInit);
  auto const t = value->type();
  always_assert(t.isBoxed() || t.notBoxed());

  if (t.notBoxed()) {
    if (value->isA(Type::Uninit)) {
      value = cns(env, Type::InitNull);
    }
    value = gen(env, Box, value);
    stLocRaw(env, id, fp(env), value);
  }
  pushIncRef(env, value);
}
示例#10
0
void emitCGetS(IRGS& env) {
  auto const ssaPropName = topC(env, BCSPOffset{1});

  if (!ssaPropName->isA(TStr)) {
    PUNT(CGetS-PropNameNotString);
  }

  auto const ssaCls   = popA(env);
  auto const propAddr = ldClsPropAddr(env, ssaCls, ssaPropName, true);
  auto const unboxed  = gen(env, UnboxPtr, propAddr);
  auto const ldMem    = gen(env, LdMem, unboxed->type().deref(), unboxed);

  destroyName(env, ssaPropName);
  pushIncRef(env, ldMem);
}
示例#11
0
void emitBindL(HTS& env, int32_t id) {
  if (curFunc(env)->isPseudoMain()) {
    interpOne(env, Type::BoxedInitCell, 1);
    return;
  }

  auto const ldPMExit = makePseudoMainExit(env);
  auto const newValue = popV(env);
  // Note that the IncRef must happen first, for correctness in a
  // pseudo-main: the destructor could decref the value again after
  // we've stored it into the local.
  pushIncRef(env, newValue);
  auto const oldValue = ldLoc(env, id, ldPMExit, DataTypeSpecific);
  stLocRaw(env, id, fp(env), newValue);
  gen(env, DecRef, oldValue);
}
示例#12
0
void emitVGetS(IRGS& env) {
  auto const ssaPropName = topC(env, BCSPOffset{1});

  if (!ssaPropName->isA(TStr)) {
    PUNT(VGetS-PropNameNotString);
  }

  auto const ssaCls   = popA(env);
  auto const propAddr = ldClsPropAddr(env, ssaCls, ssaPropName, true);

  destroyName(env, ssaPropName);
  auto const val = gen(
    env,
    LdMem,
    TBoxedInitCell,
    gen(env, BoxPtr, propAddr)
  );
  pushIncRef(env, val);
}
示例#13
0
void inlSingletonSProp(IRGS& env,
                       const Func* func,
                       const Op* clsOp,
                       const Op* propOp) {
  assertx(*clsOp == Op::String);
  assertx(*propOp == Op::String);

  TransFlags trflags;
  trflags.noinlineSingleton = true;

  auto exitBlock = makeExit(env, trflags);

  // Pull the class and property names.
  auto const unit = func->unit();
  auto const clsName  = unit->lookupLitstrId(getImmPtr(clsOp,  0)->u_SA);
  auto const propName = unit->lookupLitstrId(getImmPtr(propOp, 0)->u_SA);

  // Make sure we have a valid class.
  auto const cls = Unit::lookupClass(clsName);
  if (UNLIKELY(!classHasPersistentRDS(cls))) {
    PUNT(SingletonSProp-Persistent);
  }

  // Make sure the sprop is accessible from the singleton method's context.
  auto const lookup = cls->findSProp(func->cls(), propName);
  if (UNLIKELY(lookup.prop == kInvalidSlot || !lookup.accessible)) {
    PUNT(SingletonSProp-Accessibility);
  }

  // Look up the static property.
  auto const sprop   = ldClsPropAddrKnown(env, cls, propName);
  auto const unboxed = gen(env, UnboxPtr, sprop);
  auto const value   = gen(env, LdMem, unboxed->type().deref(), unboxed);

  // Side exit if the static property is null.
  auto isnull = gen(env, IsType, TNull, value);
  gen(env, JmpNZero, exitBlock, isnull);

  // Return the singleton.
  pushIncRef(env, value);
}
示例#14
0
void inlSingletonSLoc(IRGS& env, const Func* func, const Op* op) {
  assertx(*op == Op::StaticLocInit);

  TransFlags trflags;
  trflags.noinlineSingleton = true;

  auto exit = makeExit(env, trflags);
  auto const name = func->unit()->lookupLitstrId(getImmPtr(op, 1)->u_SA);

  // Side exit if the static local is uninitialized.
  auto const box = gen(env, LdStaticLocCached, StaticLocName { func, name });
  gen(env, CheckStaticLocInit, exit, box);

  // Side exit if the static local is null.
  auto const value  = gen(env, LdRef, TInitCell, box);
  auto const isnull = gen(env, IsType, TInitNull, value);
  gen(env, JmpNZero, exit, isnull);

  // Return the singleton.
  pushIncRef(env, value);
}
示例#15
0
void emitDup(HTS& env) { pushIncRef(env, topC(env)); }
示例#16
0
void emitThis(HTS& env) {
  auto const ctx = gen(env, LdCtx, fp(env));
  checkThis(env, ctx);
  auto const this_ = gen(env, CastCtxThis, ctx);
  pushIncRef(env, this_);
}