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:
xujie 2022-06-29 17:09:09 +08:00
parent 0618a06957
commit 92d366b8fc
27 changed files with 668 additions and 355 deletions

View File

@ -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());
}
}

View File

@ -376,6 +376,7 @@ enum BytecodeOffset {
enum CommonArgIdx : uint8_t {
GLUE = 0,
LEXENV,
ACTUAL_ARGC,
FUNC,
NEW_TARGET,

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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++) {

View File

@ -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};

View File

@ -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

View File

@ -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);

View File

@ -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:

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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());
}

View File

@ -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(&copyArgLoop);
__ 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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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:

View File

@ -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> &currentLexEnv)
JSHandle<JSTaggedValue> &currentLexEnv,
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

View File

@ -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);

View File

@ -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> &currentLexEnv);
static inline JSTaggedValue RuntimeNewAotLexicalEnvWithNameDyn(JSThread *thread, uint16_t numVars, uint16_t scopeId,
JSHandle<JSTaggedValue> &currentLexEnv);
static inline JSTaggedValue RuntimeCopyAotRestArgs(JSThread *thread, uint32_t autualArgc, uint32_t restId);
JSHandle<JSTaggedValue> &currentLexEnv,
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

View File

@ -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",