From 1485bab6566504e375219ba6346def5ba8b31622 Mon Sep 17 00:00:00 2001 From: "@wang-jingwu001" Date: Mon, 29 Aug 2022 17:08:06 +0800 Subject: [PATCH] Optimize the asyncgenerator interface in slow_runtime_stub.cpp Signed-off-by: @wang-jingwu001 https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I5OMTF --- BUILD.gn | 1 - ecmascript/builtins/builtins_global.cpp | 5 +- .../interpreter/slow_runtime_helper.cpp | 101 ----------------- ecmascript/interpreter/slow_runtime_helper.h | 34 ------ ecmascript/interpreter/slow_runtime_stub.cpp | 105 ++---------------- ecmascript/interpreter/slow_runtime_stub.h | 6 - ecmascript/stubs/runtime_stubs-inl.h | 20 +++- ecmascript/stubs/runtime_stubs.cpp | 75 +++++++++++++ ecmascript/stubs/runtime_stubs.h | 8 ++ 9 files changed, 112 insertions(+), 243 deletions(-) delete mode 100644 ecmascript/interpreter/slow_runtime_helper.cpp delete mode 100644 ecmascript/interpreter/slow_runtime_helper.h diff --git a/BUILD.gn b/BUILD.gn index a54577b9e..c5a9b4c2f 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -435,7 +435,6 @@ ecma_source = [ "ecmascript/interpreter/frame_handler.cpp", "ecmascript/interpreter/interpreter.cpp", "ecmascript/interpreter/interpreter_assembly.cpp", - "ecmascript/interpreter/slow_runtime_helper.cpp", "ecmascript/interpreter/slow_runtime_stub.cpp", "ecmascript/jobs/micro_job_queue.cpp", "ecmascript/jspandafile/js_pandafile.cpp", diff --git a/ecmascript/builtins/builtins_global.cpp b/ecmascript/builtins/builtins_global.cpp index b946d5658..786dd3371 100644 --- a/ecmascript/builtins/builtins_global.cpp +++ b/ecmascript/builtins/builtins_global.cpp @@ -23,8 +23,9 @@ #include "ecmascript/base/number_helper.h" #include "ecmascript/base/string_helper.h" #include "ecmascript/ecma_macros.h" -#include "ecmascript/interpreter/slow_runtime_helper.h" +#include "ecmascript/js_function.h" #include "ecmascript/mem/c_containers.h" +#include "ecmascript/stubs/runtime_stubs.h" #include "ecmascript/tagged_array-inl.h" namespace panda::ecmascript::builtins { @@ -515,7 +516,7 @@ JSTaggedValue BuiltinsGlobal::CallJsBoundFunction(EcmaRuntimeCallInfo *msg) JSHandle boundFunc(GetConstructor(msg)); JSHandle thisObj(thread, boundFunc->GetBoundThis()); msg->SetThis(thisObj.GetTaggedValue()); - return SlowRuntimeHelper::CallBoundFunction(msg); + return RuntimeStubs::CallBoundFunction(msg); } JSTaggedValue BuiltinsGlobal::CallJsProxy(EcmaRuntimeCallInfo *msg) diff --git a/ecmascript/interpreter/slow_runtime_helper.cpp b/ecmascript/interpreter/slow_runtime_helper.cpp deleted file mode 100644 index fd76565ea..000000000 --- a/ecmascript/interpreter/slow_runtime_helper.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "slow_runtime_helper.h" - -#include "ecmascript/global_env.h" -#include "ecmascript/interpreter/frame_handler.h" -#include "ecmascript/interpreter/interpreter-inl.h" -#include "ecmascript/js_generator_object.h" -#include "ecmascript/js_tagged_value.h" -#include "ecmascript/mem/c_containers.h" -#include "ecmascript/tagged_array-inl.h" - -namespace panda::ecmascript { -JSTaggedValue SlowRuntimeHelper::CallBoundFunction(EcmaRuntimeCallInfo *info) -{ - JSThread *thread = info->GetThread(); - JSHandle boundFunc(info->GetFunction()); - JSHandle targetFunc(thread, boundFunc->GetBoundTarget()); - if (targetFunc->IsClassConstructor()) { - THROW_TYPE_ERROR_AND_RETURN(thread, "class constructor cannot called without 'new'", - JSTaggedValue::Exception()); - } - - JSHandle boundArgs(thread, boundFunc->GetBoundArguments()); - const uint32_t boundLength = boundArgs->GetLength(); - const uint32_t argsLength = info->GetArgsNumber() + boundLength; - JSHandle undefined = thread->GlobalConstants()->GetHandledUndefined(); - EcmaRuntimeCallInfo *runtimeInfo = EcmaInterpreter::NewRuntimeCallInfo(thread, JSHandle(targetFunc), - info->GetThis(), undefined, argsLength); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - if (boundLength == 0) { - runtimeInfo->SetCallArg(argsLength, 0, info, 0); - } else { - // 0 ~ boundLength is boundArgs; boundLength ~ argsLength is args of EcmaRuntimeCallInfo. - runtimeInfo->SetCallArg(boundLength, boundArgs); - runtimeInfo->SetCallArg(argsLength, boundLength, info, 0); - } - return EcmaInterpreter::Execute(runtimeInfo); -} - -JSTaggedValue SlowRuntimeHelper::NewObject(EcmaRuntimeCallInfo *info) -{ - ASSERT(info); - JSThread *thread = info->GetThread(); - JSHandle func(info->GetFunction()); - if (!func->IsHeapObject()) { - THROW_TYPE_ERROR_AND_RETURN(thread, "function is nullptr", JSTaggedValue::Exception()); - } - - if (!func->IsJSFunction()) { - if (func->IsBoundFunction()) { - JSTaggedValue result = JSBoundFunction::ConstructInternal(info); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - return result; - } - - if (func->IsJSProxy()) { - JSTaggedValue jsObj = JSProxy::ConstructInternal(info); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - return jsObj; - } - THROW_TYPE_ERROR_AND_RETURN(thread, "Constructed NonConstructable", JSTaggedValue::Exception()); - } - - JSTaggedValue result = JSFunction::ConstructInternal(info); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - return result; -} - -void SlowRuntimeHelper::SaveFrameToContext(JSThread *thread, JSHandle context) -{ - FrameHandler frameHandler(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - uint32_t nregs = frameHandler.GetNumberArgs(); - JSHandle regsArray = factory->NewTaggedArray(nregs); - for (uint32_t i = 0; i < nregs; i++) { - JSTaggedValue value = frameHandler.GetVRegValue(i); - regsArray->Set(thread, i, value); - } - context->SetRegsArray(thread, regsArray.GetTaggedValue()); - context->SetMethod(thread, frameHandler.GetFunction()); - - context->SetAcc(thread, frameHandler.GetAcc()); - context->SetLexicalEnv(thread, thread->GetCurrentLexenv()); - context->SetNRegs(nregs); - context->SetBCOffset(frameHandler.GetBytecodeOffset()); -} -} // namespace panda::ecmascript diff --git a/ecmascript/interpreter/slow_runtime_helper.h b/ecmascript/interpreter/slow_runtime_helper.h deleted file mode 100644 index a118e5f97..000000000 --- a/ecmascript/interpreter/slow_runtime_helper.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ECMASCRIPT_INTERPRETER_SLOW_RUNTIME_HELPER_H -#define ECMASCRIPT_INTERPRETER_SLOW_RUNTIME_HELPER_H - -#include "ecmascript/js_function.h" -#include "ecmascript/js_thread.h" -#include "ecmascript/object_factory.h" - -namespace panda::ecmascript { -class SlowRuntimeHelper { -public: - static JSTaggedValue NewObject(EcmaRuntimeCallInfo *info); - - static JSTaggedValue CallBoundFunction(EcmaRuntimeCallInfo *info); - - static void SaveFrameToContext(JSThread *thread, JSHandle context); -}; -} // namespace panda::ecmascript - -#endif // ECMASCRIPT_INTERPRETER_SLOW_RUNTIME_HELPER_H diff --git a/ecmascript/interpreter/slow_runtime_stub.cpp b/ecmascript/interpreter/slow_runtime_stub.cpp index a31c83183..3695f91c0 100644 --- a/ecmascript/interpreter/slow_runtime_stub.cpp +++ b/ecmascript/interpreter/slow_runtime_stub.cpp @@ -21,8 +21,7 @@ #include "ecmascript/ic/profile_type_info.h" #include "ecmascript/interpreter/frame_handler.h" #include "ecmascript/interpreter/interpreter-inl.h" -#include "ecmascript/interpreter/slow_runtime_helper.h" -#include "ecmascript/jspandafile/class_info_extractor.h" +#include "ecmascript/jobs/micro_job_queue.h" #include "ecmascript/jspandafile/program_object.h" #include "ecmascript/jspandafile/scope_info_extractor.h" #include "ecmascript/js_arguments.h" @@ -429,15 +428,8 @@ JSTaggedValue SlowRuntimeStub::CreateAsyncGeneratorObj(JSThread *thread, JSTagge INTERPRETER_TRACE(thread, CreateAsyncGeneratorObj); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle asyncGeneratorFunction(thread, genFunc); - JSHandle obj = factory->NewJSAsyncGeneratorObject(asyncGeneratorFunction); - JSHandle context = factory->NewGeneratorContext(); - context->SetGeneratorObject(thread, obj.GetTaggedValue()); - // change state to SUSPENDED_START - obj->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_START); - obj->SetGeneratorContext(thread, context); - return obj.GetTaggedValue(); + return RuntimeStubs::RuntimeCreateAsyncGeneratorObj(thread, asyncGeneratorFunction); } JSTaggedValue SlowRuntimeStub::SuspendGenerator(JSThread *thread, JSTaggedValue genObj, JSTaggedValue value) @@ -446,54 +438,8 @@ JSTaggedValue SlowRuntimeStub::SuspendGenerator(JSThread *thread, JSTaggedValue [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle genObjHandle(thread, genObj); - if (genObjHandle->IsGeneratorObject()) { - JSHandle obj = JSTaggedValue::ToObject(thread, genObjHandle); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSHandle generatorObjectHandle = JSHandle::Cast(obj); - JSHandle genContextHandle(thread, generatorObjectHandle->GetGeneratorContext()); - return SuspendGeneratorHelper(thread, generatorObjectHandle, genContextHandle, value); - } - if (genObjHandle->IsAsyncGeneratorObject()) { - JSHandle obj = JSTaggedValue::ToObject(thread, genObjHandle); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSHandle generatorObjectHandle = JSHandle::Cast(obj); - JSHandle genContextHandle(thread, generatorObjectHandle->GetGeneratorContext()); - return SuspendAsyncGeneratorHelper(thread, generatorObjectHandle, genContextHandle, value); - } - return JSTaggedValue::Undefined(); -} - -JSTaggedValue SlowRuntimeStub::SuspendGeneratorHelper(JSThread *thread, - JSHandle generatorObjectHandle, - JSHandle genContextHandle, JSTaggedValue value) -{ JSHandle valueHandle(thread, value); - // save stack, should copy cur_frame, function execute over will free cur_frame - SlowRuntimeHelper::SaveFrameToContext(thread, genContextHandle); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - // change state to SuspendedYield - if (generatorObjectHandle->IsExecuting()) { - generatorObjectHandle->SetGeneratorState(JSGeneratorState::SUSPENDED_YIELD); - return valueHandle.GetTaggedValue(); - } - return generatorObjectHandle.GetTaggedValue(); -} - -JSTaggedValue SlowRuntimeStub::SuspendAsyncGeneratorHelper(JSThread *thread, - JSHandle generatorObjectHandle, - JSHandle genContextHandle, - JSTaggedValue value) -{ - JSHandle valueHandle(thread, value); - // save stack, should copy cur_frame, function execute over will free cur_frame - SlowRuntimeHelper::SaveFrameToContext(thread, genContextHandle); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - // change state to SuspendedYield - if (generatorObjectHandle->IsExecuting()) { - generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_YIELD); - return valueHandle.GetTaggedValue(); - } - return generatorObjectHandle.GetTaggedValue(); + return RuntimeStubs::RuntimeSuspendGenerator(thread, genObjHandle, valueHandle); } JSTaggedValue SlowRuntimeStub::AsyncFunctionAwaitUncaught(JSThread *thread, JSTaggedValue asyncFuncObj, @@ -504,24 +450,7 @@ JSTaggedValue SlowRuntimeStub::AsyncFunctionAwaitUncaught(JSThread *thread, JSTa JSHandle asyncFuncObjHandle(thread, asyncFuncObj); JSHandle valueHandle(thread, value); - JSAsyncFunction::AsyncFunctionAwait(thread, asyncFuncObjHandle, valueHandle); - if (asyncFuncObjHandle->IsAsyncGeneratorObject()) { - JSHandle obj = JSTaggedValue::ToObject(thread, asyncFuncObjHandle); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSHandle generator = JSHandle::Cast(obj); - JSHandle queue(thread, generator->GetAsyncGeneratorQueue()); - if (queue->Empty()) { - return JSTaggedValue::Undefined(); - } - JSHandle next(thread, queue->Front()); - JSHandle completion(thread, next->GetCapability()); - JSHandle promise(thread, completion->GetPromise()); - return promise.GetTaggedValue(); - } - JSHandle asyncFunc(asyncFuncObjHandle); - JSHandle promise(thread, asyncFunc->GetPromise()); - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - return promise.GetTaggedValue(); + return RuntimeStubs::RuntimeAsyncFunctionAwaitUncaught(thread, asyncFuncObjHandle, valueHandle); } JSTaggedValue SlowRuntimeStub::AsyncFunctionResolveOrReject(JSThread *thread, JSTaggedValue asyncFuncObj, @@ -1174,32 +1103,18 @@ JSTaggedValue SlowRuntimeStub::AsyncGeneratorResolve(JSThread *thread, JSTaggedV INTERPRETER_TRACE(thread, AsyncGeneratorResolve); [[maybe_unused]] EcmaHandleScope handleScope(thread); - JSHandle asyncFuncObjHandle(thread, asyncFuncObj); + JSHandle genObjHandle(thread, asyncFuncObj); JSHandle valueHandle(thread, value); - ASSERT(flag.IsBoolean()); - bool done = flag.IsTrue(); - return JSAsyncGeneratorObject::AsyncGeneratorResolve(thread, asyncFuncObjHandle, valueHandle, done); + + return RuntimeStubs::RuntimeAsyncGeneratorResolve(thread, genObjHandle, valueHandle, flag); } JSTaggedValue SlowRuntimeStub::DefineAsyncGeneratorFunc(JSThread *thread, JSFunction *func) { INTERPRETER_TRACE(thread, DefineAsyncGeneratorFunc); [[maybe_unused]] EcmaHandleScope handleScope(thread); - JSHandle method(thread, func->GetMethod()); - - JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle jsFunc = factory->NewJSAsyncGeneratorFunction(method); - ASSERT_NO_ABRUPT_COMPLETION(thread); - // 26.3.4.3 prototype - // Whenever a GeneratorFunction instance is created another ordinary object is also created and - // is the initial value of the generator function's "prototype" property. - JSHandle objFun(env->GetObjectFunction()); - JSHandle initialAsyncGeneratorFuncPrototype = factory->NewJSObjectByConstructor(objFun); - JSObject::SetPrototype(thread, initialAsyncGeneratorFuncPrototype, env->GetAsyncGeneratorPrototype()); - ASSERT_NO_ABRUPT_COMPLETION(thread); - jsFunc->SetProtoOrDynClass(thread, initialAsyncGeneratorFuncPrototype); - - return jsFunc.GetTaggedValue(); + JSHandle funcHandle(thread, func); + + return RuntimeStubs::RuntimeDefineAsyncGeneratorFunc(thread, funcHandle); } } // namespace panda::ecmascript diff --git a/ecmascript/interpreter/slow_runtime_stub.h b/ecmascript/interpreter/slow_runtime_stub.h index 968321096..d20836829 100644 --- a/ecmascript/interpreter/slow_runtime_stub.h +++ b/ecmascript/interpreter/slow_runtime_stub.h @@ -73,12 +73,6 @@ public: static JSTaggedValue CreateGeneratorObj(JSThread *thread, JSTaggedValue genFunc); static JSTaggedValue SuspendGenerator(JSThread *thread, JSTaggedValue genObj, JSTaggedValue value); - static JSTaggedValue SuspendGeneratorHelper(JSThread *thread, JSHandle generatorObjectHandle, - JSHandle genContextHandle, JSTaggedValue value); - static JSTaggedValue SuspendAsyncGeneratorHelper(JSThread *thread, - JSHandle generatorObjectHandle, - JSHandle genContextHandle, - JSTaggedValue value); static JSTaggedValue AsyncFunctionAwaitUncaught(JSThread *thread, JSTaggedValue asyncFuncObj, JSTaggedValue value); static JSTaggedValue AsyncFunctionResolveOrReject(JSThread *thread, JSTaggedValue asyncFuncObj, JSTaggedValue value, bool is_resolve); diff --git a/ecmascript/stubs/runtime_stubs-inl.h b/ecmascript/stubs/runtime_stubs-inl.h index 168f637c4..8c2f063fe 100644 --- a/ecmascript/stubs/runtime_stubs-inl.h +++ b/ecmascript/stubs/runtime_stubs-inl.h @@ -25,7 +25,6 @@ #include "ecmascript/global_env.h" #include "ecmascript/ic/profile_type_info.h" #include "ecmascript/interpreter/frame_handler.h" -#include "ecmascript/interpreter/slow_runtime_helper.h" #include "ecmascript/js_arguments.h" #include "ecmascript/js_async_function.h" #include "ecmascript/js_async_generator_object.h" @@ -249,7 +248,7 @@ JSTaggedValue RuntimeStubs::RuntimeNewObjSpreadDyn(JSThread *thread, const JSHan EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, newTarget, length); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); info->SetCallArg(length, argsArray); - return SlowRuntimeHelper::NewObject(info); + return NewObject(info); } JSTaggedValue RuntimeStubs::RuntimeCreateIterResultObj(JSThread *thread, const JSHandle &value, @@ -267,6 +266,19 @@ JSTaggedValue RuntimeStubs::RuntimeAsyncFunctionAwaitUncaught(JSThread *thread, const JSHandle &value) { JSAsyncFunction::AsyncFunctionAwait(thread, asyncFuncObj, value); + if (asyncFuncObj->IsAsyncGeneratorObject()) { + JSHandle obj = JSTaggedValue::ToObject(thread, asyncFuncObj); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + JSHandle generator = JSHandle::Cast(obj); + JSHandle queue(thread, generator->GetAsyncGeneratorQueue()); + if (queue->Empty()) { + return JSTaggedValue::Undefined(); + } + JSHandle next(thread, queue->Front()); + JSHandle completion(thread, next->GetCapability()); + JSHandle promise(thread, completion->GetPromise()); + return promise.GetTaggedValue(); + } JSHandle asyncFuncObjHandle(asyncFuncObj); JSHandle promise(thread, asyncFuncObjHandle->GetPromise()); @@ -900,7 +912,7 @@ JSTaggedValue RuntimeStubs::RuntimeSuspendGenerator(JSThread *thread, const JSHa JSHandle generatorObjectHandle(genObj); JSHandle genContextHandle(thread, generatorObjectHandle->GetGeneratorContext()); // save stack, should copy cur_frame, function execute over will free cur_frame - SlowRuntimeHelper::SaveFrameToContext(thread, genContextHandle); + SaveFrameToContext(thread, genContextHandle); // change state to SuspendedYield if (generatorObjectHandle->IsExecuting()) { @@ -914,7 +926,7 @@ JSTaggedValue RuntimeStubs::RuntimeSuspendGenerator(JSThread *thread, const JSHa JSHandle generatorObjectHandle(genObj); JSHandle genContextHandle(thread, generatorObjectHandle->GetGeneratorContext()); // save stack, should copy cur_frame, function execute over will free cur_frame - SlowRuntimeHelper::SaveFrameToContext(thread, genContextHandle); + SaveFrameToContext(thread, genContextHandle); // change state to SuspendedYield if (generatorObjectHandle->IsExecuting()) { diff --git a/ecmascript/stubs/runtime_stubs.cpp b/ecmascript/stubs/runtime_stubs.cpp index c693413aa..1a0578d46 100644 --- a/ecmascript/stubs/runtime_stubs.cpp +++ b/ecmascript/stubs/runtime_stubs.cpp @@ -1833,6 +1833,81 @@ bool RuntimeStubs::BigIntEquals(JSTaggedType left, JSTaggedType right) return BigInt::Equal(JSTaggedValue(left), JSTaggedValue(right)); } +JSTaggedValue RuntimeStubs::NewObject(EcmaRuntimeCallInfo *info) +{ + ASSERT(info); + JSThread *thread = info->GetThread(); + JSHandle func(info->GetFunction()); + if (!func->IsHeapObject()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "function is nullptr", JSTaggedValue::Exception()); + } + + if (!func->IsJSFunction()) { + if (func->IsBoundFunction()) { + JSTaggedValue result = JSBoundFunction::ConstructInternal(info); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result; + } + + if (func->IsJSProxy()) { + JSTaggedValue jsObj = JSProxy::ConstructInternal(info); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return jsObj; + } + THROW_TYPE_ERROR_AND_RETURN(thread, "Constructed NonConstructable", JSTaggedValue::Exception()); + } + + JSTaggedValue result = JSFunction::ConstructInternal(info); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result; +} + +void RuntimeStubs::SaveFrameToContext(JSThread *thread, JSHandle context) +{ + FrameHandler frameHandler(thread); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + uint32_t nregs = frameHandler.GetNumberArgs(); + JSHandle regsArray = factory->NewTaggedArray(nregs); + for (uint32_t i = 0; i < nregs; i++) { + JSTaggedValue value = frameHandler.GetVRegValue(i); + regsArray->Set(thread, i, value); + } + context->SetRegsArray(thread, regsArray.GetTaggedValue()); + context->SetMethod(thread, frameHandler.GetFunction()); + + context->SetAcc(thread, frameHandler.GetAcc()); + context->SetLexicalEnv(thread, thread->GetCurrentLexenv()); + context->SetNRegs(nregs); + context->SetBCOffset(frameHandler.GetBytecodeOffset()); +} + +JSTaggedValue RuntimeStubs::CallBoundFunction(EcmaRuntimeCallInfo *info) +{ + JSThread *thread = info->GetThread(); + JSHandle boundFunc(info->GetFunction()); + JSHandle targetFunc(thread, boundFunc->GetBoundTarget()); + if (targetFunc->IsClassConstructor()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "class constructor cannot called without 'new'", + JSTaggedValue::Exception()); + } + + JSHandle boundArgs(thread, boundFunc->GetBoundArguments()); + const int32_t boundLength = static_cast(boundArgs->GetLength()); + const int32_t argsLength = info->GetArgsNumber() + boundLength; + JSHandle undefined = thread->GlobalConstants()->GetHandledUndefined(); + EcmaRuntimeCallInfo *runtimeInfo = EcmaInterpreter::NewRuntimeCallInfo(thread, JSHandle(targetFunc), + info->GetThis(), undefined, argsLength); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (boundLength == 0) { + runtimeInfo->SetCallArg(argsLength, 0, info, 0); + } else { + // 0 ~ boundLength is boundArgs; boundLength ~ argsLength is args of EcmaRuntimeCallInfo. + runtimeInfo->SetCallArg(boundLength, boundArgs); + runtimeInfo->SetCallArg(argsLength, boundLength, info, 0); + } + return EcmaInterpreter::Execute(runtimeInfo); +} + void RuntimeStubs::Initialize(JSThread *thread) { #define DEF_RUNTIME_STUB(name) kungfu::RuntimeStubCSigns::ID_##name diff --git a/ecmascript/stubs/runtime_stubs.h b/ecmascript/stubs/runtime_stubs.h index db442f759..7093348a3 100644 --- a/ecmascript/stubs/runtime_stubs.h +++ b/ecmascript/stubs/runtime_stubs.h @@ -34,6 +34,9 @@ class ObjectFactory; class JSBoundFunction; class JSProxy; +class GeneratorContext; +struct EcmaRuntimeCallInfo; + using JSFunctionEntryType = JSTaggedValue (*)(uintptr_t glue, uintptr_t prevFp, uint32_t expectedNumArgs, uint32_t actualNumArgs, const JSTaggedType argV[], uintptr_t codeAddr); @@ -306,6 +309,8 @@ public: JSTaggedType key, int32_t num); static bool StringsAreEquals(EcmaString *str1, EcmaString *str2); static bool BigIntEquals(JSTaggedType left, JSTaggedType right); + + static JSTaggedValue CallBoundFunction(EcmaRuntimeCallInfo *info); private: static void PrintHeapReginInfo(uintptr_t argGlue); @@ -564,6 +569,9 @@ private: static inline JSTaggedType *GetActualArgv(JSThread *thread); static inline OptimizedJSFunctionFrame *GetOptimizedJSFunctionFrame(JSThread *thread); + static JSTaggedValue NewObject(EcmaRuntimeCallInfo *info); + static void SaveFrameToContext(JSThread *thread, JSHandle context); + friend class SlowRuntimeStub; }; } // namespace panda::ecmascript -- Gitee