mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
Support Lexenv In TSAOT
1. Support lexical env when running tsaot 2. fix getunmappedargs and copyrestargs bugs Issue: https://gitee.com/openharmony/ark_js_runtime/issues/I5C1P2 Signed-off-by: xujie <xujie101@huawei.com> Change-Id: Ia78ea4d89654d6924c0dee6f491cdf1e4fe718ee
This commit is contained in:
parent
0618a06957
commit
92d366b8fc
@ -1843,13 +1843,18 @@ void BytecodeCircuitBuilder::BuildCircuitArgs()
|
||||
const size_t numArgs = method_->GetNumArgs();
|
||||
const size_t actualNumArgs = GetActualNumArgs(numArgs);
|
||||
actualArgs_.resize(actualNumArgs);
|
||||
auto argRoot = Circuit::GetCircuitRoot(OpCode(OpCode::ARG_LIST));
|
||||
|
||||
auto glueGate = circuit_.NewGate(OpCode(OpCode::ARG), MachineType::I64, 0,
|
||||
{Circuit::GetCircuitRoot(OpCode(OpCode::ARG_LIST))},
|
||||
GateType::NJSValue());
|
||||
{argRoot}, GateType::NJSValue());
|
||||
actualArgs_.at(0) = glueGate;
|
||||
commonArgs_.at(0) = glueGate;
|
||||
auto argRoot = Circuit::GetCircuitRoot(OpCode(OpCode::ARG_LIST));
|
||||
|
||||
auto envGate = circuit_.NewGate(OpCode(OpCode::ARG), MachineType::I64, CommonArgIdx::LEXENV,
|
||||
{argRoot}, GateType::TaggedValue());
|
||||
actualArgs_.at(CommonArgIdx::LEXENV) = envGate;
|
||||
commonArgs_.at(CommonArgIdx::LEXENV) = envGate;
|
||||
|
||||
auto actualArgc = circuit_.NewGate(OpCode(OpCode::ARG), MachineType::I32, CommonArgIdx::ACTUAL_ARGC,
|
||||
{argRoot}, GateType::NJSValue());
|
||||
actualArgs_.at(CommonArgIdx::ACTUAL_ARGC) = actualArgc;
|
||||
@ -1863,8 +1868,7 @@ void BytecodeCircuitBuilder::BuildCircuitArgs()
|
||||
|
||||
for (size_t argIdx = CommonArgIdx::NUM_OF_ARGS; argIdx < actualNumArgs; argIdx++) {
|
||||
actualArgs_.at(argIdx) = circuit_.NewGate(OpCode(OpCode::ARG), MachineType::I64, argIdx,
|
||||
{Circuit::GetCircuitRoot(OpCode(OpCode::ARG_LIST))},
|
||||
GateType::TaggedValue());
|
||||
{argRoot}, GateType::TaggedValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,6 +376,7 @@ enum BytecodeOffset {
|
||||
|
||||
enum CommonArgIdx : uint8_t {
|
||||
GLUE = 0,
|
||||
LEXENV,
|
||||
ACTUAL_ARGC,
|
||||
FUNC,
|
||||
NEW_TARGET,
|
||||
|
@ -550,11 +550,12 @@ DEF_CALL_SIGNATURE(OptimizedCallOptimized)
|
||||
DEF_CALL_SIGNATURE(JSCall)
|
||||
{
|
||||
// 5 : 5 input parameters
|
||||
CallSignature jSCall("JSCall", 0, 5,
|
||||
CallSignature jSCall("JSCall", 0, 6,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = jSCall;
|
||||
std::array<VariableType, 5> params = { // 5 : 5 input parameters
|
||||
std::array<VariableType, 6> params = { // 6 : 6 input parameters
|
||||
VariableType::NATIVE_POINTER(), // glue
|
||||
VariableType::JS_ANY(), // lexenv
|
||||
VariableType::INT32(), // actual argC
|
||||
VariableType::JS_ANY(), // call target
|
||||
VariableType::JS_ANY(), // new target
|
||||
|
@ -469,6 +469,11 @@ void CircuitBuilder::SetLexicalEnvToFunction(GateRef glue, GateRef function, Gat
|
||||
Store(VariableType::JS_ANY(), glue, function, offset, value);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetLexicalEnv(GateRef function)
|
||||
{
|
||||
return Load(VariableType::JS_POINTER(), function, IntPtr(JSFunction::LEXICAL_ENV_OFFSET));
|
||||
}
|
||||
|
||||
void CircuitBuilder::SetModuleToFunction(GateRef glue, GateRef function, GateRef value)
|
||||
{
|
||||
GateRef offset = IntPtr(JSFunction::ECMA_MODULE_OFFSET);
|
||||
|
@ -355,6 +355,7 @@ public:
|
||||
void SetResolvedToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetConstPoolToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetLexicalEnvToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
GateRef GetLexicalEnv(GateRef function);
|
||||
void SetModuleToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass,
|
||||
GateRef value, GateRef attrOffset, VariableType type);
|
||||
|
@ -488,8 +488,9 @@ void JsProxyCallInternalStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
GateRef arrHandle = CallRuntime(glue, RTSTUB_ID(CreateArrayFromList), argc, argv);
|
||||
GateRef thisArg = Load(VariableType::JS_POINTER(), argv, IntPtr(2*sizeof(JSTaggedValue)));
|
||||
GateRef numArgs = Int32(6);
|
||||
GateRef lexEnv = Load(VariableType::JS_POINTER(), method, IntPtr(JSFunction::LEXICAL_ENV_OFFSET));
|
||||
result = CallNGCRuntime(glue, RTSTUB_ID(JSCall),
|
||||
{glue, numArgs, method, Undefined(), handler, target, thisArg, arrHandle});
|
||||
{glue, lexEnv, numArgs, method, Undefined(), handler, target, thisArg, arrHandle});
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
|
@ -1072,12 +1072,29 @@ void LLVMIRBuilder::VisitParameter(GateRef gate)
|
||||
ASSERT(LLVMTypeOf(value) == ConvertLLVMTypeFromGate(gate));
|
||||
gate2LValue_[gate] = value;
|
||||
// NOTE: caller put args, otherwise crash
|
||||
if (value == nullptr) {
|
||||
COMPILER_OPTIONAL_LOG(FATAL) << "generate LLVM IR for para: " << argth << "fail";
|
||||
return;
|
||||
ASSERT(value != nullptr);
|
||||
|
||||
// add env slot for optimized jsfunction frame
|
||||
auto frameType = circuit_->GetFrameType();
|
||||
if (frameType == panda::ecmascript::FrameType::OPTIMIZED_JS_FUNCTION_FRAME) {
|
||||
if (argth == CommonArgIdx::LEXENV) {
|
||||
SaveLexicalEnvOnFrame(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLVMIRBuilder::SaveLexicalEnvOnFrame(LLVMValueRef value)
|
||||
{
|
||||
LLVMValueRef llvmFpAddr = CallingFp(module_, builder_, false);
|
||||
LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder_, llvmFpAddr, slotType_, "cast_int_t");
|
||||
LLVMValueRef frameEnvSlotAddr = LLVMBuildSub(builder_, frameAddr, LLVMConstInt(slotType_,
|
||||
static_cast<int>(ReservedSlots::OPTIMIZED_JS_FUNCTION_RESERVED_SLOT) * slotSize_, false), "");
|
||||
LLVMValueRef envAddr = LLVMBuildIntToPtr(builder_, frameEnvSlotAddr,
|
||||
LLVMPointerType(slotType_, 0), "env.Addr");
|
||||
LLVMValueRef envValue = LLVMBuildPtrToInt(builder_, value, slotType_, "cast_to_i64");
|
||||
LLVMBuildStore(builder_, envValue, envAddr);
|
||||
}
|
||||
|
||||
void LLVMIRBuilder::HandleBranch(GateRef gate)
|
||||
{
|
||||
std::vector<GateRef> ins = circuit_->GetInVector(gate);
|
||||
@ -1942,6 +1959,8 @@ LLVMValueRef LLVMModule::AddFunc(const panda::ecmascript::JSMethod *method)
|
||||
auto paramCount = method->GetNumArgs() + CommonArgIdx::NUM_OF_ARGS;
|
||||
VariableType glueParamType(MachineType::I64, GateType::NJSValue());
|
||||
paramTys.push_back(ConvertLLVMTypeFromVariableType(glueParamType));
|
||||
VariableType lexEnv(MachineType::I64, GateType::TaggedValue());
|
||||
paramTys.push_back(ConvertLLVMTypeFromVariableType(lexEnv));
|
||||
VariableType actualArgc(MachineType::I32, GateType::NJSValue());
|
||||
paramTys.push_back(ConvertLLVMTypeFromVariableType(actualArgc));
|
||||
for (uint32_t i = CommonArgIdx::FUNC; i < CommonArgIdx::NUM_OF_ARGS; i++) {
|
||||
|
@ -305,6 +305,7 @@ private:
|
||||
bool NeedBCOffset(OpCode op);
|
||||
void ComputeArgCountAndBCOffset(size_t &actualNumArgs, LLVMValueRef &bcOffset, const std::vector<GateRef> &inList,
|
||||
OpCode op);
|
||||
void SaveLexicalEnvOnFrame(LLVMValueRef value);
|
||||
const CompilationConfig *compCfg_ {nullptr};
|
||||
const std::vector<std::vector<GateRef>> *scheduledGates_ {nullptr};
|
||||
const Circuit *circuit_ {nullptr};
|
||||
|
@ -204,12 +204,6 @@ GateRef SlowPathLowering::GetConstPool(GateRef jsFunc)
|
||||
return builder_.Load(VariableType::JS_ANY(), jsFunc, builder_.IntPtr(JSFunction::CONSTANT_POOL_OFFSET));
|
||||
}
|
||||
|
||||
// labelmanager must be initialized
|
||||
GateRef SlowPathLowering::GetCurrentEnv(GateRef jsFunc)
|
||||
{
|
||||
return builder_.Load(VariableType::JS_ANY(), jsFunc, builder_.IntPtr(JSFunction::LEXICAL_ENV_OFFSET));
|
||||
}
|
||||
|
||||
// labelmanager must be initialized
|
||||
GateRef SlowPathLowering::GetObjectFromConstPool(GateRef jsFunc, GateRef index)
|
||||
{
|
||||
@ -269,7 +263,7 @@ void SlowPathLowering::Lower(GateRef gate)
|
||||
LowerCallIRangeDyn(gate, glue);
|
||||
break;
|
||||
case LDLEXENVDYN_PREF:
|
||||
LowerLexicalEnv(gate, glue, jsFunc);
|
||||
LowerLexicalEnv(gate, glue);
|
||||
break;
|
||||
case GETUNMAPPEDARGS_PREF:
|
||||
LowerGetUnmappedArgs(gate, glue);
|
||||
@ -529,13 +523,13 @@ void SlowPathLowering::Lower(GateRef gate)
|
||||
LowerDefineAsyncFunc(gate, glue, jsFunc);
|
||||
break;
|
||||
case NEWLEXENVDYN_PREF_IMM16:
|
||||
LowerNewLexicalEnvDyn(gate, glue, jsFunc);
|
||||
LowerNewLexicalEnvDyn(gate, glue);
|
||||
break;
|
||||
case NEWLEXENVWITHNAMEDYN_PREF_IMM16_IMM16:
|
||||
LowerNewLexicalEnvWithNameDyn(gate, glue, jsFunc);
|
||||
break;
|
||||
case POPLEXENVDYN_PREF:
|
||||
LowerPopLexicalEnv(gate, glue, jsFunc);
|
||||
LowerPopLexicalEnv(gate, glue);
|
||||
break;
|
||||
case LDSUPERBYVALUE_PREF_V8_V8:
|
||||
LowerLdSuperByValue(gate, glue, jsFunc);
|
||||
@ -600,12 +594,12 @@ void SlowPathLowering::Lower(GateRef gate)
|
||||
case LDLEXVARDYN_PREF_IMM4_IMM4:
|
||||
case LDLEXVARDYN_PREF_IMM8_IMM8:
|
||||
case LDLEXVARDYN_PREF_IMM16_IMM16:
|
||||
LowerLdLexVarDyn(gate, jsFunc);
|
||||
LowerLdLexVarDyn(gate, glue);
|
||||
break;
|
||||
case STLEXVARDYN_PREF_IMM4_IMM4_V8:
|
||||
case STLEXVARDYN_PREF_IMM8_IMM8_V8:
|
||||
case STLEXVARDYN_PREF_IMM16_IMM16_V8:
|
||||
LowerStLexVarDyn(gate, glue, jsFunc);
|
||||
LowerStLexVarDyn(gate, glue);
|
||||
break;
|
||||
case CREATEOBJECTHAVINGMETHOD_PREF_IMM16:
|
||||
LowerCreateObjectHavingMethod(gate, glue, jsFunc);
|
||||
@ -703,10 +697,10 @@ void SlowPathLowering::LowerLoadStr(GateRef gate, GateRef glue)
|
||||
ReplaceHirToCall(gate, newGate);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerLexicalEnv(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
void SlowPathLowering::LowerLexicalEnv(GateRef gate, GateRef glue)
|
||||
{
|
||||
const int id = RTSTUB_ID(GetAotLexicalEnv);
|
||||
GateRef newGate = LowerCallRuntime(glue, id, {jsFunc});
|
||||
GateRef newGate = LowerCallRuntime(glue, id, {});
|
||||
ReplaceHirToCall(gate, newGate, true);
|
||||
}
|
||||
|
||||
@ -810,8 +804,10 @@ void SlowPathLowering::LowerCallArg0Dyn(GateRef gate, GateRef glue)
|
||||
GateRef actualArgc = builder_.Int32(ComputeCallArgc(gate, EcmaOpcode::CALLARG0DYN_PREF_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = builder_.Undefined();
|
||||
LowerToJSCall(gate, glue, {glue, actualArgc, acc_.GetValueIn(gate, 0), newTarget, thisObj,
|
||||
acc_.GetValueIn(gate, 1)});
|
||||
GateRef func = acc_.GetValueIn(gate, 0);
|
||||
GateRef env = builder_.GetLexicalEnv(func);
|
||||
GateRef bcOffset = acc_.GetValueIn(gate, 1);
|
||||
LowerToJSCall(gate, glue, {glue, env, actualArgc, func, newTarget, thisObj, bcOffset});
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerCallArg1Dyn(GateRef gate, GateRef glue)
|
||||
@ -822,8 +818,10 @@ void SlowPathLowering::LowerCallArg1Dyn(GateRef gate, GateRef glue)
|
||||
GateRef actualArgc = builder_.Int32(ComputeCallArgc(gate, EcmaOpcode::CALLARG1DYN_PREF_V8_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = builder_.Undefined();
|
||||
LowerToJSCall(gate, glue, {glue, actualArgc,
|
||||
acc_.GetValueIn(gate, 0), newTarget, thisObj, acc_.GetValueIn(gate, 1), acc_.GetValueIn(gate, 2)});
|
||||
GateRef func = acc_.GetValueIn(gate, 0);
|
||||
GateRef env = builder_.GetLexicalEnv(func);
|
||||
GateRef bcOffset = acc_.GetValueIn(gate, 2); // 2: bytecode offset
|
||||
LowerToJSCall(gate, glue, {glue, env, actualArgc, func, newTarget, thisObj, acc_.GetValueIn(gate, 1), bcOffset});
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerCallArgs2Dyn(GateRef gate, GateRef glue)
|
||||
@ -834,9 +832,11 @@ void SlowPathLowering::LowerCallArgs2Dyn(GateRef gate, GateRef glue)
|
||||
GateRef actualArgc = builder_.Int32(ComputeCallArgc(gate, EcmaOpcode::CALLARGS2DYN_PREF_V8_V8_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = builder_.Undefined();
|
||||
LowerToJSCall(gate, glue, {glue, actualArgc,
|
||||
acc_.GetValueIn(gate, 0), newTarget, thisObj, acc_.GetValueIn(gate, 1), acc_.GetValueIn(gate, 2),
|
||||
acc_.GetValueIn(gate, 3)});
|
||||
GateRef func = acc_.GetValueIn(gate, 0);
|
||||
GateRef env = builder_.GetLexicalEnv(func);
|
||||
GateRef bcOffset = acc_.GetValueIn(gate, 3); // 3: bytecode offset
|
||||
LowerToJSCall(gate, glue, {glue, env, actualArgc, func, newTarget, thisObj, acc_.GetValueIn(gate, 1),
|
||||
acc_.GetValueIn(gate, 2), bcOffset});
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerCallArgs3Dyn(GateRef gate, GateRef glue)
|
||||
@ -847,9 +847,11 @@ void SlowPathLowering::LowerCallArgs3Dyn(GateRef gate, GateRef glue)
|
||||
GateRef actualArgc = builder_.Int32(ComputeCallArgc(gate, EcmaOpcode::CALLARGS3DYN_PREF_V8_V8_V8_V8));
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = builder_.Undefined();
|
||||
LowerToJSCall(gate, glue, {glue, actualArgc,
|
||||
acc_.GetValueIn(gate, 0), newTarget, thisObj, acc_.GetValueIn(gate, 1),
|
||||
acc_.GetValueIn(gate, 2), acc_.GetValueIn(gate, 3)});
|
||||
GateRef func = acc_.GetValueIn(gate, 0);
|
||||
GateRef env = builder_.GetLexicalEnv(func);
|
||||
GateRef bcOffset = acc_.GetValueIn(gate, 4); // 4: bytecode offset
|
||||
LowerToJSCall(gate, glue, {glue, env, actualArgc, func, newTarget, thisObj, acc_.GetValueIn(gate, 1),
|
||||
acc_.GetValueIn(gate, 2), acc_.GetValueIn(gate, 3), bcOffset});
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerCallIThisRangeDyn(GateRef gate, GateRef glue)
|
||||
@ -862,13 +864,16 @@ void SlowPathLowering::LowerCallIThisRangeDyn(GateRef gate, GateRef glue)
|
||||
GateRef callTarget = acc_.GetValueIn(gate, 0);
|
||||
GateRef thisObj = acc_.GetValueIn(gate, 1);
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef env = builder_.GetLexicalEnv(callTarget);
|
||||
vec.emplace_back(glue);
|
||||
vec.emplace_back(env);
|
||||
vec.emplace_back(actualArgc);
|
||||
vec.emplace_back(callTarget);
|
||||
vec.emplace_back(newTarget);
|
||||
vec.emplace_back(thisObj);
|
||||
// add common args
|
||||
for (size_t i = fixedInputsNum; i < acc_.GetNumValueIn(gate); i++) {
|
||||
size_t numIns = acc_.GetNumValueIn(gate);
|
||||
for (size_t i = fixedInputsNum; i < numIns; i++) {
|
||||
vec.emplace_back(acc_.GetValueIn(gate, i));
|
||||
}
|
||||
LowerToJSCall(gate, glue, vec);
|
||||
@ -893,7 +898,9 @@ void SlowPathLowering::LowerCallIRangeDyn(GateRef gate, GateRef glue)
|
||||
GateRef callTarget = acc_.GetValueIn(gate, 0);
|
||||
GateRef newTarget = builder_.Undefined();
|
||||
GateRef thisObj = builder_.Undefined();
|
||||
GateRef env = builder_.GetLexicalEnv(callTarget);
|
||||
vec.emplace_back(glue);
|
||||
vec.emplace_back(env);
|
||||
vec.emplace_back(actualArgc);
|
||||
vec.emplace_back(callTarget);
|
||||
vec.emplace_back(newTarget);
|
||||
@ -1877,13 +1884,13 @@ void SlowPathLowering::LowerDefineAsyncFunc(GateRef gate, GateRef glue, GateRef
|
||||
ReplaceHirToSubCfg(gate, result, successControl, failControl);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerNewLexicalEnvDyn(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
void SlowPathLowering::LowerNewLexicalEnvDyn(GateRef gate, GateRef glue)
|
||||
{
|
||||
std::vector<GateRef> successControl;
|
||||
std::vector<GateRef> failControl;
|
||||
// 1: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 1);
|
||||
GateRef lexEnv = LowerCallRuntime(glue, RTSTUB_ID(GetAotLexicalEnv), {jsFunc}, true);
|
||||
GateRef lexEnv = LowerCallRuntime(glue, RTSTUB_ID(GetAotLexicalEnv), {}, true);
|
||||
GateRef result = LowerCallRuntime(glue, RTSTUB_ID(NewAotLexicalEnvDyn),
|
||||
{builder_.TaggedTypeNGC(acc_.GetValueIn(gate, 0)), lexEnv}, true);
|
||||
successControl.emplace_back(builder_.GetState());
|
||||
@ -1899,10 +1906,10 @@ void SlowPathLowering::LowerNewLexicalEnvWithNameDyn(GateRef gate, GateRef glue,
|
||||
std::vector<GateRef> failControl;
|
||||
// 2: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 2);
|
||||
GateRef lexEnv = LowerCallRuntime(glue, RTSTUB_ID(GetAotLexicalEnv), {jsFunc}, true);
|
||||
GateRef lexEnv = LowerCallRuntime(glue, RTSTUB_ID(GetAotLexicalEnv), {}, true);
|
||||
auto args = { builder_.TaggedTypeNGC(acc_.GetValueIn(gate, 0)),
|
||||
builder_.TaggedTypeNGC(acc_.GetValueIn(gate, 1)),
|
||||
lexEnv};
|
||||
lexEnv, jsFunc};
|
||||
GateRef result = LowerCallRuntime(glue, RTSTUB_ID(NewAotLexicalEnvWithNameDyn), args, true);
|
||||
successControl.emplace_back(builder_.GetState());
|
||||
successControl.emplace_back(builder_.GetDepend());
|
||||
@ -1911,14 +1918,11 @@ void SlowPathLowering::LowerNewLexicalEnvWithNameDyn(GateRef gate, GateRef glue,
|
||||
ReplaceHirToSubCfg(gate, result, successControl, failControl, true);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerPopLexicalEnv(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
void SlowPathLowering::LowerPopLexicalEnv(GateRef gate, GateRef glue)
|
||||
{
|
||||
std::vector<GateRef> successControl;
|
||||
std::vector<GateRef> failControl;
|
||||
GateRef result = LowerCallRuntime(glue, RTSTUB_ID(GetAotLexicalEnv), {jsFunc}, true);
|
||||
GateRef index = builder_.Int32(LexicalEnv::PARENT_ENV_INDEX);
|
||||
GateRef parentLexEnv = builder_.GetValueFromTaggedArray(VariableType::JS_ANY(), result, index);
|
||||
builder_.SetLexicalEnvToFunction(glue, jsFunc, parentLexEnv);
|
||||
LowerCallRuntime(glue, RTSTUB_ID(PopAotLexicalEnv), {}, true);
|
||||
successControl.emplace_back(builder_.GetState());
|
||||
successControl.emplace_back(builder_.GetDepend());
|
||||
failControl.emplace_back(Circuit::NullGate());
|
||||
@ -2496,13 +2500,14 @@ void SlowPathLowering::LowerStArraySpread(GateRef gate, GateRef glue)
|
||||
ReplaceHirToCall(gate, newGate);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerLdLexVarDyn(GateRef gate, GateRef jsFunc)
|
||||
void SlowPathLowering::LowerLdLexVarDyn(GateRef gate, GateRef glue)
|
||||
{
|
||||
// 2: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 2);
|
||||
GateRef level = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0));
|
||||
GateRef slot = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 1));
|
||||
DEFVAlUE(currentEnv, (&builder_), VariableType::JS_ANY(), GetCurrentEnv(jsFunc));
|
||||
DEFVAlUE(currentEnv, (&builder_), VariableType::JS_ANY(),
|
||||
LowerCallRuntime(glue, RTSTUB_ID(GetAotLexicalEnv), {}, true));
|
||||
DEFVAlUE(i, (&builder_), VariableType::INT32(), builder_.Int32(0));
|
||||
std::vector<GateRef> successControl;
|
||||
std::vector<GateRef> exceptionControl;
|
||||
@ -2528,14 +2533,15 @@ void SlowPathLowering::LowerLdLexVarDyn(GateRef gate, GateRef jsFunc)
|
||||
ReplaceHirToSubCfg(gate, result, successControl, exceptionControl, true);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerStLexVarDyn(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
void SlowPathLowering::LowerStLexVarDyn(GateRef gate, GateRef glue)
|
||||
{
|
||||
// 3: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 3);
|
||||
GateRef level = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0));
|
||||
GateRef slot = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 1));
|
||||
GateRef value = acc_.GetValueIn(gate, 2);
|
||||
DEFVAlUE(currentEnv, (&builder_), VariableType::JS_ANY(), GetCurrentEnv(jsFunc));
|
||||
DEFVAlUE(currentEnv, (&builder_), VariableType::JS_ANY(),
|
||||
LowerCallRuntime(glue, RTSTUB_ID(GetAotLexicalEnv), {}, true));
|
||||
DEFVAlUE(i, (&builder_), VariableType::INT32(), builder_.Int32(0));
|
||||
std::vector<GateRef> successControl;
|
||||
std::vector<GateRef> exceptionControl;
|
||||
@ -2986,59 +2992,20 @@ void SlowPathLowering::LowerGetUnmappedArgs(GateRef gate, GateRef glue)
|
||||
{
|
||||
GateRef actualArgc = bcBuilder_->GetCommonArgByIndex(CommonArgIdx::ACTUAL_ARGC);
|
||||
GateRef taggedArgc = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(actualArgc));
|
||||
std::vector<GateRef> vec;
|
||||
const size_t fixedArgs = 3;
|
||||
GateRef argList = Circuit::GetCircuitRoot(OpCode(OpCode::ARG_LIST));
|
||||
auto uses = acc_.ConstUses(argList);
|
||||
for (auto useIt = uses.begin(); useIt != uses.end(); useIt++) {
|
||||
vec.emplace_back(*useIt);
|
||||
}
|
||||
std::vector<GateRef> args({vec.rbegin() + CommonArgIdx::NUM_OF_ARGS, vec.rend()});
|
||||
size_t argsNum = args.size() + fixedArgs;
|
||||
args.insert(args.begin(), taggedArgc);
|
||||
DEFVAlUE(unmappedObj, (&builder_), VariableType::JS_ANY(), builder_.Undefined());
|
||||
Label normalArgs(&builder_);
|
||||
Label restArgs(&builder_);
|
||||
Label successExit(&builder_);
|
||||
Label exceptionExit(&builder_);
|
||||
GateRef result;
|
||||
std::vector<GateRef> successControl;
|
||||
std::vector<GateRef> failControl;
|
||||
builder_.Branch(builder_.Int32GreaterThan(actualArgc, builder_.Int32(argsNum)), &restArgs, &normalArgs);
|
||||
builder_.Bind(&restArgs);
|
||||
{
|
||||
unmappedObj = LowerCallRuntime(glue, RTSTUB_ID(GetAotUnmapedArgsWithRestArgs), {taggedArgc}, true);
|
||||
builder_.Branch(builder_.IsSpecial(*unmappedObj, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
}
|
||||
builder_.Bind(&normalArgs);
|
||||
{
|
||||
unmappedObj = LowerCallRuntime(glue, RTSTUB_ID(GetAotUnmapedArgs), args, true);
|
||||
builder_.Branch(builder_.IsSpecial(*unmappedObj, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
}
|
||||
builder_.Bind(&successExit);
|
||||
{
|
||||
result = *unmappedObj;
|
||||
successControl.emplace_back(builder_.GetState());
|
||||
successControl.emplace_back(builder_.GetDepend());
|
||||
}
|
||||
builder_.Bind(&exceptionExit);
|
||||
{
|
||||
failControl.emplace_back(builder_.GetState());
|
||||
failControl.emplace_back(builder_.GetDepend());
|
||||
}
|
||||
ReplaceHirToSubCfg(gate, result, successControl, failControl);
|
||||
const int id = RTSTUB_ID(GetAotUnmapedArgs);
|
||||
GateRef newGate = LowerCallRuntime(glue, id, {taggedArgc});
|
||||
ReplaceHirToCall(gate, newGate);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerCopyRestArgs(GateRef gate, GateRef glue)
|
||||
{
|
||||
GateRef actualArgc = bcBuilder_->GetCommonArgByIndex(CommonArgIdx::ACTUAL_ARGC);
|
||||
GateRef restIdx = acc_.GetValueIn(gate, 0);
|
||||
GateRef taggedArgc = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(actualArgc));
|
||||
GateRef taggedRestId = builder_.TaggedTypeNGC(restIdx);
|
||||
int id = RTSTUB_ID(CopyAotRestArgs);
|
||||
GateRef newGate = LowerCallRuntime(glue, id, {taggedArgc, taggedRestId});
|
||||
GateRef restIdx = acc_.GetValueIn(gate, 0);
|
||||
GateRef taggedRestIdx = builder_.TaggedTypeNGC(restIdx);
|
||||
|
||||
const int id = RTSTUB_ID(CopyAotRestArgs);
|
||||
GateRef newGate = LowerCallRuntime(glue, id, {taggedArgc, taggedRestIdx});
|
||||
ReplaceHirToCall(gate, newGate);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -133,8 +133,6 @@ private:
|
||||
// environment must be initialized
|
||||
GateRef GetConstPool(GateRef jsFunc);
|
||||
// environment must be initialized
|
||||
GateRef GetCurrentEnv(GateRef jsFunc);
|
||||
// environment must be initialized
|
||||
GateRef GetObjectFromConstPool(GateRef jsFunc, GateRef index);
|
||||
// environment must be initialized
|
||||
GateRef GetHomeObjectFromJSFunction(GateRef jsFunc);
|
||||
@ -147,7 +145,7 @@ private:
|
||||
void LowerAsyncFunctionResolve(GateRef gate, GateRef glue);
|
||||
void LowerAsyncFunctionReject(GateRef gate, GateRef glue);
|
||||
void LowerLoadStr(GateRef gate, GateRef glue);
|
||||
void LowerLexicalEnv(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerLexicalEnv(GateRef gate, GateRef glue);
|
||||
void LowerStGlobalVar(GateRef gate, GateRef glue);
|
||||
void LowerTryLdGlobalByName(GateRef gate, GateRef glue);
|
||||
void LowerGetIterator(GateRef gate, GateRef glue);
|
||||
@ -226,9 +224,9 @@ private:
|
||||
void LowerDefineFuncDyn(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerDefineGeneratorFunc(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerDefineAsyncFunc(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerNewLexicalEnvDyn(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerNewLexicalEnvDyn(GateRef gate, GateRef glue);
|
||||
void LowerNewLexicalEnvWithNameDyn(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerPopLexicalEnv(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerPopLexicalEnv(GateRef gate, GateRef glue);
|
||||
void LowerLdSuperByValue(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerStSuperByValue(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerTryStGlobalByName(GateRef gate, GateRef glue);
|
||||
@ -249,8 +247,8 @@ private:
|
||||
void LowerStObjByValue(GateRef gate, GateRef glue);
|
||||
void LowerCreateGeneratorObj(GateRef gate, GateRef glue);
|
||||
void LowerStArraySpread(GateRef gate, GateRef glue);
|
||||
void LowerLdLexVarDyn(GateRef gate, GateRef jsFunc);
|
||||
void LowerStLexVarDyn(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerLdLexVarDyn(GateRef gate, GateRef glue);
|
||||
void LowerStLexVarDyn(GateRef gate, GateRef glue);
|
||||
void LowerCreateObjectHavingMethod(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerLdHomeObject(GateRef gate, GateRef jsFunc);
|
||||
void LowerDefineClassWithBuffer(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
|
@ -4018,26 +4018,27 @@ GateRef Stub::JSCallDispatch(GateRef glue, GateRef func, GateRef actualNumArgs,
|
||||
{
|
||||
GateRef newTarget = Undefined();
|
||||
GateRef thisValue = Undefined();
|
||||
GateRef lexEnv = builder_.GetLexicalEnv(func);
|
||||
GateRef realNumArgs = Int32Add(actualNumArgs, Int32(NUM_MANDATORY_JSFUNC_ARGS));
|
||||
switch (mode) {
|
||||
case JSCallMode::CALL_ARG0:
|
||||
result = CallNGCRuntime(glue, RTSTUB_ID(JSCall),
|
||||
{ glue, realNumArgs, func, newTarget, thisValue});
|
||||
{ glue, lexEnv, realNumArgs, func, newTarget, thisValue});
|
||||
Jump(&exit);
|
||||
break;
|
||||
case JSCallMode::CALL_ARG1:
|
||||
result = CallNGCRuntime(glue, RTSTUB_ID(JSCall),
|
||||
{ glue, realNumArgs, func, newTarget, thisValue, data[0] });
|
||||
{ glue, lexEnv, realNumArgs, func, newTarget, thisValue, data[0] });
|
||||
Jump(&exit);
|
||||
break;
|
||||
case JSCallMode::CALL_ARG2:
|
||||
result = CallNGCRuntime(glue, RTSTUB_ID(JSCall),
|
||||
{ glue, realNumArgs, func, newTarget, thisValue, data[0], data[1] });
|
||||
{ glue, lexEnv, realNumArgs, func, newTarget, thisValue, data[0], data[1] });
|
||||
Jump(&exit);
|
||||
break;
|
||||
case JSCallMode::CALL_ARG3:
|
||||
result = CallNGCRuntime(glue, RTSTUB_ID(JSCall),
|
||||
{ glue, realNumArgs, func, newTarget, thisValue,
|
||||
{ glue, lexEnv, realNumArgs, func, newTarget, thisValue,
|
||||
data[0], data[1], data[2] }); // 2: args2
|
||||
Jump(&exit);
|
||||
break;
|
||||
@ -4056,12 +4057,12 @@ GateRef Stub::JSCallDispatch(GateRef glue, GateRef func, GateRef actualNumArgs,
|
||||
break;
|
||||
case JSCallMode::CALL_GETTER:
|
||||
result = CallNGCRuntime(glue, RTSTUB_ID(JSCall),
|
||||
{ glue, realNumArgs, func, newTarget, data[0]});
|
||||
{ glue, lexEnv, realNumArgs, func, newTarget, data[0]});
|
||||
Jump(&exit);
|
||||
break;
|
||||
case JSCallMode::CALL_SETTER:
|
||||
result = CallNGCRuntime(glue, RTSTUB_ID(JSCall),
|
||||
{ glue, realNumArgs, func, newTarget, data[0], data[1]});
|
||||
{ glue, lexEnv, realNumArgs, func, newTarget, data[0], data[1]});
|
||||
Jump(&exit);
|
||||
break;
|
||||
default:
|
||||
|
@ -27,18 +27,20 @@ void FooAOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef argc = Int32Argument(1);
|
||||
GateRef calltarget = TaggedArgument(2);
|
||||
GateRef newtarget = TaggedArgument(3);
|
||||
GateRef thisObj = TaggedArgument(4);
|
||||
GateRef a = TaggedArgument(5);
|
||||
GateRef b = TaggedArgument(6);
|
||||
GateRef bcOffset = Int32Argument(1);
|
||||
GateRef env = TaggedArgument(1);
|
||||
GateRef argc = Int32Argument(2);
|
||||
GateRef calltarget = TaggedArgument(3);
|
||||
GateRef newtarget = TaggedArgument(4);
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
(void)calltarget;
|
||||
GateRef barIndex = IntToTaggedNGC(Int32(CommonStubCSigns::BarAOT));
|
||||
GateRef numArgs = IntToTaggedNGC(Int32(2));
|
||||
GateRef barfunc = CallRuntime(glue, RTSTUB_ID(DefineAotFunc), {barIndex, numArgs});
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, argc, barfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
GateRef result =
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, barfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
@ -46,12 +48,13 @@ void BarAOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
GateRef glue = PtrArgument(0);
|
||||
[[maybe_unused]] GateRef argc = Int32Argument(1);
|
||||
[[maybe_unused]] GateRef calltarget = TaggedArgument(2);
|
||||
[[maybe_unused]] GateRef newtarget = TaggedArgument(3);
|
||||
[[maybe_unused]] GateRef thisObj = TaggedArgument(4);
|
||||
GateRef a = TaggedArgument(5);
|
||||
GateRef b = TaggedArgument(6);
|
||||
[[maybe_unused]] GateRef env = TaggedArgument(1);
|
||||
[[maybe_unused]] GateRef argc = Int32Argument(2);
|
||||
[[maybe_unused]] GateRef calltarget = TaggedArgument(3);
|
||||
[[maybe_unused]] GateRef newtarget = TaggedArgument(4);
|
||||
[[maybe_unused]] GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef result = CallRuntime(glue, RTSTUB_ID(Add2Dyn), {a, b});
|
||||
Return(result);
|
||||
}
|
||||
@ -60,18 +63,20 @@ void Foo1AOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef argc = Int32Argument(1);
|
||||
GateRef calltarget = TaggedArgument(2);
|
||||
GateRef newtarget = TaggedArgument(3);
|
||||
GateRef thisObj = TaggedArgument(4);
|
||||
GateRef a = TaggedArgument(5);
|
||||
GateRef b = TaggedArgument(6);
|
||||
GateRef bcOffset = Int32Argument(1);
|
||||
GateRef env = TaggedArgument(1);
|
||||
GateRef argc = Int32Argument(2);
|
||||
GateRef calltarget = TaggedArgument(3);
|
||||
GateRef newtarget = TaggedArgument(4);
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
(void)calltarget;
|
||||
GateRef barIndex = IntToTaggedTypeNGC(Int32(CommonStubCSigns::Bar1AOT));
|
||||
GateRef numArgs = IntToTaggedTypeNGC(Int32(3));
|
||||
GateRef barfunc = CallRuntime(glue, RTSTUB_ID(DefineAotFunc), {barIndex, numArgs});
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, argc, barfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
GateRef result =
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, barfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
@ -79,17 +84,19 @@ void Bar1AOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef argc = Int32Argument(1);
|
||||
GateRef calltarget = TaggedArgument(2);
|
||||
GateRef newtarget = TaggedArgument(3);
|
||||
GateRef thisObj = TaggedArgument(4);
|
||||
GateRef env = TaggedArgument(1);
|
||||
GateRef argc = Int32Argument(2);
|
||||
GateRef calltarget = TaggedArgument(3);
|
||||
GateRef newtarget = TaggedArgument(4);
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
(void)env;
|
||||
(void)argc;
|
||||
(void)calltarget;
|
||||
(void)newtarget;
|
||||
(void)thisObj;
|
||||
GateRef a = TaggedArgument(5);
|
||||
GateRef b = TaggedArgument(6);
|
||||
GateRef c = TaggedArgument(7);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef c = TaggedArgument(8);
|
||||
GateRef result = CallRuntime(glue, RTSTUB_ID(Add2Dyn), {a, b});
|
||||
GateRef result2 = CallRuntime(glue, RTSTUB_ID(Add2Dyn), {result, c});
|
||||
Return(result2);
|
||||
@ -99,19 +106,20 @@ void Foo2AOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef argc = Int32Argument(1);
|
||||
GateRef calltarget = TaggedArgument(2);
|
||||
GateRef newtarget = TaggedArgument(3);
|
||||
GateRef thisObj = TaggedArgument(4);
|
||||
GateRef a = TaggedArgument(5);
|
||||
GateRef b = TaggedArgument(6);
|
||||
GateRef bcOffset = Int32Argument(1);
|
||||
GateRef env = TaggedArgument(1);
|
||||
GateRef argc = Int32Argument(2);
|
||||
GateRef calltarget = TaggedArgument(3);
|
||||
GateRef newtarget = TaggedArgument(4);
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
(void)calltarget;
|
||||
GateRef actualArgC = Int32Add(argc, Int32(1));
|
||||
GateRef barIndex = IntToTaggedTypeNGC(Int32(CommonStubCSigns::BarAOT));
|
||||
GateRef numArgs = IntToTaggedTypeNGC(Int32(2));
|
||||
GateRef barfunc = CallRuntime(glue, RTSTUB_ID(DefineAotFunc), {barIndex, numArgs});
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, actualArgC, barfunc, newtarget, thisObj,
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, actualArgC, barfunc, newtarget, thisObj,
|
||||
a, b, Undefined(), bcOffset});
|
||||
Return(result);
|
||||
}
|
||||
@ -120,17 +128,18 @@ void FooNativeAOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef argc = Int32Argument(1);
|
||||
GateRef calltarget = TaggedArgument(2);
|
||||
GateRef newtarget = TaggedArgument(3);
|
||||
GateRef thisObj = TaggedArgument(4);
|
||||
GateRef a = TaggedArgument(5);
|
||||
GateRef b = TaggedArgument(6);
|
||||
GateRef bcOffset = Int32Argument(1);
|
||||
GateRef env = TaggedArgument(1);
|
||||
GateRef argc = Int32Argument(2);
|
||||
GateRef calltarget = TaggedArgument(3);
|
||||
GateRef newtarget = TaggedArgument(4);
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
(void)calltarget;
|
||||
GateRef actualArgC = Int32Add(argc, Int32(1));
|
||||
GateRef printfunc = CallRuntime(glue, RTSTUB_ID(GetPrintFunc), {});
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, actualArgC, printfunc, newtarget, thisObj,
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, actualArgC, printfunc, newtarget, thisObj,
|
||||
a, b, Undefined(), bcOffset});
|
||||
Return(result);
|
||||
}
|
||||
@ -139,22 +148,23 @@ void FooBoundAOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef argc = Int32Argument(1);
|
||||
GateRef calltarget = TaggedArgument(2);
|
||||
GateRef newtarget = TaggedArgument(3);
|
||||
GateRef thisObj = TaggedArgument(4);
|
||||
GateRef a = TaggedArgument(5);
|
||||
GateRef b = TaggedArgument(6);
|
||||
GateRef env = TaggedArgument(1);
|
||||
GateRef argc = Int32Argument(2);
|
||||
GateRef calltarget = TaggedArgument(3);
|
||||
GateRef newtarget = TaggedArgument(4);
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bindArguments = IntToTaggedTypeNGC(Int32(37));
|
||||
GateRef bcOffset = Int32Argument(1);
|
||||
GateRef bcOffset = Int32(1);
|
||||
(void)calltarget;
|
||||
GateRef numArgs = IntToTaggedTypeNGC(Int32(2));
|
||||
GateRef barIndex = IntToTaggedTypeNGC(Int32(CommonStubCSigns::BarAOT));
|
||||
GateRef barfunc = CallRuntime(glue, RTSTUB_ID(DefineAotFunc), {barIndex, numArgs});
|
||||
GateRef bindfunc = CallRuntime(glue, RTSTUB_ID(GetBindFunc), {barfunc});
|
||||
GateRef newjsfunc = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, Int32(5), bindfunc, newtarget, barfunc,
|
||||
GateRef newjsfunc = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, Int32(5), bindfunc, newtarget, barfunc,
|
||||
Int64(0x02), bindArguments, bcOffset});
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, argc, newjsfunc, newtarget, thisObj,
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, newjsfunc, newtarget, thisObj,
|
||||
a, b, bcOffset});
|
||||
Return(result);
|
||||
}
|
||||
@ -163,13 +173,14 @@ void FooProxyAOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef argc = Int32Argument(1);
|
||||
[[maybe_unused]] GateRef calltarget = TaggedArgument(2);
|
||||
GateRef newtarget = TaggedArgument(3);
|
||||
GateRef thisObj = TaggedArgument(4);
|
||||
GateRef a = TaggedArgument(5);
|
||||
GateRef b = TaggedArgument(6);
|
||||
GateRef bcOffset = Int32Argument(1);
|
||||
GateRef env = TaggedArgument(1);
|
||||
GateRef argc = Int32Argument(2);
|
||||
[[maybe_unused]] GateRef calltarget = TaggedArgument(3);
|
||||
GateRef newtarget = TaggedArgument(4);
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
|
||||
GateRef barIndex = IntToTaggedTypeNGC(Int32(CommonStubCSigns::BarAOT));
|
||||
GateRef numArgs = IntToTaggedTypeNGC(Int32(2));
|
||||
@ -177,7 +188,7 @@ void FooProxyAOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
|
||||
GateRef proxyfunc = CallRuntime(glue, RTSTUB_ID(DefineProxyFunc), {barfunc});
|
||||
GateRef result =
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, argc, proxyfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, proxyfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
@ -185,13 +196,14 @@ void FooProxy2AOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef argc = Int32Argument(1);
|
||||
[[maybe_unused]] GateRef calltarget = TaggedArgument(2);
|
||||
GateRef newtarget = TaggedArgument(3);
|
||||
GateRef thisObj = TaggedArgument(4);
|
||||
GateRef a = TaggedArgument(5);
|
||||
GateRef b = TaggedArgument(6);
|
||||
GateRef bcOffset = Int32Argument(1);
|
||||
GateRef env = TaggedArgument(1);
|
||||
GateRef argc = Int32Argument(2);
|
||||
[[maybe_unused]] GateRef calltarget = TaggedArgument(3);
|
||||
GateRef newtarget = TaggedArgument(4);
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
|
||||
GateRef barIndex = IntToTaggedTypeNGC(Int32(CommonStubCSigns::Bar2AOT));
|
||||
GateRef numArgs = IntToTaggedTypeNGC(Int32(2));
|
||||
@ -200,7 +212,7 @@ void FooProxy2AOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
|
||||
GateRef proxyfunc = CallRuntime(glue, RTSTUB_ID(DefineProxyFunc2), {barfunc, proxyHandler});
|
||||
GateRef result =
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, argc, proxyfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, proxyfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
@ -208,10 +220,11 @@ void Bar2AOTStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
[[maybe_unused]] GateRef glue = PtrArgument(0);
|
||||
[[maybe_unused]] GateRef argc = Int32Argument(1);
|
||||
[[maybe_unused]] GateRef calltarget = TaggedArgument(2);
|
||||
[[maybe_unused]] GateRef newtarget = TaggedArgument(3);
|
||||
[[maybe_unused]] GateRef thisObj = TaggedArgument(4);
|
||||
[[maybe_unused]] GateRef env = TaggedArgument(1);
|
||||
[[maybe_unused]] GateRef argc = Int32Argument(2);
|
||||
[[maybe_unused]] GateRef calltarget = TaggedArgument(3);
|
||||
[[maybe_unused]] GateRef newtarget = TaggedArgument(4);
|
||||
[[maybe_unused]] GateRef thisObj = TaggedArgument(5);
|
||||
CallRuntime(glue, RTSTUB_ID(DumpTaggedType), {thisObj});
|
||||
Return(thisObj);
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ namespace panda::ecmascript::kungfu {
|
||||
|
||||
class FooAOTStub : public Stub {
|
||||
public:
|
||||
// 7 : 7 means argument counts
|
||||
explicit FooAOTStub(Circuit *circuit) : Stub("FooAOT", 7, circuit)
|
||||
// 8 : 8 means argument counts
|
||||
explicit FooAOTStub(Circuit *circuit) : Stub("FooAOT", 8, circuit)
|
||||
{
|
||||
}
|
||||
~FooAOTStub() = default;
|
||||
@ -51,8 +51,8 @@ public:
|
||||
|
||||
class BarAOTStub : public Stub {
|
||||
public:
|
||||
// 7 : 7 means argument counts
|
||||
explicit BarAOTStub(Circuit *circuit) : Stub("BarAOT", 7, circuit)
|
||||
// 8 : 8 means argument counts
|
||||
explicit BarAOTStub(Circuit *circuit) : Stub("BarAOT", 8, circuit)
|
||||
{
|
||||
}
|
||||
~BarAOTStub() = default;
|
||||
@ -63,8 +63,8 @@ public:
|
||||
|
||||
class Foo1AOTStub : public Stub {
|
||||
public:
|
||||
// 7 : 7 means argument counts
|
||||
explicit Foo1AOTStub(Circuit *circuit) : Stub("Foo1AOT", 7, circuit)
|
||||
// 8 : 8 means argument counts
|
||||
explicit Foo1AOTStub(Circuit *circuit) : Stub("Foo1AOT", 8, circuit)
|
||||
{
|
||||
}
|
||||
~Foo1AOTStub() = default;
|
||||
@ -75,8 +75,8 @@ public:
|
||||
|
||||
class Foo2AOTStub : public Stub {
|
||||
public:
|
||||
// 7 : 7 means argument counts
|
||||
explicit Foo2AOTStub(Circuit *circuit) : Stub("Foo2AOT", 7, circuit)
|
||||
// 8 : 8 means argument counts
|
||||
explicit Foo2AOTStub(Circuit *circuit) : Stub("Foo2AOT", 8, circuit)
|
||||
{
|
||||
}
|
||||
~Foo2AOTStub() = default;
|
||||
@ -87,8 +87,8 @@ public:
|
||||
|
||||
class FooNativeAOTStub : public Stub {
|
||||
public:
|
||||
// 7 : 7 means argument counts
|
||||
explicit FooNativeAOTStub(Circuit *circuit) : Stub("FooNativeAOT", 7, circuit)
|
||||
// 8 : 8 means argument counts
|
||||
explicit FooNativeAOTStub(Circuit *circuit) : Stub("FooNativeAOT", 8, circuit)
|
||||
{
|
||||
}
|
||||
~FooNativeAOTStub() = default;
|
||||
@ -99,8 +99,8 @@ public:
|
||||
|
||||
class FooBoundAOTStub : public Stub {
|
||||
public:
|
||||
// 7 : 7 means argument counts
|
||||
explicit FooBoundAOTStub(Circuit *circuit) : Stub("FooBoundAOT", 7, circuit)
|
||||
// 8 : 8 means argument counts
|
||||
explicit FooBoundAOTStub(Circuit *circuit) : Stub("FooBoundAOT", 8, circuit)
|
||||
{
|
||||
}
|
||||
~FooBoundAOTStub() = default;
|
||||
@ -111,8 +111,8 @@ public:
|
||||
|
||||
class Bar1AOTStub : public Stub {
|
||||
public:
|
||||
// 8 : 8 means argument counts
|
||||
explicit Bar1AOTStub(Circuit *circuit) : Stub("Bar1AOT", 8, circuit)
|
||||
// 9 : 9 means argument counts
|
||||
explicit Bar1AOTStub(Circuit *circuit) : Stub("Bar1AOT", 9, circuit)
|
||||
{
|
||||
}
|
||||
~Bar1AOTStub() = default;
|
||||
@ -123,8 +123,8 @@ public:
|
||||
|
||||
class FooProxyAOTStub : public Stub {
|
||||
public:
|
||||
// 7 : 7 means argument counts
|
||||
explicit FooProxyAOTStub(Circuit *circuit) : Stub("FooProxyAOT", 7, circuit)
|
||||
// 8 : 8 means argument counts
|
||||
explicit FooProxyAOTStub(Circuit *circuit) : Stub("FooProxyAOT", 8, circuit)
|
||||
{
|
||||
}
|
||||
~FooProxyAOTStub() = default;
|
||||
@ -135,8 +135,8 @@ public:
|
||||
|
||||
class FooProxy2AOTStub : public Stub {
|
||||
public:
|
||||
// 7 : 7 means argument counts
|
||||
explicit FooProxy2AOTStub(Circuit *circuit) : Stub("FooProxy2AOTStub", 7, circuit)
|
||||
// 8 : 8 means argument counts
|
||||
explicit FooProxy2AOTStub(Circuit *circuit) : Stub("FooProxy2AOTStub", 8, circuit)
|
||||
{
|
||||
}
|
||||
~FooProxy2AOTStub() = default;
|
||||
@ -147,8 +147,8 @@ public:
|
||||
|
||||
class Bar2AOTStub : public Stub {
|
||||
public:
|
||||
// 5 : 5 means argument counts
|
||||
explicit Bar2AOTStub(Circuit *circuit) : Stub("Bar2AOT", 5, circuit)
|
||||
// 6 : 6 means argument counts
|
||||
explicit Bar2AOTStub(Circuit *circuit) : Stub("Bar2AOT", 6, circuit)
|
||||
{
|
||||
}
|
||||
~Bar2AOTStub() = default;
|
||||
|
@ -19,11 +19,12 @@ namespace panda::ecmascript::kungfu {
|
||||
DEF_CALL_SIGNATURE(FooAOT)
|
||||
{
|
||||
// 7 : 7 input parameters
|
||||
CallSignature fooAot("FooAOT", 0, 7,
|
||||
CallSignature fooAot("FooAOT", 0, 8,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = fooAot;
|
||||
std::array<VariableType, 7> params = { // 7 : 7 input parameters
|
||||
std::array<VariableType, 8> params = { // 8 : 8 input parameters
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_ANY(), // lexenv
|
||||
VariableType::INT32(),
|
||||
VariableType::JS_ANY(), // calltarget
|
||||
VariableType::JS_ANY(), // newTarget
|
||||
@ -38,11 +39,12 @@ DEF_CALL_SIGNATURE(FooAOT)
|
||||
DEF_CALL_SIGNATURE(Foo1AOT)
|
||||
{
|
||||
// 7 : 7 input parameters
|
||||
CallSignature foo1Aot("Foo1AOT", 0, 7,
|
||||
CallSignature foo1Aot("Foo1AOT", 0, 8,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = foo1Aot;
|
||||
std::array<VariableType, 7> params = { // 7 : 7 input parameters
|
||||
std::array<VariableType, 8> params = { // 8 : 8 input parameters
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_ANY(), // lexenv
|
||||
VariableType::INT32(),
|
||||
VariableType::JS_ANY(), // calltarget
|
||||
VariableType::JS_ANY(), // newTarget
|
||||
@ -57,11 +59,12 @@ DEF_CALL_SIGNATURE(Foo1AOT)
|
||||
DEF_CALL_SIGNATURE(Foo2AOT)
|
||||
{
|
||||
// 7 : 7 input parameters
|
||||
CallSignature foo2Aot("Foo2AOT", 0, 7,
|
||||
CallSignature foo2Aot("Foo2AOT", 0, 8,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = foo2Aot;
|
||||
std::array<VariableType, 7> params = { // 7 : 7 input parameters
|
||||
std::array<VariableType, 8> params = { // 8 : 8 input parameters
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_ANY(), // lexenv
|
||||
VariableType::INT32(),
|
||||
VariableType::JS_ANY(), // calltarget
|
||||
VariableType::JS_ANY(), // newTarget
|
||||
@ -76,11 +79,12 @@ DEF_CALL_SIGNATURE(Foo2AOT)
|
||||
DEF_CALL_SIGNATURE(FooNativeAOT)
|
||||
{
|
||||
// 7 : 7 input parameters
|
||||
CallSignature foo2Aot("FooNativeAOT", 0, 7,
|
||||
CallSignature foo2Aot("FooNativeAOT", 0, 8,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = foo2Aot;
|
||||
std::array<VariableType, 7> params = { // 7 : 7 input parameters
|
||||
std::array<VariableType, 8> params = { // 8 : 8 input parameters
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_ANY(), // lexenv
|
||||
VariableType::INT32(),
|
||||
VariableType::JS_ANY(), // calltarget
|
||||
VariableType::JS_ANY(), // newTarget
|
||||
@ -95,11 +99,12 @@ DEF_CALL_SIGNATURE(FooNativeAOT)
|
||||
DEF_CALL_SIGNATURE(FooBoundAOT)
|
||||
{
|
||||
// 7 : 7 input parameters
|
||||
CallSignature foo2Aot("FooBoundAOT", 0, 7,
|
||||
CallSignature foo2Aot("FooBoundAOT", 0, 8,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = foo2Aot;
|
||||
std::array<VariableType, 7> params = { // 7 : 7 input parameters
|
||||
std::array<VariableType, 8> params = { // 8 : 8 input parameters
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_ANY(), // lexenv
|
||||
VariableType::INT32(),
|
||||
VariableType::JS_ANY(), // calltarget
|
||||
VariableType::JS_ANY(), // newTarget
|
||||
@ -114,11 +119,12 @@ DEF_CALL_SIGNATURE(FooBoundAOT)
|
||||
DEF_CALL_SIGNATURE(Bar1AOT)
|
||||
{
|
||||
// 8 : 8 input parameters
|
||||
CallSignature barAot("Bar1AOT", 0, 8,
|
||||
CallSignature barAot("Bar1AOT", 0, 9,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = barAot;
|
||||
std::array<VariableType, 8> params = { // 8 : 8 input parameters
|
||||
std::array<VariableType, 9> params = { // 9 : 9 input parameters
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_ANY(), // lexenv
|
||||
VariableType::INT32(),
|
||||
VariableType::JS_ANY(), // calltarget
|
||||
VariableType::JS_ANY(), // newTarget
|
||||
@ -134,11 +140,12 @@ DEF_CALL_SIGNATURE(Bar1AOT)
|
||||
DEF_CALL_SIGNATURE(BarAOT)
|
||||
{
|
||||
// 7 : 7 input parameters
|
||||
CallSignature barAot("BarAOT", 0, 7,
|
||||
CallSignature barAot("BarAOT", 0, 8,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = barAot;
|
||||
std::array<VariableType, 7> params = { // 7 : 7 input parameters
|
||||
std::array<VariableType, 8> params = { // 8 : 8 input parameters
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_ANY(), // lexEnv
|
||||
VariableType::INT32(),
|
||||
VariableType::JS_ANY(), // calltarget
|
||||
VariableType::JS_ANY(), // newTarget
|
||||
@ -153,11 +160,12 @@ DEF_CALL_SIGNATURE(BarAOT)
|
||||
DEF_CALL_SIGNATURE(FooProxyAOT)
|
||||
{
|
||||
// 8 : 8 input parameters
|
||||
CallSignature fooProxyAot("FooProxyAOT", 0, 7,
|
||||
CallSignature fooProxyAot("FooProxyAOT", 0, 8,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = fooProxyAot;
|
||||
std::array<VariableType, 7> params = { // 7 : 7 input parameters
|
||||
std::array<VariableType, 8> params = { // 8 : 8 input parameters
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_ANY(), // lexEnv
|
||||
VariableType::INT32(),
|
||||
VariableType::JS_ANY(), // calltarget
|
||||
VariableType::JS_ANY(), // newTarget
|
||||
@ -172,11 +180,12 @@ DEF_CALL_SIGNATURE(FooProxyAOT)
|
||||
DEF_CALL_SIGNATURE(FooProxy2AOT)
|
||||
{
|
||||
// 8 : 8 input parameters
|
||||
CallSignature FooProxy2AOT("FooProxy2AOT", 0, 7,
|
||||
CallSignature FooProxy2AOT("FooProxy2AOT", 0, 8,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = FooProxy2AOT;
|
||||
std::array<VariableType, 7> params = { // 7 : 7 input parameters
|
||||
std::array<VariableType, 8> params = { // 8 : 8 input parameters
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_ANY(), // lexEnv
|
||||
VariableType::INT32(),
|
||||
VariableType::JS_ANY(), // calltarget
|
||||
VariableType::JS_ANY(), // newTarget
|
||||
@ -191,11 +200,12 @@ DEF_CALL_SIGNATURE(FooProxy2AOT)
|
||||
DEF_CALL_SIGNATURE(Bar2AOT)
|
||||
{
|
||||
// 7 : 7 input parameters
|
||||
CallSignature bar2Aot("Bar2AOT", 0, 5,
|
||||
CallSignature bar2Aot("Bar2AOT", 0, 6,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = bar2Aot;
|
||||
std::array<VariableType, 5> params = { // 5 : 5 input parameters
|
||||
std::array<VariableType, 6> params = { // 6 : 6 input parameters
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_ANY(), // lexenv
|
||||
VariableType::INT32(),
|
||||
VariableType::JS_ANY(), // calltarget
|
||||
VariableType::JS_ANY(), // newTarget
|
||||
|
@ -1270,12 +1270,13 @@ HWTEST_F_L0(StubTest, JSCallTest2)
|
||||
auto glue = thread->GetGlueAddr();
|
||||
int x = 1;
|
||||
int y = 2;
|
||||
JSTaggedType argV[5] = {
|
||||
JSTaggedType argV[6] = {
|
||||
foo1target.GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
JSTaggedValue(x).GetRawData(),
|
||||
JSTaggedValue(y).GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
};
|
||||
|
||||
auto entry = thread->GetRTInterface(kungfu::RuntimeStubCSigns::ID_JSFunctionEntry);
|
||||
@ -1291,12 +1292,13 @@ HWTEST_F_L0(StubTest, JSCallNativeTest)
|
||||
auto glue = thread->GetGlueAddr();
|
||||
int x = 1;
|
||||
int y = 2;
|
||||
JSTaggedType argV[5] = {
|
||||
JSTaggedType argV[6] = {
|
||||
footarget.GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
JSTaggedValue(x).GetRawData(),
|
||||
JSTaggedValue(y).GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
};
|
||||
auto entry = thread->GetRTInterface(kungfu::RuntimeStubCSigns::ID_JSFunctionEntry);
|
||||
auto result = reinterpret_cast<JSFunctionEntryType>(entry)(glue,
|
||||
@ -1311,12 +1313,13 @@ HWTEST_F_L0(StubTest, JSCallBoundTest)
|
||||
auto glue = thread->GetGlueAddr();
|
||||
int x = 1;
|
||||
int y = 2;
|
||||
JSTaggedType argV[5] = {
|
||||
JSTaggedType argV[6] = {
|
||||
footarget.GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
JSTaggedValue(x).GetRawData(),
|
||||
JSTaggedValue(y).GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
};
|
||||
|
||||
auto entry = thread->GetRTInterface(kungfu::RuntimeStubCSigns::ID_JSFunctionEntry);
|
||||
@ -1333,19 +1336,20 @@ HWTEST_F_L0(StubTest, JSCallTest3)
|
||||
auto glue = thread->GetGlueAddr();
|
||||
int x = 1;
|
||||
int y = 2;
|
||||
JSTaggedType argV[6] = {
|
||||
JSTaggedType argV[7] = {
|
||||
foo2target.GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
JSTaggedValue(x).GetRawData(),
|
||||
JSTaggedValue(y).GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
JSTaggedValue::Undefined().GetRawData(),
|
||||
};
|
||||
JSThread::GlueData::GetCOStubEntriesOffset(false);
|
||||
JSThread::GlueData::GetCOStubEntriesOffset(true);
|
||||
auto entry = thread->GetRTInterface(kungfu::RuntimeStubCSigns::ID_JSFunctionEntry);
|
||||
auto result = reinterpret_cast<JSFunctionEntryType>(entry)(glue,
|
||||
reinterpret_cast<uintptr_t>(thread->GetCurrentSPFrame()), 5, 5, argV, fooProxyEntry);
|
||||
reinterpret_cast<uintptr_t>(thread->GetCurrentSPFrame()), 6, 6, argV, fooProxyEntry);
|
||||
EXPECT_EQ(result, JSTaggedValue(3.0).GetRawData());
|
||||
}
|
||||
|
||||
|
@ -169,6 +169,7 @@ void AssemblerStubs::JSFunctionEntry(ExtendedAssembler *assembler)
|
||||
Register argVEnd(X9);
|
||||
Register argC(X8, W);
|
||||
Register argValue(X10);
|
||||
Register env(X11);
|
||||
Label copyArgLoop;
|
||||
|
||||
// expectedNumArgs <= actualNumArgs
|
||||
@ -177,6 +178,7 @@ void AssemblerStubs::JSFunctionEntry(ExtendedAssembler *assembler)
|
||||
__ Cbz(argC, &invokeCompiledJSFunction);
|
||||
__ Sub(argVEnd.W(), argC, Immediate(1));
|
||||
__ Add(argVEnd, argV, Operand(argVEnd.W(), UXTW, 3));
|
||||
__ Ldr(env, MemoryOperand(argVEnd, FRAME_SLOT_SIZE));
|
||||
|
||||
__ Bind(©ArgLoop);
|
||||
__ Ldr(argValue, MemoryOperand(argVEnd, -FRAME_SLOT_SIZE, AddrMode::POSTINDEX));
|
||||
@ -186,14 +188,16 @@ void AssemblerStubs::JSFunctionEntry(ExtendedAssembler *assembler)
|
||||
}
|
||||
__ Bind(&invokeCompiledJSFunction);
|
||||
{
|
||||
Register env(X11);
|
||||
__ Str(actualNumArgs, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(env, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Blr(codeAddr);
|
||||
}
|
||||
|
||||
// pop argV argC
|
||||
// pop argV
|
||||
// 3 : 3 means argC * 8
|
||||
__ Add(sp, sp, Operand(tmp, UXTW, 3));
|
||||
__ Add(sp, sp, Immediate(FRAME_SLOT_SIZE));
|
||||
__ Add(sp, sp, Immediate(FRAME_SLOT_SIZE * 2)); // 2: pop argc and env
|
||||
|
||||
// pop prevLeaveFrameFp to restore thread->currentFrame_
|
||||
__ Ldr(prevFp, MemoryOperand(sp, FRAME_SLOT_SIZE, AddrMode::POSTINDEX));
|
||||
@ -235,15 +239,17 @@ void AssemblerStubs::OptimizedCallOptimized(ExtendedAssembler *assembler)
|
||||
Register sp(SP);
|
||||
__ SaveFpAndLr();
|
||||
// Construct frame
|
||||
Register frameType(X5);
|
||||
Register frameType(X6);
|
||||
__ Mov(frameType, Immediate(static_cast<int64_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME)));
|
||||
__ Str(frameType, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
Register env(X5);
|
||||
__ Str(env, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
|
||||
// callee save
|
||||
Register tmp(X19);
|
||||
__ Str(tmp, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
|
||||
Register count(X5, W);
|
||||
Register count(X6, W);
|
||||
Register actualNumArgs(X2, W);
|
||||
Label copyArguments;
|
||||
__ Mov(count, expectedNumArgs);
|
||||
@ -284,15 +290,16 @@ void AssemblerStubs::OptimizedCallOptimized(ExtendedAssembler *assembler)
|
||||
Register codeAddr(X3);
|
||||
__ Bind(&invokeCompiledJSFunction);
|
||||
__ Str(actualNumArgs, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(env, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Blr(codeAddr);
|
||||
// pop argv
|
||||
// 3 : 3 means count * 8
|
||||
__ Add(sp, sp, Operand(saveNumArgs, UXTW, 3));
|
||||
__ Add(sp, sp, Immediate(FRAME_SLOT_SIZE));
|
||||
__ Add(sp, sp, Immediate(FRAME_SLOT_SIZE * 2)); // 2: pop argc and env
|
||||
// callee restore
|
||||
__ Ldr(saveNumArgs, MemoryOperand(sp, FRAME_SLOT_SIZE, AddrMode::POSTINDEX));
|
||||
// desconstruct frame
|
||||
__ Add(sp, sp, Immediate(FRAME_SLOT_SIZE));
|
||||
__ Add(sp, sp, Immediate(FRAME_SLOT_SIZE * 2)); // 2: skip type and env
|
||||
__ RestoreFpAndLr();
|
||||
__ Ret();
|
||||
}
|
||||
@ -354,7 +361,7 @@ void AssemblerStubs::CallBuiltinTrampoline(ExtendedAssembler *assembler)
|
||||
|
||||
// construct leave frame and callee save
|
||||
Register frameType(X1);
|
||||
__ Mov(frameType, Immediate(static_cast<int64_t>(FrameType::LEAVE_FRAME)));
|
||||
__ Mov(frameType, Immediate(static_cast<int64_t>(FrameType::BUILTIN_CALL_LEAVE_FRAME)));
|
||||
// 2 : 2 means pair
|
||||
__ Stp(nativeFuncAddr, frameType, MemoryOperand(sp, -FRAME_SLOT_SIZE * 2, AddrMode::PREINDEX));
|
||||
|
||||
@ -369,13 +376,11 @@ void AssemblerStubs::CallBuiltinTrampoline(ExtendedAssembler *assembler)
|
||||
__ Sub(thread, glue, glueToThread); // thread
|
||||
__ Str(thread, MemoryOperand(sp, 0));
|
||||
Register argC(X0);
|
||||
// 1 : 1 means argC id
|
||||
__ Ldr(argC, MemoryOperand(fp, GetStackArgOffSetToFp(1))); // argc
|
||||
__ Ldr(argC, MemoryOperand(fp, GetStackArgOffSetToFp(BuiltinsLeaveFrameArgId::ARGC))); // load argc
|
||||
__ Sub(argC, argC, Immediate(NUM_MANDATORY_JSFUNC_ARGS));
|
||||
__ Str(argC, MemoryOperand(sp, EcmaRuntimeCallInfo::GetNumArgsOffset()));
|
||||
Register argV(X0);
|
||||
// 2 : 2 means argV id
|
||||
__ Add(argV, fp, Immediate(GetStackArgOffSetToFp(2))); // argV
|
||||
__ Add(argV, fp, Immediate(GetStackArgOffSetToFp(BuiltinsLeaveFrameArgId::ARGV))); // argV
|
||||
__ Str(argV, MemoryOperand(sp, EcmaRuntimeCallInfo::GetStackArgsOffset()));
|
||||
|
||||
Register callInfo(X0);
|
||||
@ -425,7 +430,7 @@ void AssemblerStubs::JSCall(ExtendedAssembler *assembler)
|
||||
__ BindAssemblerStub(RTSTUB_ID(JSCall));
|
||||
Register jsfunc(X1);
|
||||
Register sp(SP);
|
||||
__ Ldr(jsfunc, MemoryOperand(sp, FRAME_SLOT_SIZE));
|
||||
__ Ldr(jsfunc, MemoryOperand(sp, FRAME_SLOT_SIZE * 2)); // 2: skip env and argc
|
||||
JSCallBody(assembler, jsfunc);
|
||||
}
|
||||
|
||||
@ -464,14 +469,14 @@ void AssemblerStubs::JSCallBody(ExtendedAssembler *assembler, Register jsfunc)
|
||||
Label callNativeMethod;
|
||||
Label callOptimizedMethod;
|
||||
__ Ldr(method, MemoryOperand(jsfunc, JSFunction::METHOD_OFFSET));
|
||||
__ Ldr(actualArgC, MemoryOperand(sp, 0));
|
||||
__ Ldr(actualArgC, MemoryOperand(sp, FRAME_SLOT_SIZE));
|
||||
__ Ldr(callField, MemoryOperand(method, JSMethod::GetCallFieldOffset(false)));
|
||||
__ Tbnz(callField, JSMethod::IsNativeBit::START_BIT, &callNativeMethod);
|
||||
__ Tbnz(callField, JSMethod::IsAotCodeBit::START_BIT, &callOptimizedMethod);
|
||||
{
|
||||
Register argV(X5);
|
||||
// 8 : 8 mean argV = sp + 8
|
||||
__ Add(argV, sp, Immediate(8));
|
||||
// argV = sp + 16
|
||||
__ Add(argV, sp, Immediate(DOUBLE_SLOT_SIZE));
|
||||
OptimizedCallAsmInterpreter(assembler);
|
||||
}
|
||||
|
||||
@ -490,6 +495,7 @@ void AssemblerStubs::JSCallBody(ExtendedAssembler *assembler, Register jsfunc)
|
||||
Register arg2(X2);
|
||||
Register codeAddress(X3);
|
||||
Register argV(X4);
|
||||
Register env(X5);
|
||||
Label directCallCodeEntry;
|
||||
__ Mov(Register(X5), jsfunc);
|
||||
__ Mov(arg2, actualArgC);
|
||||
@ -498,9 +504,10 @@ void AssemblerStubs::JSCallBody(ExtendedAssembler *assembler, Register jsfunc)
|
||||
LogicalImmediate::Create(JSMethod::NumArgsBits::Mask() >> JSMethod::NumArgsBits::START_BIT, RegWSize));
|
||||
__ Add(expectedNumArgs, callField.W(), Immediate(NUM_MANDATORY_JSFUNC_ARGS));
|
||||
__ Cmp(arg2.W(), expectedNumArgs);
|
||||
// 8 : 8 mean argV = sp + 8
|
||||
__ Add(argV, sp, Immediate(8));
|
||||
// argV = sp + 16
|
||||
__ Add(argV, sp, Immediate(DOUBLE_SLOT_SIZE));
|
||||
__ Ldr(codeAddress, MemoryOperand(Register(X5), JSFunctionBase::CODE_ENTRY_OFFSET));
|
||||
__ Ldr(env, MemoryOperand(sp, 0));
|
||||
__ B(Condition::HS, &directCallCodeEntry);
|
||||
__ CallAssemblerStub(RTSTUB_ID(OptimizedCallOptimized), true);
|
||||
__ Bind(&directCallCodeEntry);
|
||||
@ -528,8 +535,10 @@ void AssemblerStubs::JSCallBody(ExtendedAssembler *assembler, Register jsfunc)
|
||||
__ Mov(frameType, Immediate(static_cast<int64_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME)));
|
||||
__ Str(frameType, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
Register argVEnd(X6);
|
||||
__ Add(argVEnd, fp, Immediate(GetStackArgOffSetToFp(0)));
|
||||
__ Add(argVEnd, fp, Immediate(GetStackArgOffSetToFp(1)));
|
||||
__ Ldr(actualArgC, MemoryOperand(argVEnd, 0));
|
||||
Register envReg(X11);
|
||||
__ Ldr(envReg, MemoryOperand(argVEnd, -8)); // -8: get env
|
||||
// callee save
|
||||
Register tmp(X19);
|
||||
__ Str(tmp, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
@ -589,9 +598,10 @@ void AssemblerStubs::JSCallBody(ExtendedAssembler *assembler, Register jsfunc)
|
||||
__ Ldr(boundTarget, MemoryOperand(jsfunc, JSBoundFunction::BOUND_TARGET_OFFSET));
|
||||
// 2 : 2 means pair
|
||||
__ Stp(realArgC.X(), boundTarget, MemoryOperand(sp, -FRAME_SLOT_SIZE * 2, AddrMode::PREINDEX));
|
||||
__ Str(envReg, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
}
|
||||
__ CallAssemblerStub(RTSTUB_ID(JSCall), false);
|
||||
__ Add(sp, sp, Immediate(FRAME_SLOT_SIZE));
|
||||
__ Add(sp, sp, Immediate(FRAME_SLOT_SIZE * 2)); // 2: skip argc and env
|
||||
// 3 : 3 means 2^3 = 8
|
||||
__ Add(sp, sp, Operand(realArgC, UXTW, 3));
|
||||
__ Ldr(tmp, MemoryOperand(sp, FRAME_SLOT_SIZE, AddrMode::POSTINDEX));
|
||||
@ -604,8 +614,8 @@ void AssemblerStubs::JSCallBody(ExtendedAssembler *assembler, Register jsfunc)
|
||||
// input: x1(calltarget)
|
||||
// output: glue:x0 argc:x1 calltarget:x2 argv:x3
|
||||
__ Mov(Register(X2), jsfunc);
|
||||
__ Ldr(Register(X1), MemoryOperand(sp, 0));
|
||||
__ Add(X3, sp, Immediate(FRAME_SLOT_SIZE));
|
||||
__ Ldr(Register(X1), MemoryOperand(sp, FRAME_SLOT_SIZE)); // 8: skip env
|
||||
__ Add(X3, sp, Immediate(FRAME_SLOT_SIZE * 2)); // 2: get argv
|
||||
|
||||
Register proxyCallInternalId(Register(X9).W());
|
||||
Register codeAddress(X10);
|
||||
|
@ -24,7 +24,9 @@ namespace panda::ecmascript::aarch64 {
|
||||
using Label = panda::ecmascript::Label;
|
||||
class AssemblerStubs {
|
||||
public:
|
||||
static const int FRAME_SLOT_SIZE = 8;
|
||||
static constexpr int FRAME_SLOT_SIZE = 8;
|
||||
static constexpr int DOUBLE_SLOT_SIZE = 16;
|
||||
enum BuiltinsLeaveFrameArgId : unsigned {CODE_ADDRESS = 0, ENV, ARGC, ARGV};
|
||||
static inline int64_t GetStackArgOffSetToFp(unsigned argId)
|
||||
{
|
||||
// +--------------------------+
|
||||
@ -32,10 +34,12 @@ public:
|
||||
// +--------------------------+ ---
|
||||
// | argc | ^
|
||||
// |--------------------------| arguments
|
||||
// | env | |
|
||||
// |--------------------------| |
|
||||
// | codeAddress | |
|
||||
// |--------------------------| |
|
||||
// | returnAddr | |
|
||||
// |--------------------------| Fixed OptimizedLeaveFrame
|
||||
// |--------------------------| Fixed OptimizedBuiltinLeaveFrame
|
||||
// | callsiteFp | |
|
||||
// |--------------------------| |
|
||||
// | frameType | v
|
||||
|
@ -101,7 +101,7 @@ void AssemblerStubsX64::JSFunctionEntry(ExtendedAssembler *assembler)
|
||||
// 16 bytes align check
|
||||
__ Movl(expectedNumArgsReg, r14);
|
||||
__ Testb(1, r14);
|
||||
__ Jne(&lAlign16Bytes);
|
||||
__ Je(&lAlign16Bytes);
|
||||
__ Pushq(0); // push zero to align 16 bytes stack
|
||||
|
||||
__ Bind(&lAlign16Bytes);
|
||||
@ -137,13 +137,15 @@ void AssemblerStubsX64::JSFunctionEntry(ExtendedAssembler *assembler)
|
||||
__ Jne(&lCopyLoop);
|
||||
|
||||
__ Pushq(r14);
|
||||
__ Movq(Operand(argvReg, r14, Scale::Times8, 0), actualNumArgsReg);
|
||||
__ Push(actualNumArgsReg); // env
|
||||
__ Movq(glueReg, rax); // mov glue to rax
|
||||
__ Callq(codeAddrReg); // then call jsFunction
|
||||
__ Leaq(Operand(r14, Scale::Times8, 0), actualNumArgsReg); // Note: fixed for 3 extra arguments
|
||||
__ Addq(actualNumArgsReg, rsp);
|
||||
__ Addq(8, rsp); // 8: skip r14
|
||||
__ Addq(16, rsp); // 16: skip r14 and env
|
||||
__ Testb(1, r14); // stack 16bytes align check
|
||||
__ Jne(&lPopFrame);
|
||||
__ Je(&lPopFrame);
|
||||
__ Addq(8, rsp); // 8: align byte
|
||||
}
|
||||
|
||||
@ -159,13 +161,14 @@ void AssemblerStubsX64::JSFunctionEntry(ExtendedAssembler *assembler)
|
||||
}
|
||||
}
|
||||
|
||||
// uint64_t OptimizedCallOptimized(uintptr_t glue, uintptr_t codeAddr, uint32_t actualNumArgs,
|
||||
// uint32_t expectedNumArgs, uintptr_t argv)
|
||||
// uint64_t OptimizedCallOptimized(uintptr_t glue, uint32_t expectedNumArgs,
|
||||
// uint32_t actualNumArgs, uintptr_t codeAddr, uintptr_t argv, uintptr_t lexEnv)
|
||||
// Input: %rdi - glue
|
||||
// %rsi - codeAddr
|
||||
// %rdx - actualNumArgs
|
||||
// %rcx - expectedNumArgs
|
||||
// %r8 - argv
|
||||
// %r9 - lexEnv
|
||||
|
||||
// sp[0 * 8] - argc
|
||||
// sp[1 * 8] - argv[0]
|
||||
@ -185,6 +188,7 @@ void AssemblerStubsX64::OptimizedCallOptimized(ExtendedAssembler *assembler)
|
||||
Register actualNumArgsReg = rdx;
|
||||
Register codeAddrReg = rsi;
|
||||
Register argvReg = r8;
|
||||
Register envReg = r9;
|
||||
|
||||
Label lAlign16Bytes1;
|
||||
Label lCopyExtraAument1;
|
||||
@ -194,6 +198,7 @@ void AssemblerStubsX64::OptimizedCallOptimized(ExtendedAssembler *assembler)
|
||||
__ Pushq(rbp);
|
||||
__ Movq(rsp, rbp);
|
||||
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME));
|
||||
__ Pushq(envReg);
|
||||
// callee save
|
||||
__ Pushq(r14);
|
||||
__ Pushq(rbx);
|
||||
@ -230,11 +235,13 @@ void AssemblerStubsX64::OptimizedCallOptimized(ExtendedAssembler *assembler)
|
||||
__ Addq(-1, rax);
|
||||
__ Jne(&lCopyLoop1);
|
||||
__ Pushq(actualNumArgsReg); // actual argc
|
||||
__ Pushq(envReg);
|
||||
|
||||
__ Movq(glueReg, rax); // mov glue to rax
|
||||
__ Callq(codeAddrReg); // then call jsFunction
|
||||
__ Leaq(Operand(r14, Scale::Times8, 0), codeAddrReg);
|
||||
__ Addq(codeAddrReg, rsp);
|
||||
__ Addq(8, rsp); // 8: skip actualNumArgsReg
|
||||
__ Addq(DOUBLE_SLOT_SIZE, rsp); // skip actualNumArgsReg and envReg
|
||||
__ Testb(1, r14); // stack 16bytes align check
|
||||
__ Jne(&lPopFrame1);
|
||||
__ Addq(8, rsp); // 8: align byte
|
||||
@ -243,7 +250,7 @@ void AssemblerStubsX64::OptimizedCallOptimized(ExtendedAssembler *assembler)
|
||||
__ Addq(8, rsp); // 8: skip rax
|
||||
__ Popq(rbx);
|
||||
__ Popq(r14);
|
||||
__ Addq(8, rsp); // 8: skip frame type
|
||||
__ Addq(DOUBLE_SLOT_SIZE, rsp); // skip frame type, env reg
|
||||
__ Pop(rbp);
|
||||
__ Ret();
|
||||
}
|
||||
@ -294,7 +301,7 @@ void AssemblerStubsX64::CallBuiltinTrampoline(ExtendedAssembler *assembler)
|
||||
__ Pushq(rbp);
|
||||
__ Movq(rsp, rbp);
|
||||
__ Movq(rbp, Operand(glueReg, JSThread::GlueData::GetLeaveFrameOffset(false))); // save to thread->leaveFrame_
|
||||
__ Pushq(static_cast<int32_t>(FrameType::LEAVE_FRAME));
|
||||
__ Pushq(static_cast<int32_t>(FrameType::BUILTIN_CALL_LEAVE_FRAME));
|
||||
|
||||
// callee save
|
||||
__ Pushq(r10);
|
||||
@ -314,12 +321,12 @@ void AssemblerStubsX64::CallBuiltinTrampoline(ExtendedAssembler *assembler)
|
||||
__ Movq(threadReg, Operand(rsp, EcmaRuntimeCallInfo::GetThreadOffset())); // thread_
|
||||
// get numArgs
|
||||
__ Movq(0, rax);
|
||||
__ Movl(Operand(rdx, 8), rax); // 8: sp + 8 actualArgc
|
||||
__ Movl(Operand(rdx, DOUBLE_SLOT_SIZE), rax); // sp + 16 actualArgc
|
||||
__ Subl(3, rax); // 3: size
|
||||
__ Movq(rax, Operand(rsp, EcmaRuntimeCallInfo::GetNumArgsOffset())); // actualArgc
|
||||
// get gpr data
|
||||
__ Movq(rdx, rbx);
|
||||
__ Addq(16, rbx); // 16: argv[0]
|
||||
__ Addq(TRIPLE_SLOT_SIZE, rbx); // argv[0]
|
||||
__ Movq(rbx, Operand(rsp, EcmaRuntimeCallInfo::GetStackArgsOffset())); // argv0
|
||||
|
||||
__ Movq(rsp, rdi);
|
||||
@ -372,7 +379,7 @@ void AssemblerStubsX64::JSProxyCallInternalWithArgV(ExtendedAssembler *assembler
|
||||
{
|
||||
__ Movq(glueReg, rdi);
|
||||
glueReg = rdi;
|
||||
__ Movq(Operand(rsp, 16), rax); // 16: get jsFunc
|
||||
__ Movq(Operand(rsp, TRIPLE_SLOT_SIZE), rax); // get jsFunc
|
||||
}
|
||||
__ Bind(&lJSCallStart);
|
||||
Register jsFuncReg = rax;
|
||||
@ -436,14 +443,14 @@ void AssemblerStubsX64::JSProxyCallInternalWithArgV(ExtendedAssembler *assembler
|
||||
Register argV = r9;
|
||||
{
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::METHOD_OFFSET), jsMethod); // get method
|
||||
__ Movl(Operand(rsp, 8), argc); // 8: sp + 8 actual argc
|
||||
__ Movl(Operand(rsp, DOUBLE_SLOT_SIZE), argc); // sp + 16 actual argc
|
||||
__ Mov(Operand(jsMethod, JSMethod::GetCallFieldOffset(false)), methodCallField); // get call field
|
||||
__ Btq(JSMethod::IsNativeBit::START_BIT, methodCallField); // is native
|
||||
__ Jb(&lCallNativeMethod);
|
||||
__ Btq(JSMethod::IsAotCodeBit::START_BIT, methodCallField); // is aot
|
||||
__ Jb(&lCallOptimziedMethod);
|
||||
__ Movq(rsp, argV);
|
||||
__ Addq(16, argV); // 16: sp + 16 argv
|
||||
__ Addq(TRIPLE_SLOT_SIZE, argV); // sp + 24 argv
|
||||
OptimizedCallAsmInterpreter(assembler);
|
||||
}
|
||||
|
||||
@ -457,9 +464,11 @@ void AssemblerStubsX64::JSProxyCallInternalWithArgV(ExtendedAssembler *assembler
|
||||
__ Addl(NUM_MANDATORY_JSFUNC_ARGS, methodCallField); // add mandatory argument
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::CODE_ENTRY_OFFSET), codeAddrReg); // get codeAddress
|
||||
__ Movq(rsp, r8);
|
||||
Register envReg = r9;
|
||||
__ Movq(Operand(r8, DOUBLE_SLOT_SIZE), envReg); // get env
|
||||
argvReg = r8;
|
||||
__ Addq(16, argvReg); // 16: sp + 8 argv
|
||||
__ Cmpl(expectedNumArgsReg, argc); // expectedNumArgs <= actualNumArgs
|
||||
__ Addq(TRIPLE_SLOT_SIZE, argvReg); // get argv
|
||||
__ Cmpl(expectedNumArgsReg, rdx); // expectedNumArgs <= actualNumArgs
|
||||
__ Jg(&lDirectCallCodeEntry);
|
||||
__ CallAssemblerStub(RTSTUB_ID(OptimizedCallOptimized), true);
|
||||
}
|
||||
@ -489,8 +498,10 @@ void AssemblerStubsX64::JSProxyCallInternalWithArgV(ExtendedAssembler *assembler
|
||||
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME));
|
||||
__ Pushq(r10); // callee save
|
||||
__ Movq(rsp, rdx);
|
||||
__ Addq(32, rdx); // 32: sp + 32 argv
|
||||
__ Addq(QUINTUPLE_SLOT_SIZE, rdx); // sp + 40 argv
|
||||
__ Mov(Operand(rdx, 0), rax); // get origin argc
|
||||
Register envReg = r9;
|
||||
__ Mov(Operand(rdx, -FRAME_SLOT_SIZE), envReg); // get env
|
||||
__ Movq(rax, r10);
|
||||
// get bound target
|
||||
__ Mov(Operand(jsFuncReg, JSBoundFunction::BOUND_ARGUMENTS_OFFSET), rcx);
|
||||
@ -500,7 +511,7 @@ void AssemblerStubsX64::JSProxyCallInternalWithArgV(ExtendedAssembler *assembler
|
||||
|
||||
// 16 bytes align check
|
||||
__ Testb(1, r10);
|
||||
__ Jne(&lAlign16Bytes2);
|
||||
__ Je(&lAlign16Bytes2);
|
||||
__ PushAlignBytes(); // push zero to align 16 bytes stack
|
||||
}
|
||||
|
||||
@ -544,17 +555,20 @@ void AssemblerStubsX64::JSProxyCallInternalWithArgV(ExtendedAssembler *assembler
|
||||
__ Mov(Operand(jsFuncReg, JSBoundFunction::BOUND_TARGET_OFFSET), rax); // callTarget
|
||||
__ Pushq(rax);
|
||||
__ Pushq(r10); // push actual arguments
|
||||
Register envReg = r9;
|
||||
__ Pushq(envReg);
|
||||
__ Movq(rdi, rax);
|
||||
__ Callq(&jsCall); // call JSCall
|
||||
__ Leaq(Operand(r10, Scale::Times8, 8), rcx); // 8: offset
|
||||
__ Addq(rcx, rsp);
|
||||
__ Testb(1, r10); // stack 16bytes align check
|
||||
__ Jne(&lPopFrame2);
|
||||
__ Je(&lPopFrame2);
|
||||
__ Addq(8, rsp); // 8: sp + 8
|
||||
}
|
||||
|
||||
__ Bind(&lPopFrame2);
|
||||
{
|
||||
__ Addq(FRAME_SLOT_SIZE, rsp); // skip r9
|
||||
__ Pop(r10);
|
||||
__ Addq(8, rsp); // 8: sp + 8
|
||||
__ Pop(rbp);
|
||||
@ -572,7 +586,8 @@ void AssemblerStubsX64::JSProxyCallInternalWithArgV(ExtendedAssembler *assembler
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
// uint64_t JSCall(uintptr_t glue, uint32_t argc, JSTaggedType calltarget, JSTaggedType new, JSTaggedType this, ...)
|
||||
// uint64_t JSCall(uintptr_t glue, JSTaggedType env, uint32_t argc, JSTaggedType calltarget, JSTaggedType new,
|
||||
// JSTaggedType this, ...)
|
||||
// webkit_jscc calling convention call js function()
|
||||
// Input: %rax - glue
|
||||
// stack layout:
|
||||
@ -593,13 +608,17 @@ void AssemblerStubsX64::JSProxyCallInternalWithArgV(ExtendedAssembler *assembler
|
||||
// +--------------------------+ ---
|
||||
// | jsfunction | ^
|
||||
// |--------------------------| Fixed
|
||||
// | argc | OptimizedFrame
|
||||
// | argc | OptimizedJSFunctionFrame
|
||||
// |--------------------------| |
|
||||
// | lexEnv | |
|
||||
// |--------------------------| |
|
||||
// | returnAddr | |
|
||||
// |--------------------------| |
|
||||
// | callsiteFp | |
|
||||
// |--------------------------| |
|
||||
// | frameType | v
|
||||
// | frameType | |
|
||||
// |--------------------------| |
|
||||
// | lexEnv | v
|
||||
// +--------------------------+ ---
|
||||
void AssemblerStubsX64::JSCall(ExtendedAssembler *assembler)
|
||||
{
|
||||
@ -625,7 +644,7 @@ void AssemblerStubsX64::JSCall(ExtendedAssembler *assembler)
|
||||
{
|
||||
__ Movq(glueReg, rdi);
|
||||
glueReg = rdi;
|
||||
__ Movq(Operand(rsp, 16), rax); // 16: sp + 16 get jsFunc
|
||||
__ Movq(Operand(rsp, TRIPLE_SLOT_SIZE), rax); // sp + 24 get jsFunc
|
||||
}
|
||||
__ Bind(&lJSCallStart);
|
||||
Register jsFuncReg = rax;
|
||||
@ -689,14 +708,14 @@ void AssemblerStubsX64::JSCall(ExtendedAssembler *assembler)
|
||||
Register argV = r9;
|
||||
{
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::METHOD_OFFSET), jsMethod); // get method
|
||||
__ Movl(Operand(rsp, 8), argc); // 8: sp + 8 actual argc
|
||||
__ Movl(Operand(rsp, DOUBLE_SLOT_SIZE), argc); // sp + 16 actual argc
|
||||
__ Mov(Operand(jsMethod, JSMethod::GetCallFieldOffset(false)), methodCallField); // get call field
|
||||
__ Btq(JSMethod::IsNativeBit::START_BIT, methodCallField); // is native
|
||||
__ Jb(&lCallNativeMethod);
|
||||
__ Btq(JSMethod::IsAotCodeBit::START_BIT, methodCallField); // is aot
|
||||
__ Jb(&lCallOptimziedMethod);
|
||||
__ Movq(rsp, argV);
|
||||
__ Addq(16, argV); // 16: sp + 16 argv
|
||||
__ Addq(TRIPLE_SLOT_SIZE, argV); // sp + 24 argv
|
||||
OptimizedCallAsmInterpreter(assembler);
|
||||
}
|
||||
|
||||
@ -710,8 +729,10 @@ void AssemblerStubsX64::JSCall(ExtendedAssembler *assembler)
|
||||
__ Addl(NUM_MANDATORY_JSFUNC_ARGS, methodCallField); // add mandatory argumentr
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::CODE_ENTRY_OFFSET), codeAddrReg); // get codeAddress
|
||||
__ Movq(rsp, r8);
|
||||
Register envReg = r9;
|
||||
__ Movq(Operand(r8, 16), envReg); // 16: get env
|
||||
Register argvReg = r8;
|
||||
__ Addq(16, argvReg); // 16: sp + 16 argv
|
||||
__ Addq(24, argvReg); // 24: sp + 24 argv
|
||||
__ Cmpl(expectedNumArgsReg, rdx); // expectedNumArgs <= actualNumArgs
|
||||
__ Jge(&lDirectCallCodeEntry);
|
||||
__ CallAssemblerStub(RTSTUB_ID(OptimizedCallOptimized), true);
|
||||
@ -742,8 +763,10 @@ void AssemblerStubsX64::JSCall(ExtendedAssembler *assembler)
|
||||
__ Pushq(static_cast<int32_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME));
|
||||
__ Pushq(r10); // callee save
|
||||
__ Movq(rsp, rdx);
|
||||
__ Addq(32, rdx); // 32: sp + 32 argv
|
||||
__ Addq(QUINTUPLE_SLOT_SIZE, rdx); // sp + 40 argv
|
||||
__ Mov(Operand(rdx, 0), rax); // get origin argc
|
||||
Register envReg = r9;
|
||||
__ Mov(Operand(rdx, -FRAME_SLOT_SIZE), envReg); // get env
|
||||
__ Movq(rax, r10);
|
||||
// get bound target
|
||||
__ Mov(Operand(jsFuncReg, JSBoundFunction::BOUND_ARGUMENTS_OFFSET), rcx);
|
||||
@ -753,7 +776,7 @@ void AssemblerStubsX64::JSCall(ExtendedAssembler *assembler)
|
||||
|
||||
// 16 bytes align check
|
||||
__ Testb(1, r10);
|
||||
__ Jne(&lAlign16Bytes2);
|
||||
__ Je(&lAlign16Bytes2);
|
||||
__ PushAlignBytes(); // push zero to align 16 bytes stack
|
||||
}
|
||||
|
||||
@ -797,17 +820,20 @@ void AssemblerStubsX64::JSCall(ExtendedAssembler *assembler)
|
||||
__ Mov(Operand(jsFuncReg, JSBoundFunction::BOUND_TARGET_OFFSET), rax); // callTarget
|
||||
__ Pushq(rax);
|
||||
__ Pushq(r10); // push actual arguments
|
||||
Register envReg = r9;
|
||||
__ Pushq(envReg);
|
||||
__ Movq(rdi, rax);
|
||||
__ Callq(&jsCall); // call JSCall
|
||||
__ Leaq(Operand(r10, Scale::Times8, 8), rcx); // 8: disp
|
||||
__ Addq(rcx, rsp);
|
||||
__ Testb(1, r10); // stack 16bytes align check
|
||||
__ Jne(&lPopFrame2);
|
||||
__ Je(&lPopFrame2);
|
||||
__ Addq(8, rsp); // 8: align byte
|
||||
}
|
||||
|
||||
__ Bind(&lPopFrame2);
|
||||
{
|
||||
__ Addq(8, rsp); // 8: sp + 8
|
||||
__ Pop(r10);
|
||||
__ Addq(8, rsp); // 8: sp + 8
|
||||
__ Pop(rbp);
|
||||
@ -816,7 +842,7 @@ void AssemblerStubsX64::JSCall(ExtendedAssembler *assembler)
|
||||
__ Bind(&lJSProxy);
|
||||
__ Movq(jsFuncReg, rdx); // calltarget
|
||||
__ Movq(rsp, rcx);
|
||||
__ Addq(8, rcx); // 8: sp + 8 skip returnAddr
|
||||
__ Addq(DOUBLE_SLOT_SIZE, rcx); // sp + 16 skip returnAddr
|
||||
__ Mov(Operand(rcx, 0), rsi); // get origin argc
|
||||
__ Addq(8, rcx); // 8: sp + 8 argv
|
||||
__ Movq(kungfu::CommonStubCSigns::JsProxyCallInternal, r9);
|
||||
|
@ -23,6 +23,11 @@
|
||||
namespace panda::ecmascript::x64 {
|
||||
class AssemblerStubsX64 {
|
||||
public:
|
||||
static constexpr int FRAME_SLOT_SIZE = 8;
|
||||
static constexpr int DOUBLE_SLOT_SIZE = 16;
|
||||
static constexpr int TRIPLE_SLOT_SIZE = 24;
|
||||
static constexpr int QUADRUPLE_SLOT_SIZE = 32;
|
||||
static constexpr int QUINTUPLE_SLOT_SIZE = 40;
|
||||
static void CallRuntime(ExtendedAssembler *assembler);
|
||||
|
||||
static void JSFunctionEntry(ExtendedAssembler *assembler);
|
||||
|
@ -360,13 +360,15 @@ EcmaVM::CpuProfilingScope::~CpuProfilingScope()
|
||||
JSTaggedValue EcmaVM::InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, const JSPandaFile *jsPandaFile)
|
||||
{
|
||||
fileLoader_->UpdateJSMethods(mainFunc, jsPandaFile);
|
||||
std::vector<JSTaggedType> args(6, JSTaggedValue::Undefined().GetRawData()); // 6: number of para
|
||||
std::vector<JSTaggedType> args(7, JSTaggedValue::Undefined().GetRawData()); // 7: number of para
|
||||
args[0] = mainFunc.GetTaggedValue().GetRawData();
|
||||
auto entry = thread_->GetRTInterface(kungfu::RuntimeStubCSigns::ID_JSFunctionEntry);
|
||||
JSTaggedValue env = mainFunc->GetLexicalEnv();
|
||||
args[6] = env.GetRawData(); // 6: last arg is env.
|
||||
auto res = reinterpret_cast<JSFunctionEntryType>(entry)(thread_->GetGlueAddr(),
|
||||
reinterpret_cast<uintptr_t>(thread_->GetCurrentSPFrame()),
|
||||
static_cast<uint32_t>(args.size()),
|
||||
static_cast<uint32_t>(args.size()),
|
||||
static_cast<uint32_t>(args.size()) - 1,
|
||||
static_cast<uint32_t>(args.size()) - 1,
|
||||
args.data(),
|
||||
mainFunc->GetCodeEntry());
|
||||
return JSTaggedValue(res);
|
||||
|
@ -37,6 +37,11 @@ FrameIterator::FrameIterator(JSTaggedType *sp, const JSThread *thread) : current
|
||||
}
|
||||
}
|
||||
|
||||
int FrameIterator::ComputeDelta() const
|
||||
{
|
||||
return stackmapParser_->GetFuncFpDelta(optimizedReturnAddr_);
|
||||
}
|
||||
|
||||
void FrameIterator::Advance()
|
||||
{
|
||||
ASSERT(!Done());
|
||||
@ -84,6 +89,13 @@ void FrameIterator::Advance()
|
||||
current_ = frame->GetPrevFrameFp();
|
||||
break;
|
||||
}
|
||||
case FrameType::BUILTIN_CALL_LEAVE_FRAME : {
|
||||
auto frame = GetFrame<OptimizedBuiltinLeaveFrame>();
|
||||
optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
|
||||
optimizedReturnAddr_ = frame->GetReturnAddr();
|
||||
current_ = frame->GetPrevFrameFp();
|
||||
break;
|
||||
}
|
||||
case FrameType::INTERPRETER_FRAME:
|
||||
case FrameType::INTERPRETER_FAST_NEW_FRAME : {
|
||||
auto frame = GetFrame<InterpretedFrame>();
|
||||
@ -156,6 +168,10 @@ uintptr_t FrameIterator::GetPrevFrameCallSiteSp(uintptr_t curPc) const
|
||||
auto frame = GetFrame<OptimizedWithArgvLeaveFrame>();
|
||||
return frame->GetCallSiteSp();
|
||||
}
|
||||
case FrameType::BUILTIN_CALL_LEAVE_FRAME: {
|
||||
auto frame = GetFrame<OptimizedBuiltinLeaveFrame>();
|
||||
return frame->GetCallSiteSp();
|
||||
}
|
||||
case FrameType::BUILTIN_FRAME_WITH_ARGV: {
|
||||
auto frame = GetFrame<BuiltinWithArgvFrame>();
|
||||
return frame->GetCallSiteSp();
|
||||
@ -224,13 +240,19 @@ ARK_INLINE void OptimizedFrame::GCIterate(const FrameIterator &it,
|
||||
|
||||
ARK_INLINE JSTaggedType* OptimizedJSFunctionFrame::GetArgv(const FrameIterator &it) const
|
||||
{
|
||||
auto thread = it.GetThread();
|
||||
ASSERT(thread != nullptr);
|
||||
int delta = thread->GetEcmaVM()->GetFileLoader()->GetStackMapParser()->GetFuncFpDelta(it.GetOptimizedReturnAddr());
|
||||
uintptr_t *preFrameSp = ComputePrevFrameSp(it.GetSp(), delta);
|
||||
uintptr_t *preFrameSp = ComputePrevFrameSp(it);
|
||||
return GetArgv(preFrameSp);
|
||||
}
|
||||
|
||||
ARK_INLINE uintptr_t* OptimizedJSFunctionFrame::ComputePrevFrameSp(const FrameIterator &it) const
|
||||
{
|
||||
const JSTaggedType *sp = it.GetSp();
|
||||
int delta = it.ComputeDelta();
|
||||
uintptr_t *preFrameSp = reinterpret_cast<uintptr_t *>(const_cast<JSTaggedType *>(sp))
|
||||
+ delta / sizeof(uintptr_t);
|
||||
return preFrameSp;
|
||||
}
|
||||
|
||||
ARK_INLINE void OptimizedJSFunctionFrame::GCIterate(const FrameIterator &it,
|
||||
const RootVisitor &v0,
|
||||
const RootRangeVisitor &v1,
|
||||
@ -238,13 +260,13 @@ ARK_INLINE void OptimizedJSFunctionFrame::GCIterate(const FrameIterator &it,
|
||||
bool isVerifying) const
|
||||
{
|
||||
OptimizedJSFunctionFrame *frame = OptimizedJSFunctionFrame::GetFrameFromSp(it.GetSp());
|
||||
uintptr_t *envPtr = reinterpret_cast<uintptr_t *>(frame);
|
||||
uintptr_t envslot = ToUintPtr(envPtr);
|
||||
v0(Root::ROOT_FRAME, ObjectSlot(envslot));
|
||||
|
||||
const JSThread *thread = it.GetThread();
|
||||
ASSERT(thread != nullptr);
|
||||
int delta = thread->GetEcmaVM()->GetFileLoader()->GetStackMapParser()->GetFuncFpDelta(it.GetOptimizedReturnAddr());
|
||||
uintptr_t *preFrameSp = frame->ComputePrevFrameSp(it.GetSp(), delta);
|
||||
uintptr_t *preFrameSp = frame->ComputePrevFrameSp(it);
|
||||
|
||||
auto argc = *(reinterpret_cast<uint64_t *>(preFrameSp));
|
||||
auto argc = frame->GetArgc(preFrameSp);
|
||||
JSTaggedType *argv = frame->GetArgv(reinterpret_cast<uintptr_t *>(preFrameSp));
|
||||
if (argc > 0) {
|
||||
uintptr_t start = ToUintPtr(argv); // argv
|
||||
@ -364,6 +386,22 @@ ARK_INLINE void OptimizedWithArgvLeaveFrame::GCIterate(const FrameIterator &it,
|
||||
}
|
||||
}
|
||||
|
||||
ARK_INLINE void OptimizedBuiltinLeaveFrame::GCIterate(const FrameIterator &it,
|
||||
[[maybe_unused]] const RootVisitor &v0,
|
||||
const RootRangeVisitor &v1,
|
||||
[[maybe_unused]] ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers,
|
||||
[[maybe_unused]] bool isVerifying) const
|
||||
{
|
||||
const JSTaggedType *sp = it.GetSp();
|
||||
OptimizedBuiltinLeaveFrame *frame = OptimizedBuiltinLeaveFrame::GetFrameFromSp(sp);
|
||||
if (frame->argc > 0) {
|
||||
JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(&frame->argc + 1);
|
||||
uintptr_t start = ToUintPtr(argv); // argv
|
||||
uintptr_t end = ToUintPtr(argv + frame->argc);
|
||||
v1(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
|
||||
}
|
||||
}
|
||||
|
||||
ARK_INLINE void BuiltinWithArgvFrame::GCIterate(const FrameIterator &it,
|
||||
[[maybe_unused]] const RootVisitor &v0,
|
||||
const RootRangeVisitor &v1,
|
||||
|
@ -106,6 +106,19 @@
|
||||
// | callSiteSp | v
|
||||
// +--------------------------+
|
||||
|
||||
// Optimized JSFunction Frame Frame(alias OptimizedJSFunctionFrame) layout
|
||||
// +--------------------------+
|
||||
// | calleesave registers | ^
|
||||
// |----------------------| |
|
||||
// | returnaddress | Fixed
|
||||
// |----------------------| OptimizedJSFunctionFrame
|
||||
// | prevFp | |
|
||||
// |----------------------| |
|
||||
// | frameType | |
|
||||
// |----------------------| |
|
||||
// | lexEnv | v
|
||||
// +--------------------------+
|
||||
|
||||
// Optimized Entry Frame(alias OptimizedEntryFrame) layout
|
||||
// +--------------------------+
|
||||
// | returnaddress | ^
|
||||
@ -194,12 +207,13 @@
|
||||
// | calleesave registers | ^ ^
|
||||
// |----------------------| | |
|
||||
// | returnaddress | Fixed |
|
||||
// |----------------------| OptimizedFrame |
|
||||
// |----------------------| OptimizedJSFunctionFrame |
|
||||
// | prevFp | | |
|
||||
// |----------------------| | baz's frame Header
|
||||
// | frameType | | |
|
||||
// |----------------------| | |
|
||||
// | callsitesp | v V
|
||||
// | lexEnv | | V
|
||||
// +--------------------------+
|
||||
// +--------------------------+---------------------------+
|
||||
// | ............. |
|
||||
// +--------------------------+---------------------------+
|
||||
@ -249,17 +263,18 @@ enum class FrameType: uintptr_t {
|
||||
OPTIMIZED_JS_FUNCTION_FRAME = 2,
|
||||
LEAVE_FRAME = 3,
|
||||
LEAVE_FRAME_WITH_ARGV = 4,
|
||||
INTERPRETER_FRAME = 5,
|
||||
ASM_INTERPRETER_FRAME = 6,
|
||||
INTERPRETER_CONSTRUCTOR_FRAME = 7,
|
||||
BUILTIN_FRAME = 8,
|
||||
BUILTIN_FRAME_WITH_ARGV = 9,
|
||||
BUILTIN_ENTRY_FRAME = 10,
|
||||
INTERPRETER_FAST_NEW_FRAME = 11,
|
||||
INTERPRETER_ENTRY_FRAME = 12,
|
||||
ASM_INTERPRETER_ENTRY_FRAME = 13,
|
||||
ASM_INTERPRETER_BRIDGE_FRAME = 14,
|
||||
OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME = 15,
|
||||
BUILTIN_CALL_LEAVE_FRAME = 5,
|
||||
INTERPRETER_FRAME = 6,
|
||||
ASM_INTERPRETER_FRAME = 7,
|
||||
INTERPRETER_CONSTRUCTOR_FRAME = 8,
|
||||
BUILTIN_FRAME = 9,
|
||||
BUILTIN_FRAME_WITH_ARGV = 10,
|
||||
BUILTIN_ENTRY_FRAME = 11,
|
||||
INTERPRETER_FAST_NEW_FRAME = 12,
|
||||
INTERPRETER_ENTRY_FRAME = 13,
|
||||
ASM_INTERPRETER_ENTRY_FRAME = 14,
|
||||
ASM_INTERPRETER_BRIDGE_FRAME = 15,
|
||||
OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME = 16,
|
||||
|
||||
INTERPRETER_BEGIN = INTERPRETER_FRAME,
|
||||
INTERPRETER_END = INTERPRETER_FAST_NEW_FRAME,
|
||||
@ -269,7 +284,7 @@ enum class FrameType: uintptr_t {
|
||||
|
||||
enum class ReservedSlots: int {
|
||||
OPTIMIZED_RESERVED_SLOT = 1,
|
||||
OPTIMIZED_JS_FUNCTION_RESERVED_SLOT = 1,
|
||||
OPTIMIZED_JS_FUNCTION_RESERVED_SLOT = 2,
|
||||
OPTIMIZED_ENTRY_RESERVED_SLOT = 2,
|
||||
};
|
||||
|
||||
@ -358,13 +373,16 @@ STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionArgConfigFrame),
|
||||
OptimizedJSFunctionArgConfigFrame::SizeArch32, OptimizedJSFunctionArgConfigFrame::SizeArch64);
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
||||
struct OptimizedJSFunctionFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
||||
struct OptimizedJSFunctionFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
|
||||
JSTaggedValue,
|
||||
base::AlignedPointer,
|
||||
base::AlignedPointer,
|
||||
base::AlignedPointer> {
|
||||
public:
|
||||
static constexpr size_t ENV_SLOT_DIFF = 2;
|
||||
enum class Index : size_t {
|
||||
TypeIndex = 0,
|
||||
EnvIndex = 0,
|
||||
TypeIndex,
|
||||
PrevFpIndex,
|
||||
ReturnAddrIndex,
|
||||
NumOfMembers
|
||||
@ -375,15 +393,16 @@ public:
|
||||
{
|
||||
return prevFp;
|
||||
}
|
||||
uintptr_t* ComputePrevFrameSp(const JSTaggedType *sp, int delta) const
|
||||
{
|
||||
uintptr_t *preFrameSp = reinterpret_cast<uintptr_t *>(const_cast<JSTaggedType *>(sp))
|
||||
+ delta / sizeof(uintptr_t);
|
||||
return preFrameSp;
|
||||
}
|
||||
uintptr_t* ComputePrevFrameSp(const FrameIterator &it) const;
|
||||
|
||||
JSTaggedType* GetArgv(uintptr_t *preFrameSp) const
|
||||
{
|
||||
return reinterpret_cast<JSTaggedType *>(preFrameSp + sizeof(uint64_t) / sizeof(uintptr_t));
|
||||
return reinterpret_cast<JSTaggedType *>(preFrameSp + ENV_SLOT_DIFF * sizeof(uint64_t) / sizeof(uintptr_t));
|
||||
}
|
||||
|
||||
size_t GetArgc(uintptr_t *preFrameSp) const
|
||||
{
|
||||
return *(preFrameSp + sizeof(uint64_t) / sizeof(uintptr_t));
|
||||
}
|
||||
|
||||
JSTaggedType* GetArgv(const FrameIterator &it) const;
|
||||
@ -395,7 +414,25 @@ public:
|
||||
void GCIterate(
|
||||
const FrameIterator &it, const RootVisitor &v0, const RootRangeVisitor &v1,
|
||||
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying) const;
|
||||
|
||||
inline JSTaggedValue GetEnv() const
|
||||
{
|
||||
return env;
|
||||
}
|
||||
inline void SetEnv(JSTaggedValue lexEnv)
|
||||
{
|
||||
env = lexEnv;
|
||||
}
|
||||
friend class FrameIterator;
|
||||
|
||||
private:
|
||||
static OptimizedJSFunctionFrame* GetFrameFromSp(const JSTaggedType *sp)
|
||||
{
|
||||
return reinterpret_cast<OptimizedJSFunctionFrame *>(reinterpret_cast<uintptr_t>(sp)
|
||||
- MEMBER_OFFSET(OptimizedJSFunctionFrame, prevFp));
|
||||
}
|
||||
// dynamic callee saveregisters for x86-64
|
||||
alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
|
||||
[[maybe_unused]] alignas(EAS) FrameType type {0};
|
||||
alignas(EAS) JSTaggedType *prevFp {nullptr};
|
||||
alignas(EAS) uintptr_t returnAddr {0};
|
||||
@ -404,13 +441,6 @@ public:
|
||||
// argv[0]
|
||||
// argv[1]
|
||||
// ... argv[n - 1]
|
||||
friend class FrameIterator;
|
||||
private:
|
||||
static OptimizedJSFunctionFrame* GetFrameFromSp(const JSTaggedType *sp)
|
||||
{
|
||||
return reinterpret_cast<OptimizedJSFunctionFrame *>(reinterpret_cast<uintptr_t>(sp)
|
||||
- MEMBER_OFFSET(OptimizedJSFunctionFrame, prevFp));
|
||||
}
|
||||
};
|
||||
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionFrame), OptimizedJSFunctionFrame::SizeArch32,
|
||||
OptimizedJSFunctionFrame::SizeArch64);
|
||||
@ -802,6 +832,39 @@ struct OptimizedWithArgvLeaveFrame {
|
||||
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying) const;
|
||||
};
|
||||
|
||||
struct OptimizedBuiltinLeaveFrame {
|
||||
public:
|
||||
static OptimizedBuiltinLeaveFrame* GetFrameFromSp(const JSTaggedType *sp)
|
||||
{
|
||||
return reinterpret_cast<OptimizedBuiltinLeaveFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
||||
MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, callsiteFp));
|
||||
}
|
||||
uintptr_t GetCallSiteSp() const
|
||||
{
|
||||
return ToUintPtr(this) + MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, argRuntimeId);
|
||||
}
|
||||
inline JSTaggedType* GetPrevFrameFp() const
|
||||
{
|
||||
return reinterpret_cast<JSTaggedType*>(callsiteFp);
|
||||
}
|
||||
uintptr_t GetReturnAddr() const
|
||||
{
|
||||
return returnAddr;
|
||||
}
|
||||
void GCIterate(
|
||||
const FrameIterator &it, const RootVisitor &v0, const RootRangeVisitor &v1,
|
||||
ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers, bool isVerifying) const;
|
||||
|
||||
private:
|
||||
[[maybe_unused]] FrameType type;
|
||||
uintptr_t callsiteFp; // thread sp set here
|
||||
uintptr_t returnAddr;
|
||||
[[maybe_unused]] uint64_t argRuntimeId;
|
||||
JSTaggedValue env;
|
||||
uint64_t argc;
|
||||
// argv[0]...argv[argc-1] dynamic according to agc
|
||||
};
|
||||
|
||||
struct BuiltinFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
||||
base::AlignedSize,
|
||||
base::AlignedPointer,
|
||||
@ -978,6 +1041,7 @@ public:
|
||||
{
|
||||
return current_;
|
||||
}
|
||||
int ComputeDelta() const;
|
||||
void Advance();
|
||||
uintptr_t GetPrevFrameCallSiteSp(uintptr_t curPc = 0) const;
|
||||
uintptr_t GetCallSiteSp() const
|
||||
|
@ -174,6 +174,7 @@ JSTaggedValue FrameHandler::GetFunction() const
|
||||
case FrameType::OPTIMIZED_FRAME:
|
||||
case FrameType::LEAVE_FRAME:
|
||||
case FrameType::LEAVE_FRAME_WITH_ARGV:
|
||||
case FrameType::BUILTIN_CALL_LEAVE_FRAME:
|
||||
case FrameType::OPTIMIZED_ENTRY_FRAME:
|
||||
default: {
|
||||
LOG_ECMA(FATAL) << "frame type error!";
|
||||
@ -268,6 +269,7 @@ ARK_INLINE uintptr_t FrameHandler::GetInterpretedFrameEnd(JSTaggedType *prevSp)
|
||||
case FrameType::OPTIMIZED_FRAME:
|
||||
case FrameType::LEAVE_FRAME:
|
||||
case FrameType::LEAVE_FRAME_WITH_ARGV:
|
||||
case FrameType::BUILTIN_CALL_LEAVE_FRAME:
|
||||
case FrameType::OPTIMIZED_ENTRY_FRAME:
|
||||
case FrameType::ASM_INTERPRETER_ENTRY_FRAME:
|
||||
case FrameType::ASM_INTERPRETER_BRIDGE_FRAME:
|
||||
@ -366,6 +368,11 @@ void FrameHandler::IterateFrameChain(JSTaggedType *start, const RootVisitor &v0,
|
||||
frame->GCIterate(it, v0, v1, derivedPointers, isVerifying);
|
||||
break;
|
||||
}
|
||||
case FrameType::BUILTIN_CALL_LEAVE_FRAME: {
|
||||
auto frame = it.GetFrame<OptimizedBuiltinLeaveFrame>();
|
||||
frame->GCIterate(it, v0, v1, derivedPointers, isVerifying);
|
||||
break;
|
||||
}
|
||||
case FrameType::BUILTIN_FRAME_WITH_ARGV: {
|
||||
auto frame = it.GetFrame<BuiltinWithArgvFrame>();
|
||||
frame->GCIterate(it, v0, v1, derivedPointers, isVerifying);
|
||||
@ -408,8 +415,8 @@ void FrameHandler::CollectBCOffsetInfo()
|
||||
thread_->GetEcmaVM()->ClearExceptionBCList();
|
||||
JSTaggedType *current = const_cast<JSTaggedType *>(thread_->GetLastLeaveFrame());
|
||||
FrameIterator it(current, thread_);
|
||||
ASSERT(it.GetFrameType() == FrameType::LEAVE_FRAME);
|
||||
auto leaveFrame = it.GetFrame<OptimizedLeaveFrame>();
|
||||
ASSERT(it.GetFrameType() == FrameType::BUILTIN_CALL_LEAVE_FRAME);
|
||||
auto leaveFrame = it.GetFrame<OptimizedBuiltinLeaveFrame>();
|
||||
auto returnAddr = leaveFrame->GetReturnAddr();
|
||||
// skip native function, need to fixit later.
|
||||
it.Advance();
|
||||
@ -428,11 +435,12 @@ void FrameHandler::CollectBCOffsetInfo()
|
||||
returnAddr = frame->GetReturnAddr();
|
||||
break;
|
||||
}
|
||||
case FrameType::LEAVE_FRAME: {
|
||||
auto frame = it.GetFrame<OptimizedLeaveFrame>();
|
||||
case FrameType::BUILTIN_CALL_LEAVE_FRAME: {
|
||||
auto frame = it.GetFrame<OptimizedBuiltinLeaveFrame>();
|
||||
returnAddr = frame->GetReturnAddr();
|
||||
break;
|
||||
}
|
||||
case FrameType::LEAVE_FRAME:
|
||||
case FrameType::OPTIMIZED_ENTRY_FRAME:
|
||||
case FrameType::ASM_INTERPRETER_ENTRY_FRAME:
|
||||
case FrameType::ASM_INTERPRETER_FRAME:
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "ecmascript/builtins/builtins_regexp.h"
|
||||
#include "ecmascript/llvm_stackmap_parser.h"
|
||||
#include "ecmascript/ecma_string_table.h"
|
||||
#include "ecmascript/file_loader.h"
|
||||
#include "ecmascript/global_dictionary-inl.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/ic/profile_type_info.h"
|
||||
@ -35,6 +36,8 @@
|
||||
#include "ecmascript/module/js_module_manager.h"
|
||||
#include "ecmascript/template_string.h"
|
||||
#include "ecmascript/ts_types/ts_loader.h"
|
||||
#include "ecmascript/jspandafile/literal_data_extractor.h"
|
||||
#include "ecmascript/jspandafile/scope_info_extractor.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
static constexpr size_t FIXED_NUM_ARGS = 3;
|
||||
@ -1575,14 +1578,18 @@ JSTaggedValue RuntimeStubs::RuntimeNewLexicalEnvWithNameDyn(JSThread *thread, ui
|
||||
return newEnv.GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue RuntimeStubs::RuntimeGetAotUnmapedArgs(JSThread *thread, uint32_t actualNumArgs, uintptr_t argv)
|
||||
JSTaggedValue RuntimeStubs::RuntimeGetAotUnmapedArgs(JSThread *thread, uint32_t actualNumArgs)
|
||||
{
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<TaggedArray> argumentsList = factory->NewTaggedArray(actualNumArgs - FIXED_NUM_ARGS);
|
||||
for (uint32_t i = 0; i < actualNumArgs - FIXED_NUM_ARGS; ++i) {
|
||||
|
||||
auto argv = GetActualArgv(thread);
|
||||
int idx = 0;
|
||||
for (uint32_t i = FIXED_NUM_ARGS; i < actualNumArgs; ++i) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
JSTaggedType arg = reinterpret_cast<JSTaggedType *>(argv)[i + 1]; // skip actualNumArgs
|
||||
argumentsList->Set(thread, i, JSTaggedValue(arg));
|
||||
JSTaggedType arg = reinterpret_cast<JSTaggedType *>(argv)[i];
|
||||
JSTaggedValue args = JSTaggedValue(arg);
|
||||
argumentsList->Set(thread, idx++, args);
|
||||
}
|
||||
return RuntimeGetUnmapedJSArgumentObj(thread, argumentsList);
|
||||
}
|
||||
@ -1652,36 +1659,41 @@ JSTaggedValue RuntimeStubs::RuntimeNewAotLexicalEnvDyn(JSThread *thread, uint16_
|
||||
newEnv->SetParentEnv(thread, currentLexEnv.GetTaggedValue());
|
||||
newEnv->SetScopeInfo(thread, JSTaggedValue::Hole());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return newEnv.GetTaggedValue();
|
||||
JSTaggedValue taggedEnv = newEnv.GetTaggedValue();
|
||||
RuntimeSetAotLexEnv(thread, taggedEnv);
|
||||
return taggedEnv;
|
||||
}
|
||||
|
||||
JSTaggedValue RuntimeStubs::RuntimeNewAotLexicalEnvWithNameDyn(JSThread *thread, uint16_t numVars, uint16_t scopeId,
|
||||
JSHandle<JSTaggedValue> ¤tLexEnv)
|
||||
JSHandle<JSTaggedValue> ¤tLexEnv,
|
||||
JSHandle<JSTaggedValue> &func)
|
||||
{
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars);
|
||||
|
||||
newEnv->SetParentEnv(thread, currentLexEnv.GetTaggedValue());
|
||||
JSTaggedValue scopeInfo = ScopeInfoExtractor::GenerateScopeInfo(thread, scopeId);
|
||||
JSTaggedValue scopeInfo = RuntimeGenerateAotScopeInfo(thread, scopeId, func.GetTaggedValue());
|
||||
newEnv->SetScopeInfo(thread, scopeInfo);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return newEnv.GetTaggedValue();
|
||||
JSTaggedValue taggedEnv = newEnv.GetTaggedValue();
|
||||
RuntimeSetAotLexEnv(thread, taggedEnv);
|
||||
return taggedEnv;
|
||||
}
|
||||
|
||||
JSTaggedValue RuntimeStubs::RuntimeCopyAotRestArgs(JSThread *thread, uint32_t autualArgc, uint32_t restId)
|
||||
JSTaggedValue RuntimeStubs::RuntimeCopyAotRestArgs(JSThread *thread, uint32_t actualArgc, uint32_t restIndex)
|
||||
{
|
||||
auto leaveFrame = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
|
||||
auto frame = OptimizedLeaveFrame::GetFrameFromSp(leaveFrame);
|
||||
uint32_t actualRestNum = autualArgc - restId - FIXED_NUM_ARGS;
|
||||
uint32_t actualRestNum = actualArgc - FIXED_NUM_ARGS - restIndex;
|
||||
JSHandle<JSTaggedValue> restArray = JSArray::ArrayCreate(thread, JSTaggedNumber(actualRestNum));
|
||||
JSTaggedType *argv = frame->GetJsFuncFrameArgv(thread);
|
||||
|
||||
auto argv = GetActualArgv(thread);
|
||||
int idx = 0;
|
||||
JSMutableHandle<JSTaggedValue> element(thread, JSTaggedValue::Undefined());
|
||||
for (uint32_t i = 0; i < actualRestNum; ++i) {
|
||||
|
||||
for (uint32_t i = FIXED_NUM_ARGS + restIndex; i < actualArgc; ++i) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
JSTaggedType arg = argv[i + FIXED_NUM_ARGS + restId];
|
||||
[[maybe_unused]]auto a = JSTaggedValue(arg);
|
||||
JSTaggedType arg = reinterpret_cast<JSTaggedType *>(argv)[i];
|
||||
element.Update(JSTaggedValue(arg));
|
||||
JSObject::SetProperty(thread, restArray, i, element, true);
|
||||
JSObject::SetProperty(thread, restArray, idx++, element, true);
|
||||
}
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return restArray.GetTaggedValue();
|
||||
@ -1753,5 +1765,69 @@ JSTaggedValue RuntimeStubs::RuntimeAotNewObjWithIHClass(JSThread *thread, uintpt
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
JSTaggedValue RuntimeStubs::RuntimeGetAotLexEnv(JSThread *thread)
|
||||
{
|
||||
[[maybe_unused]] DisallowGarbageCollection noGc;
|
||||
auto optimizedJSFunctionFrame = GetOptimizedJSFunctionFrame(thread);
|
||||
return optimizedJSFunctionFrame->GetEnv();
|
||||
}
|
||||
|
||||
void RuntimeStubs::RuntimeSetAotLexEnv(JSThread *thread, JSTaggedValue lexEnv)
|
||||
{
|
||||
auto optimizedJSFunctionFrame = GetOptimizedJSFunctionFrame(thread);
|
||||
optimizedJSFunctionFrame->SetEnv(lexEnv);
|
||||
}
|
||||
|
||||
JSTaggedValue RuntimeStubs::RuntimeGenerateAotScopeInfo(JSThread *thread, uint16_t scopeId, JSTaggedValue func)
|
||||
{
|
||||
EcmaVM *ecmaVm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = ecmaVm->GetFactory();
|
||||
JSMethod *method = ECMAObject::Cast(func.GetTaggedObject())->GetCallTarget();
|
||||
const JSPandaFile *jsPandaFile = method->GetJSPandaFile();
|
||||
JSHandle<TaggedArray> elementsLiteral = LiteralDataExtractor::GetDatasIgnoreType(thread, jsPandaFile, scopeId);
|
||||
ASSERT(elementsLiteral->GetLength() > 0);
|
||||
size_t length = elementsLiteral->GetLength();
|
||||
|
||||
auto buffer = ecmaVm->GetNativeAreaAllocator()->New<struct ScopeDebugInfo>();
|
||||
auto scopeDebugInfo = static_cast<struct ScopeDebugInfo *>(buffer);
|
||||
|
||||
for (size_t i = 1; i < length; i += 2) { // 2: Each literal buffer contains a pair of key-value.
|
||||
JSTaggedValue val = elementsLiteral->Get(i);
|
||||
ASSERT(val.IsString());
|
||||
CString name = ConvertToString(EcmaString::Cast(val.GetTaggedObject()));
|
||||
int32_t slot = elementsLiteral->Get(i + 1).GetInt();
|
||||
if (scopeDebugInfo == nullptr) {
|
||||
return JSTaggedValue::Hole();
|
||||
}
|
||||
scopeDebugInfo->scopeInfo.insert(std::make_pair(name, slot));
|
||||
}
|
||||
|
||||
auto freeObjFunc = NativeAreaAllocator::FreeObjectFunc<struct ScopeDebugInfo>;
|
||||
auto allocator = ecmaVm->GetNativeAreaAllocator();
|
||||
JSHandle<JSNativePointer> pointer = factory->NewJSNativePointer(buffer, freeObjFunc, allocator);
|
||||
return pointer.GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedType *RuntimeStubs::GetActualArgv(JSThread *thread)
|
||||
{
|
||||
JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
|
||||
ASSERT(FrameHandler::GetFrameType(current) == FrameType::LEAVE_FRAME);
|
||||
FrameIterator it(current, thread);
|
||||
it.Advance();
|
||||
ASSERT(it.GetFrameType() == FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
|
||||
auto optimizedJSFunctionFrame = it.GetFrame<OptimizedJSFunctionFrame>();
|
||||
return optimizedJSFunctionFrame->GetArgv(it);
|
||||
}
|
||||
|
||||
OptimizedJSFunctionFrame *RuntimeStubs::GetOptimizedJSFunctionFrame(JSThread *thread)
|
||||
{
|
||||
JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
|
||||
ASSERT(FrameHandler::GetFrameType(current) == FrameType::LEAVE_FRAME);
|
||||
FrameIterator it(current, thread);
|
||||
it.Advance();
|
||||
ASSERT(it.GetFrameType() == FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
|
||||
return it.GetFrame<OptimizedJSFunctionFrame>();
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_STUBS_RUNTIME_STUBS_INL_H
|
||||
|
@ -1542,7 +1542,7 @@ DEF_RUNTIME_STUBS(GetAotUnmapedArgs)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(GetAotUnmapedArgs);
|
||||
JSTaggedValue actualNumArgs = GetArg(argv, argc, 0);
|
||||
return RuntimeGetAotUnmapedArgs(thread, actualNumArgs.GetInt(), argv).GetRawData();
|
||||
return RuntimeGetAotUnmapedArgs(thread, actualNumArgs.GetInt()).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(GetAotUnmapedArgsWithRestArgs)
|
||||
@ -1555,8 +1555,7 @@ DEF_RUNTIME_STUBS(GetAotUnmapedArgsWithRestArgs)
|
||||
DEF_RUNTIME_STUBS(GetAotLexicalEnv)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(GetAotLexicalEnv);
|
||||
JSFunction *jsFunc = GetPtrArg<JSFunction *>(argv, argc, 0);
|
||||
return jsFunc->GetLexicalEnv().GetRawData();
|
||||
return RuntimeGetAotLexEnv(thread).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(NewAotLexicalEnvDyn)
|
||||
@ -1570,19 +1569,30 @@ DEF_RUNTIME_STUBS(NewAotLexicalEnvDyn)
|
||||
DEF_RUNTIME_STUBS(NewAotLexicalEnvWithNameDyn)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(NewAotLexicalEnvWithNameDyn);
|
||||
JSTaggedValue numVars = GetArg(argv, argc, 0);
|
||||
JSTaggedValue scopeId = GetArg(argv, argc, 1);
|
||||
JSTaggedValue taggedNumVars = GetArg(argv, argc, 0);
|
||||
JSTaggedValue taggedScopeId = GetArg(argv, argc, 1);
|
||||
JSHandle<JSTaggedValue> currentLexEnv = GetHArg<JSTaggedValue>(argv, argc, 2);
|
||||
return RuntimeNewAotLexicalEnvWithNameDyn(thread, static_cast<uint16_t>(numVars.GetInt()),
|
||||
static_cast<uint16_t>(scopeId.GetInt()), currentLexEnv).GetRawData();
|
||||
JSHandle<JSTaggedValue> func = GetHArg<JSTaggedValue>(argv, argc, 3);
|
||||
uint16_t numVars = static_cast<uint16_t>(taggedNumVars.GetInt());
|
||||
uint16_t scopeId = static_cast<uint16_t>(taggedScopeId.GetInt());
|
||||
return RuntimeNewAotLexicalEnvWithNameDyn(thread, numVars, scopeId, currentLexEnv, func).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(PopAotLexicalEnv)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(PopAotLexicalEnv);
|
||||
JSTaggedValue currentLexenv = RuntimeGetAotLexEnv(thread);
|
||||
JSTaggedValue parentLexenv = LexicalEnv::Cast(currentLexenv.GetTaggedObject())->GetParentEnv();
|
||||
RuntimeSetAotLexEnv(thread, parentLexenv);
|
||||
return JSTaggedValue::VALUE_HOLE;
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(CopyAotRestArgs)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(CopyAotRestArgs);
|
||||
JSTaggedValue actualArgc = GetArg(argv, argc, 0);
|
||||
JSTaggedValue restId = GetArg(argv, argc, 1);
|
||||
return RuntimeCopyAotRestArgs(thread, actualArgc.GetInt(), restId.GetInt()).GetRawData();
|
||||
JSTaggedValue restIndex = GetArg(argv, argc, 1);
|
||||
return RuntimeCopyAotRestArgs(thread, actualArgc.GetInt(), restIndex.GetInt()).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(NewAotObjDynRange)
|
||||
@ -1616,6 +1626,37 @@ DEF_RUNTIME_STUBS(AotNewObjWithIHClass)
|
||||
return RuntimeAotNewObjWithIHClass(thread, argv, argc).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(LdAotLexVarDyn)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(LdAotLexVarDyn);
|
||||
JSTaggedValue level = GetArg(argv, argc, 0);
|
||||
JSTaggedValue slot = GetArg(argv, argc, 1);
|
||||
JSTaggedValue env = RuntimeGetAotLexEnv(thread);
|
||||
for (int32_t i = 0; i < level.GetInt(); i++) {
|
||||
JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
|
||||
ASSERT(!taggedParentEnv.IsUndefined());
|
||||
env = taggedParentEnv;
|
||||
}
|
||||
return LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot.GetInt()).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(StAotLexVarDyn)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(StAotLexVarDyn);
|
||||
JSTaggedValue level = GetArg(argv, argc, 0);
|
||||
JSTaggedValue slot = GetArg(argv, argc, 1);
|
||||
JSTaggedValue value = GetArg(argv, argc, 2);
|
||||
JSTaggedValue env = RuntimeGetAotLexEnv(thread);
|
||||
|
||||
for (int32_t i = 0; i < level.GetInt(); i++) {
|
||||
JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
|
||||
ASSERT(!taggedParentEnv.IsUndefined());
|
||||
env = taggedParentEnv;
|
||||
}
|
||||
LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot.GetInt(), value);
|
||||
return JSTaggedValue::VALUE_HOLE;
|
||||
}
|
||||
|
||||
JSTaggedType RuntimeStubs::CreateArrayFromList([[maybe_unused]]uintptr_t argGlue, int32_t argc, JSTaggedValue *argvPtr)
|
||||
{
|
||||
auto thread = JSThread::GlueToJSThread(argGlue);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define ECMASCRIPT_RUNTIME_STUBS_H
|
||||
|
||||
#include "ecmascript/compiler/call_signature.h"
|
||||
#include "ecmascript/frames.h"
|
||||
#include "ecmascript/stubs/test_runtime_stubs.h"
|
||||
#include "ecmascript/ecma_macros.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
@ -226,7 +227,10 @@ using JSFunctionEntryType = uint64_t (*)(uintptr_t glue, uintptr_t prevFp, uint3
|
||||
V(NewAotObjDynRange) \
|
||||
V(GetTypeArrayPropertyByIndex) \
|
||||
V(SetTypeArrayPropertyByIndex) \
|
||||
V(AotNewObjWithIHClass)
|
||||
V(AotNewObjWithIHClass) \
|
||||
V(PopAotLexicalEnv) \
|
||||
V(LdAotLexVarDyn) \
|
||||
V(StAotLexVarDyn)
|
||||
|
||||
#define RUNTIME_STUB_LIST(V) \
|
||||
RUNTIME_ASM_STUB_LIST(V) \
|
||||
@ -467,20 +471,26 @@ private:
|
||||
static inline JSTaggedValue RuntimeThrowSyntaxError(JSThread *thread, const char *message);
|
||||
static inline JSTaggedValue RuntimeLdBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &numberBigInt);
|
||||
static inline JSTaggedValue RuntimeNewLexicalEnvWithNameDyn(JSThread *thread, uint16_t numVars, uint16_t scopeId);
|
||||
static inline JSTaggedValue RuntimeGetAotUnmapedArgs(JSThread *thread, uint32_t actualNumArgs, uintptr_t argv);
|
||||
static inline JSTaggedValue RuntimeGetAotUnmapedArgs(JSThread *thread, uint32_t actualNumArgs);
|
||||
static inline JSTaggedValue RuntimeGetAotUnmapedArgsWithRestArgs(JSThread *thread, uint32_t actualNumArgs);
|
||||
static inline JSTaggedValue RuntimeGetUnmapedJSArgumentObj(JSThread *thread,
|
||||
const JSHandle<TaggedArray> &argumentsList);
|
||||
static inline JSTaggedValue RuntimeNewAotLexicalEnvDyn(JSThread *thread, uint16_t numVars,
|
||||
JSHandle<JSTaggedValue> ¤tLexEnv);
|
||||
static inline JSTaggedValue RuntimeNewAotLexicalEnvWithNameDyn(JSThread *thread, uint16_t numVars, uint16_t scopeId,
|
||||
JSHandle<JSTaggedValue> ¤tLexEnv);
|
||||
static inline JSTaggedValue RuntimeCopyAotRestArgs(JSThread *thread, uint32_t autualArgc, uint32_t restId);
|
||||
JSHandle<JSTaggedValue> ¤tLexEnv,
|
||||
JSHandle<JSTaggedValue> &func);
|
||||
static inline JSTaggedValue RuntimeCopyAotRestArgs(JSThread *thread, uint32_t actualArgc, uint32_t restIndex);
|
||||
static inline JSTaggedValue RuntimeSuspendAotGenerator(JSThread *thread, const JSHandle<JSTaggedValue> &genObj,
|
||||
const JSHandle<JSTaggedValue> &value);
|
||||
static inline JSTaggedValue RuntimeNewAotObjDynRange(JSThread *thread, uintptr_t argv, uint32_t argc);
|
||||
|
||||
static inline JSTaggedValue RuntimeAotNewObjWithIHClass(JSThread *thread, uintptr_t argv, uint32_t argc);
|
||||
static inline JSTaggedValue RuntimeGetAotLexEnv(JSThread *thread);
|
||||
static inline void RuntimeSetAotLexEnv(JSThread *thread, JSTaggedValue lexEnv);
|
||||
static inline JSTaggedValue RuntimeGenerateAotScopeInfo(JSThread *thread, uint16_t scopeId, JSTaggedValue func);
|
||||
static inline JSTaggedType *GetActualArgv(JSThread *thread);
|
||||
static inline OptimizedJSFunctionFrame *GetOptimizedJSFunctionFrame(JSThread *thread);
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif
|
||||
|
@ -48,8 +48,10 @@ group("ark_aot_test") {
|
||||
"mul:mulAotAction",
|
||||
"neg:negAotAction",
|
||||
"new:newAotAction",
|
||||
"newlexenv:newlexenvAotAction",
|
||||
"not:notAotAction",
|
||||
"or:orAotAction",
|
||||
"poplexenv:poplexenvAotAction",
|
||||
"setobjectwithproto:setobjectwithprotoAotAction",
|
||||
"shl:shlAotAction",
|
||||
"shr:shrAotAction",
|
||||
@ -68,6 +70,7 @@ group("ark_aot_test") {
|
||||
"strictnotequal:strictnotequalAotAction",
|
||||
"sub:subAotAction",
|
||||
"throw:throwAotAction",
|
||||
"throwundefindeifhole:throwundefindeifholeAotAction",
|
||||
"tonumber:tonumberAotAction",
|
||||
"trystglobalbynameprefid32:trystglobalbynameprefid32AotAction",
|
||||
"typeof:typeofAotAction",
|
||||
|
Loading…
Reference in New Issue
Block a user