in lib/BCGen/HBC/Passes.cpp [91:209]
bool LoadConstants::operandMustBeLiteral(Instruction *Inst, unsigned opIndex) {
// HBCLoadConstInst is meant to load a constant
if (llvh::isa<HBCLoadConstInst>(Inst))
return true;
// The operand of HBCLoadParamInst is a literal index.
if (llvh::isa<HBCLoadParamInst>(Inst))
return true;
if (llvh::isa<HBCAllocObjectFromBufferInst>(Inst))
return true;
// All operands of AllocArrayInst are literals.
if (llvh::isa<AllocArrayInst>(Inst))
return true;
if (llvh::isa<AllocObjectInst>(Inst)) {
// The AllocObjectInst::SizeIdx is a literal.
if (opIndex == AllocObjectInst::SizeIdx)
return true;
// AllocObjectInst::ParentObjectIdx is a literal if it is the EmptySentinel.
if (opIndex == AllocObjectInst::ParentObjectIdx &&
llvh::isa<EmptySentinel>(Inst->getOperand(opIndex)))
return true;
return false;
}
// SwitchInst's rest of the operands are case values,
// hence they will stay as constant.
if (llvh::isa<SwitchInst>(Inst) && opIndex > 0)
return true;
// StoreOwnPropertyInst and StoreNewOwnPropertyInst.
if (auto *SOP = llvh::dyn_cast<StoreOwnPropertyInst>(Inst)) {
if (opIndex == StoreOwnPropertyInst::PropertyIdx) {
if (llvh::isa<StoreNewOwnPropertyInst>(Inst)) {
// In StoreNewOwnPropertyInst the property name must be a literal.
return true;
}
// If the propery is a LiteralNumber, the property is enumerable, and it
// is a valid array index, it is coming from an array initialization and
// we will emit it as PutByIndex.
if (auto *LN = llvh::dyn_cast<LiteralNumber>(Inst->getOperand(opIndex))) {
if (SOP->getIsEnumerable() && LN->convertToArrayIndex().hasValue())
return true;
}
}
// StoreOwnPropertyInst's isEnumerable is a boolean constant.
if (opIndex == StoreOwnPropertyInst::IsEnumerableIdx)
return true;
return false;
}
// If StorePropertyInst's property ID is a LiteralString, we will keep it
// untouched and emit try_put_by_id eventually.
if (llvh::isa<StorePropertyInst>(Inst) &&
opIndex == StorePropertyInst::PropertyIdx &&
llvh::isa<LiteralString>(Inst->getOperand(opIndex)))
return true;
// If LoadPropertyInst's property ID is a LiteralString, we will keep it
// untouched and emit try_put_by_id eventually.
if (llvh::isa<LoadPropertyInst>(Inst) &&
opIndex == LoadPropertyInst::PropertyIdx &&
llvh::isa<LiteralString>(Inst->getOperand(opIndex)))
return true;
// If DeletePropertyInst's property ID is a LiteralString, we will keep it
// untouched and emit try_put_by_id eventually.
if (llvh::isa<DeletePropertyInst>(Inst) &&
opIndex == DeletePropertyInst::PropertyIdx &&
llvh::isa<LiteralString>(Inst->getOperand(opIndex)))
return true;
// StoreGetterSetterInst's isEnumerable is a boolean constant.
if (llvh::isa<StoreGetterSetterInst>(Inst) &&
opIndex == StoreGetterSetterInst::IsEnumerableIdx)
return true;
// Both pattern and flags operands of the CreateRegExpInst
// are literal strings.
if (llvh::isa<CreateRegExpInst>(Inst))
return true;
if (llvh::isa<SwitchImmInst>(Inst) &&
(opIndex == SwitchImmInst::MinValueIdx ||
opIndex == SwitchImmInst::SizeIdx ||
opIndex >= SwitchImmInst::FirstCaseIdx))
return true;
/// CallBuiltin's callee and "this" should always be literals.
if (llvh::isa<CallBuiltinInst>(Inst) &&
(opIndex == CallBuiltinInst::CalleeIdx ||
opIndex == CallBuiltinInst::ThisIdx))
return true;
/// GetBuiltinClosureInst's builtin index is always literal.
if (llvh::isa<GetBuiltinClosureInst>(Inst) &&
opIndex == GetBuiltinClosureInst::BuiltinIndexIdx)
return true;
#ifdef HERMES_RUN_WASM
/// CallIntrinsic's IntrinsicIndexIdx should always be literals.
if (llvh::isa<CallIntrinsicInst>(Inst) &&
(opIndex == CallIntrinsicInst::IntrinsicIndexIdx))
return true;
#endif
if (llvh::isa<IteratorCloseInst>(Inst) &&
opIndex == IteratorCloseInst::IgnoreInnerExceptionIdx) {
return true;
}
return false;
}