Ejemplo n.º 1
0
void emitSetS(IRGS& env) {
  auto const ssaPropName = topC(env, BCSPOffset{2});

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

  auto const value    = popC(env, DataTypeCountness);
  auto const ssaCls   = popA(env);
  auto const propAddr = ldClsPropAddr(env, ssaCls, ssaPropName, true);
  auto const ptr      = gen(env, UnboxPtr, propAddr);

  destroyName(env, ssaPropName);
  bindMem(env, ptr, value);
}
Ejemplo n.º 2
0
void emitCGetS(HTS& env) {
  auto const ssaPropName = topC(env, BCSPOffset{1});

  if (!ssaPropName->isA(Type::Str)) {
    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);
}
Ejemplo n.º 3
0
void emitIssetG(IRGS& env) {
  auto const name = topC(env, BCSPOffset{0});
  if (!name->isA(TStr)) PUNT(IssetG-NameNotStr);

  auto const ret = cond(
    env,
    [&] (Block* taken) {
      return gen(env, LdGblAddr, taken, name);
    },
    [&] (SSATmp* ptr) { // Next: global exists
      return gen(env, IsNTypeMem, TNull, gen(env, UnboxPtr, ptr));
    },
    [&] { // Taken: global doesn't exist
      return cns(env, false);
    }
  );
  destroyName(env, name);
  push(env, ret);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
void emitEmptyG(IRGS& env) {
  auto const name = topC(env);
  if (!name->isA(TStr)) PUNT(EmptyG-NameNotStr);

  auto const ret = cond(
    env,
    [&] (Block* taken) {
      return gen(env, LdGblAddr, taken, name);
    },
    [&] (SSATmp* ptr) { // Next: global exists
      auto const unboxed = gen(env, UnboxPtr, ptr);
      auto const val     = gen(env, LdMem, TCell, unboxed);
      return gen(env, XorBool, gen(env, ConvCellToBool, val), cns(env, true));
    },
    [&] { // Taken: global doesn't exist
      return cns(env, true);
    });
  destroyName(env, name);
  push(env, ret);
}
Ejemplo n.º 6
0
void emitCGetQuietG(IRGS& env) {
  auto const name = topC(env);
  if (!name->isA(TStr)) PUNT(CGetQuietG-NonStrName);

  auto ret = cond(
    env,
    [&] (Block* taken) { return gen(env, LdGblAddr, taken, name); },
    [&] (SSATmp* ptr) {
      auto tmp = gen(env, LdMem, TCell, gen(env, UnboxPtr, ptr));
      gen(env, IncRef, tmp);
      return tmp;
    },
    // Taken: LdGblAddr branched here because no global variable exists with
    // that name.
    [&] { return cns(env, TInitNull); }
  );

  destroyName(env, name);
  push(env, ret);
}
Ejemplo n.º 7
0
void emitIssetS(IRGS& env) {
  auto const ssaPropName = topC(env, BCSPOffset{1});
  if (!ssaPropName->isA(TStr)) {
    PUNT(IssetS-PropNameNotString);
  }
  auto const ssaCls = popA(env);

  auto const ret = cond(
    env,
    [&] (Block* taken) {
      auto propAddr = ldClsPropAddr(env, ssaCls, ssaPropName, false);
      return gen(env, CheckNonNull, taken, propAddr);
    },
    [&] (SSATmp* ptr) { // Next: property or global exists
      return gen(env, IsNTypeMem, TNull, gen(env, UnboxPtr, ptr));
    },
    [&] { // Taken: LdClsPropAddr* returned Nullptr because it isn't defined
      return cns(env, false);
    }
  );

  destroyName(env, ssaPropName);
  push(env, ret);
}