mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-03-01 08:48:03 +00:00
Reason:add aot callthis calltarget check
Description:add aot callthis calltarget check Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6O72O?from=project-issue Signed-off-by: wupengyong <wupengyong@huawei.com> Change-Id: I8a5efa8abdf958e8285b49e9e27e563614d3b0e2
This commit is contained in:
parent
b359990a1c
commit
ef03e0aa6f
@ -170,6 +170,10 @@ BytecodeMetaData BytecodeMetaData::InitBytecodeMetaData(const uint8_t *pc)
|
||||
case EcmaOpcode::CALLARGS2_IMM8_V8_V8:
|
||||
case EcmaOpcode::CALLARGS3_IMM8_V8_V8_V8:
|
||||
case EcmaOpcode::CALLRANGE_IMM8_IMM8_V8:
|
||||
case EcmaOpcode::CALLTHIS0_IMM8_V8:
|
||||
case EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8:
|
||||
case EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8:
|
||||
case EcmaOpcode::CALLTHISRANGE_IMM8_IMM8_V8:
|
||||
flags |= BytecodeFlags::SUPPORT_DEOPT;
|
||||
break;
|
||||
case EcmaOpcode::RETURNUNDEFINED:
|
||||
|
@ -115,6 +115,14 @@ public:
|
||||
GATE_META_DATA_LIST_WITH_ONE_PARAMETER(DECLARE_GATE_META)
|
||||
#undef DECLARE_GATE_META
|
||||
|
||||
#define DECLARE_LOAD_PROPERTY_GATE_META(NAME, OP, R, S, D, V) \
|
||||
const GateMetaData* NAME(bool isFunction) \
|
||||
{ \
|
||||
return metaBuilder_.NAME(isFunction); \
|
||||
}
|
||||
LOAD_PROPERTY_LIST(DECLARE_LOAD_PROPERTY_GATE_META)
|
||||
#undef DECLARE_LOAD_PROPERTY_GATE_META
|
||||
|
||||
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
|
||||
const GateMetaData* NAME(uint64_t value, uint64_t pcOffset) \
|
||||
{ \
|
||||
|
@ -367,6 +367,20 @@ GateRef CircuitBuilder::JSCallTargetTypeCheck(GateType type, GateRef func, GateR
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::JSCallThisTargetTypeCheck(GateType type, GateRef func)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
ASSERT(acc_.HasFrameState(currentDepend));
|
||||
auto frameState = acc_.GetFrameState(currentDepend);
|
||||
GateRef ret = GetCircuit()->NewGate(circuit_->JSCallThisTargetTypeCheck(static_cast<size_t>(type.Value())),
|
||||
MachineType::I1, {currentControl, currentDepend, func, frameState}, GateType::NJSValue());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::DeoptCheck(GateRef condition, GateRef frameState, DeoptType type)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
@ -755,12 +769,12 @@ GateRef CircuitBuilder::HeapAlloc(GateRef initialHClass, GateType type, RegionSp
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::LoadProperty(GateRef receiver, GateRef propertyLookupResult)
|
||||
GateRef CircuitBuilder::LoadProperty(GateRef receiver, GateRef propertyLookupResult, bool isFunction)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto ret = GetCircuit()->NewGate(circuit_->LoadProperty(), MachineType::I64,
|
||||
auto ret = GetCircuit()->NewGate(circuit_->LoadProperty(isFunction), MachineType::I64,
|
||||
{ currentControl, currentDepend, receiver, propertyLookupResult },
|
||||
GateType::AnyType());
|
||||
currentLabel->SetControl(ret);
|
||||
|
@ -237,6 +237,7 @@ public:
|
||||
GateRef TryPrimitiveTypeCheck(GateType type, GateRef gate);
|
||||
GateRef CallTargetCheck(GateRef function, GateRef id, GateRef param);
|
||||
GateRef JSCallTargetTypeCheck(GateType type, GateRef func, GateRef methodIndex);
|
||||
GateRef JSCallThisTargetTypeCheck(GateType type, GateRef func);
|
||||
GateRef DeoptCheck(GateRef condition, GateRef frameState, DeoptType type = DeoptType::NOTCHECK);
|
||||
GateRef TypedBinaryOperator(MachineType type, TypedBinOp binOp, GateType typeLeft, GateType typeRight,
|
||||
std::vector<GateRef> inList, GateType gateType);
|
||||
@ -450,7 +451,7 @@ public:
|
||||
GateRef LoadElement(GateRef receiver, GateRef index);
|
||||
template<TypedStoreOp Op>
|
||||
GateRef StoreElement(GateRef receiver, GateRef index, GateRef value);
|
||||
GateRef LoadProperty(GateRef receiver, GateRef propertyLookupResult);
|
||||
GateRef LoadProperty(GateRef receiver, GateRef propertyLookupResult, bool isFunction);
|
||||
GateRef StoreProperty(GateRef receiver, GateRef propertyLookupResult, GateRef value);
|
||||
GateRef LoadArrayLength(GateRef array);
|
||||
GateRef HeapAlloc(GateRef initialHClass, GateType type, RegionSpaceFlag flag);
|
||||
|
@ -238,6 +238,11 @@ public:
|
||||
return JSBytecodeMetaData::Cast(meta_);
|
||||
}
|
||||
|
||||
LoadPropertyMetaDate* GetLoadPropertyMetaDate()
|
||||
{
|
||||
return LoadPropertyMetaDate::Cast(meta_);
|
||||
}
|
||||
|
||||
std::string MachineTypeStr(MachineType machineType) const;
|
||||
std::string GateTypeStr(GateType gateType) const;
|
||||
~Gate() = default;
|
||||
|
@ -130,7 +130,8 @@ GateType GateAccessor::GetParamGateType(GateRef gate) const
|
||||
GetOpCode(gate) == OpCode::OBJECT_TYPE_CHECK ||
|
||||
GetOpCode(gate) == OpCode::TYPED_ARRAY_CHECK ||
|
||||
GetOpCode(gate) == OpCode::INDEX_CHECK ||
|
||||
GetOpCode(gate) == OpCode::JSCALLTARGET_TYPE_CHECK);
|
||||
GetOpCode(gate) == OpCode::JSCALLTARGET_TYPE_CHECK ||
|
||||
GetOpCode(gate) == OpCode::JSCALLTHISTARGET_TYPE_CHECK);
|
||||
Gate *gatePtr = circuit_->LoadGatePtr(gate);
|
||||
GateTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
|
||||
return accessor.GetGateType();
|
||||
@ -195,6 +196,13 @@ const ChunkVector<char>& GateAccessor::GetConstantString(GateRef gate) const
|
||||
return gatePtr->GetStringMetaData()->GetString();
|
||||
}
|
||||
|
||||
bool GateAccessor::IsVtable(GateRef gate) const
|
||||
{
|
||||
ASSERT(GetOpCode(gate) == OpCode::LOAD_PROPERTY);
|
||||
Gate *gatePtr = circuit_->LoadGatePtr(gate);
|
||||
return gatePtr->GetLoadPropertyMetaDate()->IsVtable();
|
||||
}
|
||||
|
||||
uint32_t GateAccessor::TryGetPcOffset(GateRef gate) const
|
||||
{
|
||||
Gate *gatePtr = circuit_->LoadGatePtr(gate);
|
||||
|
@ -381,6 +381,7 @@ public:
|
||||
TypedUnaryAccessor GetTypedUnOp(GateRef gate) const;
|
||||
uint64_t GetConstantValue(GateRef gate) const;
|
||||
const ChunkVector<char>& GetConstantString(GateRef gate) const;
|
||||
bool IsVtable(GateRef gate) const;
|
||||
uint32_t TryGetPcOffset(GateRef gate) const;
|
||||
EcmaOpcode GetByteCodeOpcode(GateRef gate) const;
|
||||
void Print(GateRef gate) const;
|
||||
|
@ -49,6 +49,7 @@ std::string GateMetaData::Str(OpCode opcode)
|
||||
const std::map<OpCode, const char *> strMap = {
|
||||
#define GATE_NAME_MAP(NAME, OP, R, S, D, V) { OpCode::OP, #OP },
|
||||
IMMUTABLE_META_DATA_CACHE_LIST(GATE_NAME_MAP)
|
||||
LOAD_PROPERTY_LIST(GATE_NAME_MAP)
|
||||
GATE_META_DATA_LIST_WITH_SIZE(GATE_NAME_MAP)
|
||||
GATE_META_DATA_LIST_WITH_ONE_PARAMETER(GATE_NAME_MAP)
|
||||
GATE_META_DATA_LIST_WITH_PC_OFFSET(GATE_NAME_MAP)
|
||||
@ -214,6 +215,15 @@ const GateMetaData* GateMetaBuilder::NAME() \
|
||||
IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_GATE_META)
|
||||
#undef DECLARE_GATE_META
|
||||
|
||||
#define DECLARE_LOAD_PROPERTY_GATE_META(NAME, OP, R, S, D, V) \
|
||||
const GateMetaData* GateMetaBuilder::NAME(bool isFunction) \
|
||||
{ \
|
||||
auto meta = new (chunk_) LoadPropertyMetaDate(OpCode::OP, R, S, D, V, isFunction); \
|
||||
return meta; \
|
||||
}
|
||||
LOAD_PROPERTY_LIST(DECLARE_LOAD_PROPERTY_GATE_META)
|
||||
#undef DECLARE_LOAD_PROPERTY_GATE_META
|
||||
|
||||
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
|
||||
const GateMetaData* GateMetaBuilder::NAME(size_t value) \
|
||||
{ \
|
||||
|
@ -199,7 +199,6 @@ std::string MachineTypeToStr(MachineType machineType);
|
||||
V(ArrayCheck, ARRAY_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(StableArrayCheck, STABLE_ARRAY_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(DeoptCheck, DEOPT_CHECK, GateFlags::NONE_FLAG, 1, 1, 3) \
|
||||
V(LoadProperty, LOAD_PROPERTY, GateFlags::NO_WRITE, 1, 1, 2) \
|
||||
V(StoreProperty, STORE_PROPERTY, GateFlags::NONE_FLAG, 1, 1, 3) \
|
||||
V(ToLength, TO_LENGTH, GateFlags::NONE_FLAG, 1, 1, 1) \
|
||||
V(DefaultCase, DEFAULT_CASE, GateFlags::CONTROL, 1, 0, 0) \
|
||||
@ -240,17 +239,18 @@ std::string MachineTypeToStr(MachineType machineType);
|
||||
V(DependSelector, DEPEND_SELECTOR, GateFlags::FIXED, 1, value, 0) \
|
||||
GATE_META_DATA_LIST_WITH_VALUE_IN(V)
|
||||
|
||||
#define GATE_META_DATA_LIST_WITH_GATE_TYPE(V) \
|
||||
V(PrimitiveTypeCheck, PRIMITIVE_TYPE_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(ObjectTypeCheck, OBJECT_TYPE_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(JSCallTargetTypeCheck, JSCALLTARGET_TYPE_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(TypedArrayCheck, TYPED_ARRAY_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(IndexCheck, INDEX_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(Int32OverflowCheck, INT32_OVERFLOW_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(TypedUnaryOp, TYPED_UNARY_OP, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(TypedConvert, TYPE_CONVERT, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(CheckAndConvert, CHECK_AND_CONVERT, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(Convert, CONVERT, GateFlags::NONE_FLAG, 0, 0, 1) \
|
||||
#define GATE_META_DATA_LIST_WITH_GATE_TYPE(V) \
|
||||
V(PrimitiveTypeCheck, PRIMITIVE_TYPE_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(ObjectTypeCheck, OBJECT_TYPE_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(JSCallTargetTypeCheck, JSCALLTARGET_TYPE_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(JSCallThisTargetTypeCheck, JSCALLTHISTARGET_TYPE_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(TypedArrayCheck, TYPED_ARRAY_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(IndexCheck, INDEX_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(Int32OverflowCheck, INT32_OVERFLOW_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(TypedUnaryOp, TYPED_UNARY_OP, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(TypedConvert, TYPE_CONVERT, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(CheckAndConvert, CHECK_AND_CONVERT, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(Convert, CONVERT, GateFlags::NONE_FLAG, 0, 0, 1) \
|
||||
|
||||
#define GATE_META_DATA_LIST_WITH_VALUE(V) \
|
||||
V(Icmp, ICMP, GateFlags::NONE_FLAG, 0, 0, 2) \
|
||||
@ -276,6 +276,9 @@ std::string MachineTypeToStr(MachineType machineType);
|
||||
V(TYPED_BINARY_OP) \
|
||||
V(CONSTSTRING)
|
||||
|
||||
#define LOAD_PROPERTY_LIST(V) \
|
||||
V(LoadProperty, LOAD_PROPERTY, GateFlags::NO_WRITE, 1, 1, 2) \
|
||||
|
||||
enum class OpCode : uint8_t {
|
||||
NOP = 0,
|
||||
#define DECLARE_GATE_OPCODE(NAME, OP, R, S, D, V) OP,
|
||||
@ -284,6 +287,7 @@ enum class OpCode : uint8_t {
|
||||
GATE_META_DATA_LIST_WITH_ONE_PARAMETER(DECLARE_GATE_OPCODE)
|
||||
GATE_META_DATA_LIST_WITH_PC_OFFSET(DECLARE_GATE_OPCODE)
|
||||
GATE_META_DATA_LIST_WITH_PC_OFFSET_FIXED_VALUE(DECLARE_GATE_OPCODE)
|
||||
LOAD_PROPERTY_LIST(DECLARE_GATE_OPCODE)
|
||||
#undef DECLARE_GATE_OPCODE
|
||||
#define DECLARE_GATE_OPCODE(NAME) NAME,
|
||||
GATE_OPCODE_LIST(DECLARE_GATE_OPCODE)
|
||||
@ -474,6 +478,27 @@ inline std::ostream& operator<<(std::ostream& os, OpCode opcode)
|
||||
return os << GateMetaData::Str(opcode);
|
||||
}
|
||||
|
||||
class LoadPropertyMetaDate : public GateMetaData {
|
||||
public:
|
||||
LoadPropertyMetaDate(OpCode opcode, GateFlags flags, uint32_t statesIn,
|
||||
uint16_t dependsIn, uint32_t valuesIn, bool isVtable)
|
||||
: GateMetaData(opcode, flags, statesIn, dependsIn, valuesIn), isVtable_(isVtable) {}
|
||||
|
||||
static LoadPropertyMetaDate* Cast(const GateMetaData* meta)
|
||||
{
|
||||
ASSERT(meta->GetOpCode() == OpCode::LOAD_PROPERTY);
|
||||
return static_cast<LoadPropertyMetaDate*>(const_cast<GateMetaData*>(meta));
|
||||
}
|
||||
|
||||
bool IsVtable() const
|
||||
{
|
||||
return isVtable_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool isVtable_ { false };
|
||||
};
|
||||
|
||||
class JSBytecodeMetaData : public GateMetaData {
|
||||
public:
|
||||
explicit JSBytecodeMetaData(size_t valuesIn, EcmaOpcode opcode, uint32_t pcOffset, GateFlags flags)
|
||||
|
@ -60,6 +60,10 @@ static constexpr size_t FIVE_VALUE = 5;
|
||||
IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_CACHED_GATE_META)
|
||||
#undef DECLARE_CACHED_GATE_META
|
||||
|
||||
#define DECLARE_LOAD_PROPERTY_META(NAME, OP, R, S, D, V) \
|
||||
LoadPropertyMetaDate cached##NAME##_ { OpCode::OP, R, S, D, V };
|
||||
#undef DECLARE_LOAD_PROPERTY_META
|
||||
|
||||
#define DECLARE_CACHED_VALUE_META(VALUE) \
|
||||
GateMetaData cachedMerge##VALUE##_ { OpCode::MERGE, GateFlags::CONTROL, VALUE, 0, 0 }; \
|
||||
GateMetaData cachedDependSelector##VALUE##_ { OpCode::DEPEND_SELECTOR, GateFlags::FIXED, 1, VALUE, 0 };
|
||||
@ -118,6 +122,7 @@ public:
|
||||
#undef DECLARE_GATE_META
|
||||
|
||||
explicit GateMetaBuilder(Chunk* chunk);
|
||||
const GateMetaData* LoadProperty(bool isFunction);
|
||||
const GateMetaData* JSBytecode(size_t valuesIn, EcmaOpcode opcode, uint32_t pcOffset, GateFlags flags)
|
||||
{
|
||||
return new (chunk_) JSBytecodeMetaData(valuesIn, opcode, pcOffset, flags);
|
||||
|
@ -182,7 +182,7 @@ HWTEST_F_L0(LoweringRelateGateTests, HeapAllocTest)
|
||||
builder.StoreElement<ecmascript::kungfu::TypedStoreOp::FLOAT32ARRAY_STORE_ELEMENT>(array, builder.IntPtr(1),
|
||||
builder.ToTaggedInt(builder.Int64(1)));
|
||||
builder.StoreProperty(array, lengthString, builder.ToTaggedInt(builder.Int64(2)));
|
||||
auto length = builder.LoadProperty(array, lengthString);
|
||||
auto length = builder.LoadProperty(array, lengthString, false);
|
||||
Label less2(&builder);
|
||||
Label notLess2(&builder);
|
||||
auto condtion = builder.TaggedIsTrue(builder.NumberBinaryOp<TypedBinOp::TYPED_LESS>(length,
|
||||
|
@ -235,9 +235,6 @@ void TSTypeLowering::Lower(GateRef gate)
|
||||
case EcmaOpcode::WIDE_SUPERCALLTHISRANGE_PREF_IMM16_V8:
|
||||
LowerTypedSuperCall(gate, jsFunc, newTarget);
|
||||
break;
|
||||
case EcmaOpcode::CALLTHIS1_IMM8_V8_V8:
|
||||
LowerCallThis1Imm8V8V8(gate);
|
||||
break;
|
||||
case EcmaOpcode::CALLARG0_IMM8:
|
||||
LowerTypedCallArg0(gate);
|
||||
break;
|
||||
@ -253,6 +250,21 @@ void TSTypeLowering::Lower(GateRef gate)
|
||||
case EcmaOpcode::CALLRANGE_IMM8_IMM8_V8:
|
||||
LowerTypedCallrange(gate);
|
||||
break;
|
||||
case EcmaOpcode::CALLTHIS0_IMM8_V8:
|
||||
LowerTypedCallthis0(gate);
|
||||
break;
|
||||
case EcmaOpcode::CALLTHIS1_IMM8_V8_V8:
|
||||
LowerTypedCallthis1(gate);
|
||||
break;
|
||||
case EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8:
|
||||
LowerTypedCallthis2(gate);
|
||||
break;
|
||||
case EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8:
|
||||
LowerTypedCallthis3(gate);
|
||||
break;
|
||||
case EcmaOpcode::CALLTHISRANGE_IMM8_IMM8_V8:
|
||||
LowerTypedCallthisrange(gate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -663,7 +675,7 @@ void TSTypeLowering::LowerTypedLdObjByName(GateRef gate)
|
||||
GateRef pfrGate = builder_.Int32(plr.GetData());
|
||||
GateRef result = Circuit::NullGate();
|
||||
if (LIKELY(!plr.IsAccessor())) {
|
||||
result = builder_.LoadProperty(receiver, pfrGate);
|
||||
result = builder_.LoadProperty(receiver, pfrGate, plr.IsVtable());
|
||||
} else {
|
||||
result = builder_.CallGetter(gate, receiver, pfrGate);
|
||||
}
|
||||
@ -940,25 +952,9 @@ BuiltinsStubCSigns::ID TSTypeLowering::GetBuiltinId(GateRef func, GateRef receiv
|
||||
return id;
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerCallThis1Imm8V8V8(GateRef gate)
|
||||
{
|
||||
GateRef thisObj = acc_.GetValueIn(gate, 0);
|
||||
GateRef a0 = acc_.GetValueIn(gate, 1); // 1:parameter index
|
||||
GateType a0Type = acc_.GetGateType(a0);
|
||||
GateRef func = acc_.GetValueIn(gate, 2); // 2:function
|
||||
BuiltinsStubCSigns::ID id = GetBuiltinId(func, thisObj);
|
||||
if (id != BuiltinsStubCSigns::ID::NONE && a0Type.IsNumberType()) {
|
||||
AddProfiling(gate);
|
||||
SpeculateCallBuiltin(gate, id);
|
||||
} else {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
}
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedCallArg0(GateRef gate)
|
||||
{
|
||||
GateRef func = acc_.GetValueIn(gate, 0);
|
||||
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
if (!tsManager_->IsFunctionTypeKind(funcType)) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
@ -970,25 +966,35 @@ void TSTypeLowering::LowerTypedCallArg0(GateRef gate)
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
int methodIndex = tsManager_->GetMethodIndex(funcGt);
|
||||
builder_.JSCallTargetTypeCheck(funcType, func, builder_.IntPtr(methodIndex));
|
||||
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate),
|
||||
EcmaOpcode::CALLARG0_IMM8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = builder_.Undefined();
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj };
|
||||
if (IsLoadVtable(func)) {
|
||||
builder_.JSCallThisTargetTypeCheck(funcType, func);
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj };
|
||||
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
} else {
|
||||
int methodIndex = tsManager_->GetMethodIndex(funcGt);
|
||||
if (methodIndex == -1) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
builder_.JSCallTargetTypeCheck(funcType, func, builder_.IntPtr(methodIndex));
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj };
|
||||
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedCallArg1(GateRef gate)
|
||||
{
|
||||
GateRef a0Value = acc_.GetValueIn(gate, 0);
|
||||
GateRef func = acc_.GetValueIn(gate, 1);
|
||||
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
if (!tsManager_->IsFunctionTypeKind(funcType)) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
@ -1000,25 +1006,34 @@ void TSTypeLowering::LowerTypedCallArg1(GateRef gate)
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
int methodIndex = tsManager_->GetMethodIndex(funcGt);
|
||||
builder_.JSCallTargetTypeCheck(funcType, func, builder_.IntPtr(methodIndex));
|
||||
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate),
|
||||
EcmaOpcode::CALLARG1_IMM8_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = builder_.Undefined();
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0Value };
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
GateRef a0Value = acc_.GetValueIn(gate, 0);
|
||||
if (IsLoadVtable(func)) {
|
||||
builder_.JSCallThisTargetTypeCheck(funcType, func);
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0Value };
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
} else {
|
||||
int methodIndex = tsManager_->GetMethodIndex(funcGt);
|
||||
if (methodIndex == -1) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
builder_.JSCallTargetTypeCheck(funcType, func, builder_.IntPtr(methodIndex));
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0Value };
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedCallArg2(GateRef gate)
|
||||
{
|
||||
GateRef a0 = acc_.GetValueIn(gate, 0);
|
||||
GateRef a1 = acc_.GetValueIn(gate, 1); // 1:first parameter
|
||||
GateRef func = acc_.GetValueIn(gate, 2); // 2:function
|
||||
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
if (!tsManager_->IsFunctionTypeKind(funcType)) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
@ -1030,24 +1045,34 @@ void TSTypeLowering::LowerTypedCallArg2(GateRef gate)
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
int methodIndex = tsManager_->GetMethodIndex(funcGt);
|
||||
builder_.JSCallTargetTypeCheck(funcType, func, builder_.IntPtr(methodIndex));
|
||||
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate),
|
||||
EcmaOpcode::CALLARGS2_IMM8_V8_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = builder_.Undefined();
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0, a1 };
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
GateRef a0 = acc_.GetValueIn(gate, 0);
|
||||
GateRef a1 = acc_.GetValueIn(gate, 1); // 1:first parameter
|
||||
if (IsLoadVtable(func)) {
|
||||
builder_.JSCallThisTargetTypeCheck(funcType, func);
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0, a1 };
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
} else {
|
||||
int methodIndex = tsManager_->GetMethodIndex(funcGt);
|
||||
if (methodIndex == -1) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
builder_.JSCallTargetTypeCheck(funcType, func, builder_.IntPtr(methodIndex));
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0, a1 };
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedCallArg3(GateRef gate)
|
||||
{
|
||||
GateRef a0 = acc_.GetValueIn(gate, 0);
|
||||
GateRef a1 = acc_.GetValueIn(gate, 1);
|
||||
GateRef a2 = acc_.GetValueIn(gate, 2);
|
||||
GateRef func = acc_.GetValueIn(gate, 3); // 3:function
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
if (!tsManager_->IsFunctionTypeKind(funcType)) {
|
||||
@ -1060,17 +1085,31 @@ void TSTypeLowering::LowerTypedCallArg3(GateRef gate)
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
int methodIndex = tsManager_->GetMethodIndex(funcGt);
|
||||
builder_.JSCallTargetTypeCheck(funcType, func, builder_.IntPtr(methodIndex));
|
||||
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate),
|
||||
EcmaOpcode::CALLARGS3_IMM8_V8_V8_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = builder_.Undefined();
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0, a1, a2 };
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
GateRef a0 = acc_.GetValueIn(gate, 0);
|
||||
GateRef a1 = acc_.GetValueIn(gate, 1);
|
||||
GateRef a2 = acc_.GetValueIn(gate, 2);
|
||||
if (IsLoadVtable(func)) {
|
||||
builder_.JSCallThisTargetTypeCheck(funcType, func);
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0, a1, a2 };
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
} else {
|
||||
int methodIndex = tsManager_->GetMethodIndex(funcGt);
|
||||
if (methodIndex == -1) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
builder_.JSCallTargetTypeCheck(funcType, func, builder_.IntPtr(methodIndex));
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0, a1, a2 };
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedCallrange(GateRef gate)
|
||||
@ -1082,7 +1121,6 @@ void TSTypeLowering::LowerTypedCallrange(GateRef gate)
|
||||
const size_t callTargetIndex = 1; // acc
|
||||
size_t argc = numArgs - callTargetIndex;
|
||||
GateRef func = acc_.GetValueIn(gate, argc);
|
||||
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
if (!tsManager_->IsFunctionTypeKind(funcType)) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
@ -1094,14 +1132,9 @@ void TSTypeLowering::LowerTypedCallrange(GateRef gate)
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
int methodIndex = tsManager_->GetMethodIndex(funcGt);
|
||||
builder_.JSCallTargetTypeCheck(funcType, func, builder_.IntPtr(methodIndex));
|
||||
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = builder_.Undefined();
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
vec.emplace_back(glue_);
|
||||
vec.emplace_back(env);
|
||||
vec.emplace_back(actualArgc);
|
||||
vec.emplace_back(func);
|
||||
vec.emplace_back(newTarget);
|
||||
@ -1109,7 +1142,187 @@ void TSTypeLowering::LowerTypedCallrange(GateRef gate)
|
||||
for (size_t i = 0; i < argc; i++) {
|
||||
vec.emplace_back(acc_.GetValueIn(gate, i));
|
||||
}
|
||||
if (IsLoadVtable(func)) {
|
||||
builder_.JSCallThisTargetTypeCheck(funcType, func);
|
||||
GateRef newEnv = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef>::iterator pos = vec.begin();
|
||||
vec.insert(++pos, newEnv);
|
||||
GateRef result = builder_.TypedAotCall(gate, vec);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
} else {
|
||||
int methodIndex = tsManager_->GetMethodIndex(funcGt);
|
||||
if (methodIndex == -1) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
builder_.JSCallTargetTypeCheck(funcType, func, builder_.IntPtr(methodIndex));
|
||||
GateRef newEnv = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef>::iterator pos = vec.begin();
|
||||
vec.insert(++pos, newEnv);
|
||||
GateRef result = builder_.TypedAotCall(gate, vec);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
}
|
||||
|
||||
bool TSTypeLowering::IsLoadVtable(GateRef func)
|
||||
{
|
||||
auto op = acc_.GetOpCode(func);
|
||||
if (op != OpCode::LOAD_PROPERTY || !acc_.IsVtable(func)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TSTypeLowering::CanOptimizeAsFastCall(GateRef func, uint32_t len)
|
||||
{
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
if (!tsManager_->IsFunctionTypeKind(funcType)) {
|
||||
return false;
|
||||
}
|
||||
GlobalTSTypeRef funcGt = funcType.GetGTRef();
|
||||
uint32_t length = tsManager_->GetFunctionTypeLength(funcGt);
|
||||
if (len != length) {
|
||||
return false;
|
||||
}
|
||||
auto op = acc_.GetOpCode(func);
|
||||
if (op != OpCode::LOAD_PROPERTY || !acc_.IsVtable(func)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedCallthis0(GateRef gate)
|
||||
{
|
||||
// 2: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 2);
|
||||
GateRef func = acc_.GetValueIn(gate, 1);
|
||||
if (!CanOptimizeAsFastCall(func, 0)) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
builder_.JSCallThisTargetTypeCheck(funcType, func);
|
||||
GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate),
|
||||
EcmaOpcode::CALLTHIS0_IMM8_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = acc_.GetValueIn(gate, 0);
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj };
|
||||
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedCallthis1(GateRef gate)
|
||||
{
|
||||
// 3: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 3);
|
||||
|
||||
GateRef thisObj = acc_.GetValueIn(gate, 0);
|
||||
GateRef a0 = acc_.GetValueIn(gate, 1); // 1:parameter index
|
||||
GateType a0Type = acc_.GetGateType(a0);
|
||||
GateRef func = acc_.GetValueIn(gate, 2); // 2:function
|
||||
BuiltinsStubCSigns::ID id = GetBuiltinId(func, thisObj);
|
||||
if (id != BuiltinsStubCSigns::ID::NONE && a0Type.IsNumberType()) {
|
||||
AddProfiling(gate);
|
||||
SpeculateCallBuiltin(gate, id);
|
||||
} else {
|
||||
if (!CanOptimizeAsFastCall(func, 1)) {
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
builder_.JSCallThisTargetTypeCheck(funcType, func);
|
||||
GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate),
|
||||
EcmaOpcode::CALLTHIS1_IMM8_V8_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0 };
|
||||
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedCallthis2(GateRef gate)
|
||||
{
|
||||
// 4: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 4);
|
||||
GateRef func = acc_.GetValueIn(gate, 3); // 3: func
|
||||
if (!CanOptimizeAsFastCall(func, 2)) { // 2: 2 params
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
builder_.JSCallThisTargetTypeCheck(funcType, func);
|
||||
GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate),
|
||||
EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = acc_.GetValueIn(gate, 0);
|
||||
GateRef a0Value = acc_.GetValueIn(gate, 1);
|
||||
GateRef a1Value = acc_.GetValueIn(gate, 2);
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0Value, a1Value };
|
||||
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedCallthis3(GateRef gate)
|
||||
{
|
||||
// 5: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 5);
|
||||
GateRef func = acc_.GetValueIn(gate, 4); // 4: func
|
||||
if (!CanOptimizeAsFastCall(func, 3)) { // 3: 3 params
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
builder_.JSCallThisTargetTypeCheck(funcType, func);
|
||||
GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate),
|
||||
EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = acc_.GetValueIn(gate, 0);
|
||||
GateRef a0Value = acc_.GetValueIn(gate, 1);
|
||||
GateRef a1Value = acc_.GetValueIn(gate, 2);
|
||||
GateRef a2Value = acc_.GetValueIn(gate, 3);
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
std::vector<GateRef> args { glue_, env, actualArgc, func, newTarget, thisObj, a0Value, a1Value, a2Value };
|
||||
|
||||
GateRef result = builder_.TypedAotCall(gate, args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedCallthisrange(GateRef gate)
|
||||
{
|
||||
std::vector<GateRef> vec;
|
||||
// this
|
||||
size_t fixedInputsNum = 1;
|
||||
ASSERT(acc_.GetNumValueIn(gate) - fixedInputsNum >= 0);
|
||||
size_t numIns = acc_.GetNumValueIn(gate);
|
||||
GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate),
|
||||
EcmaOpcode::CALLTHISRANGE_IMM8_IMM8_V8));
|
||||
const size_t callTargetIndex = 1; // 1: acc
|
||||
GateRef func = acc_.GetValueIn(gate, numIns - callTargetIndex); // acc
|
||||
if (!CanOptimizeAsFastCall(func, numIns - 2)) { // 2 :func and thisobj
|
||||
acc_.DeleteStateSplitAndFrameState(gate);
|
||||
return;
|
||||
}
|
||||
GateType funcType = acc_.GetGateType(func);
|
||||
builder_.JSCallThisTargetTypeCheck(funcType, func);
|
||||
GateRef thisObj = acc_.GetValueIn(gate, 0);
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef env = builder_.GetFunctionLexicalEnv(func);
|
||||
vec.emplace_back(glue_);
|
||||
vec.emplace_back(env);
|
||||
vec.emplace_back(actualArgc);
|
||||
vec.emplace_back(func);
|
||||
vec.emplace_back(newTarget);
|
||||
vec.emplace_back(thisObj);
|
||||
// add common args
|
||||
for (size_t i = fixedInputsNum; i < numIns - callTargetIndex; i++) {
|
||||
vec.emplace_back(acc_.GetValueIn(gate, i));
|
||||
}
|
||||
GateRef result = builder_.TypedAotCall(gate, vec);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
@ -90,12 +90,19 @@ private:
|
||||
void LowerTypedNewObjRange(GateRef gate);
|
||||
void LowerTypedSuperCall(GateRef gate, GateRef ctor, GateRef newTarget);
|
||||
|
||||
void LowerCallThis1Imm8V8V8(GateRef gate);
|
||||
void LowerTypedCallArg0(GateRef gate);
|
||||
void LowerTypedCallArg1(GateRef gate);
|
||||
void LowerTypedCallArg2(GateRef gate);
|
||||
void LowerTypedCallArg3(GateRef gate);
|
||||
void LowerTypedCallrange(GateRef gate);
|
||||
void LowerTypedCallthis0(GateRef gate);
|
||||
void LowerTypedCallthis1(GateRef gate);
|
||||
void LowerTypedCallthis2(GateRef gate);
|
||||
void LowerTypedCallthis3(GateRef gate);
|
||||
void LowerTypedCallthisrange(GateRef gate);
|
||||
bool IsLoadVtable(GateRef func);
|
||||
bool CanOptimizeAsFastCall(GateRef func, uint32_t len);
|
||||
|
||||
bool CheckParam(GateRef gate, bool isCallThis, MethodLiteral* method);
|
||||
|
||||
// TypeTrusted means the type of gate is already PrimitiveTypeCheck-passed,
|
||||
|
@ -70,6 +70,9 @@ void TypeLowering::LowerType(GateRef gate)
|
||||
case OpCode::JSCALLTARGET_TYPE_CHECK:
|
||||
LowerJSCallTargetTypeCheck(gate);
|
||||
break;
|
||||
case OpCode::JSCALLTHISTARGET_TYPE_CHECK:
|
||||
LowerJSCallThisTargetTypeCheck(gate);
|
||||
break;
|
||||
case OpCode::TYPED_CALL_CHECK:
|
||||
LowerCallTargetCheck(gate);
|
||||
break;
|
||||
@ -3019,6 +3022,27 @@ void TypeLowering::LowerJSCallTargetTypeCheck(GateRef gate)
|
||||
}
|
||||
}
|
||||
|
||||
void TypeLowering::LowerJSCallThisTargetTypeCheck(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
auto type = acc_.GetParamGateType(gate);
|
||||
if (tsManager_->IsFunctionTypeKind(type)) {
|
||||
GateRef frameState = GetFrameState(gate);
|
||||
auto func = acc_.GetValueIn(gate, 0);
|
||||
GateRef isObj = builder_.TaggedIsHeapObject(func);
|
||||
GateRef isJsFunc = builder_.IsJSFunction(func);
|
||||
GateRef checkFunc = builder_.BoolAnd(isObj, isJsFunc);
|
||||
GateRef funcMethodTarget = builder_.GetMethodFromFunction(func);
|
||||
GateRef isAot = builder_.HasAotCode(funcMethodTarget);
|
||||
GateRef check = builder_.BoolAnd(checkFunc, isAot);
|
||||
builder_.DeoptCheck(check, frameState, DeoptType::NOTJSCALLTGT);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
} else {
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void TypeLowering::LowerCallTargetCheck(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
@ -203,6 +203,7 @@ private:
|
||||
void LowerTypedCallBuitin(GateRef gate);
|
||||
void LowerCallTargetCheck(GateRef gate);
|
||||
void LowerJSCallTargetTypeCheck(GateRef gate);
|
||||
void LowerJSCallThisTargetTypeCheck(GateRef gate);
|
||||
void LowerTypedNewAllocateThis(GateRef gate, GateRef glue);
|
||||
void LowerTypedSuperAllocateThis(GateRef gate, GateRef glue);
|
||||
void LowerGetSuperConstructor(GateRef gate);
|
||||
|
@ -121,8 +121,7 @@ public:
|
||||
return i;
|
||||
}
|
||||
}
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline void SetIndexHeader(const panda_file::File::IndexHeader *indexHeader)
|
||||
|
Loading…
x
Reference in New Issue
Block a user