void emitIssetS(HTS& env) { auto const ssaPropName = topC(env, BCSPOffset{1}); if (!ssaPropName->isA(Type::Str)) { PUNT(IssetS-PropNameNotString); } auto const ssaCls = popA(env); auto const ret = cond( env, 0, [&] (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, Type::Null, gen(env, UnboxPtr, ptr)); }, [&] { // Taken: LdClsPropAddr* returned Nullptr because it isn't defined return cns(env, false); } ); destroyName(env, ssaPropName); push(env, ret); }
void emitEmptyS(IRGS& env) { auto const ssaPropName = topC(env, BCSPOffset{1}); if (!ssaPropName->isA(TStr)) { PUNT(EmptyS-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) { auto const unbox = gen(env, UnboxPtr, ptr); auto const val = gen(env, LdMem, unbox->type().deref(), unbox); return gen(env, XorBool, gen(env, ConvCellToBool, val), cns(env, true)); }, [&] { // Taken: LdClsPropAddr* returned Nullptr because it isn't defined return cns(env, true); }); destroyName(env, ssaPropName); push(env, ret); }
void emitBindS(IRGS& env) { auto const ssaPropName = topC(env, BCSPOffset{2}); if (!ssaPropName->isA(TStr)) { PUNT(BindS-PropNameNotString); } auto const value = popV(env); auto const ssaCls = popA(env); auto const propAddr = ldClsPropAddr(env, ssaCls, ssaPropName, true); destroyName(env, ssaPropName); bindMem(env, propAddr, value); }
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); }
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); }
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); }
void emitPopA(HTS& env) { popA(env); }
void emitNameA(HTS& env) { push(env, gen(env, LdClsName, popA(env))); }