void cgCheckInitProps(IRLS& env, const IRInstruction* inst) { auto const cls = inst->extra<CheckInitProps>()->cls; auto& v = vmain(env); auto const sf = checkRDSHandleInitialized(v, cls->propHandle()); v << jcc{CC_NE, sf, {label(env, inst->next()), label(env, inst->taken())}}; }
void cgInitObjProps(IRLS& env, const IRInstruction* inst) { auto const cls = inst->extra<InitObjProps>()->cls; auto const obj = srcLoc(env, inst, 0).reg(); auto& v = vmain(env); // Set the attributes, if any. auto const odAttrs = cls->getODAttrs(); if (odAttrs) { static_assert(sizeof(ObjectData::Attribute) == 2, "Codegen expects 2-byte ObjectData attributes"); assertx(!(odAttrs & 0xffff0000)); v << orwim{odAttrs, obj[ObjectData::attributeOff()], v.makeReg()}; } // Initialize the properties. auto const nprops = cls->numDeclProperties(); if (nprops > 0) { if (cls->pinitVec().size() == 0) { // If the Class has no 86pinit property-initializer functions, we can // just copy the initial values from a data member on the Class. implInitObjPropsFast(v, env, inst, obj, cls, nprops); } else { // Load the Class's propInitVec from the target cache. We know it's // already been initialized as a pre-condition on this op. auto const propHandle = cls->propHandle(); assertx(rds::isNormalHandle(propHandle)); auto const propInitVec = v.makeReg(); auto const propData = v.makeReg(); v << load{Vreg(rvmtl())[propHandle], propInitVec}; v << load{propInitVec[Class::PropInitVec::dataOff()], propData}; auto const propsOff = sizeof(ObjectData) + cls->builtinODTailSize(); auto args = argGroup(env, inst) .addr(obj, safe_cast<int32_t>(propsOff)) .reg(propData); if (!cls->hasDeepInitProps()) { cgCallHelper(v, env, CallSpec::direct(memcpy), kVoidDest, SyncOptions::None, args.imm(cellsToBytes(nprops))); } else { cgCallHelper(v, env, CallSpec::direct(deepInitHelper), kVoidDest, SyncOptions::None, args.imm(nprops)); } } } }