14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_STUBS_RUNTIME_STUBS_INL_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_STUBS_RUNTIME_STUBS_INL_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/ecma_macros.h" 204514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value.h" 214514f5e3Sopenharmony_ci#include "ecmascript/stubs/runtime_stubs.h" 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_ci#include "ecmascript/base/array_helper.h" 244514f5e3Sopenharmony_ci#include "ecmascript/builtins/builtins_regexp.h" 254514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_file/aot_file_manager.h" 264514f5e3Sopenharmony_ci#include "ecmascript/debugger/js_debugger_manager.h" 274514f5e3Sopenharmony_ci#include "ecmascript/ecma_string_table.h" 284514f5e3Sopenharmony_ci#include "ecmascript/global_dictionary-inl.h" 294514f5e3Sopenharmony_ci#include "ecmascript/global_env.h" 304514f5e3Sopenharmony_ci#include "ecmascript/ic/profile_type_info.h" 314514f5e3Sopenharmony_ci#include "ecmascript/interpreter/frame_handler.h" 324514f5e3Sopenharmony_ci#include "ecmascript/interpreter/interpreter.h" 334514f5e3Sopenharmony_ci#include "ecmascript/jobs/micro_job_queue.h" 344514f5e3Sopenharmony_ci#include "ecmascript/js_arguments.h" 354514f5e3Sopenharmony_ci#include "ecmascript/js_async_function.h" 364514f5e3Sopenharmony_ci#include "ecmascript/js_async_generator_object.h" 374514f5e3Sopenharmony_ci#include "ecmascript/js_bigint.h" 384514f5e3Sopenharmony_ci#include "ecmascript/js_for_in_iterator.h" 394514f5e3Sopenharmony_ci#include "ecmascript/js_generator_object.h" 404514f5e3Sopenharmony_ci#include "ecmascript/js_iterator.h" 414514f5e3Sopenharmony_ci#include "ecmascript/js_promise.h" 424514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/class_info_extractor.h" 434514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/literal_data_extractor.h" 444514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/program_object.h" 454514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/scope_info_extractor.h" 464514f5e3Sopenharmony_ci#include "ecmascript/message_string.h" 474514f5e3Sopenharmony_ci#include "ecmascript/module/js_module_manager.h" 484514f5e3Sopenharmony_ci#include "ecmascript/module/js_module_source_text.h" 494514f5e3Sopenharmony_ci#include "ecmascript/object_factory-inl.h" 504514f5e3Sopenharmony_ci#include "ecmascript/patch/quick_fix_helper.h" 514514f5e3Sopenharmony_ci#include "ecmascript/platform/file.h" 524514f5e3Sopenharmony_ci#include "ecmascript/runtime.h" 534514f5e3Sopenharmony_ci#include "ecmascript/stackmap/llvm/llvm_stackmap_parser.h" 544514f5e3Sopenharmony_ci#include "ecmascript/sendable_env.h" 554514f5e3Sopenharmony_ci#include "ecmascript/template_string.h" 564514f5e3Sopenharmony_ci 574514f5e3Sopenharmony_cinamespace panda::ecmascript { 584514f5e3Sopenharmony_ciusing ArrayHelper = base::ArrayHelper; 594514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeInc(JSThread *thread, const JSHandle<JSTaggedValue> &value) 604514f5e3Sopenharmony_ci{ 614514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value); 624514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 634514f5e3Sopenharmony_ci if (inputVal->IsBigInt()) { 644514f5e3Sopenharmony_ci JSHandle<BigInt> bigValue(inputVal); 654514f5e3Sopenharmony_ci return BigInt::BigintAddOne(thread, bigValue).GetTaggedValue(); 664514f5e3Sopenharmony_ci } 674514f5e3Sopenharmony_ci JSTaggedNumber number(inputVal.GetTaggedValue()); 684514f5e3Sopenharmony_ci return JSTaggedValue(++number); 694514f5e3Sopenharmony_ci} 704514f5e3Sopenharmony_ci 714514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeDec(JSThread *thread, const JSHandle<JSTaggedValue> &value) 724514f5e3Sopenharmony_ci{ 734514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value); 744514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 754514f5e3Sopenharmony_ci if (inputVal->IsBigInt()) { 764514f5e3Sopenharmony_ci JSHandle<BigInt> bigValue(inputVal); 774514f5e3Sopenharmony_ci return BigInt::BigintSubOne(thread, bigValue).GetTaggedValue(); 784514f5e3Sopenharmony_ci } 794514f5e3Sopenharmony_ci JSTaggedNumber number(inputVal.GetTaggedValue()); 804514f5e3Sopenharmony_ci return JSTaggedValue(--number); 814514f5e3Sopenharmony_ci} 824514f5e3Sopenharmony_ci 834514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeExp(JSThread *thread, JSTaggedValue base, JSTaggedValue exponent) 844514f5e3Sopenharmony_ci{ 854514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> baseTag(thread, base); 864514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> exponentTag(thread, exponent); 874514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valBase = JSTaggedValue::ToNumeric(thread, baseTag); 884514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 894514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valExponent = JSTaggedValue::ToNumeric(thread, exponentTag); 904514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 914514f5e3Sopenharmony_ci if (valBase->IsBigInt() || valExponent->IsBigInt()) { 924514f5e3Sopenharmony_ci if (valBase->IsBigInt() && valExponent->IsBigInt()) { 934514f5e3Sopenharmony_ci JSHandle<BigInt> bigBaseVale(valBase); 944514f5e3Sopenharmony_ci JSHandle<BigInt> bigExponentValue(valExponent); 954514f5e3Sopenharmony_ci return BigInt::Exponentiate(thread, bigBaseVale, bigExponentValue).GetTaggedValue(); 964514f5e3Sopenharmony_ci } 974514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot mix BigInt and other types, use explicit conversions", 984514f5e3Sopenharmony_ci JSTaggedValue::Exception()); 994514f5e3Sopenharmony_ci } 1004514f5e3Sopenharmony_ci double doubleBase = valBase->GetNumber(); 1014514f5e3Sopenharmony_ci double doubleExponent = valExponent->GetNumber(); 1024514f5e3Sopenharmony_ci if (std::abs(doubleBase) == 1 && std::isinf(doubleExponent)) { 1034514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 1044514f5e3Sopenharmony_ci } 1054514f5e3Sopenharmony_ci if (((doubleBase == 0) && 1064514f5e3Sopenharmony_ci ((base::bit_cast<uint64_t>(doubleBase)) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) && 1074514f5e3Sopenharmony_ci std::isfinite(doubleExponent) && base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent && 1084514f5e3Sopenharmony_ci base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF == (doubleExponent / 2)) { // 2: half 1094514f5e3Sopenharmony_ci if (doubleExponent > 0) { 1104514f5e3Sopenharmony_ci return JSTaggedValue(-0.0); 1114514f5e3Sopenharmony_ci } 1124514f5e3Sopenharmony_ci if (doubleExponent < 0) { 1134514f5e3Sopenharmony_ci return JSTaggedValue(-base::POSITIVE_INFINITY); 1144514f5e3Sopenharmony_ci } 1154514f5e3Sopenharmony_ci } 1164514f5e3Sopenharmony_ci return JSTaggedValue(std::pow(doubleBase, doubleExponent)); 1174514f5e3Sopenharmony_ci} 1184514f5e3Sopenharmony_ci 1194514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeIsIn(JSThread *thread, const JSHandle<JSTaggedValue> &prop, 1204514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &obj) 1214514f5e3Sopenharmony_ci{ 1224514f5e3Sopenharmony_ci if (!obj->IsECMAObject()) { 1234514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot use 'in' operator in Non-Object"); 1244514f5e3Sopenharmony_ci } 1254514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop); 1264514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1274514f5e3Sopenharmony_ci bool ret = JSTaggedValue::HasProperty(thread, obj, propKey); 1284514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1294514f5e3Sopenharmony_ci return JSTaggedValue(ret); 1304514f5e3Sopenharmony_ci} 1314514f5e3Sopenharmony_ci 1324514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeInstanceof(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 1334514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &target) 1344514f5e3Sopenharmony_ci{ 1354514f5e3Sopenharmony_ci bool ret = JSObject::InstanceOf(thread, obj, target); 1364514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1374514f5e3Sopenharmony_ci return JSTaggedValue(ret); 1384514f5e3Sopenharmony_ci} 1394514f5e3Sopenharmony_ci 1404514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeInstanceofByHandler(JSThread *thread, JSHandle<JSTaggedValue> target, 1414514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> object, 1424514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> instOfHandler) 1434514f5e3Sopenharmony_ci{ 1444514f5e3Sopenharmony_ci // 3. ReturnIfAbrupt(instOfHandler). 1454514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1464514f5e3Sopenharmony_ci // 4. If instOfHandler is not undefined, then 1474514f5e3Sopenharmony_ci if (!instOfHandler->IsUndefined()) { 1484514f5e3Sopenharmony_ci // a. Return ! ToBoolean(? Call(instOfHandler, target, «object»)). 1494514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 1504514f5e3Sopenharmony_ci JSTaggedValue function = env->GetTaggedHasInstanceFunction(); 1514514f5e3Sopenharmony_ci JSTaggedValue instOf = instOfHandler.GetTaggedValue(); 1524514f5e3Sopenharmony_ci // slowpath 1534514f5e3Sopenharmony_ci if (function != instOf) { 1544514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 1554514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, instOfHandler, target, 1564514f5e3Sopenharmony_ci undefined, 1); 1574514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1584514f5e3Sopenharmony_ci info->SetCallArg(object.GetTaggedValue()); 1594514f5e3Sopenharmony_ci JSTaggedValue tagged = JSFunction::Call(info); 1604514f5e3Sopenharmony_ci 1614514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1624514f5e3Sopenharmony_ci return tagged; 1634514f5e3Sopenharmony_ci } 1644514f5e3Sopenharmony_ci } 1654514f5e3Sopenharmony_ci // 5. If IsCallable(target) is false, throw a TypeError exception. 1664514f5e3Sopenharmony_ci if (!target->IsCallable()) { 1674514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "InstanceOf error when target is not Callable", JSTaggedValue::Exception()); 1684514f5e3Sopenharmony_ci } 1694514f5e3Sopenharmony_ci // fastpath 1704514f5e3Sopenharmony_ci // 6. Return ? OrdinaryHasInstance(target, object). 1714514f5e3Sopenharmony_ci bool res = JSFunction::OrdinaryHasInstance(thread, target, object); 1724514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1734514f5e3Sopenharmony_ci return JSTaggedValue(res); 1744514f5e3Sopenharmony_ci} 1754514f5e3Sopenharmony_ci 1764514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateGeneratorObj(JSThread *thread, const JSHandle<JSTaggedValue> &genFunc) 1774514f5e3Sopenharmony_ci{ 1784514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 1794514f5e3Sopenharmony_ci JSHandle<JSGeneratorObject> obj = factory->NewJSGeneratorObject(genFunc); 1804514f5e3Sopenharmony_ci JSHandle<GeneratorContext> context = factory->NewGeneratorContext(); 1814514f5e3Sopenharmony_ci context->SetGeneratorObject(thread, obj.GetTaggedValue()); 1824514f5e3Sopenharmony_ci 1834514f5e3Sopenharmony_ci // change state to SUSPENDED_START 1844514f5e3Sopenharmony_ci obj->SetGeneratorState(JSGeneratorState::SUSPENDED_START); 1854514f5e3Sopenharmony_ci obj->SetGeneratorContext(thread, context); 1864514f5e3Sopenharmony_ci 1874514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1884514f5e3Sopenharmony_ci return obj.GetTaggedValue(); 1894514f5e3Sopenharmony_ci} 1904514f5e3Sopenharmony_ci 1914514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateAsyncGeneratorObj(JSThread *thread, const JSHandle<JSTaggedValue> &genFunc) 1924514f5e3Sopenharmony_ci{ 1934514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 1944514f5e3Sopenharmony_ci JSHandle<JSAsyncGeneratorObject> obj = factory->NewJSAsyncGeneratorObject(genFunc); 1954514f5e3Sopenharmony_ci JSHandle<GeneratorContext> context = factory->NewGeneratorContext(); 1964514f5e3Sopenharmony_ci context->SetGeneratorObject(thread, obj.GetTaggedValue()); 1974514f5e3Sopenharmony_ci 1984514f5e3Sopenharmony_ci // change state to SUSPENDED_START 1994514f5e3Sopenharmony_ci obj->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_START); 2004514f5e3Sopenharmony_ci obj->SetGeneratorContext(thread, context); 2014514f5e3Sopenharmony_ci 2024514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2034514f5e3Sopenharmony_ci return obj.GetTaggedValue(); 2044514f5e3Sopenharmony_ci} 2054514f5e3Sopenharmony_ci 2064514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetTemplateObject(JSThread *thread, const JSHandle<JSTaggedValue> &literal) 2074514f5e3Sopenharmony_ci{ 2084514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> templateObj = TemplateString::GetTemplateObject(thread, literal); 2094514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2104514f5e3Sopenharmony_ci return templateObj.GetTaggedValue(); 2114514f5e3Sopenharmony_ci} 2124514f5e3Sopenharmony_ci 2134514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetNextPropName(JSThread *thread, const JSHandle<JSTaggedValue> &iter) 2144514f5e3Sopenharmony_ci{ 2154514f5e3Sopenharmony_ci ASSERT(iter->IsForinIterator()); 2164514f5e3Sopenharmony_ci JSTaggedValue res = JSForInIterator::NextInternal(thread, JSHandle<JSForInIterator>::Cast(iter)); 2174514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2184514f5e3Sopenharmony_ci return res; 2194514f5e3Sopenharmony_ci} 2204514f5e3Sopenharmony_ci 2214514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeIterNext(JSThread *thread, const JSHandle<JSTaggedValue> &iter) 2224514f5e3Sopenharmony_ci{ 2234514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> resultObj = JSIterator::IteratorNext(thread, iter); 2244514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2254514f5e3Sopenharmony_ci return resultObj.GetTaggedValue(); 2264514f5e3Sopenharmony_ci} 2274514f5e3Sopenharmony_ci 2284514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCloseIterator(JSThread *thread, const JSHandle<JSTaggedValue> &iter) 2294514f5e3Sopenharmony_ci{ 2304514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 2314514f5e3Sopenharmony_ci const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 2324514f5e3Sopenharmony_ci 2334514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> record; 2344514f5e3Sopenharmony_ci if (thread->HasPendingException()) { 2354514f5e3Sopenharmony_ci record = JSHandle<JSTaggedValue>(factory->NewCompletionRecord( 2364514f5e3Sopenharmony_ci CompletionRecordType::THROW, JSHandle<JSTaggedValue>(thread, thread->GetException()))); 2374514f5e3Sopenharmony_ci } else { 2384514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefinedVal = globalConst->GetHandledUndefined(); 2394514f5e3Sopenharmony_ci record = JSHandle<JSTaggedValue>(factory->NewCompletionRecord(CompletionRecordType::NORMAL, undefinedVal)); 2404514f5e3Sopenharmony_ci } 2414514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> result = JSIterator::IteratorClose(thread, iter, record); 2424514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2434514f5e3Sopenharmony_ci if (result->IsCompletionRecord()) { 2444514f5e3Sopenharmony_ci return CompletionRecord::Cast(result->GetTaggedObject())->GetValue(); 2454514f5e3Sopenharmony_ci } 2464514f5e3Sopenharmony_ci return result.GetTaggedValue(); 2474514f5e3Sopenharmony_ci} 2484514f5e3Sopenharmony_ci 2494514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeSuperCallSpread(JSThread *thread, const JSHandle<JSTaggedValue> &func, 2504514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &newTarget, 2514514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &array) 2524514f5e3Sopenharmony_ci{ 2534514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func)); 2544514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2554514f5e3Sopenharmony_ci if (!superFunc->IsJSFunction()) { 2564514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Super constructor is not JSFunction", JSTaggedValue::Exception()); 2574514f5e3Sopenharmony_ci } 2584514f5e3Sopenharmony_ci 2594514f5e3Sopenharmony_ci JSHandle<TaggedArray> argv(thread, RuntimeGetCallSpreadArgs(thread, array)); 2604514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2614514f5e3Sopenharmony_ci const uint32_t argsLength = argv->GetLength(); 2624514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 2634514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = 2644514f5e3Sopenharmony_ci EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, argsLength); 2654514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2664514f5e3Sopenharmony_ci info->SetCallArg(argsLength, argv); 2674514f5e3Sopenharmony_ci JSTaggedValue result = JSFunction::Construct(info); 2684514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2694514f5e3Sopenharmony_ci 2704514f5e3Sopenharmony_ci return result; 2714514f5e3Sopenharmony_ci} 2724514f5e3Sopenharmony_ci 2734514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptSuperCallSpread(JSThread *thread, const JSHandle<JSTaggedValue> &func, 2744514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &newTarget, 2754514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &taggedArray) 2764514f5e3Sopenharmony_ci{ 2774514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func)); 2784514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2794514f5e3Sopenharmony_ci if (!superFunc->IsJSFunction()) { 2804514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Super constructor is not JSFunction", JSTaggedValue::Exception()); 2814514f5e3Sopenharmony_ci } 2824514f5e3Sopenharmony_ci 2834514f5e3Sopenharmony_ci JSHandle<TaggedArray> argv(thread, taggedArray.GetTaggedValue()); 2844514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2854514f5e3Sopenharmony_ci const uint32_t argsLength = argv->GetLength(); 2864514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 2874514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = 2884514f5e3Sopenharmony_ci EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, argsLength); 2894514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2904514f5e3Sopenharmony_ci info->SetCallArg(argsLength, argv); 2914514f5e3Sopenharmony_ci JSTaggedValue result = JSFunction::Construct(info); 2924514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2934514f5e3Sopenharmony_ci 2944514f5e3Sopenharmony_ci return result; 2954514f5e3Sopenharmony_ci} 2964514f5e3Sopenharmony_ci 2974514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeSuperCallForwardAllArgs(JSThread *thread, JSTaggedType *sp, 2984514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &superFunc, 2994514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &newTarget, 3004514f5e3Sopenharmony_ci uint32_t restNumArgs, uint32_t startIdx) 3014514f5e3Sopenharmony_ci{ 3024514f5e3Sopenharmony_ci if (!superFunc->IsConstructor()) { 3034514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Super constructor is not a constructor", JSTaggedValue::Exception()); 3044514f5e3Sopenharmony_ci } 3054514f5e3Sopenharmony_ci 3064514f5e3Sopenharmony_ci // prepare callinfo 3074514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 3084514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = 3094514f5e3Sopenharmony_ci EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, restNumArgs); 3104514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3114514f5e3Sopenharmony_ci // set args for callinfo 3124514f5e3Sopenharmony_ci for (uint32_t i = 0; i < restNumArgs; ++i) { 3134514f5e3Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 3144514f5e3Sopenharmony_ci info->SetCallArg(i, JSTaggedValue(sp[startIdx + i])); 3154514f5e3Sopenharmony_ci } 3164514f5e3Sopenharmony_ci // execute super ctor with call info 3174514f5e3Sopenharmony_ci JSTaggedValue res = JSFunction::Construct(info); 3184514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3194514f5e3Sopenharmony_ci return res; 3204514f5e3Sopenharmony_ci} 3214514f5e3Sopenharmony_ci 3224514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeDelObjProp(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 3234514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &prop) 3244514f5e3Sopenharmony_ci{ 3254514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> jsObj(JSTaggedValue::ToObject(thread, obj)); 3264514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3274514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop); 3284514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3294514f5e3Sopenharmony_ci bool ret = JSTaggedValue::DeletePropertyOrThrow(thread, jsObj, propKey); 3304514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3314514f5e3Sopenharmony_ci return JSTaggedValue(ret); 3324514f5e3Sopenharmony_ci} 3334514f5e3Sopenharmony_ci 3344514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNewObjApply(JSThread *thread, const JSHandle<JSTaggedValue> &func, 3354514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &array) 3364514f5e3Sopenharmony_ci{ 3374514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 3384514f5e3Sopenharmony_ci if (!array->IsJSArray()) { 3394514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot Newobjspread"); 3404514f5e3Sopenharmony_ci } 3414514f5e3Sopenharmony_ci 3424514f5e3Sopenharmony_ci uint32_t length = JSHandle<JSArray>::Cast(array)->GetArrayLength(); 3434514f5e3Sopenharmony_ci JSHandle<TaggedArray> argsArray = factory->NewTaggedArray(length); 3444514f5e3Sopenharmony_ci for (uint32_t i = 0; i < length; ++i) { 3454514f5e3Sopenharmony_ci auto prop = JSTaggedValue::GetProperty(thread, array, i).GetValue(); 3464514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3474514f5e3Sopenharmony_ci argsArray->Set(thread, i, prop); 3484514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3494514f5e3Sopenharmony_ci } 3504514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 3514514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, func, length); 3524514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3534514f5e3Sopenharmony_ci info->SetCallArg(length, argsArray); 3544514f5e3Sopenharmony_ci return NewObject(info); 3554514f5e3Sopenharmony_ci} 3564514f5e3Sopenharmony_ci 3574514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateIterResultObj(JSThread *thread, const JSHandle<JSTaggedValue> &value, 3584514f5e3Sopenharmony_ci JSTaggedValue flag) 3594514f5e3Sopenharmony_ci{ 3604514f5e3Sopenharmony_ci ASSERT(flag.IsBoolean()); 3614514f5e3Sopenharmony_ci bool done = flag.IsTrue(); 3624514f5e3Sopenharmony_ci JSHandle<JSObject> iter = JSIterator::CreateIterResultObject(thread, value, done); 3634514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3644514f5e3Sopenharmony_ci return iter.GetTaggedValue(); 3654514f5e3Sopenharmony_ci} 3664514f5e3Sopenharmony_ci 3674514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeAsyncFunctionAwaitUncaught(JSThread *thread, 3684514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &asyncFuncObj, 3694514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 3704514f5e3Sopenharmony_ci{ 3714514f5e3Sopenharmony_ci JSAsyncFunction::AsyncFunctionAwait(thread, asyncFuncObj, value); 3724514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3734514f5e3Sopenharmony_ci if (asyncFuncObj->IsAsyncGeneratorObject()) { 3744514f5e3Sopenharmony_ci JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, asyncFuncObj); 3754514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3764514f5e3Sopenharmony_ci JSHandle<JSAsyncGeneratorObject> generator = JSHandle<JSAsyncGeneratorObject>::Cast(obj); 3774514f5e3Sopenharmony_ci JSHandle<TaggedQueue> queue(thread, generator->GetAsyncGeneratorQueue()); 3784514f5e3Sopenharmony_ci if (queue->Empty()) { 3794514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 3804514f5e3Sopenharmony_ci } 3814514f5e3Sopenharmony_ci JSHandle<AsyncGeneratorRequest> next(thread, queue->Front()); 3824514f5e3Sopenharmony_ci JSHandle<PromiseCapability> completion(thread, next->GetCapability()); 3834514f5e3Sopenharmony_ci JSHandle<JSPromise> promise(thread, completion->GetPromise()); 3844514f5e3Sopenharmony_ci return promise.GetTaggedValue(); 3854514f5e3Sopenharmony_ci } 3864514f5e3Sopenharmony_ci JSHandle<JSAsyncFuncObject> asyncFuncObjHandle(asyncFuncObj); 3874514f5e3Sopenharmony_ci JSHandle<JSPromise> promise(thread, asyncFuncObjHandle->GetPromise()); 3884514f5e3Sopenharmony_ci 3894514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3904514f5e3Sopenharmony_ci return promise.GetTaggedValue(); 3914514f5e3Sopenharmony_ci} 3924514f5e3Sopenharmony_ci 3934514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeAsyncFunctionResolveOrReject(JSThread *thread, 3944514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &asyncFuncObj, const JSHandle<JSTaggedValue> &value, bool is_resolve) 3954514f5e3Sopenharmony_ci{ 3964514f5e3Sopenharmony_ci JSHandle<JSAsyncFuncObject> asyncFuncObjHandle(asyncFuncObj); 3974514f5e3Sopenharmony_ci JSHandle<JSPromise> promise(thread, asyncFuncObjHandle->GetPromise()); 3984514f5e3Sopenharmony_ci 3994514f5e3Sopenharmony_ci // ActivePromise 4004514f5e3Sopenharmony_ci JSHandle<ResolvingFunctionsRecord> reactions = JSPromise::CreateResolvingFunctions(thread, promise); 4014514f5e3Sopenharmony_ci const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 4024514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisArg = globalConst->GetHandledUndefined(); 4034514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> activeFunc; 4044514f5e3Sopenharmony_ci if (is_resolve) { 4054514f5e3Sopenharmony_ci activeFunc = JSHandle<JSTaggedValue>(thread, reactions->GetResolveFunction()); 4064514f5e3Sopenharmony_ci } else { 4074514f5e3Sopenharmony_ci activeFunc = JSHandle<JSTaggedValue>(thread, reactions->GetRejectFunction()); 4084514f5e3Sopenharmony_ci } 4094514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 4104514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, activeFunc, thisArg, undefined, 1); 4114514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 4124514f5e3Sopenharmony_ci info->SetCallArg(value.GetTaggedValue()); 4134514f5e3Sopenharmony_ci [[maybe_unused]] JSTaggedValue res = JSFunction::Call(info); 4144514f5e3Sopenharmony_ci 4154514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 4164514f5e3Sopenharmony_ci return promise.GetTaggedValue(); 4174514f5e3Sopenharmony_ci} 4184514f5e3Sopenharmony_ci 4194514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeAsyncGeneratorResolve(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj, 4204514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value, JSTaggedValue flag) 4214514f5e3Sopenharmony_ci{ 4224514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 4234514f5e3Sopenharmony_ci 4244514f5e3Sopenharmony_ci JSHandle<JSAsyncGeneratorObject> asyncGeneratorObjHandle(asyncFuncObj); 4254514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valueHandle(value); 4264514f5e3Sopenharmony_ci JSHandle<GeneratorContext> genContextHandle(thread, asyncGeneratorObjHandle->GetGeneratorContext()); 4274514f5e3Sopenharmony_ci // save stack, should copy cur_frame, function execute over will free cur_frame 4284514f5e3Sopenharmony_ci SaveFrameToContext(thread, genContextHandle); 4294514f5e3Sopenharmony_ci 4304514f5e3Sopenharmony_ci ASSERT(flag.IsBoolean()); 4314514f5e3Sopenharmony_ci bool done = flag.IsTrue(); 4324514f5e3Sopenharmony_ci 4334514f5e3Sopenharmony_ci return JSAsyncGeneratorObject::AsyncGeneratorResolve(thread, asyncGeneratorObjHandle, valueHandle, done); 4344514f5e3Sopenharmony_ci} 4354514f5e3Sopenharmony_ci 4364514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeAsyncGeneratorReject(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj, 4374514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value) 4384514f5e3Sopenharmony_ci{ 4394514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 4404514f5e3Sopenharmony_ci 4414514f5e3Sopenharmony_ci JSHandle<JSAsyncGeneratorObject> asyncGeneratorObjHandle(asyncFuncObj); 4424514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valueHandle(value); 4434514f5e3Sopenharmony_ci 4444514f5e3Sopenharmony_ci return JSAsyncGeneratorObject::AsyncGeneratorReject(thread, asyncGeneratorObjHandle, valueHandle); 4454514f5e3Sopenharmony_ci} 4464514f5e3Sopenharmony_ci 4474514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCopyDataProperties(JSThread *thread, const JSHandle<JSTaggedValue> &dst, 4484514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &src) 4494514f5e3Sopenharmony_ci{ 4504514f5e3Sopenharmony_ci if (!src->IsNull() && !src->IsUndefined()) { 4514514f5e3Sopenharmony_ci // 2. Let from be ! ToObject(source). 4524514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> from(JSTaggedValue::ToObject(thread, src)); 4534514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 4544514f5e3Sopenharmony_ci JSHandle<TaggedArray> keys = JSTaggedValue::GetOwnPropertyKeys(thread, from); 4554514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 4564514f5e3Sopenharmony_ci 4574514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined()); 4584514f5e3Sopenharmony_ci uint32_t keysLen = keys->GetLength(); 4594514f5e3Sopenharmony_ci for (uint32_t i = 0; i < keysLen; i++) { 4604514f5e3Sopenharmony_ci PropertyDescriptor desc(thread); 4614514f5e3Sopenharmony_ci key.Update(keys->Get(i)); 4624514f5e3Sopenharmony_ci bool success = JSTaggedValue::GetOwnProperty(thread, from, key, desc); 4634514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 4644514f5e3Sopenharmony_ci 4654514f5e3Sopenharmony_ci if (success && desc.IsEnumerable()) { 4664514f5e3Sopenharmony_ci desc.SetWritable(true); 4674514f5e3Sopenharmony_ci desc.SetConfigurable(true); 4684514f5e3Sopenharmony_ci JSTaggedValue::DefineOwnProperty(thread, dst, key, desc); 4694514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 4704514f5e3Sopenharmony_ci } 4714514f5e3Sopenharmony_ci } 4724514f5e3Sopenharmony_ci } 4734514f5e3Sopenharmony_ci return dst.GetTaggedValue(); 4744514f5e3Sopenharmony_ci} 4754514f5e3Sopenharmony_ci 4764514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStArraySpread(JSThread *thread, const JSHandle<JSTaggedValue> &dst, 4774514f5e3Sopenharmony_ci JSTaggedValue index, const JSHandle<JSTaggedValue> &src) 4784514f5e3Sopenharmony_ci{ 4794514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 4804514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefinedHandle(thread, JSTaggedValue::Undefined()); 4814514f5e3Sopenharmony_ci ASSERT(dst->IsJSArray()); 4824514f5e3Sopenharmony_ci if (dst->IsJSArray()) { 4834514f5e3Sopenharmony_ci if (src->IsNull() || src->IsUndefined()) { 4844514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "src is not iterable", JSTaggedValue::Exception()); 4854514f5e3Sopenharmony_ci } 4864514f5e3Sopenharmony_ci } else { 4874514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "dst is not iterable", JSTaggedValue::Exception()); 4884514f5e3Sopenharmony_ci } 4894514f5e3Sopenharmony_ci if (src->IsString()) { 4904514f5e3Sopenharmony_ci JSHandle<EcmaString> srcString = JSTaggedValue::ToString(thread, src); 4914514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 4924514f5e3Sopenharmony_ci JSHandle<EcmaString> srcFlat = JSHandle<EcmaString>(thread, 4934514f5e3Sopenharmony_ci EcmaStringAccessor::Flatten(thread->GetEcmaVM(), srcString)); 4944514f5e3Sopenharmony_ci uint32_t dstLen = static_cast<uint32_t>(index.GetInt()); 4954514f5e3Sopenharmony_ci uint32_t strLen = EcmaStringAccessor(srcFlat).GetLength(); 4964514f5e3Sopenharmony_ci for (uint32_t i = 0; i < strLen; i++) { 4974514f5e3Sopenharmony_ci uint16_t res = EcmaStringAccessor(srcFlat).Get<false>(i); 4984514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> strValue(factory->NewFromUtf16Literal(&res, 1)); 4994514f5e3Sopenharmony_ci JSTaggedValue::SetProperty(thread, dst, dstLen + i, strValue, true); 5004514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 5014514f5e3Sopenharmony_ci } 5024514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> length(thread, JSTaggedValue(dstLen + strLen)); 5034514f5e3Sopenharmony_ci if (strLen == 0U) { 5044514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> lengthKey = thread->GlobalConstants()->GetHandledLengthString(); 5054514f5e3Sopenharmony_ci JSTaggedValue::SetProperty(thread, dst, lengthKey, length); 5064514f5e3Sopenharmony_ci } 5074514f5e3Sopenharmony_ci return length.GetTaggedValue(); 5084514f5e3Sopenharmony_ci } 5094514f5e3Sopenharmony_ci 5104514f5e3Sopenharmony_ci if (index.GetInt() == 0 && src->IsStableJSArray(thread)) { 5114514f5e3Sopenharmony_ci JSHandle<TaggedArray> srcElements(thread, JSHandle<JSObject>::Cast(src)->GetElements()); 5124514f5e3Sopenharmony_ci uint32_t length = JSHandle<JSArray>::Cast(src)->GetArrayLength(); 5134514f5e3Sopenharmony_ci JSHandle<TaggedArray> dstElements = factory->NewTaggedArray(length); 5144514f5e3Sopenharmony_ci JSHandle<JSArray> dstArray = JSHandle<JSArray>::Cast(dst); 5154514f5e3Sopenharmony_ci dstArray->SetElements(thread, dstElements); 5164514f5e3Sopenharmony_ci dstArray->SetArrayLength(thread, length); 5174514f5e3Sopenharmony_ci JSHandle<JSObject> srcObj(src); 5184514f5e3Sopenharmony_ci JSHandle<JSObject> dstObj(dst); 5194514f5e3Sopenharmony_ci ElementAccessor::CopyJSArrayObject(thread, srcObj, dstObj, length); 5204514f5e3Sopenharmony_ci for (uint32_t i = 0; i < length; i++) { 5214514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> reg(thread, ElementAccessor::Get(srcObj, i)); 5224514f5e3Sopenharmony_ci if (reg->IsHole()) { 5234514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> reg2(thread, JSArray::FastGetPropertyByValue(thread, src, i).GetTaggedValue()); 5244514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 5254514f5e3Sopenharmony_ci if (reg2->IsHole()) { 5264514f5e3Sopenharmony_ci ElementAccessor::Set(thread, dstObj, i, undefinedHandle, true); 5274514f5e3Sopenharmony_ci } else { 5284514f5e3Sopenharmony_ci ElementAccessor::Set(thread, dstObj, i, reg2, true); 5294514f5e3Sopenharmony_ci } 5304514f5e3Sopenharmony_ci } else { 5314514f5e3Sopenharmony_ci ElementAccessor::Set(thread, dstObj, i, reg, true); 5324514f5e3Sopenharmony_ci } 5334514f5e3Sopenharmony_ci } 5344514f5e3Sopenharmony_ci return JSTaggedValue(length); 5354514f5e3Sopenharmony_ci } 5364514f5e3Sopenharmony_ci 5374514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> iter; 5384514f5e3Sopenharmony_ci auto globalConst = thread->GlobalConstants(); 5394514f5e3Sopenharmony_ci if (src->IsJSArrayIterator() || src->IsJSMapIterator() || src->IsJSSetIterator() || 5404514f5e3Sopenharmony_ci src->IsIterator()) { 5414514f5e3Sopenharmony_ci iter = src; 5424514f5e3Sopenharmony_ci } else if (src->IsJSArray()) { 5434514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valuesStr = globalConst->GetHandledValuesString(); 5444514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valuesMethod = JSObject::GetMethod(thread, src, valuesStr); 5454514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 5464514f5e3Sopenharmony_ci iter = JSIterator::GetIterator(thread, src, valuesMethod); 5474514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 5484514f5e3Sopenharmony_ci } else { 5494514f5e3Sopenharmony_ci iter = JSIterator::GetIterator(thread, src); 5504514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 5514514f5e3Sopenharmony_ci } 5524514f5e3Sopenharmony_ci 5534514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> indexHandle(thread, index); 5544514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valueStr = globalConst->GetHandledValueString(); 5554514f5e3Sopenharmony_ci PropertyDescriptor desc(thread); 5564514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> iterResult; 5574514f5e3Sopenharmony_ci uint32_t srcLen = 0U; 5584514f5e3Sopenharmony_ci do { 5594514f5e3Sopenharmony_ci iterResult = JSIterator::IteratorStep(thread, iter); 5604514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 5614514f5e3Sopenharmony_ci if (iterResult->IsFalse()) { 5624514f5e3Sopenharmony_ci break; 5634514f5e3Sopenharmony_ci } 5644514f5e3Sopenharmony_ci bool success = JSTaggedValue::GetOwnProperty(thread, iterResult, valueStr, desc); 5654514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 5664514f5e3Sopenharmony_ci if (success && desc.IsEnumerable()) { 5674514f5e3Sopenharmony_ci JSTaggedValue::DefineOwnProperty(thread, dst, indexHandle, desc); 5684514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 5694514f5e3Sopenharmony_ci int tmp = indexHandle->GetInt(); 5704514f5e3Sopenharmony_ci indexHandle.Update(JSTaggedValue(tmp + 1)); 5714514f5e3Sopenharmony_ci ++srcLen; 5724514f5e3Sopenharmony_ci } 5734514f5e3Sopenharmony_ci } while (true); 5744514f5e3Sopenharmony_ci if (srcLen == 0U) { 5754514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> lengthKey = thread->GlobalConstants()->GetHandledLengthString(); 5764514f5e3Sopenharmony_ci JSTaggedValue::SetProperty(thread, dst, lengthKey, indexHandle); 5774514f5e3Sopenharmony_ci } 5784514f5e3Sopenharmony_ci return indexHandle.GetTaggedValue(); 5794514f5e3Sopenharmony_ci} 5804514f5e3Sopenharmony_ci 5814514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetIteratorNext(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 5824514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &method) 5834514f5e3Sopenharmony_ci{ 5844514f5e3Sopenharmony_ci ASSERT(method->IsCallable()); 5854514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 5864514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, method, obj, undefined, 0); 5874514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 5884514f5e3Sopenharmony_ci JSTaggedValue ret = JSFunction::Call(info); 5894514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 5904514f5e3Sopenharmony_ci if (!ret.IsECMAObject()) { 5914514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "the Iterator is not an ecmaobject."); 5924514f5e3Sopenharmony_ci } 5934514f5e3Sopenharmony_ci return ret; 5944514f5e3Sopenharmony_ci} 5954514f5e3Sopenharmony_ci 5964514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeSetObjectWithProto(JSThread *thread, const JSHandle<JSTaggedValue> &proto, 5974514f5e3Sopenharmony_ci const JSHandle<JSObject> &obj) 5984514f5e3Sopenharmony_ci{ 5994514f5e3Sopenharmony_ci if (!proto->IsECMAObject() && !proto->IsNull()) { 6004514f5e3Sopenharmony_ci return JSTaggedValue::False(); 6014514f5e3Sopenharmony_ci } 6024514f5e3Sopenharmony_ci if (UNLIKELY(proto->IsJSShared())) { 6034514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, GET_MESSAGE_STRING(SetProtoWithSendable), JSTaggedValue::Exception()); 6044514f5e3Sopenharmony_ci } 6054514f5e3Sopenharmony_ci JSObject::SetPrototype(thread, obj, proto); 6064514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6074514f5e3Sopenharmony_ci return JSTaggedValue::True(); 6084514f5e3Sopenharmony_ci} 6094514f5e3Sopenharmony_ci 6104514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdObjByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 6114514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &prop, bool callGetter, 6124514f5e3Sopenharmony_ci JSTaggedValue receiver) 6134514f5e3Sopenharmony_ci{ 6144514f5e3Sopenharmony_ci // Ecma Spec 2015 12.3.2.1 6154514f5e3Sopenharmony_ci // 7. Let bv be RequireObjectCoercible(baseValue). 6164514f5e3Sopenharmony_ci // 8. ReturnIfAbrupt(bv). 6174514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> object = 6184514f5e3Sopenharmony_ci JSTaggedValue::RequireObjectCoercible(thread, obj, "Cannot load property of null or undefined"); 6194514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6204514f5e3Sopenharmony_ci 6214514f5e3Sopenharmony_ci JSTaggedValue res; 6224514f5e3Sopenharmony_ci if (callGetter) { 6234514f5e3Sopenharmony_ci res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), object); 6244514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6254514f5e3Sopenharmony_ci } else { 6264514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop); 6274514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6284514f5e3Sopenharmony_ci res = JSTaggedValue::GetProperty(thread, object, propKey).GetValue().GetTaggedValue(); 6294514f5e3Sopenharmony_ci } 6304514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6314514f5e3Sopenharmony_ci return res; 6324514f5e3Sopenharmony_ci} 6334514f5e3Sopenharmony_ci 6344514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStObjByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 6354514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &prop, 6364514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 6374514f5e3Sopenharmony_ci{ 6384514f5e3Sopenharmony_ci // Ecma Spec 2015 12.3.2.1 6394514f5e3Sopenharmony_ci // 7. Let bv be RequireObjectCoercible(baseValue). 6404514f5e3Sopenharmony_ci // 8. ReturnIfAbrupt(bv). 6414514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> object = 6424514f5e3Sopenharmony_ci JSTaggedValue::RequireObjectCoercible(thread, obj, "Cannot store property of null or undefined"); 6434514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6444514f5e3Sopenharmony_ci 6454514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, prop)); 6464514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6474514f5e3Sopenharmony_ci // strict mode is true 6484514f5e3Sopenharmony_ci JSTaggedValue::SetProperty(thread, object, propKey, value, true); 6494514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6504514f5e3Sopenharmony_ci return JSTaggedValue::True(); 6514514f5e3Sopenharmony_ci} 6524514f5e3Sopenharmony_ci 6534514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStOwnByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 6544514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &key, 6554514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 6564514f5e3Sopenharmony_ci{ 6574514f5e3Sopenharmony_ci const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 6584514f5e3Sopenharmony_ci 6594514f5e3Sopenharmony_ci if (obj->IsClassConstructor() && 6604514f5e3Sopenharmony_ci JSTaggedValue::SameValue(key, globalConst->GetHandledPrototypeString())) { 6614514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "In a class, static property named 'prototype' throw a TypeError"); 6624514f5e3Sopenharmony_ci } 6634514f5e3Sopenharmony_ci 6644514f5e3Sopenharmony_ci // property in class is non-enumerable 6654514f5e3Sopenharmony_ci bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor()); 6664514f5e3Sopenharmony_ci 6674514f5e3Sopenharmony_ci PropertyDescriptor desc(thread, value, true, enumerable, true); 6684514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, key); 6694514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6704514f5e3Sopenharmony_ci bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, propKey, desc); 6714514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6724514f5e3Sopenharmony_ci if (!ret) { 6734514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "StOwnByValue failed"); 6744514f5e3Sopenharmony_ci } 6754514f5e3Sopenharmony_ci return JSTaggedValue::True(); 6764514f5e3Sopenharmony_ci} 6774514f5e3Sopenharmony_ci 6784514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdSuperByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 6794514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &key, JSTaggedValue thisFunc) 6804514f5e3Sopenharmony_ci{ 6814514f5e3Sopenharmony_ci ASSERT(thisFunc.IsJSFunction()); 6824514f5e3Sopenharmony_ci // get Homeobject form function 6834514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> homeObject(thread, JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject()); 6844514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> superBase(thread, JSTaggedValue::GetSuperBase(thread, homeObject)); 6854514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6864514f5e3Sopenharmony_ci JSTaggedValue::RequireObjectCoercible(thread, superBase); 6874514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6884514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, key)); 6894514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6904514f5e3Sopenharmony_ci 6914514f5e3Sopenharmony_ci JSTaggedValue res = JSTaggedValue::GetProperty(thread, superBase, propKey, obj).GetValue().GetTaggedValue(); 6924514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6934514f5e3Sopenharmony_ci return res; 6944514f5e3Sopenharmony_ci} 6954514f5e3Sopenharmony_ci 6964514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStSuperByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 6974514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &key, 6984514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value, JSTaggedValue thisFunc) 6994514f5e3Sopenharmony_ci{ 7004514f5e3Sopenharmony_ci ASSERT(thisFunc.IsJSFunction()); 7014514f5e3Sopenharmony_ci // get Homeobject form function 7024514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> homeObject(thread, JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject()); 7034514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> superBase(thread, JSTaggedValue::GetSuperBase(thread, homeObject)); 7044514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 7054514f5e3Sopenharmony_ci JSTaggedValue::RequireObjectCoercible(thread, superBase); 7064514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 7074514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, key)); 7084514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 7094514f5e3Sopenharmony_ci 7104514f5e3Sopenharmony_ci // check may_throw is false? 7114514f5e3Sopenharmony_ci JSTaggedValue::SetProperty(thread, superBase, propKey, value, obj, true); 7124514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 7134514f5e3Sopenharmony_ci return JSTaggedValue::True(); 7144514f5e3Sopenharmony_ci} 7154514f5e3Sopenharmony_ci 7164514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdObjByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 7174514f5e3Sopenharmony_ci uint32_t idx, bool callGetter, JSTaggedValue receiver) 7184514f5e3Sopenharmony_ci{ 7194514f5e3Sopenharmony_ci JSTaggedValue res; 7204514f5e3Sopenharmony_ci if (callGetter) { 7214514f5e3Sopenharmony_ci res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), obj); 7224514f5e3Sopenharmony_ci } else { 7234514f5e3Sopenharmony_ci res = JSTaggedValue::GetProperty(thread, obj, idx).GetValue().GetTaggedValue(); 7244514f5e3Sopenharmony_ci } 7254514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 7264514f5e3Sopenharmony_ci return res; 7274514f5e3Sopenharmony_ci} 7284514f5e3Sopenharmony_ci 7294514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdObjByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, 7304514f5e3Sopenharmony_ci bool callGetter, JSTaggedValue receiver) 7314514f5e3Sopenharmony_ci{ 7324514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> objHandle(thread, obj); 7334514f5e3Sopenharmony_ci JSTaggedValue res; 7344514f5e3Sopenharmony_ci if (callGetter) { 7354514f5e3Sopenharmony_ci res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), objHandle); 7364514f5e3Sopenharmony_ci } else { 7374514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propHandle(thread, prop); 7384514f5e3Sopenharmony_ci res = JSTaggedValue::GetProperty(thread, objHandle, propHandle).GetValue().GetTaggedValue(); 7394514f5e3Sopenharmony_ci } 7404514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 7414514f5e3Sopenharmony_ci return res; 7424514f5e3Sopenharmony_ci} 7434514f5e3Sopenharmony_ci 7444514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStObjByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 7454514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &prop, 7464514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 7474514f5e3Sopenharmony_ci{ 7484514f5e3Sopenharmony_ci JSTaggedValue::SetProperty(thread, obj, prop, value, true); 7494514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 7504514f5e3Sopenharmony_ci return JSTaggedValue::True(); 7514514f5e3Sopenharmony_ci} 7524514f5e3Sopenharmony_ci 7534514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStObjByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 7544514f5e3Sopenharmony_ci uint32_t idx, const JSHandle<JSTaggedValue> &value) 7554514f5e3Sopenharmony_ci{ 7564514f5e3Sopenharmony_ci JSTaggedValue::SetProperty(thread, obj, idx, value, true); 7574514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 7584514f5e3Sopenharmony_ci return JSTaggedValue::True(); 7594514f5e3Sopenharmony_ci} 7604514f5e3Sopenharmony_ci 7614514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStOwnByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 7624514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &idx, 7634514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 7644514f5e3Sopenharmony_ci{ 7654514f5e3Sopenharmony_ci // property in class is non-enumerable 7664514f5e3Sopenharmony_ci bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor()); 7674514f5e3Sopenharmony_ci 7684514f5e3Sopenharmony_ci PropertyDescriptor desc(thread, value, true, enumerable, true); 7694514f5e3Sopenharmony_ci bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, idx, desc); 7704514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 7714514f5e3Sopenharmony_ci if (!ret) { 7724514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "SetOwnByIndex failed"); 7734514f5e3Sopenharmony_ci } 7744514f5e3Sopenharmony_ci return JSTaggedValue::True(); 7754514f5e3Sopenharmony_ci} 7764514f5e3Sopenharmony_ci 7774514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStGlobalRecord(JSThread *thread, const JSHandle<JSTaggedValue> &prop, 7784514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value, bool isConst) 7794514f5e3Sopenharmony_ci{ 7804514f5e3Sopenharmony_ci ObjectFactory* factory = thread->GetEcmaVM()->GetFactory(); 7814514f5e3Sopenharmony_ci if (thread->GetEcmaVM()->GetJSOptions().IsEnableLoweringBuiltin()) { 7824514f5e3Sopenharmony_ci BuiltinIndex& builtinIndex = BuiltinIndex::GetInstance(); 7834514f5e3Sopenharmony_ci auto index = builtinIndex.GetBuiltinIndex(prop.GetTaggedValue()); 7844514f5e3Sopenharmony_ci if (index != BuiltinIndex::NOT_FOUND) { 7854514f5e3Sopenharmony_ci auto box = factory->NewPropertyBox(JSHandle<JSTaggedValue>(thread, JSTaggedValue::Hole())); 7864514f5e3Sopenharmony_ci thread->GetBuiltinEntriesPointer()->ClearByIndex(index, box.GetTaggedValue()); 7874514f5e3Sopenharmony_ci } 7884514f5e3Sopenharmony_ci } 7894514f5e3Sopenharmony_ci 7904514f5e3Sopenharmony_ci EcmaVM *vm = thread->GetEcmaVM(); 7914514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = vm->GetGlobalEnv(); 7924514f5e3Sopenharmony_ci GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); 7934514f5e3Sopenharmony_ci 7944514f5e3Sopenharmony_ci // cross files global record name binding judgment 7954514f5e3Sopenharmony_ci int entry = dict->FindEntry(prop.GetTaggedValue()); 7964514f5e3Sopenharmony_ci if (entry != -1) { 7974514f5e3Sopenharmony_ci return RuntimeThrowSyntaxError(thread, "Duplicate identifier"); 7984514f5e3Sopenharmony_ci } 7994514f5e3Sopenharmony_ci 8004514f5e3Sopenharmony_ci PropertyAttributes attributes; 8014514f5e3Sopenharmony_ci if (isConst) { 8024514f5e3Sopenharmony_ci attributes.SetIsConstProps(true); 8034514f5e3Sopenharmony_ci } 8044514f5e3Sopenharmony_ci JSHandle<GlobalDictionary> dictHandle(thread, dict); 8054514f5e3Sopenharmony_ci JSHandle<PropertyBox> box = factory->NewPropertyBox(value); 8064514f5e3Sopenharmony_ci PropertyBoxType boxType = value->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT; 8074514f5e3Sopenharmony_ci attributes.SetBoxType(boxType); 8084514f5e3Sopenharmony_ci 8094514f5e3Sopenharmony_ci dict = *GlobalDictionary::PutIfAbsent(thread, dictHandle, prop, JSHandle<JSTaggedValue>(box), attributes); 8104514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 8114514f5e3Sopenharmony_ci env->SetGlobalRecord(thread, JSTaggedValue(dict)); 8124514f5e3Sopenharmony_ci return JSTaggedValue::True(); 8134514f5e3Sopenharmony_ci} 8144514f5e3Sopenharmony_ci 8154514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNeg(JSThread *thread, const JSHandle<JSTaggedValue> &value) 8164514f5e3Sopenharmony_ci{ 8174514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value); 8184514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 8194514f5e3Sopenharmony_ci if (inputVal->IsBigInt()) { 8204514f5e3Sopenharmony_ci JSHandle<BigInt> bigValue(inputVal); 8214514f5e3Sopenharmony_ci return BigInt::UnaryMinus(thread, bigValue).GetTaggedValue(); 8224514f5e3Sopenharmony_ci } 8234514f5e3Sopenharmony_ci JSTaggedNumber number(inputVal.GetTaggedValue()); 8244514f5e3Sopenharmony_ci if (number.IsInt()) { 8254514f5e3Sopenharmony_ci int32_t intValue = number.GetInt(); 8264514f5e3Sopenharmony_ci if (intValue == 0) { 8274514f5e3Sopenharmony_ci return JSTaggedValue(-0.0); 8284514f5e3Sopenharmony_ci } 8294514f5e3Sopenharmony_ci if (intValue == INT32_MIN) { 8304514f5e3Sopenharmony_ci return JSTaggedValue(-static_cast<double>(INT32_MIN)); 8314514f5e3Sopenharmony_ci } 8324514f5e3Sopenharmony_ci return JSTaggedValue(-intValue); 8334514f5e3Sopenharmony_ci } 8344514f5e3Sopenharmony_ci if (number.IsDouble()) { 8354514f5e3Sopenharmony_ci return JSTaggedValue(-number.GetDouble()); 8364514f5e3Sopenharmony_ci } 8374514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "this branch is unreachable"; 8384514f5e3Sopenharmony_ci UNREACHABLE(); 8394514f5e3Sopenharmony_ci} 8404514f5e3Sopenharmony_ci 8414514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNot(JSThread *thread, const JSHandle<JSTaggedValue> &value) 8424514f5e3Sopenharmony_ci{ 8434514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value); 8444514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 8454514f5e3Sopenharmony_ci if (inputVal->IsBigInt()) { 8464514f5e3Sopenharmony_ci JSHandle<BigInt> bigValue(inputVal); 8474514f5e3Sopenharmony_ci return BigInt::BitwiseNOT(thread, bigValue).GetTaggedValue(); 8484514f5e3Sopenharmony_ci } 8494514f5e3Sopenharmony_ci int32_t number = JSTaggedValue::ToInt32(thread, inputVal); 8504514f5e3Sopenharmony_ci return JSTaggedValue(~number); // NOLINT(hicpp-signed-bitwise) 8514514f5e3Sopenharmony_ci} 8524514f5e3Sopenharmony_ci 8534514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeResolveClass(JSThread *thread, const JSHandle<JSFunction> &ctor, 8544514f5e3Sopenharmony_ci const JSHandle<TaggedArray> &literal, 8554514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &base, 8564514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &lexenv) 8574514f5e3Sopenharmony_ci{ 8584514f5e3Sopenharmony_ci ASSERT(ctor.GetTaggedValue().IsClassConstructor()); 8594514f5e3Sopenharmony_ci 8604514f5e3Sopenharmony_ci FrameHandler frameHandler(thread); 8614514f5e3Sopenharmony_ci JSTaggedValue currentFunc = frameHandler.GetFunction(); 8624514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> ecmaModule(thread, JSFunction::Cast(currentFunc.GetTaggedObject())->GetModule()); 8634514f5e3Sopenharmony_ci 8644514f5e3Sopenharmony_ci RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(ctor), base); 8654514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 8664514f5e3Sopenharmony_ci 8674514f5e3Sopenharmony_ci uint32_t literalBufferLength = literal->GetLength(); 8684514f5e3Sopenharmony_ci ASSERT(literalBufferLength > 0); 8694514f5e3Sopenharmony_ci 8704514f5e3Sopenharmony_ci // only traverse the value of key-value pair 8714514f5e3Sopenharmony_ci for (uint32_t index = 1; index < literalBufferLength - 1; index += 2) { // 2: key-value pair 8724514f5e3Sopenharmony_ci JSTaggedValue value = literal->Get(index); 8734514f5e3Sopenharmony_ci if (LIKELY(value.IsJSFunction())) { 8744514f5e3Sopenharmony_ci JSFunction *func = JSFunction::Cast(value.GetTaggedObject()); 8754514f5e3Sopenharmony_ci func->SetLexicalEnv(thread, lexenv.GetTaggedValue()); 8764514f5e3Sopenharmony_ci func->SetModule(thread, ecmaModule); 8774514f5e3Sopenharmony_ci } 8784514f5e3Sopenharmony_ci } 8794514f5e3Sopenharmony_ci 8804514f5e3Sopenharmony_ci return ctor.GetTaggedValue(); 8814514f5e3Sopenharmony_ci} 8824514f5e3Sopenharmony_ci 8834514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCloneClassFromTemplate(JSThread *thread, const JSHandle<JSFunction> &ctor, 8844514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &base, 8854514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &lexenv) 8864514f5e3Sopenharmony_ci{ 8874514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 8884514f5e3Sopenharmony_ci const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 8894514f5e3Sopenharmony_ci 8904514f5e3Sopenharmony_ci ASSERT(ctor.GetTaggedValue().IsClassConstructor()); 8914514f5e3Sopenharmony_ci JSHandle<JSObject> clsPrototype(thread, ctor->GetFunctionPrototype()); 8924514f5e3Sopenharmony_ci 8934514f5e3Sopenharmony_ci bool canShareHClass = false; 8944514f5e3Sopenharmony_ci JSHandle<JSFunction> cloneClass = factory->CloneClassCtor(ctor, lexenv, canShareHClass); 8954514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 8964514f5e3Sopenharmony_ci JSHandle<JSObject> cloneClassPrototype = factory->CloneObjectLiteral(JSHandle<JSObject>(clsPrototype), lexenv, 8974514f5e3Sopenharmony_ci canShareHClass); 8984514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 8994514f5e3Sopenharmony_ci 9004514f5e3Sopenharmony_ci // After clone both, reset "constructor" and "prototype" properties. 9014514f5e3Sopenharmony_ci JSFunction::SetFunctionPrototypeOrInstanceHClass(thread, cloneClass, cloneClassPrototype.GetTaggedValue()); 9024514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 9034514f5e3Sopenharmony_ci 9044514f5e3Sopenharmony_ci PropertyDescriptor ctorDesc(thread, JSHandle<JSTaggedValue>(cloneClass), true, false, true); 9054514f5e3Sopenharmony_ci JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(cloneClassPrototype), 9064514f5e3Sopenharmony_ci globalConst->GetHandledConstructorString(), ctorDesc); 9074514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 9084514f5e3Sopenharmony_ci 9094514f5e3Sopenharmony_ci cloneClass->SetHomeObject(thread, cloneClassPrototype); 9104514f5e3Sopenharmony_ci 9114514f5e3Sopenharmony_ci if (!canShareHClass) { 9124514f5e3Sopenharmony_ci RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cloneClass), base); 9134514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 9144514f5e3Sopenharmony_ci } 9154514f5e3Sopenharmony_ci 9164514f5e3Sopenharmony_ci return cloneClass.GetTaggedValue(); 9174514f5e3Sopenharmony_ci} 9184514f5e3Sopenharmony_ci 9194514f5e3Sopenharmony_cibool RuntimeStubs::ShouldUseAOTHClass(const JSHandle<JSTaggedValue> &ihc, 9204514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &chc, 9214514f5e3Sopenharmony_ci const JSHandle<ClassLiteral> &classLiteral) 9224514f5e3Sopenharmony_ci{ 9234514f5e3Sopenharmony_ci // In the case of incomplete data collection in PGO, AOT may not create ihc and chc at the same time. 9244514f5e3Sopenharmony_ci // Therefore, there is no need to check for the existence of both at this point. 9254514f5e3Sopenharmony_ci return (!ihc->IsUndefined() || !chc->IsUndefined()) && !classLiteral->GetIsAOTUsed(); 9264514f5e3Sopenharmony_ci} 9274514f5e3Sopenharmony_ci// clone class may need re-set inheritance relationship due to extends may be a variable. 9284514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateClassWithBuffer(JSThread *thread, 9294514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &base, 9304514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &lexenv, 9314514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &constpool, 9324514f5e3Sopenharmony_ci uint16_t methodId, uint16_t literalId, 9334514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &module, 9344514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &length) 9354514f5e3Sopenharmony_ci{ 9364514f5e3Sopenharmony_ci if (base->IsJSShared()) { 9374514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, GET_MESSAGE_STRING(NotSendableSubClass), JSTaggedValue::Exception()); 9384514f5e3Sopenharmony_ci } 9394514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 9404514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 9414514f5e3Sopenharmony_ci CString entry = ModuleManager::GetRecordName(module.GetTaggedValue()); 9424514f5e3Sopenharmony_ci 9434514f5e3Sopenharmony_ci // For class constructor. 9444514f5e3Sopenharmony_ci auto methodObj = ConstantPool::GetMethodFromCache(thread, constpool.GetTaggedValue(), methodId); 9454514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> method(thread, methodObj); 9464514f5e3Sopenharmony_ci JSHandle<ConstantPool> constpoolHandle = JSHandle<ConstantPool>::Cast(constpool); 9474514f5e3Sopenharmony_ci JSHandle<JSFunction> cls; 9484514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> ihc(thread, JSTaggedValue::Undefined()); 9494514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> chc(thread, JSTaggedValue::Undefined()); 9504514f5e3Sopenharmony_ci 9514514f5e3Sopenharmony_ci JSHandle<ConstantPool> cp(thread, 9524514f5e3Sopenharmony_ci thread->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(constpoolHandle.GetTaggedValue())); 9534514f5e3Sopenharmony_ci JSTaggedValue val = cp->GetObjectFromCache(literalId); 9544514f5e3Sopenharmony_ci if (val.IsAOTLiteralInfo()) { 9554514f5e3Sopenharmony_ci JSHandle<AOTLiteralInfo> aotLiteralInfo(thread, val); 9564514f5e3Sopenharmony_ci ihc.Update(aotLiteralInfo->GetIhc()); 9574514f5e3Sopenharmony_ci chc.Update(aotLiteralInfo->GetChc()); 9584514f5e3Sopenharmony_ci } 9594514f5e3Sopenharmony_ci 9604514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> sendableEnv(thread, JSTaggedValue::Undefined()); 9614514f5e3Sopenharmony_ci if (module->GetTaggedObject()->GetClass()->IsSourceTextModule()) { 9624514f5e3Sopenharmony_ci JSHandle<SourceTextModule> moduleRecord = JSHandle<SourceTextModule>::Cast(module); 9634514f5e3Sopenharmony_ci sendableEnv = JSHandle<JSTaggedValue>(thread, moduleRecord->GetSendableEnv()); 9644514f5e3Sopenharmony_ci } 9654514f5e3Sopenharmony_ci JSTaggedValue literalObj = ConstantPool::GetClassLiteralFromCache(thread, cp, literalId, entry, sendableEnv); 9664514f5e3Sopenharmony_ci 9674514f5e3Sopenharmony_ci JSHandle<ClassLiteral> classLiteral(thread, literalObj); 9684514f5e3Sopenharmony_ci JSHandle<TaggedArray> arrayHandle(thread, classLiteral->GetArray()); 9694514f5e3Sopenharmony_ci JSHandle<ClassInfoExtractor> extractor = factory->NewClassInfoExtractor(method); 9704514f5e3Sopenharmony_ci auto literalLength = arrayHandle->GetLength(); 9714514f5e3Sopenharmony_ci ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(thread, extractor, arrayHandle, literalLength); 9724514f5e3Sopenharmony_ci 9734514f5e3Sopenharmony_ci if (ShouldUseAOTHClass(ihc, chc, classLiteral)) { 9744514f5e3Sopenharmony_ci classLiteral->SetIsAOTUsed(true); 9754514f5e3Sopenharmony_ci cls = ClassHelper::DefineClassWithIHClass(thread, base, extractor, lexenv, ihc, chc); 9764514f5e3Sopenharmony_ci } else { 9774514f5e3Sopenharmony_ci cls = ClassHelper::DefineClassFromExtractor(thread, base, extractor, lexenv); 9784514f5e3Sopenharmony_ci } 9794514f5e3Sopenharmony_ci 9804514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 9814514f5e3Sopenharmony_ci RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cls), base); 9824514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 9834514f5e3Sopenharmony_ci 9844514f5e3Sopenharmony_ci cls->SetLexicalEnv(thread, lexenv.GetTaggedValue()); 9854514f5e3Sopenharmony_ci cls->SetModule(thread, module.GetTaggedValue()); 9864514f5e3Sopenharmony_ci RuntimeSetClassConstructorLength(thread, cls.GetTaggedValue(), length.GetTaggedValue()); 9874514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 9884514f5e3Sopenharmony_ci 9894514f5e3Sopenharmony_ci return cls.GetTaggedValue(); 9904514f5e3Sopenharmony_ci} 9914514f5e3Sopenharmony_ci 9924514f5e3Sopenharmony_civoid RuntimeStubs::SetProfileTypeInfoCellToFunction(JSThread *thread, const JSHandle<JSFunction> &jsFunc, 9934514f5e3Sopenharmony_ci const JSHandle<JSFunction> &definedFunc, uint16_t slotId) 9944514f5e3Sopenharmony_ci{ 9954514f5e3Sopenharmony_ci if (slotId == ProfileTypeInfo::INVALID_SLOT_INDEX) { // do nothing for invalid slotId 9964514f5e3Sopenharmony_ci return; 9974514f5e3Sopenharmony_ci } 9984514f5e3Sopenharmony_ci 9994514f5e3Sopenharmony_ci ASSERT(definedFunc->IsJSFunction()); 10004514f5e3Sopenharmony_ci ASSERT(!definedFunc->IsSharedFunction()); 10014514f5e3Sopenharmony_ci ASSERT(jsFunc->IsJSFunction()); 10024514f5e3Sopenharmony_ci ASSERT(!jsFunc->IsSharedFunction()); 10034514f5e3Sopenharmony_ci 10044514f5e3Sopenharmony_ci auto profileTypeInfo = jsFunc->GetProfileTypeInfo(); 10054514f5e3Sopenharmony_ci if (profileTypeInfo.IsUndefined()) { 10064514f5e3Sopenharmony_ci JSHandle<Method> method(thread, jsFunc->GetMethod()); 10074514f5e3Sopenharmony_ci uint32_t slotSize = method->GetSlotSize(); 10084514f5e3Sopenharmony_ci profileTypeInfo = RuntimeNotifyInlineCache(thread, jsFunc, slotSize); 10094514f5e3Sopenharmony_ci } 10104514f5e3Sopenharmony_ci 10114514f5e3Sopenharmony_ci ASSERT(!profileTypeInfo.IsUndefined()); 10124514f5e3Sopenharmony_ci 10134514f5e3Sopenharmony_ci JSHandle<ProfileTypeInfo> profileTypeArray(thread, profileTypeInfo); 10144514f5e3Sopenharmony_ci JSTaggedValue slotValue = profileTypeArray->Get(slotId); 10154514f5e3Sopenharmony_ci if (slotValue.IsUndefined()) { 10164514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleUndefined(thread, JSTaggedValue::Undefined()); 10174514f5e3Sopenharmony_ci JSHandle<ProfileTypeInfoCell> newProfileTypeInfoCell = 10184514f5e3Sopenharmony_ci thread->GetEcmaVM()->GetFactory()->NewProfileTypeInfoCell(handleUndefined); 10194514f5e3Sopenharmony_ci profileTypeArray->Set(thread, slotId, newProfileTypeInfoCell); 10204514f5e3Sopenharmony_ci definedFunc->SetRawProfileTypeInfo(thread, newProfileTypeInfoCell); 10214514f5e3Sopenharmony_ci } else { 10224514f5e3Sopenharmony_ci auto cellPtr = ProfileTypeInfoCell::Cast(slotValue.GetTaggedObject()); 10234514f5e3Sopenharmony_ci cellPtr->UpdateProfileTypeInfoCellType(thread); 10244514f5e3Sopenharmony_ci definedFunc->SetRawProfileTypeInfo(thread, slotValue); 10254514f5e3Sopenharmony_ci } 10264514f5e3Sopenharmony_ci} 10274514f5e3Sopenharmony_ci 10284514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateSharedClass(JSThread *thread, 10294514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &base, 10304514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &constpool, 10314514f5e3Sopenharmony_ci uint16_t methodId, uint16_t literalId, 10324514f5e3Sopenharmony_ci uint16_t length, const JSHandle<JSTaggedValue> &module) 10334514f5e3Sopenharmony_ci{ 10344514f5e3Sopenharmony_ci if (!base->IsJSShared() && !base->IsHole()) { 10354514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, GET_MESSAGE_STRING(ClassNotDerivedFromShared), JSTaggedValue::Exception()); 10364514f5e3Sopenharmony_ci } 10374514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 10384514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 10394514f5e3Sopenharmony_ci CString entry = ModuleManager::GetRecordName(module.GetTaggedValue()); 10404514f5e3Sopenharmony_ci 10414514f5e3Sopenharmony_ci auto methodObj = ConstantPool::GetMethodFromCache(thread, constpool.GetTaggedValue(), methodId); 10424514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> method(thread, methodObj); 10434514f5e3Sopenharmony_ci JSHandle<Method>(method)->SetIsSendable(true); 10444514f5e3Sopenharmony_ci JSHandle<ConstantPool> constpoolHandle = JSHandle<ConstantPool>::Cast(constpool); 10454514f5e3Sopenharmony_ci 10464514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> sendableEnv(thread, JSTaggedValue::Undefined()); 10474514f5e3Sopenharmony_ci if (module->IsSourceTextModule()) { 10484514f5e3Sopenharmony_ci JSHandle<SourceTextModule> moduleRecord = JSHandle<SourceTextModule>::Cast(module); 10494514f5e3Sopenharmony_ci sendableEnv = JSHandle<JSTaggedValue>(thread, moduleRecord->GetSendableEnv()); 10504514f5e3Sopenharmony_ci } 10514514f5e3Sopenharmony_ci auto literalObj = ConstantPool::GetClassLiteralFromCache( 10524514f5e3Sopenharmony_ci thread, constpoolHandle, literalId, entry, sendableEnv, ClassKind::SENDABLE); 10534514f5e3Sopenharmony_ci JSHandle<ClassLiteral> classLiteral(thread, literalObj); 10544514f5e3Sopenharmony_ci JSHandle<TaggedArray> arrayHandle(thread, classLiteral->GetArray()); 10554514f5e3Sopenharmony_ci auto literalLength = arrayHandle->GetLength(); 10564514f5e3Sopenharmony_ci ASSERT(literalLength > 0); 10574514f5e3Sopenharmony_ci // fieldTypeId is the last element in literal buffer 10584514f5e3Sopenharmony_ci auto fieldTypeId = static_cast<uint32_t>(arrayHandle->Get(literalLength - 1).GetInt()); 10594514f5e3Sopenharmony_ci // Don't trim array, because define class maybe called on muilt-time in the same vm or diferrent vm 10604514f5e3Sopenharmony_ci JSHandle<ClassInfoExtractor> extractor = factory->NewClassInfoExtractor(method); 10614514f5e3Sopenharmony_ci ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(thread, extractor, arrayHandle, 10624514f5e3Sopenharmony_ci literalLength - 1, ClassKind::SENDABLE); 10634514f5e3Sopenharmony_ci 10644514f5e3Sopenharmony_ci JSHandle<TaggedArray> fieldTypeArray = ConstantPool::GetFieldLiteral(thread, constpoolHandle, fieldTypeId, entry); 10654514f5e3Sopenharmony_ci JSHandle<TaggedArray> staticFieldArray = SendableClassDefiner::ExtractStaticFieldTypeArray(thread, fieldTypeArray); 10664514f5e3Sopenharmony_ci JSHandle<JSFunction> cls = 10674514f5e3Sopenharmony_ci SendableClassDefiner::DefineSendableClassFromExtractor(thread, extractor, staticFieldArray); 10684514f5e3Sopenharmony_ci ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager(); 10694514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> sendableClsModule = moduleManager->GenerateSendableFuncModule(module); 10704514f5e3Sopenharmony_ci if (sendableClsModule->IsSourceTextModule()) { 10714514f5e3Sopenharmony_ci JSHandle<SourceTextModule> sendableClsModuleRecord(sendableClsModule); 10724514f5e3Sopenharmony_ci sendableClsModuleRecord->SetSendableEnv(thread, sendableEnv); 10734514f5e3Sopenharmony_ci } 10744514f5e3Sopenharmony_ci cls->SetModule(thread, sendableClsModule.GetTaggedValue()); 10754514f5e3Sopenharmony_ci RuntimeSetClassConstructorLength(thread, cls.GetTaggedValue(), JSTaggedValue(length)); 10764514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 10774514f5e3Sopenharmony_ci RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cls), base, ClassKind::SENDABLE); 10784514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 10794514f5e3Sopenharmony_ci 10804514f5e3Sopenharmony_ci uint32_t arrayLength = fieldTypeArray->GetLength(); 10814514f5e3Sopenharmony_ci ASSERT(arrayLength > 0); 10824514f5e3Sopenharmony_ci auto instanceFieldNums = static_cast<uint32_t>(fieldTypeArray->Get(arrayLength - 1).GetInt()); 10834514f5e3Sopenharmony_ci // Don't trim array, because define class maybe called on muilt-time in the same vm or diferrent vm 10844514f5e3Sopenharmony_ci uint32_t instanceLength = instanceFieldNums * 2; // 2: key and value 10854514f5e3Sopenharmony_ci ASSERT(instanceLength < arrayLength); 10864514f5e3Sopenharmony_ci SendableClassDefiner::DefineSendableInstanceHClass(thread, fieldTypeArray, instanceLength, cls, base); 10874514f5e3Sopenharmony_ci return cls.GetTaggedValue(); 10884514f5e3Sopenharmony_ci} 10894514f5e3Sopenharmony_ci 10904514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeSetClassInheritanceRelationship(JSThread *thread, 10914514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &ctor, 10924514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &base, 10934514f5e3Sopenharmony_ci ClassKind kind) 10944514f5e3Sopenharmony_ci{ 10954514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 10964514f5e3Sopenharmony_ci const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 10974514f5e3Sopenharmony_ci 10984514f5e3Sopenharmony_ci ASSERT(ctor->IsJSFunction()); 10994514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> parent = base; 11004514f5e3Sopenharmony_ci 11014514f5e3Sopenharmony_ci /* 11024514f5e3Sopenharmony_ci * class A / class A extends null class A extends B 11034514f5e3Sopenharmony_ci * a a 11044514f5e3Sopenharmony_ci * | | 11054514f5e3Sopenharmony_ci * | __proto__ | __proto__ 11064514f5e3Sopenharmony_ci * | | 11074514f5e3Sopenharmony_ci * A ----> A.prototype A ----> A.prototype 11084514f5e3Sopenharmony_ci * | | | | 11094514f5e3Sopenharmony_ci * | __proto__ | __proto__ | __proto__ | __proto__ 11104514f5e3Sopenharmony_ci * | | | | 11114514f5e3Sopenharmony_ci * Function.prototype Object.prototype / null B ----> B.prototype 11124514f5e3Sopenharmony_ci */ 11134514f5e3Sopenharmony_ci 11144514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> parentPrototype; 11154514f5e3Sopenharmony_ci // hole means parent is not present 11164514f5e3Sopenharmony_ci Method *method = Method::Cast(JSHandle<JSFunction>::Cast(ctor)->GetMethod().GetTaggedObject()); 11174514f5e3Sopenharmony_ci if (parent->IsHole()) { 11184514f5e3Sopenharmony_ci method->SetFunctionKind(FunctionKind::CLASS_CONSTRUCTOR); 11194514f5e3Sopenharmony_ci parentPrototype = 11204514f5e3Sopenharmony_ci (kind == ClassKind::SENDABLE) ? env->GetSObjectFunctionPrototype() : env->GetObjectFunctionPrototype(); 11214514f5e3Sopenharmony_ci parent = (kind == ClassKind::SENDABLE) ? env->GetSFunctionPrototype() : env->GetFunctionPrototype(); 11224514f5e3Sopenharmony_ci } else if (parent->IsNull()) { 11234514f5e3Sopenharmony_ci method->SetFunctionKind(FunctionKind::DERIVED_CONSTRUCTOR); 11244514f5e3Sopenharmony_ci parentPrototype = JSHandle<JSTaggedValue>(thread, JSTaggedValue::Null()); 11254514f5e3Sopenharmony_ci parent = (kind == ClassKind::SENDABLE) ? env->GetSFunctionPrototype() : env->GetFunctionPrototype(); 11264514f5e3Sopenharmony_ci } else if (!parent->IsConstructor()) { 11274514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "parent class is not constructor"); 11284514f5e3Sopenharmony_ci } else { 11294514f5e3Sopenharmony_ci method->SetFunctionKind(FunctionKind::DERIVED_CONSTRUCTOR); 11304514f5e3Sopenharmony_ci parentPrototype = JSTaggedValue::GetProperty(thread, parent, 11314514f5e3Sopenharmony_ci globalConst->GetHandledPrototypeString()).GetValue(); 11324514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 11334514f5e3Sopenharmony_ci if (!parentPrototype->IsECMAObject() && !parentPrototype->IsNull()) { 11344514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "parent class have no valid prototype"); 11354514f5e3Sopenharmony_ci } 11364514f5e3Sopenharmony_ci } 11374514f5e3Sopenharmony_ci 11384514f5e3Sopenharmony_ci ctor->GetTaggedObject()->GetClass()->SetPrototype(thread, parent); // __proto__ 11394514f5e3Sopenharmony_ci 11404514f5e3Sopenharmony_ci JSHandle<JSObject> clsPrototype(thread, JSHandle<JSFunction>(ctor)->GetFunctionPrototype()); 11414514f5e3Sopenharmony_ci clsPrototype->GetClass()->SetPrototype(thread, parentPrototype); 11424514f5e3Sopenharmony_ci 11434514f5e3Sopenharmony_ci // ctor -> hclass -> EnableProtoChangeMarker 11444514f5e3Sopenharmony_ci auto constructor = JSFunction::Cast(ctor.GetTaggedValue().GetTaggedObject()); 11454514f5e3Sopenharmony_ci if (constructor->GetClass()->IsTS()) { 11464514f5e3Sopenharmony_ci JSHClass::EnableProtoChangeMarker(thread, JSHandle<JSHClass>(thread, constructor->GetClass())); 11474514f5e3Sopenharmony_ci // prototype -> hclass -> EnableProtoChangeMarker 11484514f5e3Sopenharmony_ci JSHClass::EnableProtoChangeMarker(thread, 11494514f5e3Sopenharmony_ci JSHandle<JSHClass>(thread, constructor->GetFunctionPrototype().GetTaggedObject()->GetClass())); 11504514f5e3Sopenharmony_ci } 11514514f5e3Sopenharmony_ci 11524514f5e3Sopenharmony_ci // by enableing the ProtoChangeMarker, the IHC generated in the Aot stage 11534514f5e3Sopenharmony_ci // is registered into the listener of its prototype. In this way, it is ensured 11544514f5e3Sopenharmony_ci // that when the prototype changes, the affected IHC can be notified. 11554514f5e3Sopenharmony_ci JSTaggedValue protoOrHClass = JSHandle<JSFunction>(ctor)->GetProtoOrHClass(); 11564514f5e3Sopenharmony_ci if (protoOrHClass.IsJSHClass()) { 11574514f5e3Sopenharmony_ci JSHClass *ihc = JSHClass::Cast(protoOrHClass.GetTaggedObject()); 11584514f5e3Sopenharmony_ci if (ihc->IsTS()) { 11594514f5e3Sopenharmony_ci JSHandle<JSHClass> ihcHandle(thread, ihc); 11604514f5e3Sopenharmony_ci JSHClass::EnableProtoChangeMarker(thread, ihcHandle); 11614514f5e3Sopenharmony_ci } 11624514f5e3Sopenharmony_ci } else { 11634514f5e3Sopenharmony_ci JSHandle<JSObject> protoHandle(thread, protoOrHClass); 11644514f5e3Sopenharmony_ci if (protoHandle->GetJSHClass()->IsTS()) { 11654514f5e3Sopenharmony_ci JSHClass::EnablePHCProtoChangeMarker(thread, JSHandle<JSHClass>(thread, protoHandle->GetJSHClass())); 11664514f5e3Sopenharmony_ci } 11674514f5e3Sopenharmony_ci } 11684514f5e3Sopenharmony_ci 11694514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 11704514f5e3Sopenharmony_ci} 11714514f5e3Sopenharmony_ci 11724514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeSetClassConstructorLength(JSThread *thread, JSTaggedValue ctor, 11734514f5e3Sopenharmony_ci JSTaggedValue length) 11744514f5e3Sopenharmony_ci{ 11754514f5e3Sopenharmony_ci ASSERT(ctor.IsClassConstructor()); 11764514f5e3Sopenharmony_ci 11774514f5e3Sopenharmony_ci JSFunction* cls = JSFunction::Cast(ctor.GetTaggedObject()); 11784514f5e3Sopenharmony_ci if (LIKELY(!cls->GetClass()->IsDictionaryMode())) { 11794514f5e3Sopenharmony_ci cls->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, length); 11804514f5e3Sopenharmony_ci } else { 11814514f5e3Sopenharmony_ci const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 11824514f5e3Sopenharmony_ci cls->UpdatePropertyInDictionary(thread, globalConst->GetLengthString(), length); 11834514f5e3Sopenharmony_ci } 11844514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 11854514f5e3Sopenharmony_ci} 11864514f5e3Sopenharmony_ci 11874514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNotifyInlineCache(JSThread *thread, const JSHandle<JSFunction> &function, 11884514f5e3Sopenharmony_ci uint32_t icSlotSize) 11894514f5e3Sopenharmony_ci{ 11904514f5e3Sopenharmony_ci // max ic slot index is 0xffff, the size of ic slot could extend more 11914514f5e3Sopenharmony_ci ASSERT(icSlotSize <= ProfileTypeInfo::MAX_SLOT_INDEX + MethodLiteral::EXTEND_SLOT_SIZE); 11924514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 11934514f5e3Sopenharmony_ci JSHandle<ProfileTypeInfo> profileTypeInfo; 11944514f5e3Sopenharmony_ci if (function->IsSharedFunction()) { 11954514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 11964514f5e3Sopenharmony_ci } else { 11974514f5e3Sopenharmony_ci profileTypeInfo = factory->NewProfileTypeInfo(icSlotSize); 11984514f5e3Sopenharmony_ci } 11994514f5e3Sopenharmony_ci Method* method = Method::Cast(function->GetMethod()); 12004514f5e3Sopenharmony_ci auto codeSize = method->GetCodeSize(); 12014514f5e3Sopenharmony_ci if (pgo::PGOProfilerManager::GetInstance()->IsBigMethod(codeSize)) { 12024514f5e3Sopenharmony_ci LOG_ECMA(DEBUG) << "method size is too large, skip pgo. code size: " << codeSize 12034514f5e3Sopenharmony_ci << ", max code size: " << pgo::PGOProfilerManager::GetInstance()->GetMaxAotMethodSize(); 12044514f5e3Sopenharmony_ci profileTypeInfo->SetBigMethodPeriodIndex(); 12054514f5e3Sopenharmony_ci } 12064514f5e3Sopenharmony_ci JSFunction::SetProfileTypeInfo(thread, function, JSHandle<JSTaggedValue>::Cast(profileTypeInfo)); 12074514f5e3Sopenharmony_ci return profileTypeInfo.GetTaggedValue(); 12084514f5e3Sopenharmony_ci} 12094514f5e3Sopenharmony_ci 12104514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStOwnByValueWithNameSet(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 12114514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &key, 12124514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 12134514f5e3Sopenharmony_ci{ 12144514f5e3Sopenharmony_ci const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 12154514f5e3Sopenharmony_ci 12164514f5e3Sopenharmony_ci if (obj->IsClassConstructor() && 12174514f5e3Sopenharmony_ci JSTaggedValue::SameValue(key, globalConst->GetHandledPrototypeString())) { 12184514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "In a class, static property named 'prototype' throw a TypeError"); 12194514f5e3Sopenharmony_ci } 12204514f5e3Sopenharmony_ci 12214514f5e3Sopenharmony_ci // property in class is non-enumerable 12224514f5e3Sopenharmony_ci bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor()); 12234514f5e3Sopenharmony_ci 12244514f5e3Sopenharmony_ci PropertyDescriptor desc(thread, value, true, enumerable, true); 12254514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, key); 12264514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 12274514f5e3Sopenharmony_ci bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, propKey, desc); 12284514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 12294514f5e3Sopenharmony_ci if (!ret) { 12304514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "StOwnByValueWithNameSet failed"); 12314514f5e3Sopenharmony_ci } 12324514f5e3Sopenharmony_ci if (value->IsJSFunction()) { 12334514f5e3Sopenharmony_ci if (propKey->IsNumber()) { 12344514f5e3Sopenharmony_ci propKey = JSHandle<JSTaggedValue>(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue())); 12354514f5e3Sopenharmony_ci } 12364514f5e3Sopenharmony_ci JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(value), propKey, 12374514f5e3Sopenharmony_ci JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 12384514f5e3Sopenharmony_ci } 12394514f5e3Sopenharmony_ci return JSTaggedValue::True(); 12404514f5e3Sopenharmony_ci} 12414514f5e3Sopenharmony_ci 12424514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStOwnByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 12434514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &prop, 12444514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 12454514f5e3Sopenharmony_ci{ 12464514f5e3Sopenharmony_ci ASSERT(prop->IsStringOrSymbol()); 12474514f5e3Sopenharmony_ci 12484514f5e3Sopenharmony_ci // property in class is non-enumerable 12494514f5e3Sopenharmony_ci bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor()); 12504514f5e3Sopenharmony_ci 12514514f5e3Sopenharmony_ci PropertyDescriptor desc(thread, value, true, enumerable, true); 12524514f5e3Sopenharmony_ci bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, prop, desc); 12534514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 12544514f5e3Sopenharmony_ci if (!ret) { 12554514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "SetOwnByName failed"); 12564514f5e3Sopenharmony_ci } 12574514f5e3Sopenharmony_ci return JSTaggedValue::True(); 12584514f5e3Sopenharmony_ci} 12594514f5e3Sopenharmony_ci 12604514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStOwnByNameWithNameSet(JSThread *thread, 12614514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &objHandle, 12624514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &propHandle, 12634514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &valueHandle) 12644514f5e3Sopenharmony_ci{ 12654514f5e3Sopenharmony_ci ASSERT(propHandle->IsStringOrSymbol()); 12664514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, propHandle); 12674514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 12684514f5e3Sopenharmony_ci // property in class is non-enumerable 12694514f5e3Sopenharmony_ci bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor()); 12704514f5e3Sopenharmony_ci 12714514f5e3Sopenharmony_ci PropertyDescriptor desc(thread, valueHandle, true, enumerable, true); 12724514f5e3Sopenharmony_ci bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propHandle, desc); 12734514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 12744514f5e3Sopenharmony_ci if (!ret) { 12754514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "SetOwnByNameWithNameSet failed"); 12764514f5e3Sopenharmony_ci } 12774514f5e3Sopenharmony_ci JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(valueHandle), propKey, 12784514f5e3Sopenharmony_ci JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined())); 12794514f5e3Sopenharmony_ci return JSTaggedValue::True(); 12804514f5e3Sopenharmony_ci} 12814514f5e3Sopenharmony_ci 12824514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeSuspendGenerator(JSThread *thread, const JSHandle<JSTaggedValue> &genObj, 12834514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 12844514f5e3Sopenharmony_ci{ 12854514f5e3Sopenharmony_ci if (genObj->IsAsyncGeneratorObject()) { 12864514f5e3Sopenharmony_ci JSHandle<JSAsyncGeneratorObject> generatorObjectHandle(genObj); 12874514f5e3Sopenharmony_ci JSHandle<GeneratorContext> genContextHandle(thread, generatorObjectHandle->GetGeneratorContext()); 12884514f5e3Sopenharmony_ci // save stack, should copy cur_frame, function execute over will free cur_frame 12894514f5e3Sopenharmony_ci SaveFrameToContext(thread, genContextHandle); 12904514f5e3Sopenharmony_ci 12914514f5e3Sopenharmony_ci // change state to SuspendedYield 12924514f5e3Sopenharmony_ci if (generatorObjectHandle->IsExecuting()) { 12934514f5e3Sopenharmony_ci return value.GetTaggedValue(); 12944514f5e3Sopenharmony_ci } 12954514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 12964514f5e3Sopenharmony_ci return generatorObjectHandle.GetTaggedValue(); 12974514f5e3Sopenharmony_ci } 12984514f5e3Sopenharmony_ci 12994514f5e3Sopenharmony_ci if (genObj->IsGeneratorObject()) { 13004514f5e3Sopenharmony_ci JSHandle<JSGeneratorObject> generatorObjectHandle(genObj); 13014514f5e3Sopenharmony_ci JSHandle<GeneratorContext> genContextHandle(thread, generatorObjectHandle->GetGeneratorContext()); 13024514f5e3Sopenharmony_ci // set TaskInfo for TaskPool 13034514f5e3Sopenharmony_ci generatorObjectHandle->SetTaskInfo(thread->GetTaskInfo()); 13044514f5e3Sopenharmony_ci // save stack, should copy cur_frame, function execute over will free cur_frame 13054514f5e3Sopenharmony_ci SaveFrameToContext(thread, genContextHandle); 13064514f5e3Sopenharmony_ci 13074514f5e3Sopenharmony_ci // change state to SuspendedYield 13084514f5e3Sopenharmony_ci if (generatorObjectHandle->IsExecuting()) { 13094514f5e3Sopenharmony_ci generatorObjectHandle->SetGeneratorState(JSGeneratorState::SUSPENDED_YIELD); 13104514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 13114514f5e3Sopenharmony_ci return value.GetTaggedValue(); 13124514f5e3Sopenharmony_ci } 13134514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 13144514f5e3Sopenharmony_ci return generatorObjectHandle.GetTaggedValue(); 13154514f5e3Sopenharmony_ci } 13164514f5e3Sopenharmony_ci 13174514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "RuntimeSuspendGenerator failed"); 13184514f5e3Sopenharmony_ci} 13194514f5e3Sopenharmony_ci 13204514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeSetGeneratorState(JSThread *thread, const JSHandle<JSTaggedValue> &genObj, 13214514f5e3Sopenharmony_ci const int32_t index) 13224514f5e3Sopenharmony_ci{ 13234514f5e3Sopenharmony_ci JSHandle<JSAsyncGeneratorObject> generatorObjectHandle(genObj); 13244514f5e3Sopenharmony_ci JSHandle<GeneratorContext> genContextHandle(thread, generatorObjectHandle->GetGeneratorContext()); 13254514f5e3Sopenharmony_ci 13264514f5e3Sopenharmony_ci // change state 13274514f5e3Sopenharmony_ci switch (index) { 13284514f5e3Sopenharmony_ci case static_cast<int32_t>(JSAsyncGeneratorState::SUSPENDED_START): 13294514f5e3Sopenharmony_ci generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_START); 13304514f5e3Sopenharmony_ci break; 13314514f5e3Sopenharmony_ci case static_cast<int32_t>(JSAsyncGeneratorState::SUSPENDED_YIELD): 13324514f5e3Sopenharmony_ci generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_YIELD); 13334514f5e3Sopenharmony_ci break; 13344514f5e3Sopenharmony_ci case static_cast<int32_t>(JSAsyncGeneratorState::EXECUTING): 13354514f5e3Sopenharmony_ci generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::EXECUTING); 13364514f5e3Sopenharmony_ci break; 13374514f5e3Sopenharmony_ci case static_cast<int32_t>(JSAsyncGeneratorState::COMPLETED): 13384514f5e3Sopenharmony_ci generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::COMPLETED); 13394514f5e3Sopenharmony_ci break; 13404514f5e3Sopenharmony_ci case static_cast<int32_t>(JSAsyncGeneratorState::AWAITING_RETURN): 13414514f5e3Sopenharmony_ci generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::AWAITING_RETURN); 13424514f5e3Sopenharmony_ci break; 13434514f5e3Sopenharmony_ci default: 13444514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "this branch is unreachable"; 13454514f5e3Sopenharmony_ci UNREACHABLE(); 13464514f5e3Sopenharmony_ci } 13474514f5e3Sopenharmony_ci} 13484514f5e3Sopenharmony_ci 13494514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, int32_t index) 13504514f5e3Sopenharmony_ci{ 13514514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(index); 13524514f5e3Sopenharmony_ci} 13534514f5e3Sopenharmony_ci 13544514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, int32_t index, 13554514f5e3Sopenharmony_ci JSTaggedValue jsFunc) 13564514f5e3Sopenharmony_ci{ 13574514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(index, jsFunc); 13584514f5e3Sopenharmony_ci} 13594514f5e3Sopenharmony_ci 13604514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, JSTaggedValue localName) 13614514f5e3Sopenharmony_ci{ 13624514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(localName); 13634514f5e3Sopenharmony_ci} 13644514f5e3Sopenharmony_ci 13654514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, JSTaggedValue localName, 13664514f5e3Sopenharmony_ci JSTaggedValue jsFunc) 13674514f5e3Sopenharmony_ci{ 13684514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(localName, jsFunc); 13694514f5e3Sopenharmony_ci} 13704514f5e3Sopenharmony_ci 13714514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeStModuleVar(JSThread *thread, int32_t index, JSTaggedValue value) 13724514f5e3Sopenharmony_ci{ 13734514f5e3Sopenharmony_ci thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(index, value); 13744514f5e3Sopenharmony_ci} 13754514f5e3Sopenharmony_ci 13764514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeStModuleVar(JSThread *thread, int32_t index, JSTaggedValue value, 13774514f5e3Sopenharmony_ci JSTaggedValue jsFunc) 13784514f5e3Sopenharmony_ci{ 13794514f5e3Sopenharmony_ci thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(index, value, jsFunc); 13804514f5e3Sopenharmony_ci} 13814514f5e3Sopenharmony_ci 13824514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeStModuleVar(JSThread *thread, JSTaggedValue key, JSTaggedValue value) 13834514f5e3Sopenharmony_ci{ 13844514f5e3Sopenharmony_ci thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(key, value); 13854514f5e3Sopenharmony_ci} 13864514f5e3Sopenharmony_ci 13874514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeStModuleVar(JSThread *thread, JSTaggedValue key, JSTaggedValue value, 13884514f5e3Sopenharmony_ci JSTaggedValue jsFunc) 13894514f5e3Sopenharmony_ci{ 13904514f5e3Sopenharmony_ci thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(key, value, jsFunc); 13914514f5e3Sopenharmony_ci} 13924514f5e3Sopenharmony_ci 13934514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdLocalModuleVar(JSThread *thread, int32_t index) 13944514f5e3Sopenharmony_ci{ 13954514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(index); 13964514f5e3Sopenharmony_ci} 13974514f5e3Sopenharmony_ci 13984514f5e3Sopenharmony_ciinline JSTaggedValue RuntimeStubs::RuntimeLdLocalModuleVarWithModule(JSThread* thread, int32_t index, 13994514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> moduleHdl) 14004514f5e3Sopenharmony_ci{ 14014514f5e3Sopenharmony_ci JSTaggedValue module = moduleHdl.GetTaggedValue(); 14024514f5e3Sopenharmony_ci ModuleManager* mmgr = thread->GetCurrentEcmaContext()->GetModuleManager(); 14034514f5e3Sopenharmony_ci if (SourceTextModule::IsSendableFunctionModule(module)) { 14044514f5e3Sopenharmony_ci const CString recordNameStr = SourceTextModule::GetModuleName(module); 14054514f5e3Sopenharmony_ci module = mmgr->HostGetImportedModule(recordNameStr).GetTaggedValue(); 14064514f5e3Sopenharmony_ci } 14074514f5e3Sopenharmony_ci return SourceTextModule::Cast(module)->GetModuleValue(thread, index, false); 14084514f5e3Sopenharmony_ci} 14094514f5e3Sopenharmony_ci 14104514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdLocalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc) 14114514f5e3Sopenharmony_ci{ 14124514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(index, jsFunc); 14134514f5e3Sopenharmony_ci} 14144514f5e3Sopenharmony_ci 14154514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdExternalModuleVar(JSThread *thread, int32_t index) 14164514f5e3Sopenharmony_ci{ 14174514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(index); 14184514f5e3Sopenharmony_ci} 14194514f5e3Sopenharmony_ci 14204514f5e3Sopenharmony_ciinline JSTaggedValue RuntimeStubs::RuntimeLdExternalModuleVarWithModule(JSThread* thread, int32_t index, 14214514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> moduleHdl) 14224514f5e3Sopenharmony_ci{ 14234514f5e3Sopenharmony_ci JSTaggedValue module = moduleHdl.GetTaggedValue(); 14244514f5e3Sopenharmony_ci ModuleManager* mmgr = thread->GetCurrentEcmaContext()->GetModuleManager(); 14254514f5e3Sopenharmony_ci if (SourceTextModule::IsSendableFunctionModule(module)) { 14264514f5e3Sopenharmony_ci const CString recordNameStr = SourceTextModule::GetModuleName(module); 14274514f5e3Sopenharmony_ci module = mmgr->HostGetImportedModule(recordNameStr).GetTaggedValue(); 14284514f5e3Sopenharmony_ci moduleHdl = JSHandle<JSTaggedValue>(thread, module); 14294514f5e3Sopenharmony_ci } 14304514f5e3Sopenharmony_ci return mmgr->GetModuleValueOutter(index, moduleHdl); 14314514f5e3Sopenharmony_ci} 14324514f5e3Sopenharmony_ci 14334514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdSendableExternalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc) 14344514f5e3Sopenharmony_ci{ 14354514f5e3Sopenharmony_ci return SharedModuleManager::GetInstance()->GetSendableModuleValue(thread, index, jsFunc); 14364514f5e3Sopenharmony_ci} 14374514f5e3Sopenharmony_ci 14384514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdExternalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc) 14394514f5e3Sopenharmony_ci{ 14404514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(index, jsFunc); 14414514f5e3Sopenharmony_ci} 14424514f5e3Sopenharmony_ci 14434514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdLazyExternalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc) 14444514f5e3Sopenharmony_ci{ 14454514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetLazyModuleValueOutter(index, jsFunc); 14464514f5e3Sopenharmony_ci} 14474514f5e3Sopenharmony_ci 14484514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdLazySendableExternalModuleVar( 14494514f5e3Sopenharmony_ci JSThread *thread, int32_t index, JSTaggedValue jsFunc) 14504514f5e3Sopenharmony_ci{ 14514514f5e3Sopenharmony_ci return SharedModuleManager::GetInstance()->GetLazySendableModuleValue(thread, index, jsFunc); 14524514f5e3Sopenharmony_ci} 14534514f5e3Sopenharmony_ci 14544514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdModuleVar(JSThread *thread, JSTaggedValue key, bool inner) 14554514f5e3Sopenharmony_ci{ 14564514f5e3Sopenharmony_ci if (inner) { 14574514f5e3Sopenharmony_ci JSTaggedValue moduleValue = thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(key); 14584514f5e3Sopenharmony_ci return moduleValue; 14594514f5e3Sopenharmony_ci } 14604514f5e3Sopenharmony_ci 14614514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(key); 14624514f5e3Sopenharmony_ci} 14634514f5e3Sopenharmony_ci 14644514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdModuleVar(JSThread *thread, JSTaggedValue key, bool inner, 14654514f5e3Sopenharmony_ci JSTaggedValue jsFunc) 14664514f5e3Sopenharmony_ci{ 14674514f5e3Sopenharmony_ci if (inner) { 14684514f5e3Sopenharmony_ci JSTaggedValue moduleValue = 14694514f5e3Sopenharmony_ci thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(key, jsFunc); 14704514f5e3Sopenharmony_ci return moduleValue; 14714514f5e3Sopenharmony_ci } 14724514f5e3Sopenharmony_ci 14734514f5e3Sopenharmony_ci return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(key, jsFunc); 14744514f5e3Sopenharmony_ci} 14754514f5e3Sopenharmony_ci 14764514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetPropIterator(JSThread *thread, const JSHandle<JSTaggedValue> &value) 14774514f5e3Sopenharmony_ci{ 14784514f5e3Sopenharmony_ci JSHandle<JSForInIterator> iteratorHandle = JSObject::EnumerateObjectProperties(thread, value); 14794514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 14804514f5e3Sopenharmony_ci return iteratorHandle.GetTaggedValue(); 14814514f5e3Sopenharmony_ci} 14824514f5e3Sopenharmony_ci 14834514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeAsyncFunctionEnter(JSThread *thread) 14844514f5e3Sopenharmony_ci{ 14854514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 14864514f5e3Sopenharmony_ci // 1. create promise 14874514f5e3Sopenharmony_ci JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 14884514f5e3Sopenharmony_ci JSHandle<JSFunction> promiseFunc(globalEnv->GetPromiseFunction()); 14894514f5e3Sopenharmony_ci 14904514f5e3Sopenharmony_ci JSHandle<JSPromise> promiseObject(factory->NewJSObjectByConstructor(promiseFunc)); 14914514f5e3Sopenharmony_ci promiseObject->SetPromiseState(PromiseState::PENDING); 14924514f5e3Sopenharmony_ci // 2. create asyncfuncobj 14934514f5e3Sopenharmony_ci JSHandle<JSAsyncFuncObject> asyncFuncObj = factory->NewJSAsyncFuncObject(); 14944514f5e3Sopenharmony_ci asyncFuncObj->SetPromise(thread, promiseObject); 14954514f5e3Sopenharmony_ci 14964514f5e3Sopenharmony_ci JSHandle<GeneratorContext> context = factory->NewGeneratorContext(); 14974514f5e3Sopenharmony_ci context->SetGeneratorObject(thread, asyncFuncObj); 14984514f5e3Sopenharmony_ci 14994514f5e3Sopenharmony_ci // change state to EXECUTING 15004514f5e3Sopenharmony_ci asyncFuncObj->SetGeneratorState(JSGeneratorState::EXECUTING); 15014514f5e3Sopenharmony_ci asyncFuncObj->SetGeneratorContext(thread, context); 15024514f5e3Sopenharmony_ci 15034514f5e3Sopenharmony_ci // 3. return asyncfuncobj 15044514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 15054514f5e3Sopenharmony_ci return asyncFuncObj.GetTaggedValue(); 15064514f5e3Sopenharmony_ci} 15074514f5e3Sopenharmony_ci 15084514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetIterator(JSThread *thread, const JSHandle<JSTaggedValue> &obj) 15094514f5e3Sopenharmony_ci{ 15104514f5e3Sopenharmony_ci EcmaVM *vm = thread->GetEcmaVM(); 15114514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = vm->GetGlobalEnv(); 15124514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valuesFunc = 15134514f5e3Sopenharmony_ci JSTaggedValue::GetProperty(thread, obj, env->GetIteratorSymbol()).GetValue(); 15144514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 15154514f5e3Sopenharmony_ci if (!valuesFunc->IsCallable()) { 15164514f5e3Sopenharmony_ci return valuesFunc.GetTaggedValue(); 15174514f5e3Sopenharmony_ci } 15184514f5e3Sopenharmony_ci 15194514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 15204514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, valuesFunc, obj, undefined, 0); 15214514f5e3Sopenharmony_ci return EcmaInterpreter::Execute(info); 15224514f5e3Sopenharmony_ci} 15234514f5e3Sopenharmony_ci 15244514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetAsyncIterator(JSThread *thread, const JSHandle<JSTaggedValue> &obj) 15254514f5e3Sopenharmony_ci{ 15264514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> asyncit = JSIterator::GetAsyncIterator(thread, obj); 15274514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 15284514f5e3Sopenharmony_ci return asyncit.GetTaggedValue(); 15294514f5e3Sopenharmony_ci} 15304514f5e3Sopenharmony_ci 15314514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdPrivateProperty(JSThread *thread, JSTaggedValue lexicalEnv, 15324514f5e3Sopenharmony_ci uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj) 15334514f5e3Sopenharmony_ci{ 15344514f5e3Sopenharmony_ci JSTaggedValue currentLexicalEnv = lexicalEnv; 15354514f5e3Sopenharmony_ci for (uint32_t i = 0; i < levelIndex; i++) { 15364514f5e3Sopenharmony_ci currentLexicalEnv = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetParentEnv(); 15374514f5e3Sopenharmony_ci ASSERT(!currentLexicalEnv.IsUndefined()); 15384514f5e3Sopenharmony_ci } 15394514f5e3Sopenharmony_ci JSTaggedValue key = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetProperties(slotIndex); 15404514f5e3Sopenharmony_ci // private property is invisible for proxy 15414514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleObj(thread, obj.IsJSProxy() ? JSProxy::Cast(obj)->GetPrivateField() : obj); 15424514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleKey(thread, key); 15434514f5e3Sopenharmony_ci if (handleKey->IsJSFunction()) { // getter 15444514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 15454514f5e3Sopenharmony_ci // 0: getter has 0 arg 15464514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, handleKey, handleObj, undefined, 0); 15474514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 15484514f5e3Sopenharmony_ci JSTaggedValue resGetter = JSFunction::Call(info); 15494514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 15504514f5e3Sopenharmony_ci return resGetter; 15514514f5e3Sopenharmony_ci } 15524514f5e3Sopenharmony_ci PropertyDescriptor desc(thread); 15534514f5e3Sopenharmony_ci if (!JSTaggedValue::IsPropertyKey(handleKey) || 15544514f5e3Sopenharmony_ci !JSTaggedValue::GetOwnProperty(thread, handleObj, handleKey, desc)) { 15554514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "invalid or cannot find private key", JSTaggedValue::Exception()); 15564514f5e3Sopenharmony_ci } 15574514f5e3Sopenharmony_ci JSTaggedValue res = desc.GetValue().GetTaggedValue(); 15584514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 15594514f5e3Sopenharmony_ci return res; 15604514f5e3Sopenharmony_ci} 15614514f5e3Sopenharmony_ci 15624514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStPrivateProperty(JSThread *thread, JSTaggedValue lexicalEnv, 15634514f5e3Sopenharmony_ci uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj, JSTaggedValue value) 15644514f5e3Sopenharmony_ci{ 15654514f5e3Sopenharmony_ci JSTaggedValue currentLexicalEnv = lexicalEnv; 15664514f5e3Sopenharmony_ci for (uint32_t i = 0; i < levelIndex; i++) { 15674514f5e3Sopenharmony_ci currentLexicalEnv = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetParentEnv(); 15684514f5e3Sopenharmony_ci ASSERT(!currentLexicalEnv.IsUndefined()); 15694514f5e3Sopenharmony_ci } 15704514f5e3Sopenharmony_ci JSTaggedValue key = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetProperties(slotIndex); 15714514f5e3Sopenharmony_ci // private property is invisible for proxy 15724514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleObj(thread, obj.IsJSProxy() ? JSProxy::Cast(obj)->GetPrivateField() : obj); 15734514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleKey(thread, key); 15744514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleValue(thread, value); 15754514f5e3Sopenharmony_ci if (handleKey->IsJSFunction()) { // setter 15764514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 15774514f5e3Sopenharmony_ci // 1: setter has 1 arg 15784514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, handleKey, handleObj, undefined, 1); 15794514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 15804514f5e3Sopenharmony_ci info->SetCallArg(handleValue.GetTaggedValue()); 15814514f5e3Sopenharmony_ci JSTaggedValue resSetter = JSFunction::Call(info); 15824514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 15834514f5e3Sopenharmony_ci return resSetter; 15844514f5e3Sopenharmony_ci } 15854514f5e3Sopenharmony_ci PropertyDescriptor desc(thread); 15864514f5e3Sopenharmony_ci if (!JSTaggedValue::IsPropertyKey(handleKey) || 15874514f5e3Sopenharmony_ci !JSTaggedValue::GetOwnProperty(thread, handleObj, handleKey, desc)) { 15884514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "invalid or cannot find private key", JSTaggedValue::Exception()); 15894514f5e3Sopenharmony_ci } 15904514f5e3Sopenharmony_ci desc.SetValue(handleValue); 15914514f5e3Sopenharmony_ci bool res = JSTaggedValue::DefineOwnProperty(thread, handleObj, handleKey, desc); 15924514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 15934514f5e3Sopenharmony_ci return JSTaggedValue(res); 15944514f5e3Sopenharmony_ci} 15954514f5e3Sopenharmony_ci 15964514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeTestIn(JSThread *thread, JSTaggedValue lexicalEnv, 15974514f5e3Sopenharmony_ci uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj) 15984514f5e3Sopenharmony_ci{ 15994514f5e3Sopenharmony_ci if (!obj.IsECMAObject()) { 16004514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot use 'in' operator in Non-Object", JSTaggedValue::Exception()); 16014514f5e3Sopenharmony_ci } 16024514f5e3Sopenharmony_ci JSTaggedValue currentLexicalEnv = lexicalEnv; 16034514f5e3Sopenharmony_ci for (uint32_t i = 0; i < levelIndex; i++) { 16044514f5e3Sopenharmony_ci currentLexicalEnv = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetParentEnv(); 16054514f5e3Sopenharmony_ci ASSERT(!currentLexicalEnv.IsUndefined()); 16064514f5e3Sopenharmony_ci } 16074514f5e3Sopenharmony_ci JSTaggedValue key = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetProperties(slotIndex); 16084514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleObj(thread, obj.IsJSProxy() ? JSProxy::Cast(obj)->GetPrivateField() : obj); 16094514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleKey(thread, key); 16104514f5e3Sopenharmony_ci bool res = JSTaggedValue::IsPropertyKey(handleKey) && JSTaggedValue::HasProperty(thread, handleObj, handleKey); 16114514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 16124514f5e3Sopenharmony_ci return JSTaggedValue(res); 16134514f5e3Sopenharmony_ci} 16144514f5e3Sopenharmony_ci 16154514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeThrow(JSThread *thread, JSTaggedValue value) 16164514f5e3Sopenharmony_ci{ 16174514f5e3Sopenharmony_ci thread->SetException(value); 16184514f5e3Sopenharmony_ci} 16194514f5e3Sopenharmony_ci 16204514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeThrowThrowNotExists(JSThread *thread) 16214514f5e3Sopenharmony_ci{ 16224514f5e3Sopenharmony_ci THROW_TYPE_ERROR(thread, "Throw method is not defined"); 16234514f5e3Sopenharmony_ci} 16244514f5e3Sopenharmony_ci 16254514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeThrowPatternNonCoercible(JSThread *thread) 16264514f5e3Sopenharmony_ci{ 16274514f5e3Sopenharmony_ci JSHandle<EcmaString> msg(thread->GlobalConstants()->GetHandledObjNotCoercibleString()); 16284514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 16294514f5e3Sopenharmony_ci THROW_NEW_ERROR_AND_RETURN(thread, 16304514f5e3Sopenharmony_ci factory->NewJSError(base::ErrorType::TYPE_ERROR, msg, StackCheck::NO).GetTaggedValue()); 16314514f5e3Sopenharmony_ci} 16324514f5e3Sopenharmony_ci 16334514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeThrowDeleteSuperProperty(JSThread *thread) 16344514f5e3Sopenharmony_ci{ 16354514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 16364514f5e3Sopenharmony_ci JSHandle<EcmaString> info = factory->NewFromASCII("Can not delete super property"); 16374514f5e3Sopenharmony_ci JSHandle<JSObject> errorObj = factory->NewJSError(base::ErrorType::REFERENCE_ERROR, info, StackCheck::NO); 16384514f5e3Sopenharmony_ci THROW_NEW_ERROR_AND_RETURN(thread, errorObj.GetTaggedValue()); 16394514f5e3Sopenharmony_ci} 16404514f5e3Sopenharmony_ci 16414514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeThrowUndefinedIfHole(JSThread *thread, const JSHandle<EcmaString> &obj) 16424514f5e3Sopenharmony_ci{ 16434514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 16444514f5e3Sopenharmony_ci JSHandle<EcmaString> info = factory->NewFromASCII(" is not initialized"); 16454514f5e3Sopenharmony_ci 16464514f5e3Sopenharmony_ci JSHandle<EcmaString> msg = factory->ConcatFromString(obj, info); 16474514f5e3Sopenharmony_ci THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::REFERENCE_ERROR, 16484514f5e3Sopenharmony_ci msg, StackCheck::NO).GetTaggedValue()); 16494514f5e3Sopenharmony_ci} 16504514f5e3Sopenharmony_ci 16514514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeThrowIfNotObject(JSThread *thread) 16524514f5e3Sopenharmony_ci{ 16534514f5e3Sopenharmony_ci THROW_TYPE_ERROR(thread, "Inner return result is not object"); 16544514f5e3Sopenharmony_ci} 16554514f5e3Sopenharmony_ci 16564514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeThrowConstAssignment(JSThread *thread, const JSHandle<EcmaString> &value) 16574514f5e3Sopenharmony_ci{ 16584514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 16594514f5e3Sopenharmony_ci 16604514f5e3Sopenharmony_ci JSHandle<EcmaString> info = factory->NewFromASCII("Assignment to const variable "); 16614514f5e3Sopenharmony_ci 16624514f5e3Sopenharmony_ci JSHandle<EcmaString> msg = factory->ConcatFromString(info, value); 16634514f5e3Sopenharmony_ci THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::TYPE_ERROR, 16644514f5e3Sopenharmony_ci msg, StackCheck::NO).GetTaggedValue()); 16654514f5e3Sopenharmony_ci} 16664514f5e3Sopenharmony_ci 16674514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdGlobalRecord(JSThread *thread, JSTaggedValue key) 16684514f5e3Sopenharmony_ci{ 16694514f5e3Sopenharmony_ci EcmaVM *vm = thread->GetEcmaVM(); 16704514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = vm->GetGlobalEnv(); 16714514f5e3Sopenharmony_ci GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); 16724514f5e3Sopenharmony_ci int entry = dict->FindEntry(key); 16734514f5e3Sopenharmony_ci if (entry != -1) { 16744514f5e3Sopenharmony_ci return JSTaggedValue(dict->GetBox(entry)); 16754514f5e3Sopenharmony_ci } 16764514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 16774514f5e3Sopenharmony_ci} 16784514f5e3Sopenharmony_ci 16794514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeTryLdGlobalByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj, 16804514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &prop) 16814514f5e3Sopenharmony_ci{ 16824514f5e3Sopenharmony_ci OperationResult res = JSTaggedValue::GetProperty(thread, obj, prop); 16834514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 16844514f5e3Sopenharmony_ci if (!res.GetPropertyMetaData().IsFound()) { 16854514f5e3Sopenharmony_ci return RuntimeThrowReferenceError(thread, prop, " is not defined"); 16864514f5e3Sopenharmony_ci } 16874514f5e3Sopenharmony_ci return res.GetValue().GetTaggedValue(); 16884514f5e3Sopenharmony_ci} 16894514f5e3Sopenharmony_ci 16904514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeTryUpdateGlobalRecord(JSThread *thread, JSTaggedValue prop, 16914514f5e3Sopenharmony_ci JSTaggedValue value) 16924514f5e3Sopenharmony_ci{ 16934514f5e3Sopenharmony_ci EcmaVM *vm = thread->GetEcmaVM(); 16944514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = vm->GetGlobalEnv(); 16954514f5e3Sopenharmony_ci GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); 16964514f5e3Sopenharmony_ci int entry = dict->FindEntry(prop); 16974514f5e3Sopenharmony_ci ASSERT(entry != -1); 16984514f5e3Sopenharmony_ci 16994514f5e3Sopenharmony_ci if (dict->GetAttributes(entry).IsConstProps()) { 17004514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "const variable can not be modified"); 17014514f5e3Sopenharmony_ci } 17024514f5e3Sopenharmony_ci 17034514f5e3Sopenharmony_ci PropertyBox *box = dict->GetBox(entry); 17044514f5e3Sopenharmony_ci box->SetValue(thread, value); 17054514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 17064514f5e3Sopenharmony_ci return JSTaggedValue::True(); 17074514f5e3Sopenharmony_ci} 17084514f5e3Sopenharmony_ci 17094514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeThrowReferenceError(JSThread *thread, const JSHandle<JSTaggedValue> &prop, 17104514f5e3Sopenharmony_ci const char *desc) 17114514f5e3Sopenharmony_ci{ 17124514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 17134514f5e3Sopenharmony_ci JSHandle<EcmaString> propName = JSTaggedValue::ToString(thread, prop); 17144514f5e3Sopenharmony_ci ASSERT_NO_ABRUPT_COMPLETION(thread); 17154514f5e3Sopenharmony_ci JSHandle<EcmaString> info = factory->NewFromUtf8(desc); 17164514f5e3Sopenharmony_ci JSHandle<EcmaString> msg = factory->ConcatFromString(propName, info); 17174514f5e3Sopenharmony_ci THROW_NEW_ERROR_AND_RETURN_VALUE(thread, 17184514f5e3Sopenharmony_ci factory->NewJSError(base::ErrorType::REFERENCE_ERROR, msg, StackCheck::NO).GetTaggedValue(), 17194514f5e3Sopenharmony_ci JSTaggedValue::Exception()); 17204514f5e3Sopenharmony_ci} 17214514f5e3Sopenharmony_ci 17224514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdGlobalVarFromProto(JSThread *thread, const JSHandle<JSTaggedValue> &globalObj, 17234514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &prop) 17244514f5e3Sopenharmony_ci{ 17254514f5e3Sopenharmony_ci ASSERT(globalObj->IsJSGlobalObject()); 17264514f5e3Sopenharmony_ci JSHandle<JSObject> global(globalObj); 17274514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> obj(thread, JSObject::GetPrototype(global)); 17284514f5e3Sopenharmony_ci OperationResult res = JSTaggedValue::GetProperty(thread, obj, prop); 17294514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 17304514f5e3Sopenharmony_ci return res.GetValue().GetTaggedValue(); 17314514f5e3Sopenharmony_ci} 17324514f5e3Sopenharmony_ci 17334514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStGlobalVar(JSThread *thread, const JSHandle<JSTaggedValue> &prop, 17344514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 17354514f5e3Sopenharmony_ci{ 17364514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> global(thread, thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject()); 17374514f5e3Sopenharmony_ci 17384514f5e3Sopenharmony_ci JSObject::GlobalSetProperty(thread, prop, value, true); 17394514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 17404514f5e3Sopenharmony_ci return JSTaggedValue::True(); 17414514f5e3Sopenharmony_ci} 17424514f5e3Sopenharmony_ci 17434514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeToNumber(JSThread *thread, const JSHandle<JSTaggedValue> &value) 17444514f5e3Sopenharmony_ci{ 17454514f5e3Sopenharmony_ci return JSTaggedValue::ToNumber(thread, value); 17464514f5e3Sopenharmony_ci} 17474514f5e3Sopenharmony_ci 17484514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeToNumeric(JSThread *thread, const JSHandle<JSTaggedValue> &value) 17494514f5e3Sopenharmony_ci{ 17504514f5e3Sopenharmony_ci return JSTaggedValue::ToNumeric(thread, value).GetTaggedValue(); 17514514f5e3Sopenharmony_ci} 17524514f5e3Sopenharmony_ci 17534514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeDynamicImport(JSThread *thread, const JSHandle<JSTaggedValue> &specifier, 17544514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &func) 17554514f5e3Sopenharmony_ci{ 17564514f5e3Sopenharmony_ci EcmaVM *ecmaVm = thread->GetEcmaVM(); 17574514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv(); 17584514f5e3Sopenharmony_ci ObjectFactory *factory = ecmaVm->GetFactory(); 17594514f5e3Sopenharmony_ci 17604514f5e3Sopenharmony_ci // get current filename 17614514f5e3Sopenharmony_ci JSFunction *function = JSFunction::Cast(func->GetTaggedObject()); 17624514f5e3Sopenharmony_ci const JSPandaFile *jsPandaFile = function->GetCallTarget()->GetJSPandaFile(); 17634514f5e3Sopenharmony_ci ASSERT(jsPandaFile != nullptr); 17644514f5e3Sopenharmony_ci CString currentfilename = jsPandaFile->GetJSPandaFileDesc(); 17654514f5e3Sopenharmony_ci 17664514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> dirPath(thread, thread->GlobalConstants()->GetUndefined()); 17674514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> recordName(thread, thread->GlobalConstants()->GetUndefined()); 17684514f5e3Sopenharmony_ci if (jsPandaFile->IsBundlePack()) { 17694514f5e3Sopenharmony_ci dirPath.Update(factory->NewFromUtf8(currentfilename).GetTaggedValue()); 17704514f5e3Sopenharmony_ci } else { 17714514f5e3Sopenharmony_ci recordName.Update(factory->NewFromUtf8(function->GetRecordName())); 17724514f5e3Sopenharmony_ci dirPath.Update(factory->NewFromUtf8(currentfilename).GetTaggedValue()); 17734514f5e3Sopenharmony_ci } 17744514f5e3Sopenharmony_ci 17754514f5e3Sopenharmony_ci // 4. Let promiseCapability be !NewPromiseCapability(%Promise%). 17764514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> promiseFunc = env->GetPromiseFunction(); 17774514f5e3Sopenharmony_ci JSHandle<PromiseCapability> promiseCapability = JSPromise::NewPromiseCapability(thread, promiseFunc); 17784514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 17794514f5e3Sopenharmony_ci JSHandle<job::MicroJobQueue> job = thread->GetCurrentEcmaContext()->GetMicroJobQueue(); 17804514f5e3Sopenharmony_ci 17814514f5e3Sopenharmony_ci JSHandle<TaggedArray> argv = factory->NewTaggedArray(5); // 5: 5 means parameters stored in array 17824514f5e3Sopenharmony_ci argv->Set(thread, 0, promiseCapability->GetResolve()); 17834514f5e3Sopenharmony_ci argv->Set(thread, 1, promiseCapability->GetReject()); // 1 : reject method 17844514f5e3Sopenharmony_ci argv->Set(thread, 2, dirPath); // 2 : current file path(containing file name) 17854514f5e3Sopenharmony_ci argv->Set(thread, 3, specifier); // 3 : request module's path 17864514f5e3Sopenharmony_ci argv->Set(thread, 4, recordName); // 4 : js recordName or undefined 17874514f5e3Sopenharmony_ci 17884514f5e3Sopenharmony_ci JSHandle<JSFunction> dynamicImportJob(env->GetDynamicImportJob()); 17894514f5e3Sopenharmony_ci job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, dynamicImportJob, argv); 17904514f5e3Sopenharmony_ci 17914514f5e3Sopenharmony_ci return promiseCapability->GetPromise(); 17924514f5e3Sopenharmony_ci} 17934514f5e3Sopenharmony_ci 17944514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeEq(JSThread *thread, const JSHandle<JSTaggedValue> &left, 17954514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 17964514f5e3Sopenharmony_ci{ 17974514f5e3Sopenharmony_ci bool ret = JSTaggedValue::Equal(thread, left, right); 17984514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 17994514f5e3Sopenharmony_ci return (ret ? JSTaggedValue::True() : JSTaggedValue::False()); 18004514f5e3Sopenharmony_ci} 18014514f5e3Sopenharmony_ci 18024514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNotEq(JSThread *thread, const JSHandle<JSTaggedValue> &left, 18034514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 18044514f5e3Sopenharmony_ci{ 18054514f5e3Sopenharmony_ci bool ret = JSTaggedValue::Equal(thread, left, right); 18064514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18074514f5e3Sopenharmony_ci return (ret ? JSTaggedValue::False() : JSTaggedValue::True()); 18084514f5e3Sopenharmony_ci} 18094514f5e3Sopenharmony_ci 18104514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLess(JSThread *thread, const JSHandle<JSTaggedValue> &left, 18114514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 18124514f5e3Sopenharmony_ci{ 18134514f5e3Sopenharmony_ci bool ret = JSTaggedValue::Compare(thread, left, right) == ComparisonResult::LESS; 18144514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18154514f5e3Sopenharmony_ci return (ret ? JSTaggedValue::True() : JSTaggedValue::False()); 18164514f5e3Sopenharmony_ci} 18174514f5e3Sopenharmony_ci 18184514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLessEq(JSThread *thread, const JSHandle<JSTaggedValue> &left, 18194514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 18204514f5e3Sopenharmony_ci{ 18214514f5e3Sopenharmony_ci bool ret = JSTaggedValue::Compare(thread, left, right) <= ComparisonResult::EQUAL; 18224514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18234514f5e3Sopenharmony_ci return (ret ? JSTaggedValue::True() : JSTaggedValue::False()); 18244514f5e3Sopenharmony_ci} 18254514f5e3Sopenharmony_ci 18264514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGreater(JSThread *thread, const JSHandle<JSTaggedValue> &left, 18274514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 18284514f5e3Sopenharmony_ci{ 18294514f5e3Sopenharmony_ci bool ret = JSTaggedValue::Compare(thread, left, right) == ComparisonResult::GREAT; 18304514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18314514f5e3Sopenharmony_ci return (ret ? JSTaggedValue::True() : JSTaggedValue::False()); 18324514f5e3Sopenharmony_ci} 18334514f5e3Sopenharmony_ci 18344514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGreaterEq(JSThread *thread, const JSHandle<JSTaggedValue> &left, 18354514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 18364514f5e3Sopenharmony_ci{ 18374514f5e3Sopenharmony_ci ComparisonResult comparison = JSTaggedValue::Compare(thread, left, right); 18384514f5e3Sopenharmony_ci bool ret = (comparison == ComparisonResult::GREAT) || (comparison == ComparisonResult::EQUAL); 18394514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18404514f5e3Sopenharmony_ci return (ret ? JSTaggedValue::True() : JSTaggedValue::False()); 18414514f5e3Sopenharmony_ci} 18424514f5e3Sopenharmony_ci 18434514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeAdd2(JSThread *thread, const JSHandle<JSTaggedValue> &left, 18444514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 18454514f5e3Sopenharmony_ci{ 18464514f5e3Sopenharmony_ci if (left->IsString() && right->IsString()) { 18474514f5e3Sopenharmony_ci EcmaString *resultStr = EcmaStringAccessor::Concat( 18484514f5e3Sopenharmony_ci thread->GetEcmaVM(), JSHandle<EcmaString>(left), JSHandle<EcmaString>(right)); 18494514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18504514f5e3Sopenharmony_ci return JSTaggedValue(resultStr); 18514514f5e3Sopenharmony_ci } 18524514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> primitiveA0(thread, JSTaggedValue::ToPrimitive(thread, left)); 18534514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18544514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> primitiveA1(thread, JSTaggedValue::ToPrimitive(thread, right)); 18554514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18564514f5e3Sopenharmony_ci // contain string 18574514f5e3Sopenharmony_ci if (primitiveA0->IsString() || primitiveA1->IsString()) { 18584514f5e3Sopenharmony_ci JSHandle<EcmaString> stringA0 = JSTaggedValue::ToString(thread, primitiveA0); 18594514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18604514f5e3Sopenharmony_ci JSHandle<EcmaString> stringA1 = JSTaggedValue::ToString(thread, primitiveA1); 18614514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18624514f5e3Sopenharmony_ci EcmaString *resultStr = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1); 18634514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18644514f5e3Sopenharmony_ci return JSTaggedValue(resultStr); 18654514f5e3Sopenharmony_ci } 18664514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, primitiveA0); 18674514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18684514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, primitiveA1); 18694514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18704514f5e3Sopenharmony_ci if (valLeft->IsBigInt() || valRight->IsBigInt()) { 18714514f5e3Sopenharmony_ci if (valLeft->IsBigInt() && valRight->IsBigInt()) { 18724514f5e3Sopenharmony_ci JSHandle<BigInt> bigLeft(valLeft); 18734514f5e3Sopenharmony_ci JSHandle<BigInt> bigRight(valRight); 18744514f5e3Sopenharmony_ci return BigInt::Add(thread, bigLeft, bigRight).GetTaggedValue(); 18754514f5e3Sopenharmony_ci } 18764514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 18774514f5e3Sopenharmony_ci } 18784514f5e3Sopenharmony_ci double doubleA0 = valLeft->GetNumber(); 18794514f5e3Sopenharmony_ci double doubleA1 = valRight->GetNumber(); 18804514f5e3Sopenharmony_ci return JSTaggedValue(doubleA0 + doubleA1); 18814514f5e3Sopenharmony_ci} 18824514f5e3Sopenharmony_ci 18834514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeShl2(JSThread *thread, 18844514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &left, 18854514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 18864514f5e3Sopenharmony_ci{ 18874514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> leftValue = JSTaggedValue::ToNumeric(thread, left); 18884514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18894514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> rightValue = JSTaggedValue::ToNumeric(thread, right); 18904514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 18914514f5e3Sopenharmony_ci if (leftValue->IsBigInt() || rightValue->IsBigInt()) { 18924514f5e3Sopenharmony_ci if (leftValue->IsBigInt() && rightValue->IsBigInt()) { 18934514f5e3Sopenharmony_ci JSHandle<BigInt> leftBigint(leftValue); 18944514f5e3Sopenharmony_ci JSHandle<BigInt> rightBigint(rightValue); 18954514f5e3Sopenharmony_ci return BigInt::LeftShift(thread, leftBigint, rightBigint).GetTaggedValue(); 18964514f5e3Sopenharmony_ci } 18974514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 18984514f5e3Sopenharmony_ci } 18994514f5e3Sopenharmony_ci JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, leftValue); 19004514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19014514f5e3Sopenharmony_ci JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, rightValue); 19024514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19034514f5e3Sopenharmony_ci int32_t opNumber0 = taggedNumber0.GetInt(); 19044514f5e3Sopenharmony_ci int32_t opNumber1 = taggedNumber1.GetInt(); 19054514f5e3Sopenharmony_ci uint32_t shift = 19064514f5e3Sopenharmony_ci static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers) 19074514f5e3Sopenharmony_ci using unsigned_type = std::make_unsigned_t<int32_t>; 19084514f5e3Sopenharmony_ci auto ret = 19094514f5e3Sopenharmony_ci static_cast<int32_t>(static_cast<unsigned_type>(opNumber0) << shift); // NOLINT(hicpp-signed-bitwise) 19104514f5e3Sopenharmony_ci return JSTaggedValue(ret); 19114514f5e3Sopenharmony_ci} 19124514f5e3Sopenharmony_ci 19134514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeShr2(JSThread *thread, const JSHandle<JSTaggedValue> &left, 19144514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 19154514f5e3Sopenharmony_ci{ 19164514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left); 19174514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19184514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right); 19194514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19204514f5e3Sopenharmony_ci if (valLeft->IsBigInt() || valRight->IsBigInt()) { 19214514f5e3Sopenharmony_ci if (valLeft->IsBigInt() && valRight->IsBigInt()) { 19224514f5e3Sopenharmony_ci return BigInt::UnsignedRightShift(thread); 19234514f5e3Sopenharmony_ci } 19244514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 19254514f5e3Sopenharmony_ci } 19264514f5e3Sopenharmony_ci JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft); 19274514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19284514f5e3Sopenharmony_ci JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight); 19294514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19304514f5e3Sopenharmony_ci int32_t opNumber0 = taggedNumber0.GetInt(); 19314514f5e3Sopenharmony_ci int32_t opNumber1 = taggedNumber1.GetInt(); 19324514f5e3Sopenharmony_ci uint32_t shift = static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers) 19334514f5e3Sopenharmony_ci using unsigned_type = std::make_unsigned_t<uint32_t>; 19344514f5e3Sopenharmony_ci auto ret = 19354514f5e3Sopenharmony_ci static_cast<uint32_t>(static_cast<unsigned_type>(opNumber0) >> shift); // NOLINT(hicpp-signed-bitwise) 19364514f5e3Sopenharmony_ci return JSTaggedValue(ret); 19374514f5e3Sopenharmony_ci} 19384514f5e3Sopenharmony_ci 19394514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeSub2(JSThread *thread, const JSHandle<JSTaggedValue> &left, 19404514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 19414514f5e3Sopenharmony_ci{ 19424514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left); 19434514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19444514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right); 19454514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19464514f5e3Sopenharmony_ci if (valLeft->IsBigInt() || valRight->IsBigInt()) { 19474514f5e3Sopenharmony_ci if (valLeft->IsBigInt() && valRight->IsBigInt()) { 19484514f5e3Sopenharmony_ci JSHandle<BigInt> bigLeft(valLeft); 19494514f5e3Sopenharmony_ci JSHandle<BigInt> bigRight(valRight); 19504514f5e3Sopenharmony_ci return BigInt::Subtract(thread, bigLeft, bigRight).GetTaggedValue(); 19514514f5e3Sopenharmony_ci } 19524514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 19534514f5e3Sopenharmony_ci } 19544514f5e3Sopenharmony_ci JSTaggedNumber number0(valLeft.GetTaggedValue()); 19554514f5e3Sopenharmony_ci JSTaggedNumber number1(valRight.GetTaggedValue()); 19564514f5e3Sopenharmony_ci return number0 - number1; 19574514f5e3Sopenharmony_ci} 19584514f5e3Sopenharmony_ci 19594514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeMul2(JSThread *thread, const JSHandle<JSTaggedValue> &left, 19604514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 19614514f5e3Sopenharmony_ci{ 19624514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left); 19634514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19644514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right); 19654514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19664514f5e3Sopenharmony_ci // 9. ReturnIfAbrupt(rnum). 19674514f5e3Sopenharmony_ci if (valLeft->IsBigInt() || valRight->IsBigInt()) { 19684514f5e3Sopenharmony_ci if (valLeft->IsBigInt() && valRight->IsBigInt()) { 19694514f5e3Sopenharmony_ci JSHandle<BigInt> bigLeft(valLeft); 19704514f5e3Sopenharmony_ci JSHandle<BigInt> bigRight(valRight); 19714514f5e3Sopenharmony_ci return BigInt::Multiply(thread, bigLeft, bigRight).GetTaggedValue(); 19724514f5e3Sopenharmony_ci } 19734514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 19744514f5e3Sopenharmony_ci } 19754514f5e3Sopenharmony_ci // 12.6.3.1 Applying the * Operator 19764514f5e3Sopenharmony_ci JSTaggedNumber number0(valLeft.GetTaggedValue()); 19774514f5e3Sopenharmony_ci JSTaggedNumber number1(valRight.GetTaggedValue()); 19784514f5e3Sopenharmony_ci return number0 * number1; 19794514f5e3Sopenharmony_ci} 19804514f5e3Sopenharmony_ci 19814514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeDiv2(JSThread *thread, const JSHandle<JSTaggedValue> &left, 19824514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 19834514f5e3Sopenharmony_ci{ 19844514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left); 19854514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19864514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right); 19874514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 19884514f5e3Sopenharmony_ci if (valLeft->IsBigInt() || valRight->IsBigInt()) { 19894514f5e3Sopenharmony_ci if (valLeft->IsBigInt() && valRight->IsBigInt()) { 19904514f5e3Sopenharmony_ci JSHandle<BigInt> bigLeft(valLeft); 19914514f5e3Sopenharmony_ci JSHandle<BigInt> bigRight(valRight); 19924514f5e3Sopenharmony_ci return BigInt::Divide(thread, bigLeft, bigRight).GetTaggedValue(); 19934514f5e3Sopenharmony_ci } 19944514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 19954514f5e3Sopenharmony_ci } 19964514f5e3Sopenharmony_ci double dLeft = valLeft->GetNumber(); 19974514f5e3Sopenharmony_ci double dRight = valRight->GetNumber(); 19984514f5e3Sopenharmony_ci if (dRight == 0) { 19994514f5e3Sopenharmony_ci if (dLeft == 0 || std::isnan(dLeft)) { 20004514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 20014514f5e3Sopenharmony_ci } 20024514f5e3Sopenharmony_ci bool positive = (((base::bit_cast<uint64_t>(dRight)) & base::DOUBLE_SIGN_MASK) == 20034514f5e3Sopenharmony_ci ((base::bit_cast<uint64_t>(dLeft)) & base::DOUBLE_SIGN_MASK)); 20044514f5e3Sopenharmony_ci return JSTaggedValue(positive ? base::POSITIVE_INFINITY : -base::POSITIVE_INFINITY); 20054514f5e3Sopenharmony_ci } 20064514f5e3Sopenharmony_ci return JSTaggedValue(dLeft / dRight); 20074514f5e3Sopenharmony_ci} 20084514f5e3Sopenharmony_ci 20094514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeMod2(JSThread *thread, const JSHandle<JSTaggedValue> &left, 20104514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 20114514f5e3Sopenharmony_ci{ 20124514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left); 20134514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20144514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right); 20154514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20164514f5e3Sopenharmony_ci 20174514f5e3Sopenharmony_ci // 12.6.3.3 Applying the % Operator 20184514f5e3Sopenharmony_ci if (valLeft->IsBigInt() || valRight->IsBigInt()) { 20194514f5e3Sopenharmony_ci if (valLeft->IsBigInt() && valRight->IsBigInt()) { 20204514f5e3Sopenharmony_ci JSHandle<BigInt> leftBigint(valLeft); 20214514f5e3Sopenharmony_ci JSHandle<BigInt> rightBigint(valRight); 20224514f5e3Sopenharmony_ci return BigInt::Remainder(thread, leftBigint, rightBigint).GetTaggedValue(); 20234514f5e3Sopenharmony_ci } 20244514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 20254514f5e3Sopenharmony_ci } 20264514f5e3Sopenharmony_ci double dLeft = valLeft->GetNumber(); 20274514f5e3Sopenharmony_ci double dRight = valRight->GetNumber(); 20284514f5e3Sopenharmony_ci // 12.6.3.3 Applying the % Operator 20294514f5e3Sopenharmony_ci if ((dRight == 0.0) || std::isnan(dRight) || std::isnan(dLeft) || std::isinf(dLeft)) { 20304514f5e3Sopenharmony_ci return JSTaggedValue(base::NAN_VALUE); 20314514f5e3Sopenharmony_ci } 20324514f5e3Sopenharmony_ci if ((dLeft == 0.0) || std::isinf(dRight)) { 20334514f5e3Sopenharmony_ci return JSTaggedValue(dLeft); 20344514f5e3Sopenharmony_ci } 20354514f5e3Sopenharmony_ci return JSTaggedValue(std::fmod(dLeft, dRight)); 20364514f5e3Sopenharmony_ci} 20374514f5e3Sopenharmony_ci 20384514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeAshr2(JSThread *thread, const JSHandle<JSTaggedValue> &left, 20394514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 20404514f5e3Sopenharmony_ci{ 20414514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left); 20424514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20434514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right); 20444514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20454514f5e3Sopenharmony_ci if (valLeft->IsBigInt() || valRight->IsBigInt()) { 20464514f5e3Sopenharmony_ci if (valLeft->IsBigInt() && valRight->IsBigInt()) { 20474514f5e3Sopenharmony_ci JSHandle<BigInt> bigLeft(valLeft); 20484514f5e3Sopenharmony_ci JSHandle<BigInt> bigRight(valRight); 20494514f5e3Sopenharmony_ci return BigInt::SignedRightShift(thread, bigLeft, bigRight).GetTaggedValue(); 20504514f5e3Sopenharmony_ci } 20514514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 20524514f5e3Sopenharmony_ci } 20534514f5e3Sopenharmony_ci JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft); 20544514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20554514f5e3Sopenharmony_ci JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight); 20564514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20574514f5e3Sopenharmony_ci int32_t opNumber0 = taggedNumber0.GetInt(); 20584514f5e3Sopenharmony_ci int32_t opNumber1 = taggedNumber1.GetInt(); 20594514f5e3Sopenharmony_ci uint32_t shift = static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers) 20604514f5e3Sopenharmony_ci auto ret = static_cast<int32_t>(opNumber0 >> shift); // NOLINT(hicpp-signed-bitwise) 20614514f5e3Sopenharmony_ci return JSTaggedValue(ret); 20624514f5e3Sopenharmony_ci} 20634514f5e3Sopenharmony_ci 20644514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeAnd2(JSThread *thread, const JSHandle<JSTaggedValue> &left, 20654514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 20664514f5e3Sopenharmony_ci{ 20674514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left); 20684514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20694514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right); 20704514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20714514f5e3Sopenharmony_ci if (valLeft->IsBigInt() || valRight->IsBigInt()) { 20724514f5e3Sopenharmony_ci if (valLeft->IsBigInt() && valRight->IsBigInt()) { 20734514f5e3Sopenharmony_ci JSHandle<BigInt> leftBigint(valLeft); 20744514f5e3Sopenharmony_ci JSHandle<BigInt> rightBigint(valRight); 20754514f5e3Sopenharmony_ci return BigInt::BitwiseAND(thread, leftBigint, rightBigint).GetTaggedValue(); 20764514f5e3Sopenharmony_ci } 20774514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 20784514f5e3Sopenharmony_ci } 20794514f5e3Sopenharmony_ci JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft); 20804514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20814514f5e3Sopenharmony_ci JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight); 20824514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20834514f5e3Sopenharmony_ci int32_t opNumber0 = taggedNumber0.GetInt(); 20844514f5e3Sopenharmony_ci int32_t opNumber1 = taggedNumber1.GetInt(); 20854514f5e3Sopenharmony_ci // NOLINT(hicpp-signed-bitwise) 20864514f5e3Sopenharmony_ci auto ret = static_cast<uint32_t>(opNumber0) & static_cast<uint32_t>(opNumber1); 20874514f5e3Sopenharmony_ci return JSTaggedValue(static_cast<int32_t>(ret)); 20884514f5e3Sopenharmony_ci} 20894514f5e3Sopenharmony_ci 20904514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOr2(JSThread *thread, const JSHandle<JSTaggedValue> &left, 20914514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 20924514f5e3Sopenharmony_ci{ 20934514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left); 20944514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20954514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right); 20964514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 20974514f5e3Sopenharmony_ci if (valLeft->IsBigInt() || valRight->IsBigInt()) { 20984514f5e3Sopenharmony_ci if (valLeft->IsBigInt() && valRight->IsBigInt()) { 20994514f5e3Sopenharmony_ci JSHandle<BigInt> leftBigint(valLeft); 21004514f5e3Sopenharmony_ci JSHandle<BigInt> rightBigint(valRight); 21014514f5e3Sopenharmony_ci return BigInt::BitwiseOR(thread, leftBigint, rightBigint).GetTaggedValue(); 21024514f5e3Sopenharmony_ci } 21034514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 21044514f5e3Sopenharmony_ci } 21054514f5e3Sopenharmony_ci JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft); 21064514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 21074514f5e3Sopenharmony_ci JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight); 21084514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 21094514f5e3Sopenharmony_ci int32_t opNumber0 = taggedNumber0.GetInt(); 21104514f5e3Sopenharmony_ci int32_t opNumber1 = taggedNumber1.GetInt(); 21114514f5e3Sopenharmony_ci // NOLINT(hicpp-signed-bitwise) 21124514f5e3Sopenharmony_ci auto ret = static_cast<uint32_t>(opNumber0) | static_cast<uint32_t>(opNumber1); 21134514f5e3Sopenharmony_ci return JSTaggedValue(static_cast<int32_t>(ret)); 21144514f5e3Sopenharmony_ci} 21154514f5e3Sopenharmony_ci 21164514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeXor2(JSThread *thread, const JSHandle<JSTaggedValue> &left, 21174514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &right) 21184514f5e3Sopenharmony_ci{ 21194514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left); 21204514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 21214514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right); 21224514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 21234514f5e3Sopenharmony_ci if (valLeft->IsBigInt() || valRight->IsBigInt()) { 21244514f5e3Sopenharmony_ci if (valLeft->IsBigInt() && valRight->IsBigInt()) { 21254514f5e3Sopenharmony_ci JSHandle<BigInt> leftBigint(valLeft); 21264514f5e3Sopenharmony_ci JSHandle<BigInt> rightBigint(valRight); 21274514f5e3Sopenharmony_ci return BigInt::BitwiseXOR(thread, leftBigint, rightBigint).GetTaggedValue(); 21284514f5e3Sopenharmony_ci } 21294514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions"); 21304514f5e3Sopenharmony_ci } 21314514f5e3Sopenharmony_ci JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft); 21324514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 21334514f5e3Sopenharmony_ci JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight); 21344514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 21354514f5e3Sopenharmony_ci int32_t opNumber0 = taggedNumber0.GetInt(); 21364514f5e3Sopenharmony_ci int32_t opNumber1 = taggedNumber1.GetInt(); 21374514f5e3Sopenharmony_ci // NOLINT(hicpp-signed-bitwise) 21384514f5e3Sopenharmony_ci auto ret = static_cast<uint32_t>(opNumber0) ^ static_cast<uint32_t>(opNumber1); 21394514f5e3Sopenharmony_ci return JSTaggedValue(static_cast<int32_t>(ret)); 21404514f5e3Sopenharmony_ci} 21414514f5e3Sopenharmony_ci 21424514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeToJSTaggedValueWithInt32(JSThread *thread, 21434514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 21444514f5e3Sopenharmony_ci{ 21454514f5e3Sopenharmony_ci int32_t res = JSTaggedValue::ToInt32(thread, value); 21464514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 21474514f5e3Sopenharmony_ci return JSTaggedValue(res); 21484514f5e3Sopenharmony_ci} 21494514f5e3Sopenharmony_ci 21504514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeToJSTaggedValueWithUint32(JSThread *thread, const JSHandle<JSTaggedValue> &value) 21514514f5e3Sopenharmony_ci{ 21524514f5e3Sopenharmony_ci uint32_t res = JSTaggedValue::ToUint32(thread, value); 21534514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 21544514f5e3Sopenharmony_ci return JSTaggedValue(res); 21554514f5e3Sopenharmony_ci} 21564514f5e3Sopenharmony_ci 21574514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateEmptyObject([[maybe_unused]] JSThread *thread, ObjectFactory *factory, 21584514f5e3Sopenharmony_ci JSHandle<GlobalEnv> globalEnv) 21594514f5e3Sopenharmony_ci{ 21604514f5e3Sopenharmony_ci JSHandle<JSFunction> builtinObj(globalEnv->GetObjectFunction()); 21614514f5e3Sopenharmony_ci JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(builtinObj); 21624514f5e3Sopenharmony_ci return obj.GetTaggedValue(); 21634514f5e3Sopenharmony_ci} 21644514f5e3Sopenharmony_ci 21654514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateEmptyArray([[maybe_unused]] JSThread *thread, ObjectFactory *factory, 21664514f5e3Sopenharmony_ci JSHandle<GlobalEnv> globalEnv) 21674514f5e3Sopenharmony_ci{ 21684514f5e3Sopenharmony_ci JSHandle<JSFunction> builtinObj(globalEnv->GetArrayFunction()); 21694514f5e3Sopenharmony_ci JSHandle<JSObject> arr = factory->NewJSObjectByConstructor(builtinObj); 21704514f5e3Sopenharmony_ci return arr.GetTaggedValue(); 21714514f5e3Sopenharmony_ci} 21724514f5e3Sopenharmony_ci 21734514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetUnmapedArgs(JSThread *thread, JSTaggedType *sp, uint32_t actualNumArgs, 21744514f5e3Sopenharmony_ci uint32_t startIdx) 21754514f5e3Sopenharmony_ci{ 21764514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 21774514f5e3Sopenharmony_ci JSHandle<TaggedArray> argumentsList = factory->NewTaggedArray(actualNumArgs); 21784514f5e3Sopenharmony_ci for (uint32_t i = 0; i < actualNumArgs; ++i) { 21794514f5e3Sopenharmony_ci argumentsList->Set(thread, i, 21804514f5e3Sopenharmony_ci JSTaggedValue(sp[startIdx + i])); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 21814514f5e3Sopenharmony_ci } 21824514f5e3Sopenharmony_ci return RuntimeGetUnmapedJSArgumentObj(thread, argumentsList); 21834514f5e3Sopenharmony_ci} 21844514f5e3Sopenharmony_ci 21854514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCopyRestArgs(JSThread *thread, JSTaggedType *sp, uint32_t restNumArgs, 21864514f5e3Sopenharmony_ci uint32_t startIdx) 21874514f5e3Sopenharmony_ci{ 21884514f5e3Sopenharmony_ci return JSArray::ArrayCreateWithInit( 21894514f5e3Sopenharmony_ci thread, restNumArgs, [thread, sp, startIdx] (const JSHandle<TaggedArray> &newElements, uint32_t length) { 21904514f5e3Sopenharmony_ci for (uint32_t i = 0; i < length; ++i) { 21914514f5e3Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 21924514f5e3Sopenharmony_ci newElements->Set(thread, i, JSTaggedValue(sp[startIdx + i])); 21934514f5e3Sopenharmony_ci } 21944514f5e3Sopenharmony_ci }); 21954514f5e3Sopenharmony_ci} 21964514f5e3Sopenharmony_ci 21974514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateArrayWithBuffer(JSThread *thread, ObjectFactory *factory, 21984514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &literal) 21994514f5e3Sopenharmony_ci{ 22004514f5e3Sopenharmony_ci JSHandle<JSArray> array(literal); 22014514f5e3Sopenharmony_ci JSHandle<JSArray> arrLiteral = factory->CloneArrayLiteral(array); 22024514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 22034514f5e3Sopenharmony_ci 22044514f5e3Sopenharmony_ci return arrLiteral.GetTaggedValue(); 22054514f5e3Sopenharmony_ci} 22064514f5e3Sopenharmony_ci 22074514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateObjectWithBuffer(JSThread *thread, ObjectFactory *factory, 22084514f5e3Sopenharmony_ci const JSHandle<JSObject> &literal) 22094514f5e3Sopenharmony_ci{ 22104514f5e3Sopenharmony_ci JSHandle<JSObject> objLiteral = factory->CloneObjectLiteral(literal); 22114514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 22124514f5e3Sopenharmony_ci 22134514f5e3Sopenharmony_ci return objLiteral.GetTaggedValue(); 22144514f5e3Sopenharmony_ci} 22154514f5e3Sopenharmony_ci 22164514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNewLexicalEnv(JSThread *thread, uint16_t numVars) 22174514f5e3Sopenharmony_ci{ 22184514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 22194514f5e3Sopenharmony_ci JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars); 22204514f5e3Sopenharmony_ci 22214514f5e3Sopenharmony_ci JSTaggedValue currentLexenv = thread->GetCurrentLexenv(); 22224514f5e3Sopenharmony_ci newEnv->SetParentEnv(thread, currentLexenv); 22234514f5e3Sopenharmony_ci newEnv->SetScopeInfo(thread, JSTaggedValue::Hole()); 22244514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 22254514f5e3Sopenharmony_ci return newEnv.GetTaggedValue(); 22264514f5e3Sopenharmony_ci} 22274514f5e3Sopenharmony_ci 22284514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNewSendableEnv(JSThread *thread, uint16_t numVars) 22294514f5e3Sopenharmony_ci{ 22304514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 22314514f5e3Sopenharmony_ci JSHandle<SendableEnv> newEnv = factory->NewSendableEnv(numVars); 22324514f5e3Sopenharmony_ci 22334514f5e3Sopenharmony_ci JSTaggedValue module = JSFunction::Cast(thread->GetCurrentFunction())->GetModule(); 22344514f5e3Sopenharmony_ci JSHandle<SourceTextModule> moduleHandle(thread, module); 22354514f5e3Sopenharmony_ci newEnv->SetParentEnv(thread, moduleHandle->GetSendableEnv()); 22364514f5e3Sopenharmony_ci newEnv->SetScopeInfo(thread, JSTaggedValue::Hole()); 22374514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 22384514f5e3Sopenharmony_ci return newEnv.GetTaggedValue(); 22394514f5e3Sopenharmony_ci} 22404514f5e3Sopenharmony_ci 22414514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNewObjRange(JSThread *thread, const JSHandle<JSTaggedValue> &func, 22424514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &newTarget, uint16_t firstArgIdx, uint16_t length) 22434514f5e3Sopenharmony_ci{ 22444514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> preArgs(thread, JSTaggedValue::Undefined()); 22454514f5e3Sopenharmony_ci JSHandle<TaggedArray> args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(length); 22464514f5e3Sopenharmony_ci FrameHandler frameHandler(thread); 22474514f5e3Sopenharmony_ci for (uint16_t i = 0; i < length; ++i) { 22484514f5e3Sopenharmony_ci JSTaggedValue value = frameHandler.GetVRegValue(firstArgIdx + i); 22494514f5e3Sopenharmony_ci args->Set(thread, i, value); 22504514f5e3Sopenharmony_ci } 22514514f5e3Sopenharmony_ci auto tagged = RuntimeOptConstruct(thread, func, newTarget, preArgs, args); 22524514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 22534514f5e3Sopenharmony_ci return tagged; 22544514f5e3Sopenharmony_ci} 22554514f5e3Sopenharmony_ci 22564514f5e3Sopenharmony_civoid RuntimeStubs::DefineFuncTryUseAOTHClass(JSThread* thread, 22574514f5e3Sopenharmony_ci const JSHandle<JSFunction>& func, 22584514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue>& ihc, 22594514f5e3Sopenharmony_ci const JSHandle<AOTLiteralInfo>& aotLiteralInfo) 22604514f5e3Sopenharmony_ci{ 22614514f5e3Sopenharmony_ci FunctionKind kind = Method::Cast(func->GetMethod())->GetFunctionKind(); 22624514f5e3Sopenharmony_ci // The HClass of AOT comes from .ai deserialization 22634514f5e3Sopenharmony_ci if (!ihc->IsUndefined() && kind == FunctionKind::BASE_CONSTRUCTOR) { 22644514f5e3Sopenharmony_ci ASSERT(!aotLiteralInfo.GetTaggedValue().IsHole()); 22654514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 22664514f5e3Sopenharmony_ci const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 22674514f5e3Sopenharmony_ci func->SetProtoOrHClass(thread, ihc); 22684514f5e3Sopenharmony_ci 22694514f5e3Sopenharmony_ci // build inheritance 22704514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> parentPrototype = env->GetObjectFunctionPrototype(); 22714514f5e3Sopenharmony_ci JSHandle<JSObject> clsPrototype(thread, func->GetFunctionPrototype()); 22724514f5e3Sopenharmony_ci clsPrototype->GetClass()->SetPrototype(thread, parentPrototype); 22734514f5e3Sopenharmony_ci 22744514f5e3Sopenharmony_ci // set "constructor" in prototype 22754514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString(); 22764514f5e3Sopenharmony_ci PropertyDescriptor descriptor(thread, JSHandle<JSTaggedValue>::Cast(func), true, false, true); 22774514f5e3Sopenharmony_ci JSObject::DefineOwnProperty(thread, clsPrototype, constructorKey, descriptor); 22784514f5e3Sopenharmony_ci 22794514f5e3Sopenharmony_ci // enable prototype change marker 22804514f5e3Sopenharmony_ci JSHClass::EnablePHCProtoChangeMarker(thread, 22814514f5e3Sopenharmony_ci JSHandle<JSHClass>(thread, parentPrototype->GetTaggedObject()->GetClass())); 22824514f5e3Sopenharmony_ci if (ihc->IsJSHClass()) { 22834514f5e3Sopenharmony_ci JSHClass::EnableProtoChangeMarker(thread, JSHandle<JSHClass>(ihc)); 22844514f5e3Sopenharmony_ci } else { 22854514f5e3Sopenharmony_ci JSHClass::EnablePHCProtoChangeMarker(thread, JSHandle<JSHClass>(thread, clsPrototype->GetClass())); 22864514f5e3Sopenharmony_ci } 22874514f5e3Sopenharmony_ci //avoid one thread uses ihc twice or more times 22884514f5e3Sopenharmony_ci aotLiteralInfo->SetIhc(JSTaggedValue::Undefined()); 22894514f5e3Sopenharmony_ci } 22904514f5e3Sopenharmony_ci} 22914514f5e3Sopenharmony_ci 22924514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeDefinefunc(JSThread *thread, const JSHandle<JSTaggedValue> &constpool, 22934514f5e3Sopenharmony_ci uint16_t methodId, const JSHandle<JSTaggedValue> &module, 22944514f5e3Sopenharmony_ci uint16_t length, const JSHandle<JSTaggedValue> &envHandle, 22954514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &homeObject) 22964514f5e3Sopenharmony_ci{ 22974514f5e3Sopenharmony_ci JSHandle<ConstantPool> constpoolHandle = JSHandle<ConstantPool>::Cast(constpool); 22984514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> ihc(thread, JSTaggedValue::Undefined()); 22994514f5e3Sopenharmony_ci JSMutableHandle<AOTLiteralInfo> aotLiteralInfo(thread, JSTaggedValue::Hole()); 23004514f5e3Sopenharmony_ci //AOT ihc infos always in unshareConstpool 23014514f5e3Sopenharmony_ci //If is runing on AOT,unshareConstpool is definitely not a hole 23024514f5e3Sopenharmony_ci //So wo can skip if unshareConstpool is hole 23034514f5e3Sopenharmony_ci JSTaggedValue unsharedCp = thread->GetCurrentEcmaContext()->FindUnsharedConstpool(constpoolHandle.GetTaggedValue()); 23044514f5e3Sopenharmony_ci if (!unsharedCp.IsHole()) { 23054514f5e3Sopenharmony_ci JSHandle<ConstantPool> unsharedCpHandle(thread, unsharedCp); 23064514f5e3Sopenharmony_ci JSTaggedValue val = unsharedCpHandle->GetObjectFromCache(methodId); 23074514f5e3Sopenharmony_ci if (val.IsAOTLiteralInfo()) { 23084514f5e3Sopenharmony_ci aotLiteralInfo.Update(val); 23094514f5e3Sopenharmony_ci ihc.Update(aotLiteralInfo->GetIhc()); 23104514f5e3Sopenharmony_ci } 23114514f5e3Sopenharmony_ci } 23124514f5e3Sopenharmony_ci JSTaggedValue method = ConstantPool::GetMethodFromCache(thread, constpoolHandle.GetTaggedValue(), methodId); 23134514f5e3Sopenharmony_ci const JSHandle<Method> methodHandle(thread, method); 23144514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 23154514f5e3Sopenharmony_ci JSHandle<JSFunction> result; 23164514f5e3Sopenharmony_ci if (methodHandle->IsSendableMethod()) { 23174514f5e3Sopenharmony_ci result = factory->NewJSSendableFunction(methodHandle); 23184514f5e3Sopenharmony_ci ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager(); 23194514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> sendableFuncModule = moduleManager->GenerateSendableFuncModule(module); 23204514f5e3Sopenharmony_ci if (module->IsSourceTextModule()) { 23214514f5e3Sopenharmony_ci JSHandle<SourceTextModule> sendableFuncModuleRecord(sendableFuncModule); 23224514f5e3Sopenharmony_ci sendableFuncModuleRecord->SetSendableEnv( 23234514f5e3Sopenharmony_ci thread, JSHandle<SourceTextModule>::Cast(module)->GetSendableEnv()); 23244514f5e3Sopenharmony_ci } 23254514f5e3Sopenharmony_ci result->SetModule(thread, sendableFuncModule.GetTaggedValue()); 23264514f5e3Sopenharmony_ci } else { 23274514f5e3Sopenharmony_ci result = factory->NewJSFunction(methodHandle); 23284514f5e3Sopenharmony_ci result->SetModule(thread, module.GetTaggedValue()); 23294514f5e3Sopenharmony_ci result->SetLexicalEnv(thread, envHandle.GetTaggedValue()); 23304514f5e3Sopenharmony_ci result->SetHomeObject(thread, homeObject.GetTaggedValue()); 23314514f5e3Sopenharmony_ci } 23324514f5e3Sopenharmony_ci DefineFuncTryUseAOTHClass(thread, result, ihc, aotLiteralInfo); 23334514f5e3Sopenharmony_ci 23344514f5e3Sopenharmony_ci result->SetLength(length); 23354514f5e3Sopenharmony_ci return result.GetTaggedValue(); 23364514f5e3Sopenharmony_ci} 23374514f5e3Sopenharmony_ci 23384514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateRegExpWithLiteral(JSThread *thread, 23394514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &pattern, uint8_t flags) 23404514f5e3Sopenharmony_ci{ 23414514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> flagsHandle(thread, JSTaggedValue(flags)); 23424514f5e3Sopenharmony_ci return builtins::BuiltinsRegExp::RegExpCreate(thread, pattern, flagsHandle); 23434514f5e3Sopenharmony_ci} 23444514f5e3Sopenharmony_ci 23454514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeThrowIfSuperNotCorrectCall(JSThread *thread, uint16_t index, 23464514f5e3Sopenharmony_ci JSTaggedValue thisValue) 23474514f5e3Sopenharmony_ci{ 23484514f5e3Sopenharmony_ci if (index == 0 && (thisValue.IsUndefined() || thisValue.IsHole())) { 23494514f5e3Sopenharmony_ci return RuntimeThrowReferenceError(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 23504514f5e3Sopenharmony_ci "sub-class must call super before use 'this'"); 23514514f5e3Sopenharmony_ci } 23524514f5e3Sopenharmony_ci if (index == 1 && !thisValue.IsUndefined() && !thisValue.IsHole()) { 23534514f5e3Sopenharmony_ci return RuntimeThrowReferenceError(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()), 23544514f5e3Sopenharmony_ci "super() forbidden re-bind 'this'"); 23554514f5e3Sopenharmony_ci } 23564514f5e3Sopenharmony_ci return JSTaggedValue::True(); 23574514f5e3Sopenharmony_ci} 23584514f5e3Sopenharmony_ci 23594514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateObjectHavingMethod(JSThread *thread, ObjectFactory *factory, 23604514f5e3Sopenharmony_ci const JSHandle<JSObject> &literal, 23614514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &env) 23624514f5e3Sopenharmony_ci{ 23634514f5e3Sopenharmony_ci JSHandle<JSObject> objLiteral = factory->CloneObjectLiteral(literal, env); 23644514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 23654514f5e3Sopenharmony_ci 23664514f5e3Sopenharmony_ci return objLiteral.GetTaggedValue(); 23674514f5e3Sopenharmony_ci} 23684514f5e3Sopenharmony_ci 23694514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::CommonCreateObjectWithExcludedKeys(JSThread *thread, 23704514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &objVal, 23714514f5e3Sopenharmony_ci uint32_t numExcludedKeys, 23724514f5e3Sopenharmony_ci JSHandle<TaggedArray> excludedKeys) 23734514f5e3Sopenharmony_ci{ 23744514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 23754514f5e3Sopenharmony_ci JSHandle<JSObject> restObj = factory->NewEmptyJSObject(); 23764514f5e3Sopenharmony_ci if (objVal->IsNull() || objVal->IsUndefined()) { 23774514f5e3Sopenharmony_ci return restObj.GetTaggedValue(); 23784514f5e3Sopenharmony_ci } 23794514f5e3Sopenharmony_ci JSHandle<JSObject> obj(JSTaggedValue::ToObject(thread, objVal)); 23804514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 23814514f5e3Sopenharmony_ci JSHandle<TaggedArray> allKeys = JSObject::GetOwnPropertyKeys(thread, obj); 23824514f5e3Sopenharmony_ci uint32_t numAllKeys = allKeys->GetLength(); 23834514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined()); 23844514f5e3Sopenharmony_ci for (uint32_t i = 0; i < numAllKeys; i++) { 23854514f5e3Sopenharmony_ci key.Update(allKeys->Get(i)); 23864514f5e3Sopenharmony_ci bool isExcludedKey = false; 23874514f5e3Sopenharmony_ci for (uint32_t j = 0; j < numExcludedKeys; j++) { 23884514f5e3Sopenharmony_ci if (JSTaggedValue::Equal(thread, key, JSHandle<JSTaggedValue>(thread, excludedKeys->Get(j)))) { 23894514f5e3Sopenharmony_ci isExcludedKey = true; 23904514f5e3Sopenharmony_ci break; 23914514f5e3Sopenharmony_ci } 23924514f5e3Sopenharmony_ci } 23934514f5e3Sopenharmony_ci if (!isExcludedKey) { 23944514f5e3Sopenharmony_ci PropertyDescriptor desc(thread); 23954514f5e3Sopenharmony_ci bool success = JSObject::GetOwnProperty(thread, obj, key, desc); 23964514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 23974514f5e3Sopenharmony_ci if (success && desc.IsEnumerable()) { 23984514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value = JSObject::GetProperty(thread, obj, key).GetValue(); 23994514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 24004514f5e3Sopenharmony_ci JSObject::SetProperty(thread, restObj, key, value, true); 24014514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 24024514f5e3Sopenharmony_ci } 24034514f5e3Sopenharmony_ci } 24044514f5e3Sopenharmony_ci } 24054514f5e3Sopenharmony_ci return restObj.GetTaggedValue(); 24064514f5e3Sopenharmony_ci} 24074514f5e3Sopenharmony_ci 24084514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptCreateObjectWithExcludedKeys(JSThread *thread, uintptr_t argv, uint32_t argc) 24094514f5e3Sopenharmony_ci{ 24104514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 24114514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &objVal = GetHArg<JSTaggedValue>(argv, argc, 0); // 0: means the objVal 24124514f5e3Sopenharmony_ci uint32_t firstArgRegIdx = 1; // 1: means the firstArgRegIdx 24134514f5e3Sopenharmony_ci uint32_t numExcludedKeys = 0; 24144514f5e3Sopenharmony_ci uint32_t numKeys = argc - 1; 24154514f5e3Sopenharmony_ci JSHandle<TaggedArray> excludedKeys = factory->NewTaggedArray(numKeys); 24164514f5e3Sopenharmony_ci JSTaggedValue excludedKey = GetArg(argv, argc, firstArgRegIdx); 24174514f5e3Sopenharmony_ci if (!excludedKey.IsUndefined()) { 24184514f5e3Sopenharmony_ci numExcludedKeys = numKeys; 24194514f5e3Sopenharmony_ci excludedKeys->Set(thread, 0, excludedKey); 24204514f5e3Sopenharmony_ci for (uint32_t i = 1; i < numExcludedKeys; i++) { 24214514f5e3Sopenharmony_ci excludedKey = GetArg(argv, argc, firstArgRegIdx + i); 24224514f5e3Sopenharmony_ci excludedKeys->Set(thread, i, excludedKey); 24234514f5e3Sopenharmony_ci } 24244514f5e3Sopenharmony_ci } 24254514f5e3Sopenharmony_ci return CommonCreateObjectWithExcludedKeys(thread, objVal, numExcludedKeys, excludedKeys); 24264514f5e3Sopenharmony_ci} 24274514f5e3Sopenharmony_ci 24284514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreateObjectWithExcludedKeys(JSThread *thread, uint16_t numKeys, 24294514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &objVal, 24304514f5e3Sopenharmony_ci uint16_t firstArgRegIdx) 24314514f5e3Sopenharmony_ci{ 24324514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 24334514f5e3Sopenharmony_ci uint32_t numExcludedKeys = 0; 24344514f5e3Sopenharmony_ci JSHandle<TaggedArray> excludedKeys = factory->NewTaggedArray(numKeys + 1); 24354514f5e3Sopenharmony_ci FrameHandler frameHandler(thread); 24364514f5e3Sopenharmony_ci JSTaggedValue excludedKey = frameHandler.GetVRegValue(firstArgRegIdx); 24374514f5e3Sopenharmony_ci if (!excludedKey.IsUndefined()) { 24384514f5e3Sopenharmony_ci numExcludedKeys = numKeys + 1; 24394514f5e3Sopenharmony_ci excludedKeys->Set(thread, 0, excludedKey); 24404514f5e3Sopenharmony_ci for (uint32_t i = 1; i < numExcludedKeys; i++) { 24414514f5e3Sopenharmony_ci excludedKey = frameHandler.GetVRegValue(firstArgRegIdx + i); 24424514f5e3Sopenharmony_ci excludedKeys->Set(thread, i, excludedKey); 24434514f5e3Sopenharmony_ci } 24444514f5e3Sopenharmony_ci } 24454514f5e3Sopenharmony_ci 24464514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> finalVal = objVal; 24474514f5e3Sopenharmony_ci if (finalVal->CheckIsJSProxy()) { 24484514f5e3Sopenharmony_ci JSHandle<JSProxy> proxyVal(thread, finalVal.GetTaggedValue()); 24494514f5e3Sopenharmony_ci finalVal = proxyVal->GetSourceTarget(thread); 24504514f5e3Sopenharmony_ci } 24514514f5e3Sopenharmony_ci 24524514f5e3Sopenharmony_ci return CommonCreateObjectWithExcludedKeys(thread, finalVal, numExcludedKeys, excludedKeys); 24534514f5e3Sopenharmony_ci} 24544514f5e3Sopenharmony_ci 24554514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeDefineMethod(JSThread *thread, const JSHandle<Method> &methodHandle, 24564514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &homeObject, uint16_t length, 24574514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &env, 24584514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &module) 24594514f5e3Sopenharmony_ci{ 24604514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 24614514f5e3Sopenharmony_ci JSHandle<JSFunction> func = factory->NewJSFunction(methodHandle, homeObject); 24624514f5e3Sopenharmony_ci func->SetLength(length); 24634514f5e3Sopenharmony_ci func->SetLexicalEnv(thread, env); 24644514f5e3Sopenharmony_ci func->SetModule(thread, module); 24654514f5e3Sopenharmony_ci return func.GetTaggedValue(); 24664514f5e3Sopenharmony_ci} 24674514f5e3Sopenharmony_ci 24684514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdSendableClass(const JSHandle<JSTaggedValue> &env, uint16_t level) 24694514f5e3Sopenharmony_ci{ 24704514f5e3Sopenharmony_ci JSTaggedValue currentEnv(env.GetTaggedValue()); 24714514f5e3Sopenharmony_ci for (uint32_t i = 0; i < level; i++) { 24724514f5e3Sopenharmony_ci ASSERT(currentEnv.IsLexicalEnv()); 24734514f5e3Sopenharmony_ci currentEnv = LexicalEnv::Cast(currentEnv.GetTaggedObject())->GetParentEnv(); 24744514f5e3Sopenharmony_ci } 24754514f5e3Sopenharmony_ci ASSERT(currentEnv.IsJSSharedFunction()); 24764514f5e3Sopenharmony_ci return currentEnv; 24774514f5e3Sopenharmony_ci} 24784514f5e3Sopenharmony_ci 24794514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCallSpread(JSThread *thread, 24804514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &func, 24814514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &obj, 24824514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &array) 24834514f5e3Sopenharmony_ci{ 24844514f5e3Sopenharmony_ci if ((!obj->IsUndefined() && !obj->IsECMAObject()) || !func->IsCallable() || !array->IsJSArray()) { 24854514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "cannot Callspread", JSTaggedValue::Exception()); 24864514f5e3Sopenharmony_ci } 24874514f5e3Sopenharmony_ci 24884514f5e3Sopenharmony_ci JSHandle<TaggedArray> coretypesArray(thread, RuntimeGetCallSpreadArgs(thread, array)); 24894514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 24904514f5e3Sopenharmony_ci uint32_t length = coretypesArray->GetLength(); 24914514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 24924514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, func, obj, undefined, length); 24934514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 24944514f5e3Sopenharmony_ci info->SetCallArg(length, coretypesArray); 24954514f5e3Sopenharmony_ci return EcmaInterpreter::Execute(info); 24964514f5e3Sopenharmony_ci} 24974514f5e3Sopenharmony_ci 24984514f5e3Sopenharmony_civoid RuntimeStubs::RuntimeSetPatchModule(JSThread *thread, const JSHandle<JSFunction> &func) 24994514f5e3Sopenharmony_ci{ 25004514f5e3Sopenharmony_ci JSHandle<Method> methodHandle(thread, Method::Cast(func->GetMethod())); 25014514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> coldReloadRecordName = 25024514f5e3Sopenharmony_ci thread->GetCurrentEcmaContext()->FindPatchModule(MethodLiteral::GetRecordName( 25034514f5e3Sopenharmony_ci methodHandle->GetJSPandaFile(), methodHandle->GetMethodId())); 25044514f5e3Sopenharmony_ci if (!coldReloadRecordName->IsHole()) { 25054514f5e3Sopenharmony_ci func->SetModule(thread, coldReloadRecordName.GetTaggedValue()); 25064514f5e3Sopenharmony_ci } 25074514f5e3Sopenharmony_ci} 25084514f5e3Sopenharmony_ci 25094514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeDefineGetterSetterByValue(JSThread *thread, const JSHandle<JSObject> &obj, 25104514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &prop, 25114514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &getter, 25124514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &setter, bool flag, 25134514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &func, 25144514f5e3Sopenharmony_ci int32_t pcOffset) 25154514f5e3Sopenharmony_ci{ 25164514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop); 25174514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 25184514f5e3Sopenharmony_ci auto globalConst = thread->GlobalConstants(); 25194514f5e3Sopenharmony_ci if (obj.GetTaggedValue().IsClassConstructor() && 25204514f5e3Sopenharmony_ci JSTaggedValue::SameValue(propKey, globalConst->GetHandledPrototypeString())) { 25214514f5e3Sopenharmony_ci return RuntimeThrowTypeError( 25224514f5e3Sopenharmony_ci thread, 25234514f5e3Sopenharmony_ci "In a class, computed property names for static getter that are named 'prototype' throw a TypeError"); 25244514f5e3Sopenharmony_ci } 25254514f5e3Sopenharmony_ci 25264514f5e3Sopenharmony_ci auto receiverHClass = obj->GetJSHClass(); 25274514f5e3Sopenharmony_ci 25284514f5e3Sopenharmony_ci if (flag) { 25294514f5e3Sopenharmony_ci if (!getter->IsUndefined()) { 25304514f5e3Sopenharmony_ci if (propKey->IsNumber()) { 25314514f5e3Sopenharmony_ci propKey = 25324514f5e3Sopenharmony_ci JSHandle<JSTaggedValue>::Cast(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue())); 25334514f5e3Sopenharmony_ci } 25344514f5e3Sopenharmony_ci JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(getter), propKey, 25354514f5e3Sopenharmony_ci JSHandle<JSTaggedValue>(thread, globalConst->GetGetString())); 25364514f5e3Sopenharmony_ci } 25374514f5e3Sopenharmony_ci 25384514f5e3Sopenharmony_ci if (!setter->IsUndefined()) { 25394514f5e3Sopenharmony_ci if (propKey->IsNumber()) { 25404514f5e3Sopenharmony_ci propKey = 25414514f5e3Sopenharmony_ci JSHandle<JSTaggedValue>::Cast(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue())); 25424514f5e3Sopenharmony_ci } 25434514f5e3Sopenharmony_ci JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(setter), propKey, 25444514f5e3Sopenharmony_ci JSHandle<JSTaggedValue>(thread, globalConst->GetSetString())); 25454514f5e3Sopenharmony_ci } 25464514f5e3Sopenharmony_ci } 25474514f5e3Sopenharmony_ci 25484514f5e3Sopenharmony_ci // set accessor 25494514f5e3Sopenharmony_ci bool enumerable = 25504514f5e3Sopenharmony_ci !(obj.GetTaggedValue().IsClassPrototype() || obj.GetTaggedValue().IsClassConstructor()); 25514514f5e3Sopenharmony_ci PropertyDescriptor desc(thread, true, enumerable, true); 25524514f5e3Sopenharmony_ci if (!getter->IsUndefined()) { 25534514f5e3Sopenharmony_ci Method *method = Method::Cast(JSHandle<JSFunction>::Cast(getter)->GetMethod().GetTaggedObject()); 25544514f5e3Sopenharmony_ci method->SetFunctionKind(FunctionKind::GETTER_FUNCTION); 25554514f5e3Sopenharmony_ci desc.SetGetter(getter); 25564514f5e3Sopenharmony_ci } 25574514f5e3Sopenharmony_ci if (!setter->IsUndefined()) { 25584514f5e3Sopenharmony_ci Method *method = Method::Cast(JSHandle<JSFunction>::Cast(setter)->GetMethod().GetTaggedObject()); 25594514f5e3Sopenharmony_ci method->SetFunctionKind(FunctionKind::SETTER_FUNCTION); 25604514f5e3Sopenharmony_ci desc.SetSetter(setter); 25614514f5e3Sopenharmony_ci } 25624514f5e3Sopenharmony_ci 25634514f5e3Sopenharmony_ci JSObject::DefineOwnProperty(thread, obj, propKey, desc); 25644514f5e3Sopenharmony_ci auto holderTraHClass = obj->GetJSHClass(); 25654514f5e3Sopenharmony_ci if (receiverHClass != holderTraHClass) { 25664514f5e3Sopenharmony_ci if (holderTraHClass->IsTS()) { 25674514f5e3Sopenharmony_ci JSHandle<JSHClass> phcHandle(thread, holderTraHClass); 25684514f5e3Sopenharmony_ci JSHClass::EnablePHCProtoChangeMarker(thread, phcHandle); 25694514f5e3Sopenharmony_ci } 25704514f5e3Sopenharmony_ci if (thread->GetEcmaVM()->IsEnablePGOProfiler()) { 25714514f5e3Sopenharmony_ci if (!func->IsUndefined()) { 25724514f5e3Sopenharmony_ci thread->GetEcmaVM()->GetPGOProfiler()->ProfileDefineGetterSetter( 25734514f5e3Sopenharmony_ci receiverHClass, holderTraHClass, func, pcOffset); 25744514f5e3Sopenharmony_ci } 25754514f5e3Sopenharmony_ci } 25764514f5e3Sopenharmony_ci } 25774514f5e3Sopenharmony_ci return obj.GetTaggedValue(); 25784514f5e3Sopenharmony_ci} 25794514f5e3Sopenharmony_ci 25804514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeSuperCall(JSThread *thread, const JSHandle<JSTaggedValue> &func, 25814514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &newTarget, uint16_t firstVRegIdx, 25824514f5e3Sopenharmony_ci uint16_t length) 25834514f5e3Sopenharmony_ci{ 25844514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func)); 25854514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 25864514f5e3Sopenharmony_ci 25874514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 25884514f5e3Sopenharmony_ci JSHandle<TaggedArray> argv = factory->NewTaggedArray(length); 25894514f5e3Sopenharmony_ci FrameHandler frameHandler(thread); 25904514f5e3Sopenharmony_ci for (size_t i = 0; i < length; ++i) { 25914514f5e3Sopenharmony_ci argv->Set(thread, i, frameHandler.GetVRegValue(firstVRegIdx + i)); 25924514f5e3Sopenharmony_ci } 25934514f5e3Sopenharmony_ci 25944514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 25954514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, length); 25964514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 25974514f5e3Sopenharmony_ci info->SetCallArg(length, argv); 25984514f5e3Sopenharmony_ci JSTaggedValue result = JSFunction::Construct(info); 25994514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 26004514f5e3Sopenharmony_ci 26014514f5e3Sopenharmony_ci return result; 26024514f5e3Sopenharmony_ci} 26034514f5e3Sopenharmony_ci 26044514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptSuperCall(JSThread *thread, const JSHandle<JSTaggedValue> &func, 26054514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &newTarget, 26064514f5e3Sopenharmony_ci const JSHandle<TaggedArray> &argv, 26074514f5e3Sopenharmony_ci uint16_t length) 26084514f5e3Sopenharmony_ci{ 26094514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func)); 26104514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 26114514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 26124514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, length); 26134514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 26144514f5e3Sopenharmony_ci info->SetCallArg(length, argv); 26154514f5e3Sopenharmony_ci JSTaggedValue result = JSFunction::Construct(info); 26164514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 26174514f5e3Sopenharmony_ci return result; 26184514f5e3Sopenharmony_ci} 26194514f5e3Sopenharmony_ci 26204514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeThrowTypeError(JSThread *thread, const char *message) 26214514f5e3Sopenharmony_ci{ 26224514f5e3Sopenharmony_ci ASSERT_NO_ABRUPT_COMPLETION(thread); 26234514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception()); 26244514f5e3Sopenharmony_ci} 26254514f5e3Sopenharmony_ci 26264514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetCallSpreadArgs(JSThread *thread, const JSHandle<JSTaggedValue> &jsArray) 26274514f5e3Sopenharmony_ci{ 26284514f5e3Sopenharmony_ci uint32_t argvMayMaxLength = JSHandle<JSArray>::Cast(jsArray)->GetArrayLength(); 26294514f5e3Sopenharmony_ci 26304514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 26314514f5e3Sopenharmony_ci JSHandle<TaggedArray> argv = factory->NewTaggedArray(argvMayMaxLength); 26324514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> itor = JSIterator::GetIterator(thread, jsArray); 26334514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 26344514f5e3Sopenharmony_ci 26354514f5e3Sopenharmony_ci // Fast path when array is stablearray and Iterator not change. 26364514f5e3Sopenharmony_ci if (jsArray->IsStableJSArray(thread) && itor->IsJSArrayIterator()) { 26374514f5e3Sopenharmony_ci JSHandle<JSObject> jsArrayObj(jsArray); 26384514f5e3Sopenharmony_ci ElementAccessor::CopyJSArrayToTaggedArray(thread, jsArrayObj, argv, argvMayMaxLength); 26394514f5e3Sopenharmony_ci return argv.GetTaggedValue(); 26404514f5e3Sopenharmony_ci } 26414514f5e3Sopenharmony_ci 26424514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 26434514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> next(thread, JSTaggedValue::Undefined()); 26444514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> nextArg(thread, JSTaggedValue::Undefined()); 26454514f5e3Sopenharmony_ci size_t argvIndex = 0; 26464514f5e3Sopenharmony_ci while (true) { 26474514f5e3Sopenharmony_ci next.Update(JSIterator::IteratorStep(thread, itor).GetTaggedValue()); 26484514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 26494514f5e3Sopenharmony_ci if (JSTaggedValue::SameValue(next.GetTaggedValue(), JSTaggedValue::False())) { 26504514f5e3Sopenharmony_ci break; 26514514f5e3Sopenharmony_ci } 26524514f5e3Sopenharmony_ci nextArg.Update(JSIterator::IteratorValue(thread, next).GetTaggedValue()); 26534514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 26544514f5e3Sopenharmony_ci if (UNLIKELY(argvIndex + 1 >= argvMayMaxLength)) { 26554514f5e3Sopenharmony_ci argvMayMaxLength = argvMayMaxLength + (argvMayMaxLength >> 1U) + 1U; 26564514f5e3Sopenharmony_ci argv = argv->SetCapacity(thread, argv, argvMayMaxLength); 26574514f5e3Sopenharmony_ci } 26584514f5e3Sopenharmony_ci argv->Set(thread, argvIndex++, nextArg); 26594514f5e3Sopenharmony_ci } 26604514f5e3Sopenharmony_ci argv = factory->CopyArray(argv, argvMayMaxLength, argvIndex); 26614514f5e3Sopenharmony_ci return argv.GetTaggedValue(); 26624514f5e3Sopenharmony_ci} 26634514f5e3Sopenharmony_ci 26644514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeThrowSyntaxError(JSThread *thread, const char *message) 26654514f5e3Sopenharmony_ci{ 26664514f5e3Sopenharmony_ci ASSERT_NO_ABRUPT_COMPLETION(thread); 26674514f5e3Sopenharmony_ci THROW_SYNTAX_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception()); 26684514f5e3Sopenharmony_ci} 26694514f5e3Sopenharmony_ci 26704514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &numberBigInt) 26714514f5e3Sopenharmony_ci{ 26724514f5e3Sopenharmony_ci return JSTaggedValue::ToBigInt(thread, numberBigInt); 26734514f5e3Sopenharmony_ci} 26744514f5e3Sopenharmony_ci 26754514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCallBigIntAsIntN(JSThread *thread, JSTaggedValue bits, JSTaggedValue bigint) 26764514f5e3Sopenharmony_ci{ 26774514f5e3Sopenharmony_ci auto biginteger = JSHandle<BigInt>(thread, bigint); 26784514f5e3Sopenharmony_ci JSTaggedNumber bitness = JSTaggedValue::ToNumber(thread, bits); 26794514f5e3Sopenharmony_ci return BigInt::AsintN(thread, bitness, biginteger); 26804514f5e3Sopenharmony_ci} 26814514f5e3Sopenharmony_ci 26824514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCallBigIntAsUintN(JSThread *thread, JSTaggedValue bits, JSTaggedValue bigint) 26834514f5e3Sopenharmony_ci{ 26844514f5e3Sopenharmony_ci auto biginteger = JSHandle<BigInt>(thread, bigint); 26854514f5e3Sopenharmony_ci JSTaggedNumber bitness = JSTaggedValue::ToNumber(thread, bits); 26864514f5e3Sopenharmony_ci return BigInt::AsUintN(thread, bitness, biginteger); 26874514f5e3Sopenharmony_ci} 26884514f5e3Sopenharmony_ci 26894514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNewLexicalEnvWithName(JSThread *thread, uint16_t numVars, uint16_t scopeId) 26904514f5e3Sopenharmony_ci{ 26914514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 26924514f5e3Sopenharmony_ci JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars); 26934514f5e3Sopenharmony_ci 26944514f5e3Sopenharmony_ci JSTaggedValue currentLexenv = thread->GetCurrentLexenv(); 26954514f5e3Sopenharmony_ci newEnv->SetParentEnv(thread, currentLexenv); 26964514f5e3Sopenharmony_ci JSTaggedValue scopeInfo = ScopeInfoExtractor::GenerateScopeInfo(thread, scopeId); 26974514f5e3Sopenharmony_ci newEnv->SetScopeInfo(thread, scopeInfo); 26984514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 26994514f5e3Sopenharmony_ci return newEnv.GetTaggedValue(); 27004514f5e3Sopenharmony_ci} 27014514f5e3Sopenharmony_ci 27024514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptGetUnmapedArgs(JSThread *thread, uint32_t actualNumArgs) 27034514f5e3Sopenharmony_ci{ 27044514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 27054514f5e3Sopenharmony_ci JSHandle<TaggedArray> argumentsList = factory->NewTaggedArray(actualNumArgs - NUM_MANDATORY_JSFUNC_ARGS); 27064514f5e3Sopenharmony_ci 27074514f5e3Sopenharmony_ci auto argv = GetActualArgvFromStub(thread); 27084514f5e3Sopenharmony_ci int idx = 0; 27094514f5e3Sopenharmony_ci for (uint32_t i = NUM_MANDATORY_JSFUNC_ARGS; i < actualNumArgs; ++i) { 27104514f5e3Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 27114514f5e3Sopenharmony_ci JSTaggedType arg = reinterpret_cast<JSTaggedType *>(argv)[i]; 27124514f5e3Sopenharmony_ci JSTaggedValue args = JSTaggedValue(arg); 27134514f5e3Sopenharmony_ci argumentsList->Set(thread, idx++, args); 27144514f5e3Sopenharmony_ci } 27154514f5e3Sopenharmony_ci return RuntimeGetUnmapedJSArgumentObj(thread, argumentsList); 27164514f5e3Sopenharmony_ci} 27174514f5e3Sopenharmony_ci 27184514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeGetUnmapedJSArgumentObj(JSThread *thread, const JSHandle<TaggedArray> &argumentsList) 27194514f5e3Sopenharmony_ci{ 27204514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 27214514f5e3Sopenharmony_ci JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 27224514f5e3Sopenharmony_ci // 1. Let len be the number of elements in argumentsList 27234514f5e3Sopenharmony_ci uint32_t len = argumentsList->GetLength(); 27244514f5e3Sopenharmony_ci // 2. Let obj be ObjectCreate(%ObjectPrototype%, «[[ParameterMap]]»). 27254514f5e3Sopenharmony_ci // 3. Set obj’s [[ParameterMap]] internal slot to undefined. 27264514f5e3Sopenharmony_ci // [[ParameterMap]] setted as undifined. 27274514f5e3Sopenharmony_ci JSHandle<JSArguments> obj = factory->NewJSArguments(); 27284514f5e3Sopenharmony_ci // 4. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor{[[Value]]: len, [[Writable]]: true, 27294514f5e3Sopenharmony_ci // [[Enumerable]]: false, [[Configurable]]: true}). 27304514f5e3Sopenharmony_ci obj->SetPropertyInlinedProps(thread, JSArguments::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(len)); 27314514f5e3Sopenharmony_ci // 5. Let index be 0. 27324514f5e3Sopenharmony_ci // 6. Repeat while index < len, 27334514f5e3Sopenharmony_ci // a. Let val be argumentsList[index]. 27344514f5e3Sopenharmony_ci // b. Perform CreateDataProperty(obj, ToString(index), val). 27354514f5e3Sopenharmony_ci // c. Let index be index + 1 27364514f5e3Sopenharmony_ci obj->SetElements(thread, argumentsList.GetTaggedValue()); 27374514f5e3Sopenharmony_ci // 7. Perform DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor 27384514f5e3Sopenharmony_ci // {[[Value]]:%ArrayProto_values%, 27394514f5e3Sopenharmony_ci // [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}). 27404514f5e3Sopenharmony_ci obj->SetPropertyInlinedProps(thread, JSArguments::ITERATOR_INLINE_PROPERTY_INDEX, 27414514f5e3Sopenharmony_ci globalEnv->GetArrayProtoValuesFunction().GetTaggedValue()); 27424514f5e3Sopenharmony_ci // 8. Perform DefinePropertyOrThrow(obj, "caller", PropertyDescriptor {[[Get]]: %ThrowTypeError%, 27434514f5e3Sopenharmony_ci // [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}). 27444514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> accessorCaller = globalEnv->GetArgumentsCallerAccessor(); 27454514f5e3Sopenharmony_ci obj->SetPropertyInlinedProps(thread, JSArguments::CALLER_INLINE_PROPERTY_INDEX, accessorCaller.GetTaggedValue()); 27464514f5e3Sopenharmony_ci // 9. Perform DefinePropertyOrThrow(obj, "callee", PropertyDescriptor {[[Get]]: %ThrowTypeError%, 27474514f5e3Sopenharmony_ci // [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}). 27484514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> accessorCallee = globalEnv->GetArgumentsCalleeAccessor(); 27494514f5e3Sopenharmony_ci obj->SetPropertyInlinedProps(thread, JSArguments::CALLEE_INLINE_PROPERTY_INDEX, accessorCallee.GetTaggedValue()); 27504514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 27514514f5e3Sopenharmony_ci // 11. Return obj 27524514f5e3Sopenharmony_ci return obj.GetTaggedValue(); 27534514f5e3Sopenharmony_ci} 27544514f5e3Sopenharmony_ci 27554514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptNewLexicalEnvWithName(JSThread *thread, uint16_t numVars, uint16_t scopeId, 27564514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> ¤tLexEnv, 27574514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> &func) 27584514f5e3Sopenharmony_ci{ 27594514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 27604514f5e3Sopenharmony_ci JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars); 27614514f5e3Sopenharmony_ci 27624514f5e3Sopenharmony_ci newEnv->SetParentEnv(thread, currentLexEnv.GetTaggedValue()); 27634514f5e3Sopenharmony_ci JSTaggedValue scopeInfo = RuntimeOptGenerateScopeInfo(thread, scopeId, func.GetTaggedValue()); 27644514f5e3Sopenharmony_ci newEnv->SetScopeInfo(thread, scopeInfo); 27654514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 27664514f5e3Sopenharmony_ci JSTaggedValue taggedEnv = newEnv.GetTaggedValue(); 27674514f5e3Sopenharmony_ci return taggedEnv; 27684514f5e3Sopenharmony_ci} 27694514f5e3Sopenharmony_ci 27704514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptCopyRestArgs(JSThread *thread, uint32_t actualArgc, uint32_t restIndex) 27714514f5e3Sopenharmony_ci{ 27724514f5e3Sopenharmony_ci // when only have three fixed args, restIndex in bytecode maybe not zero, but it actually should be zero. 27734514f5e3Sopenharmony_ci uint32_t actualRestNum = 0; 27744514f5e3Sopenharmony_ci if (actualArgc > NUM_MANDATORY_JSFUNC_ARGS + restIndex) { 27754514f5e3Sopenharmony_ci actualRestNum = actualArgc - NUM_MANDATORY_JSFUNC_ARGS - restIndex; 27764514f5e3Sopenharmony_ci } 27774514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> restArray = JSArray::ArrayCreate(thread, JSTaggedNumber(actualRestNum)); 27784514f5e3Sopenharmony_ci 27794514f5e3Sopenharmony_ci auto argv = GetActualArgv(thread); 27804514f5e3Sopenharmony_ci int idx = 0; 27814514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> element(thread, JSTaggedValue::Undefined()); 27824514f5e3Sopenharmony_ci 27834514f5e3Sopenharmony_ci for (uint32_t i = NUM_MANDATORY_JSFUNC_ARGS + restIndex; i < actualArgc; ++i) { 27844514f5e3Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 27854514f5e3Sopenharmony_ci JSTaggedType arg = reinterpret_cast<JSTaggedType *>(argv)[i]; 27864514f5e3Sopenharmony_ci element.Update(JSTaggedValue(arg)); 27874514f5e3Sopenharmony_ci JSObject::SetProperty(thread, restArray, idx++, element, true); 27884514f5e3Sopenharmony_ci } 27894514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 27904514f5e3Sopenharmony_ci return restArray.GetTaggedValue(); 27914514f5e3Sopenharmony_ci} 27924514f5e3Sopenharmony_ci 27934514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptSuspendGenerator(JSThread *thread, const JSHandle<JSTaggedValue> &genObj, 27944514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &value) 27954514f5e3Sopenharmony_ci{ 27964514f5e3Sopenharmony_ci if (genObj->IsAsyncGeneratorObject()) { 27974514f5e3Sopenharmony_ci JSHandle<JSAsyncGeneratorObject> generatorObjectHandle(genObj); 27984514f5e3Sopenharmony_ci // change state to SuspendedYield 27994514f5e3Sopenharmony_ci if (generatorObjectHandle->IsExecuting()) { 28004514f5e3Sopenharmony_ci return value.GetTaggedValue(); 28014514f5e3Sopenharmony_ci } 28024514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 28034514f5e3Sopenharmony_ci return generatorObjectHandle.GetTaggedValue(); 28044514f5e3Sopenharmony_ci } 28054514f5e3Sopenharmony_ci 28064514f5e3Sopenharmony_ci if (genObj->IsGeneratorObject()) { 28074514f5e3Sopenharmony_ci JSHandle<JSGeneratorObject> generatorObjectHandle(genObj); 28084514f5e3Sopenharmony_ci // set TaskInfo for TaskPool 28094514f5e3Sopenharmony_ci generatorObjectHandle->SetTaskInfo(thread->GetTaskInfo()); 28104514f5e3Sopenharmony_ci // change state to SuspendedYield 28114514f5e3Sopenharmony_ci if (generatorObjectHandle->IsExecuting()) { 28124514f5e3Sopenharmony_ci generatorObjectHandle->SetGeneratorState(JSGeneratorState::SUSPENDED_YIELD); 28134514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 28144514f5e3Sopenharmony_ci return value.GetTaggedValue(); 28154514f5e3Sopenharmony_ci } 28164514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 28174514f5e3Sopenharmony_ci return generatorObjectHandle.GetTaggedValue(); 28184514f5e3Sopenharmony_ci } 28194514f5e3Sopenharmony_ci 28204514f5e3Sopenharmony_ci return RuntimeThrowTypeError(thread, "RuntimeSuspendGenerator failed"); 28214514f5e3Sopenharmony_ci} 28224514f5e3Sopenharmony_ci 28234514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptAsyncGeneratorResolve(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj, 28244514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> value, JSTaggedValue flag) 28254514f5e3Sopenharmony_ci{ 28264514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 28274514f5e3Sopenharmony_ci 28284514f5e3Sopenharmony_ci JSHandle<JSAsyncGeneratorObject> asyncGeneratorObjHandle(asyncFuncObj); 28294514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> valueHandle(value); 28304514f5e3Sopenharmony_ci JSHandle<GeneratorContext> genContextHandle(thread, asyncGeneratorObjHandle->GetGeneratorContext()); 28314514f5e3Sopenharmony_ci ASSERT(flag.IsBoolean()); 28324514f5e3Sopenharmony_ci bool done = flag.IsTrue(); 28334514f5e3Sopenharmony_ci return JSAsyncGeneratorObject::AsyncGeneratorResolve(thread, asyncGeneratorObjHandle, valueHandle, done); 28344514f5e3Sopenharmony_ci} 28354514f5e3Sopenharmony_ci 28364514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptConstruct(JSThread *thread, JSHandle<JSTaggedValue> ctor, 28374514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> newTarget, JSHandle<JSTaggedValue> preArgs, 28384514f5e3Sopenharmony_ci JSHandle<TaggedArray> args) 28394514f5e3Sopenharmony_ci{ 28404514f5e3Sopenharmony_ci if (newTarget->IsUndefined()) { 28414514f5e3Sopenharmony_ci newTarget = ctor; 28424514f5e3Sopenharmony_ci } 28434514f5e3Sopenharmony_ci 28444514f5e3Sopenharmony_ci if (!(newTarget->IsConstructor() && ctor->IsConstructor())) { 28454514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor is false", JSTaggedValue::Exception()); 28464514f5e3Sopenharmony_ci } 28474514f5e3Sopenharmony_ci 28484514f5e3Sopenharmony_ci if (ctor->IsJSFunction()) { 28494514f5e3Sopenharmony_ci return RuntimeOptConstructGeneric(thread, JSHandle<JSFunction>::Cast(ctor), newTarget, preArgs, args); 28504514f5e3Sopenharmony_ci } 28514514f5e3Sopenharmony_ci if (ctor->IsBoundFunction()) { 28524514f5e3Sopenharmony_ci return RuntimeOptConstructBoundFunction( 28534514f5e3Sopenharmony_ci thread, JSHandle<JSBoundFunction>::Cast(ctor), newTarget, preArgs, args); 28544514f5e3Sopenharmony_ci } 28554514f5e3Sopenharmony_ci if (ctor->IsJSProxy()) { 28564514f5e3Sopenharmony_ci return RuntimeOptConstructProxy(thread, JSHandle<JSProxy>::Cast(ctor), newTarget, preArgs, args); 28574514f5e3Sopenharmony_ci } 28584514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor NonConstructor", JSTaggedValue::Exception()); 28594514f5e3Sopenharmony_ci} 28604514f5e3Sopenharmony_ci 28614514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptConstructProxy(JSThread *thread, JSHandle<JSProxy> ctor, 28624514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> newTgt, JSHandle<JSTaggedValue> preArgs, 28634514f5e3Sopenharmony_ci JSHandle<TaggedArray> args) 28644514f5e3Sopenharmony_ci{ 28654514f5e3Sopenharmony_ci // step 1 ~ 4 get ProxyHandler and ProxyTarget 28664514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handler(thread, ctor->GetHandler()); 28674514f5e3Sopenharmony_ci if (handler->IsNull()) { 28684514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor: handler is null", JSTaggedValue::Exception()); 28694514f5e3Sopenharmony_ci } 28704514f5e3Sopenharmony_ci ASSERT(handler->IsECMAObject()); 28714514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> target(thread, ctor->GetTarget()); 28724514f5e3Sopenharmony_ci 28734514f5e3Sopenharmony_ci // 5.Let trap be GetMethod(handler, "construct"). 28744514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key(thread->GlobalConstants()->GetHandledProxyConstructString()); 28754514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> method = JSObject::GetMethod(thread, handler, key); 28764514f5e3Sopenharmony_ci 28774514f5e3Sopenharmony_ci // 6.ReturnIfAbrupt(trap). 28784514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 28794514f5e3Sopenharmony_ci // 7.If trap is undefined, then 28804514f5e3Sopenharmony_ci // a.Assert: target has a [[Construct]] internal method. 28814514f5e3Sopenharmony_ci // b.Return Construct(target, argumentsList, newTarget). 28824514f5e3Sopenharmony_ci if (method->IsUndefined()) { 28834514f5e3Sopenharmony_ci ASSERT(target->IsConstructor()); 28844514f5e3Sopenharmony_ci return RuntimeOptConstruct(thread, target, newTgt, preArgs, args); 28854514f5e3Sopenharmony_ci } 28864514f5e3Sopenharmony_ci 28874514f5e3Sopenharmony_ci // 8.Let argArray be CreateArrayFromList(argumentsList). 28884514f5e3Sopenharmony_ci uint32_t preArgsSize = preArgs->IsUndefined() ? 0 : JSHandle<TaggedArray>::Cast(preArgs)->GetLength(); 28894514f5e3Sopenharmony_ci const uint32_t argsCount = args->GetLength(); 28904514f5e3Sopenharmony_ci const uint32_t size = preArgsSize + argsCount; 28914514f5e3Sopenharmony_ci JSHandle<TaggedArray> arr = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(size); 28924514f5e3Sopenharmony_ci if (preArgsSize > 0) { 28934514f5e3Sopenharmony_ci JSHandle<TaggedArray> tgaPreArgs = JSHandle<TaggedArray>::Cast(preArgs); 28944514f5e3Sopenharmony_ci for (uint32_t i = 0; i < preArgsSize; ++i) { 28954514f5e3Sopenharmony_ci JSTaggedValue value = tgaPreArgs->Get(i); 28964514f5e3Sopenharmony_ci arr->Set(thread, i, value); 28974514f5e3Sopenharmony_ci } 28984514f5e3Sopenharmony_ci } 28994514f5e3Sopenharmony_ci 29004514f5e3Sopenharmony_ci for (uint32_t i = 0; i < argsCount; ++i) { 29014514f5e3Sopenharmony_ci JSTaggedValue value = args->Get(i); 29024514f5e3Sopenharmony_ci arr->Set(thread, i + preArgsSize, value); 29034514f5e3Sopenharmony_ci } 29044514f5e3Sopenharmony_ci JSHandle<JSArray> newArr = JSArray::CreateArrayFromList(thread, arr); 29054514f5e3Sopenharmony_ci 29064514f5e3Sopenharmony_ci // step 8 ~ 9 Call(trap, handler, «target, argArray, newTarget »). 29074514f5e3Sopenharmony_ci const uint32_t argsLength = 3; // 3: «target, argArray, newTarget » 29084514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 29094514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, method, handler, undefined, argsLength); 29104514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 29114514f5e3Sopenharmony_ci info->SetCallArg(target.GetTaggedValue(), newArr.GetTaggedValue(), newTgt.GetTaggedValue()); 29124514f5e3Sopenharmony_ci JSTaggedValue newObjValue = JSFunction::Call(info); 29134514f5e3Sopenharmony_ci // 10.ReturnIfAbrupt(newObj). 29144514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 29154514f5e3Sopenharmony_ci // 11.If Type(newObj) is not Object, throw a TypeError exception. 29164514f5e3Sopenharmony_ci if (!newObjValue.IsECMAObject()) { 29174514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "new object is not object", JSTaggedValue::Exception()); 29184514f5e3Sopenharmony_ci } 29194514f5e3Sopenharmony_ci // 12.Return newObj. 29204514f5e3Sopenharmony_ci return newObjValue; 29214514f5e3Sopenharmony_ci} 29224514f5e3Sopenharmony_ci 29234514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptConstructBoundFunction(JSThread *thread, JSHandle<JSBoundFunction> ctor, 29244514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> newTgt, 29254514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> preArgs, 29264514f5e3Sopenharmony_ci JSHandle<TaggedArray> args) 29274514f5e3Sopenharmony_ci{ 29284514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> target(thread, ctor->GetBoundTarget()); 29294514f5e3Sopenharmony_ci if (!target->IsConstructor()) { 29304514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor is false", JSTaggedValue::Exception()); 29314514f5e3Sopenharmony_ci } 29324514f5e3Sopenharmony_ci 29334514f5e3Sopenharmony_ci JSHandle<TaggedArray> boundArgs(thread, ctor->GetBoundArguments()); 29344514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> newPreArgs(thread, preArgs.GetTaggedValue()); 29354514f5e3Sopenharmony_ci if (newPreArgs->IsUndefined()) { 29364514f5e3Sopenharmony_ci newPreArgs.Update(boundArgs.GetTaggedValue()); 29374514f5e3Sopenharmony_ci } else { 29384514f5e3Sopenharmony_ci newPreArgs.Update( 29394514f5e3Sopenharmony_ci TaggedArray::Append(thread, boundArgs, JSHandle<TaggedArray>::Cast(preArgs)).GetTaggedValue()); 29404514f5e3Sopenharmony_ci } 29414514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> newTargetMutable(thread, newTgt.GetTaggedValue()); 29424514f5e3Sopenharmony_ci if (JSTaggedValue::SameValue(ctor.GetTaggedValue(), newTgt.GetTaggedValue())) { 29434514f5e3Sopenharmony_ci newTargetMutable.Update(target.GetTaggedValue()); 29444514f5e3Sopenharmony_ci } 29454514f5e3Sopenharmony_ci return RuntimeOptConstruct(thread, target, newTargetMutable, newPreArgs, args); 29464514f5e3Sopenharmony_ci} 29474514f5e3Sopenharmony_ci 29484514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::GetResultValue(JSThread *thread, bool isAotMethod, JSHandle<JSFunction> ctor, 29494514f5e3Sopenharmony_ci CVector<JSTaggedType> &values, JSHandle<JSTaggedValue> newTgt, uint32_t &size, JSHandle<JSTaggedValue> obj) 29504514f5e3Sopenharmony_ci{ 29514514f5e3Sopenharmony_ci JSTaggedValue resultValue; 29524514f5e3Sopenharmony_ci if (isAotMethod) { 29534514f5e3Sopenharmony_ci uint32_t numArgs = ctor->GetCallTarget()->GetNumArgsWithCallField(); 29544514f5e3Sopenharmony_ci bool needPushArgv = numArgs != size; 29554514f5e3Sopenharmony_ci const JSTaggedType *prevFp = thread->GetLastLeaveFrame(); 29564514f5e3Sopenharmony_ci if (ctor->IsCompiledFastCall()) { 29574514f5e3Sopenharmony_ci if (needPushArgv) { 29584514f5e3Sopenharmony_ci values.reserve(numArgs + NUM_MANDATORY_JSFUNC_ARGS - 1); 29594514f5e3Sopenharmony_ci for (uint32_t i = size; i < numArgs; i++) { 29604514f5e3Sopenharmony_ci values.emplace_back(JSTaggedValue::VALUE_UNDEFINED); 29614514f5e3Sopenharmony_ci } 29624514f5e3Sopenharmony_ci size = numArgs; 29634514f5e3Sopenharmony_ci } 29644514f5e3Sopenharmony_ci resultValue = thread->GetEcmaVM()->FastCallAot(size, values.data(), prevFp); 29654514f5e3Sopenharmony_ci } else { 29664514f5e3Sopenharmony_ci resultValue = thread->GetCurrentEcmaContext()->ExecuteAot(size, values.data(), prevFp, needPushArgv); 29674514f5e3Sopenharmony_ci } 29684514f5e3Sopenharmony_ci } else { 29694514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *info = 29704514f5e3Sopenharmony_ci EcmaInterpreter::NewRuntimeCallInfo(thread, JSHandle<JSTaggedValue>(ctor), obj, newTgt, size); 29714514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 29724514f5e3Sopenharmony_ci info->SetCallArg(size, values.data()); 29734514f5e3Sopenharmony_ci resultValue = EcmaInterpreter::Execute(info); 29744514f5e3Sopenharmony_ci } 29754514f5e3Sopenharmony_ci return resultValue; 29764514f5e3Sopenharmony_ci} 29774514f5e3Sopenharmony_ci 29784514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptConstructGeneric(JSThread *thread, JSHandle<JSFunction> ctor, 29794514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> newTgt, 29804514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> preArgs, JSHandle<TaggedArray> args) 29814514f5e3Sopenharmony_ci{ 29824514f5e3Sopenharmony_ci if (!ctor->IsConstructor()) { 29834514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor is false", JSTaggedValue::Exception()); 29844514f5e3Sopenharmony_ci } 29854514f5e3Sopenharmony_ci 29864514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> obj(thread, JSTaggedValue::Undefined()); 29874514f5e3Sopenharmony_ci if (ctor->IsBase()) { 29884514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 29894514f5e3Sopenharmony_ci obj = JSHandle<JSTaggedValue>(factory->NewJSObjectByConstructor(ctor, newTgt)); 29904514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 29914514f5e3Sopenharmony_ci } 29924514f5e3Sopenharmony_ci 29934514f5e3Sopenharmony_ci uint32_t preArgsSize = preArgs->IsUndefined() ? 0 : JSHandle<TaggedArray>::Cast(preArgs)->GetLength(); 29944514f5e3Sopenharmony_ci const uint32_t argsCount = args->GetLength(); 29954514f5e3Sopenharmony_ci uint32_t size = preArgsSize + argsCount; 29964514f5e3Sopenharmony_ci CVector<JSTaggedType> values; 29974514f5e3Sopenharmony_ci bool isCompiledCode = ctor->IsCompiledCode(); 29984514f5e3Sopenharmony_ci if (isCompiledCode) { 29994514f5e3Sopenharmony_ci if (ctor->IsCompiledFastCall()) { 30004514f5e3Sopenharmony_ci values.reserve(size + NUM_MANDATORY_JSFUNC_ARGS - 1); 30014514f5e3Sopenharmony_ci values.emplace_back(ctor.GetTaggedValue().GetRawData()); 30024514f5e3Sopenharmony_ci values.emplace_back(obj.GetTaggedValue().GetRawData()); 30034514f5e3Sopenharmony_ci } else { 30044514f5e3Sopenharmony_ci values.reserve(size + NUM_MANDATORY_JSFUNC_ARGS); 30054514f5e3Sopenharmony_ci values.emplace_back(ctor.GetTaggedValue().GetRawData()); 30064514f5e3Sopenharmony_ci values.emplace_back(newTgt.GetTaggedValue().GetRawData()); 30074514f5e3Sopenharmony_ci values.emplace_back(obj.GetTaggedValue().GetRawData()); 30084514f5e3Sopenharmony_ci } 30094514f5e3Sopenharmony_ci } else { 30104514f5e3Sopenharmony_ci values.reserve(size); 30114514f5e3Sopenharmony_ci } 30124514f5e3Sopenharmony_ci 30134514f5e3Sopenharmony_ci if (preArgsSize > 0) { 30144514f5e3Sopenharmony_ci JSHandle<TaggedArray> tgaPreArgs = JSHandle<TaggedArray>::Cast(preArgs); 30154514f5e3Sopenharmony_ci for (uint32_t i = 0; i < preArgsSize; ++i) { 30164514f5e3Sopenharmony_ci JSTaggedValue value = tgaPreArgs->Get(i); 30174514f5e3Sopenharmony_ci values.emplace_back(value.GetRawData()); 30184514f5e3Sopenharmony_ci } 30194514f5e3Sopenharmony_ci for (uint32_t i = 0; i < argsCount; ++i) { 30204514f5e3Sopenharmony_ci values.emplace_back(args->Get(i).GetRawData()); 30214514f5e3Sopenharmony_ci } 30224514f5e3Sopenharmony_ci } else { 30234514f5e3Sopenharmony_ci for (uint32_t i = 0; i < argsCount; ++i) { 30244514f5e3Sopenharmony_ci values.emplace_back(args->Get(i).GetRawData()); 30254514f5e3Sopenharmony_ci } 30264514f5e3Sopenharmony_ci } 30274514f5e3Sopenharmony_ci JSTaggedValue resultValue = RuntimeStubs::GetResultValue(thread, isCompiledCode, ctor, values, newTgt, size, obj); 30284514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 30294514f5e3Sopenharmony_ci // 9.3.2 [[Construct]] (argumentsList, newTarget) 30304514f5e3Sopenharmony_ci if (resultValue.IsECMAObject()) { 30314514f5e3Sopenharmony_ci if (resultValue.IsJSShared()) { 30324514f5e3Sopenharmony_ci JSObject::Cast(resultValue.GetTaggedObject())->GetJSHClass()->SetExtensible(false); 30334514f5e3Sopenharmony_ci } 30344514f5e3Sopenharmony_ci return resultValue; 30354514f5e3Sopenharmony_ci } 30364514f5e3Sopenharmony_ci 30374514f5e3Sopenharmony_ci if (ctor->IsBase()) { 30384514f5e3Sopenharmony_ci return obj.GetTaggedValue(); 30394514f5e3Sopenharmony_ci } 30404514f5e3Sopenharmony_ci if (!resultValue.IsUndefined()) { 30414514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "function is non-constructor", JSTaggedValue::Exception()); 30424514f5e3Sopenharmony_ci } 30434514f5e3Sopenharmony_ci return obj.GetTaggedValue(); 30444514f5e3Sopenharmony_ci} 30454514f5e3Sopenharmony_ci 30464514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptNewObjRange(JSThread *thread, uintptr_t argv, uint32_t argc) 30474514f5e3Sopenharmony_ci{ 30484514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> ctor = GetHArg<JSTaggedValue>(argv, argc, 0); 30494514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined(); 30504514f5e3Sopenharmony_ci const size_t firstArgOffset = 1; 30514514f5e3Sopenharmony_ci ASSERT(argc > 0); 30524514f5e3Sopenharmony_ci size_t arrLength = argc - firstArgOffset; 30534514f5e3Sopenharmony_ci JSHandle<TaggedArray> args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(arrLength); 30544514f5e3Sopenharmony_ci for (size_t i = 0; i < arrLength; ++i) { 30554514f5e3Sopenharmony_ci args->Set(thread, i, GetArg(argv, argc, i + firstArgOffset)); 30564514f5e3Sopenharmony_ci } 30574514f5e3Sopenharmony_ci JSTaggedValue object = RuntimeOptConstruct(thread, ctor, ctor, undefined, args); 30584514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 30594514f5e3Sopenharmony_ci if (!object.IsUndefined() && !object.IsECMAObject() && !JSHandle<JSFunction>(ctor)->IsBase()) { 30604514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "Derived constructor must return object or undefined", 30614514f5e3Sopenharmony_ci JSTaggedValue::Exception()); 30624514f5e3Sopenharmony_ci } 30634514f5e3Sopenharmony_ci return object; 30644514f5e3Sopenharmony_ci} 30654514f5e3Sopenharmony_ci 30664514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeOptGenerateScopeInfo(JSThread *thread, uint16_t scopeId, JSTaggedValue func) 30674514f5e3Sopenharmony_ci{ 30684514f5e3Sopenharmony_ci EcmaVM *ecmaVm = thread->GetEcmaVM(); 30694514f5e3Sopenharmony_ci ObjectFactory *factory = ecmaVm->GetFactory(); 30704514f5e3Sopenharmony_ci Method *method = ECMAObject::Cast(func.GetTaggedObject())->GetCallTarget(); 30714514f5e3Sopenharmony_ci const JSPandaFile *jsPandaFile = method->GetJSPandaFile(); 30724514f5e3Sopenharmony_ci JSHandle<ConstantPool> constpool(thread, method->GetConstantPool()); 30734514f5e3Sopenharmony_ci panda_file::File::EntityId id = constpool->GetEntityId(scopeId); 30744514f5e3Sopenharmony_ci JSHandle<TaggedArray> elementsLiteral = 30754514f5e3Sopenharmony_ci LiteralDataExtractor::GetDatasIgnoreType(thread, jsPandaFile, id, constpool); 30764514f5e3Sopenharmony_ci 30774514f5e3Sopenharmony_ci ASSERT(elementsLiteral->GetLength() > 0); 30784514f5e3Sopenharmony_ci 30794514f5e3Sopenharmony_ci auto *scopeDebugInfo = ecmaVm->GetNativeAreaAllocator()->New<ScopeDebugInfo>(); 30804514f5e3Sopenharmony_ci if (scopeDebugInfo == nullptr) { 30814514f5e3Sopenharmony_ci return JSTaggedValue::Hole(); 30824514f5e3Sopenharmony_ci } 30834514f5e3Sopenharmony_ci 30844514f5e3Sopenharmony_ci size_t length = elementsLiteral->GetLength(); 30854514f5e3Sopenharmony_ci for (size_t i = 1; i < length; i += 2) { // 2: Each literal buffer contains a pair of key-value. 30864514f5e3Sopenharmony_ci JSTaggedValue val = elementsLiteral->Get(i); 30874514f5e3Sopenharmony_ci ASSERT(val.IsString()); 30884514f5e3Sopenharmony_ci CString name = ConvertToString(EcmaString::Cast(val.GetTaggedObject())); 30894514f5e3Sopenharmony_ci int32_t slot = elementsLiteral->Get(i + 1).GetInt(); 30904514f5e3Sopenharmony_ci scopeDebugInfo->scopeInfo.emplace(name, slot); 30914514f5e3Sopenharmony_ci } 30924514f5e3Sopenharmony_ci 30934514f5e3Sopenharmony_ci JSHandle<JSNativePointer> pointer = factory->NewJSNativePointer( 30944514f5e3Sopenharmony_ci scopeDebugInfo, NativeAreaAllocator::FreeObjectFunc<ScopeDebugInfo>, ecmaVm->GetNativeAreaAllocator()); 30954514f5e3Sopenharmony_ci return pointer.GetTaggedValue(); 30964514f5e3Sopenharmony_ci} 30974514f5e3Sopenharmony_ci 30984514f5e3Sopenharmony_ciJSTaggedType *RuntimeStubs::GetActualArgv(JSThread *thread) 30994514f5e3Sopenharmony_ci{ 31004514f5e3Sopenharmony_ci JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame()); 31014514f5e3Sopenharmony_ci FrameIterator it(current, thread); 31024514f5e3Sopenharmony_ci ASSERT(it.IsLeaveFrame()); 31034514f5e3Sopenharmony_ci it.Advance<GCVisitedFlag::VISITED>(); 31044514f5e3Sopenharmony_ci ASSERT(it.IsAotOrJitFunctionFrame()); 31054514f5e3Sopenharmony_ci if (it.IsFastJitFunctionFrame()) { 31064514f5e3Sopenharmony_ci auto optimizedJSJITFunctionFrame = it.GetFrame<FASTJITFunctionFrame>(); 31074514f5e3Sopenharmony_ci return optimizedJSJITFunctionFrame->GetArgv(it); 31084514f5e3Sopenharmony_ci } else { 31094514f5e3Sopenharmony_ci auto optimizedJSFunctionFrame = it.GetFrame<OptimizedJSFunctionFrame>(); 31104514f5e3Sopenharmony_ci return optimizedJSFunctionFrame->GetArgv(it); 31114514f5e3Sopenharmony_ci } 31124514f5e3Sopenharmony_ci} 31134514f5e3Sopenharmony_ci 31144514f5e3Sopenharmony_ciJSTaggedType *RuntimeStubs::GetActualArgvFromStub(JSThread *thread) 31154514f5e3Sopenharmony_ci{ 31164514f5e3Sopenharmony_ci JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame()); 31174514f5e3Sopenharmony_ci FrameIterator it(current, thread); 31184514f5e3Sopenharmony_ci ASSERT(it.IsLeaveFrame()); 31194514f5e3Sopenharmony_ci it.Advance<GCVisitedFlag::VISITED>(); 31204514f5e3Sopenharmony_ci ASSERT(it.IsOptimizedFrame()); 31214514f5e3Sopenharmony_ci it.Advance<GCVisitedFlag::VISITED>(); 31224514f5e3Sopenharmony_ci ASSERT(it.IsAotOrJitFunctionFrame()); 31234514f5e3Sopenharmony_ci if (it.IsFastJitFunctionFrame()) { 31244514f5e3Sopenharmony_ci auto optimizedJSJITFunctionFrame = it.GetFrame<FASTJITFunctionFrame>(); 31254514f5e3Sopenharmony_ci return optimizedJSJITFunctionFrame->GetArgv(it); 31264514f5e3Sopenharmony_ci } 31274514f5e3Sopenharmony_ci auto optimizedJSFunctionFrame = it.GetFrame<OptimizedJSFunctionFrame>(); 31284514f5e3Sopenharmony_ci return optimizedJSFunctionFrame->GetArgv(it); 31294514f5e3Sopenharmony_ci} 31304514f5e3Sopenharmony_ci 31314514f5e3Sopenharmony_ciOptimizedJSFunctionFrame *RuntimeStubs::GetOptimizedJSFunctionFrame(JSThread *thread) 31324514f5e3Sopenharmony_ci{ 31334514f5e3Sopenharmony_ci JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame()); 31344514f5e3Sopenharmony_ci FrameIterator it(current, thread); 31354514f5e3Sopenharmony_ci ASSERT(it.IsLeaveFrame()); 31364514f5e3Sopenharmony_ci it.Advance(); 31374514f5e3Sopenharmony_ci ASSERT(it.IsOptimizedJSFunctionFrame()); 31384514f5e3Sopenharmony_ci return it.GetFrame<OptimizedJSFunctionFrame>(); 31394514f5e3Sopenharmony_ci} 31404514f5e3Sopenharmony_ci 31414514f5e3Sopenharmony_ciOptimizedJSFunctionFrame *RuntimeStubs::GetOptimizedJSFunctionFrameNoGC(JSThread *thread) 31424514f5e3Sopenharmony_ci{ 31434514f5e3Sopenharmony_ci JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame()); 31444514f5e3Sopenharmony_ci FrameIterator it(current, thread); 31454514f5e3Sopenharmony_ci ASSERT(it.IsOptimizedFrame()); 31464514f5e3Sopenharmony_ci it.Advance(); 31474514f5e3Sopenharmony_ci ASSERT(it.IsOptimizedJSFunctionFrame()); 31484514f5e3Sopenharmony_ci return it.GetFrame<OptimizedJSFunctionFrame>(); 31494514f5e3Sopenharmony_ci} 31504514f5e3Sopenharmony_ci 31514514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeLdPatchVar(JSThread *thread, uint32_t index) 31524514f5e3Sopenharmony_ci{ 31534514f5e3Sopenharmony_ci JSHandle<TaggedArray> globalPatch = 31544514f5e3Sopenharmony_ci JSHandle<TaggedArray>::Cast(thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalPatch()); 31554514f5e3Sopenharmony_ci 31564514f5e3Sopenharmony_ci return globalPatch->Get(thread, index); 31574514f5e3Sopenharmony_ci} 31584514f5e3Sopenharmony_ci 31594514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeStPatchVar(JSThread *thread, uint32_t index, const JSHandle<JSTaggedValue> &value) 31604514f5e3Sopenharmony_ci{ 31614514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 31624514f5e3Sopenharmony_ci 31634514f5e3Sopenharmony_ci JSHandle<TaggedArray> globalPatch = JSHandle<TaggedArray>::Cast(env->GetGlobalPatch()); 31644514f5e3Sopenharmony_ci if (index >= globalPatch->GetLength()) { 31654514f5e3Sopenharmony_ci globalPatch = TaggedArray::SetCapacity(thread, globalPatch, index + 1); 31664514f5e3Sopenharmony_ci } 31674514f5e3Sopenharmony_ci globalPatch->Set(thread, index, value); 31684514f5e3Sopenharmony_ci env->SetGlobalPatch(thread, globalPatch.GetTaggedValue()); 31694514f5e3Sopenharmony_ci return JSTaggedValue::True(); 31704514f5e3Sopenharmony_ci} 31714514f5e3Sopenharmony_ci 31724514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNotifyConcurrentResult(JSThread *thread, JSTaggedValue result, JSTaggedValue hint) 31734514f5e3Sopenharmony_ci{ 31744514f5e3Sopenharmony_ci thread->GetEcmaVM()->TriggerConcurrentCallback(result, hint); 31754514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 31764514f5e3Sopenharmony_ci} 31774514f5e3Sopenharmony_ci 31784514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeUpdateAOTHClass(JSThread *thread, 31794514f5e3Sopenharmony_ci const JSHandle<JSHClass> &oldhclass, const JSHandle<JSHClass> &newhclass, JSTaggedValue key) 31804514f5e3Sopenharmony_ci{ 31814514f5e3Sopenharmony_ci#if ECMASCRIPT_ENABLE_IC 31824514f5e3Sopenharmony_ci if (JSHClass::IsNeedNotifyHclassChangedForAotTransition(thread, oldhclass, key)) { 31834514f5e3Sopenharmony_ci JSHClass::NotifyHclassChanged(thread, oldhclass, newhclass, key); 31844514f5e3Sopenharmony_ci } else { 31854514f5e3Sopenharmony_ci JSHClass::RefreshUsers(thread, oldhclass, newhclass); 31864514f5e3Sopenharmony_ci } 31874514f5e3Sopenharmony_ci JSHClass::EnablePHCProtoChangeMarker(thread, newhclass); 31884514f5e3Sopenharmony_ci#endif 31894514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 31904514f5e3Sopenharmony_ci} 31914514f5e3Sopenharmony_ci 31924514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeDefineField(JSThread *thread, JSTaggedValue obj, 31934514f5e3Sopenharmony_ci JSTaggedValue propKey, JSTaggedValue value) 31944514f5e3Sopenharmony_ci{ 31954514f5e3Sopenharmony_ci // Do the same thing as Object.defineProperty(obj, propKey, {value: value, 31964514f5e3Sopenharmony_ci // writable:true, enumerable: true, configurable: true}) 31974514f5e3Sopenharmony_ci if (!obj.IsECMAObject()) { 31984514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "DefineField: obj is not Object", JSTaggedValue::Exception()); 31994514f5e3Sopenharmony_ci } 32004514f5e3Sopenharmony_ci JSHandle<JSObject> handleObj(thread, obj); 32014514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleValue(thread, value); 32024514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleKey = JSTaggedValue::ToPropertyKey(thread, JSHandle<JSTaggedValue>(thread, propKey)); 32034514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 32044514f5e3Sopenharmony_ci 32054514f5e3Sopenharmony_ci JSObject::CreateDataPropertyOrThrow(thread, handleObj, handleKey, handleValue, SCheckMode::CHECK); 32064514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 32074514f5e3Sopenharmony_ci 32084514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 32094514f5e3Sopenharmony_ci} 32104514f5e3Sopenharmony_ci 32114514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeCreatePrivateProperty(JSThread *thread, JSTaggedValue lexicalEnv, 32124514f5e3Sopenharmony_ci uint32_t count, JSTaggedValue constpool, uint32_t literalId, JSTaggedValue module) 32134514f5e3Sopenharmony_ci{ 32144514f5e3Sopenharmony_ci ObjectFactory* factory = thread->GetEcmaVM()->GetFactory(); 32154514f5e3Sopenharmony_ci JSHandle<LexicalEnv> handleLexicalEnv(thread, lexicalEnv); 32164514f5e3Sopenharmony_ci JSHandle<ConstantPool> handleConstpool(thread, constpool); 32174514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleModule(thread, module); 32184514f5e3Sopenharmony_ci JSHandle<ConstantPool> unsharedConstpoolHandle( 32194514f5e3Sopenharmony_ci thread, thread->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(constpool)); 32204514f5e3Sopenharmony_ci CString entry = ModuleManager::GetRecordName(handleModule.GetTaggedValue()); 32214514f5e3Sopenharmony_ci uint32_t length = handleLexicalEnv->GetLength() - LexicalEnv::RESERVED_ENV_LENGTH; 32224514f5e3Sopenharmony_ci uint32_t startIndex = 0; 32234514f5e3Sopenharmony_ci while (startIndex < length && !handleLexicalEnv->GetProperties(startIndex).IsHole()) { 32244514f5e3Sopenharmony_ci startIndex++; 32254514f5e3Sopenharmony_ci } 32264514f5e3Sopenharmony_ci 32274514f5e3Sopenharmony_ci JSTaggedValue aotSymbolInfo = unsharedConstpoolHandle->GetAotSymbolInfo(); 32284514f5e3Sopenharmony_ci JSHandle<TaggedArray> aotSymbolInfoHandle(thread, aotSymbolInfo); 32294514f5e3Sopenharmony_ci FrameHandler frameHandler(thread); 32304514f5e3Sopenharmony_ci uint32_t abcId = frameHandler.GetAbcId(); 32314514f5e3Sopenharmony_ci ASSERT(startIndex + count <= length); 32324514f5e3Sopenharmony_ci for (uint32_t i = 0; i < count; i++) { 32334514f5e3Sopenharmony_ci auto index = startIndex + i; 32344514f5e3Sopenharmony_ci uint64_t id = JSSymbol::GeneratePrivateId(abcId, literalId, index); 32354514f5e3Sopenharmony_ci JSHandle<JSSymbol> symbolHandle; 32364514f5e3Sopenharmony_ci JSTaggedValue symbol = ConstantPool::GetSymbolFromSymbolInfo(aotSymbolInfoHandle, id); 32374514f5e3Sopenharmony_ci if (ConstantPool::IsAotSymbolInfoExist(aotSymbolInfoHandle, symbol)) { 32384514f5e3Sopenharmony_ci symbolHandle = JSHandle<JSSymbol>(thread, symbol); 32394514f5e3Sopenharmony_ci } else { 32404514f5e3Sopenharmony_ci symbolHandle = factory->NewJSSymbol(); 32414514f5e3Sopenharmony_ci symbolHandle->SetPrivateId(id); 32424514f5e3Sopenharmony_ci symbolHandle->SetPrivate(); 32434514f5e3Sopenharmony_ci } 32444514f5e3Sopenharmony_ci handleLexicalEnv->SetProperties(thread, index, symbolHandle.GetTaggedValue()); 32454514f5e3Sopenharmony_ci } 32464514f5e3Sopenharmony_ci 32474514f5e3Sopenharmony_ci JSTaggedValue literalObj = 32484514f5e3Sopenharmony_ci ConstantPool::GetClassLiteralFromCache(thread, unsharedConstpoolHandle, literalId, entry); 32494514f5e3Sopenharmony_ci JSHandle<ClassLiteral> classLiteral(thread, literalObj); 32504514f5e3Sopenharmony_ci JSHandle<TaggedArray> literalBuffer(thread, classLiteral->GetArray()); 32514514f5e3Sopenharmony_ci uint32_t literalBufferLength = literalBuffer->GetLength(); 32524514f5e3Sopenharmony_ci if (literalBufferLength == 0) { 32534514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 32544514f5e3Sopenharmony_ci } 32554514f5e3Sopenharmony_ci // instace property number is hidden in the last index of literal buffer 32564514f5e3Sopenharmony_ci uint32_t instacePropertyCount = static_cast<uint32_t>(literalBuffer->Get(literalBufferLength - 1).GetInt()); 32574514f5e3Sopenharmony_ci ASSERT(startIndex + count + literalBufferLength - (instacePropertyCount == 0) <= length); 32584514f5e3Sopenharmony_ci 32594514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> literalValue(thread, JSTaggedValue::Undefined()); 32604514f5e3Sopenharmony_ci for (uint32_t i = 0; i < literalBufferLength - 1; i++) { 32614514f5e3Sopenharmony_ci literalValue.Update(literalBuffer->Get(i)); 32624514f5e3Sopenharmony_ci if (LIKELY(literalValue->IsFunctionTemplate())) { 32634514f5e3Sopenharmony_ci auto literalFunc = JSHandle<FunctionTemplate>::Cast(literalValue); 32644514f5e3Sopenharmony_ci JSHandle<JSFunction> func = factory->CreateJSFunctionFromTemplate(literalFunc); 32654514f5e3Sopenharmony_ci func->SetLexicalEnv(thread, handleLexicalEnv.GetTaggedValue()); 32664514f5e3Sopenharmony_ci func->SetModule(thread, handleModule.GetTaggedValue()); 32674514f5e3Sopenharmony_ci literalValue.Update(func); 32684514f5e3Sopenharmony_ci } 32694514f5e3Sopenharmony_ci handleLexicalEnv->SetProperties(thread, startIndex + count + i, literalValue.GetTaggedValue()); 32704514f5e3Sopenharmony_ci } 32714514f5e3Sopenharmony_ci if (instacePropertyCount > 0) { 32724514f5e3Sopenharmony_ci auto index = startIndex + count + literalBufferLength - 1; 32734514f5e3Sopenharmony_ci uint64_t id = JSSymbol::GeneratePrivateId(abcId, literalId, index); 32744514f5e3Sopenharmony_ci JSHandle<JSSymbol> symbolHandle; 32754514f5e3Sopenharmony_ci JSTaggedValue symbol = ConstantPool::GetSymbolFromSymbolInfo(aotSymbolInfoHandle, id); 32764514f5e3Sopenharmony_ci if (ConstantPool::IsAotSymbolInfoExist(aotSymbolInfoHandle, symbol)) { 32774514f5e3Sopenharmony_ci symbolHandle = JSHandle<JSSymbol>(thread, symbol); 32784514f5e3Sopenharmony_ci } else { 32794514f5e3Sopenharmony_ci symbolHandle = factory->NewPublicSymbolWithChar("method"); 32804514f5e3Sopenharmony_ci symbolHandle->SetPrivateId(id); 32814514f5e3Sopenharmony_ci symbolHandle->SetPrivate(); 32824514f5e3Sopenharmony_ci } 32834514f5e3Sopenharmony_ci handleLexicalEnv->SetProperties(thread, index, symbolHandle.GetTaggedValue()); 32844514f5e3Sopenharmony_ci } 32854514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 32864514f5e3Sopenharmony_ci} 32874514f5e3Sopenharmony_ci 32884514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeDefinePrivateProperty(JSThread *thread, JSTaggedValue lexicalEnv, 32894514f5e3Sopenharmony_ci uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj, JSTaggedValue value) 32904514f5e3Sopenharmony_ci{ 32914514f5e3Sopenharmony_ci JSTaggedValue currentLexicalEnv = lexicalEnv; 32924514f5e3Sopenharmony_ci for (uint32_t i = 0; i < levelIndex; i++) { 32934514f5e3Sopenharmony_ci currentLexicalEnv = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetParentEnv(); 32944514f5e3Sopenharmony_ci ASSERT(!currentLexicalEnv.IsUndefined()); 32954514f5e3Sopenharmony_ci } 32964514f5e3Sopenharmony_ci JSTaggedValue key = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetProperties(slotIndex); 32974514f5e3Sopenharmony_ci // private property is invisible for proxy 32984514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleObj(thread, obj.IsJSProxy() ? JSProxy::Cast(obj)->GetPrivateField() : obj); 32994514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleKey(thread, key); 33004514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> handleValue(thread, value); 33014514f5e3Sopenharmony_ci PropertyDescriptor desc(thread); 33024514f5e3Sopenharmony_ci if (!JSTaggedValue::IsPropertyKey(handleKey) && 33034514f5e3Sopenharmony_ci JSTaggedValue::GetOwnProperty(thread, handleObj, handleKey, desc)) { 33044514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "invalid private key or already exists", JSTaggedValue::Exception()); 33054514f5e3Sopenharmony_ci } 33064514f5e3Sopenharmony_ci bool extensible = handleObj->IsExtensible(thread); 33074514f5e3Sopenharmony_ci if (handleObj->IsUndefined()) { 33084514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "DefinePrivateProperty obj is undefined", JSTaggedValue::Exception()); 33094514f5e3Sopenharmony_ci } 33104514f5e3Sopenharmony_ci if (handleObj->IsJSShared()) { 33114514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "shared obj cannot use # to define private property", 33124514f5e3Sopenharmony_ci JSTaggedValue::Exception()); 33134514f5e3Sopenharmony_ci } 33144514f5e3Sopenharmony_ci if (!extensible) { 33154514f5e3Sopenharmony_ci // private key should be always extensible 33164514f5e3Sopenharmony_ci handleObj->GetTaggedObject()->GetClass()->SetExtensible(true); 33174514f5e3Sopenharmony_ci } 33184514f5e3Sopenharmony_ci bool result = JSObject::CreateDataPropertyOrThrow(thread, JSHandle<JSObject>::Cast(handleObj), 33194514f5e3Sopenharmony_ci handleKey, handleValue); 33204514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 33214514f5e3Sopenharmony_ci if (!extensible) { 33224514f5e3Sopenharmony_ci handleObj->GetTaggedObject()->GetClass()->SetExtensible(false); 33234514f5e3Sopenharmony_ci } 33244514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 33254514f5e3Sopenharmony_ci return JSTaggedValue(result); 33264514f5e3Sopenharmony_ci} 33274514f5e3Sopenharmony_ci 33284514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::RuntimeNotifyDebuggerStatement(JSThread *thread) 33294514f5e3Sopenharmony_ci{ 33304514f5e3Sopenharmony_ci FrameHandler frameHandler(thread); 33314514f5e3Sopenharmony_ci for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) { 33324514f5e3Sopenharmony_ci if (frameHandler.IsEntryFrame() || frameHandler.IsBuiltinFrame()) { 33334514f5e3Sopenharmony_ci continue; 33344514f5e3Sopenharmony_ci } 33354514f5e3Sopenharmony_ci Method *method = frameHandler.GetMethod(); 33364514f5e3Sopenharmony_ci if (method->IsNativeWithCallField()) { 33374514f5e3Sopenharmony_ci continue; 33384514f5e3Sopenharmony_ci } 33394514f5e3Sopenharmony_ci auto bcOffset = frameHandler.GetBytecodeOffset(); 33404514f5e3Sopenharmony_ci auto *debuggerMgr = thread->GetEcmaVM()->GetJsDebuggerManager(); 33414514f5e3Sopenharmony_ci debuggerMgr->GetNotificationManager()->DebuggerStmtEvent(thread, method, bcOffset); 33424514f5e3Sopenharmony_ci return JSTaggedValue::Hole(); 33434514f5e3Sopenharmony_ci } 33444514f5e3Sopenharmony_ci return JSTaggedValue::Hole(); 33454514f5e3Sopenharmony_ci} 33464514f5e3Sopenharmony_ci 33474514f5e3Sopenharmony_cibool RuntimeStubs::CheckElementsNumber(JSHandle<TaggedArray> elements, uint32_t len) 33484514f5e3Sopenharmony_ci{ 33494514f5e3Sopenharmony_ci ASSERT(len <= elements->GetLength()); 33504514f5e3Sopenharmony_ci for (uint32_t i = 0; i < len; i++) { 33514514f5e3Sopenharmony_ci if (!elements->Get(i).IsNumber()) { 33524514f5e3Sopenharmony_ci return false; 33534514f5e3Sopenharmony_ci } 33544514f5e3Sopenharmony_ci } 33554514f5e3Sopenharmony_ci return true; 33564514f5e3Sopenharmony_ci} 33574514f5e3Sopenharmony_ci 33584514f5e3Sopenharmony_ciJSHandle<JSTaggedValue> RuntimeStubs::GetOrCreateNumberString(JSThread *thread, JSHandle<JSTaggedValue> presentValue, 33594514f5e3Sopenharmony_ci std::map<uint64_t, JSHandle<JSTaggedValue>> &cachedString) 33604514f5e3Sopenharmony_ci{ 33614514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> presentString(thread, JSTaggedValue::Undefined()); 33624514f5e3Sopenharmony_ci auto iter = cachedString.find(presentValue->GetRawData()); 33634514f5e3Sopenharmony_ci if (iter != cachedString.end()) { 33644514f5e3Sopenharmony_ci presentString.Update(iter->second); 33654514f5e3Sopenharmony_ci } else { 33664514f5e3Sopenharmony_ci presentString.Update(JSTaggedValue::ToString(thread, presentValue).GetTaggedValue()); 33674514f5e3Sopenharmony_ci cachedString[presentValue->GetRawData()] = presentString; 33684514f5e3Sopenharmony_ci } 33694514f5e3Sopenharmony_ci return presentString; 33704514f5e3Sopenharmony_ci} 33714514f5e3Sopenharmony_ci 33724514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::TryCopyCOWArray(JSThread *thread, JSHandle<JSArray> holderHandler, bool &isCOWArray) 33734514f5e3Sopenharmony_ci{ 33744514f5e3Sopenharmony_ci if (isCOWArray) { 33754514f5e3Sopenharmony_ci JSArray::CheckAndCopyArray(thread, holderHandler); 33764514f5e3Sopenharmony_ci isCOWArray = false; 33774514f5e3Sopenharmony_ci } 33784514f5e3Sopenharmony_ci return holderHandler->GetElements(); 33794514f5e3Sopenharmony_ci} 33804514f5e3Sopenharmony_ci 33814514f5e3Sopenharmony_ciJSTaggedValue RuntimeStubs::ArrayNumberSort(JSThread *thread, JSHandle<JSObject> thisObj, uint32_t len) 33824514f5e3Sopenharmony_ci{ 33834514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> presentValue(thread, JSTaggedValue::Undefined()); 33844514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> middleValue(thread, JSTaggedValue::Undefined()); 33854514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> previousValue(thread, JSTaggedValue::Undefined()); 33864514f5e3Sopenharmony_ci bool isCOWArray = JSHandle<JSTaggedValue>(thisObj)->IsJSCOWArray(); 33874514f5e3Sopenharmony_ci JSMutableHandle<TaggedArray> elements(thread, thisObj->GetElements()); 33884514f5e3Sopenharmony_ci std::map<uint64_t, JSHandle<JSTaggedValue>> cachedString; 33894514f5e3Sopenharmony_ci for (uint32_t i = 1; i < len; i++) { 33904514f5e3Sopenharmony_ci uint32_t beginIndex = 0; 33914514f5e3Sopenharmony_ci uint32_t endIndex = i; 33924514f5e3Sopenharmony_ci presentValue.Update(elements->Get(i)); 33934514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> presentString = GetOrCreateNumberString(thread, presentValue, cachedString); 33944514f5e3Sopenharmony_ci while (beginIndex < endIndex) { 33954514f5e3Sopenharmony_ci uint32_t middleIndex = beginIndex + (endIndex - beginIndex) / 2; // 2 : half 33964514f5e3Sopenharmony_ci middleValue.Update(elements->Get(middleIndex)); 33974514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> middleString = GetOrCreateNumberString(thread, middleValue, cachedString); 33984514f5e3Sopenharmony_ci double compareResult = ArrayHelper::StringSortCompare(thread, middleString, presentString); 33994514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 34004514f5e3Sopenharmony_ci if (compareResult > 0) { 34014514f5e3Sopenharmony_ci endIndex = middleIndex; 34024514f5e3Sopenharmony_ci } else { 34034514f5e3Sopenharmony_ci beginIndex = middleIndex + 1; 34044514f5e3Sopenharmony_ci } 34054514f5e3Sopenharmony_ci } 34064514f5e3Sopenharmony_ci if (endIndex >= 0 && endIndex < i) { 34074514f5e3Sopenharmony_ci for (uint32_t j = i; j > endIndex; j--) { 34084514f5e3Sopenharmony_ci previousValue.Update(elements->Get(j - 1)); 34094514f5e3Sopenharmony_ci elements.Update(TryCopyCOWArray(thread, JSHandle<JSArray>(thisObj), isCOWArray)); 34104514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 34114514f5e3Sopenharmony_ci elements->Set(thread, j, previousValue); 34124514f5e3Sopenharmony_ci } 34134514f5e3Sopenharmony_ci elements.Update(TryCopyCOWArray(thread, JSHandle<JSArray>(thisObj), isCOWArray)); 34144514f5e3Sopenharmony_ci RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); 34154514f5e3Sopenharmony_ci elements->Set(thread, endIndex, presentValue); 34164514f5e3Sopenharmony_ci } 34174514f5e3Sopenharmony_ci } 34184514f5e3Sopenharmony_ci return thisObj.GetTaggedValue(); 34194514f5e3Sopenharmony_ci} 34204514f5e3Sopenharmony_ci 34214514f5e3Sopenharmony_ciJSTaggedType RuntimeStubs::RuntimeTryGetInternString(uintptr_t argGlue, const JSHandle<EcmaString> &string) 34224514f5e3Sopenharmony_ci{ 34234514f5e3Sopenharmony_ci auto thread = JSThread::GlueToJSThread(argGlue); 34244514f5e3Sopenharmony_ci EcmaString *str = 34254514f5e3Sopenharmony_ci thread->GetEcmaVM()->GetEcmaStringTable()->TryGetInternString(thread, string); 34264514f5e3Sopenharmony_ci if (str == nullptr) { 34274514f5e3Sopenharmony_ci return JSTaggedValue::Hole().GetRawData(); 34284514f5e3Sopenharmony_ci } 34294514f5e3Sopenharmony_ci return JSTaggedValue::Cast(static_cast<void *>(str)); 34304514f5e3Sopenharmony_ci} 34314514f5e3Sopenharmony_ci 34324514f5e3Sopenharmony_ciuint32_t RuntimeStubs::RuntimeGetBytecodePcOfstForBaseline(const JSHandle<JSFunction> &func, uintptr_t nativePc) 34334514f5e3Sopenharmony_ci{ 34344514f5e3Sopenharmony_ci // Compute current bytecodePc according to nativePc of returnAddress 34354514f5e3Sopenharmony_ci LOG_BASELINEJIT(DEBUG) << "nativePc address: " << std::hex << nativePc; 34364514f5e3Sopenharmony_ci const MachineCode *machineCode = MachineCode::Cast(func->GetBaselineCode().GetTaggedObject()); 34374514f5e3Sopenharmony_ci const uintptr_t nativePcStart = machineCode->GetFuncAddr(); 34384514f5e3Sopenharmony_ci LOG_BASELINEJIT(DEBUG) << "baselineCode nativeStart address: " << std::hex << nativePcStart; 34394514f5e3Sopenharmony_ci const Method *thisMethod = Method::Cast(func->GetMethod().GetTaggedObject()); 34404514f5e3Sopenharmony_ci const uint8_t *bytecodeStart = thisMethod->GetBytecodeArray(); 34414514f5e3Sopenharmony_ci const uint8_t *bytecodeEnd = bytecodeStart + thisMethod->GetCodeSize(); 34424514f5e3Sopenharmony_ci LOG_BASELINEJIT(DEBUG) << "bytecodePc start: " << reinterpret_cast<uintptr_t>(bytecodeStart); 34434514f5e3Sopenharmony_ci LOG_BASELINEJIT(DEBUG) << "bytecodePc end: " << reinterpret_cast<uintptr_t>(bytecodeEnd); 34444514f5e3Sopenharmony_ci const uint8_t *offsetTableAddr = machineCode->GetStackMapOrOffsetTableAddress(); 34454514f5e3Sopenharmony_ci const uint32_t offsetTableSize = machineCode->GetStackMapOrOffsetTableSize(); 34464514f5e3Sopenharmony_ci uintptr_t nativePcEnd = nativePcStart; 34474514f5e3Sopenharmony_ci uint32_t pcOffsetIndex = 0; 34484514f5e3Sopenharmony_ci auto opcode = kungfu::Bytecodes::GetOpcode(bytecodeStart); 34494514f5e3Sopenharmony_ci while (nativePcEnd < nativePc && pcOffsetIndex < offsetTableSize) { 34504514f5e3Sopenharmony_ci nativePcEnd += static_cast<uintptr_t>(offsetTableAddr[pcOffsetIndex++]); 34514514f5e3Sopenharmony_ci opcode = kungfu::Bytecodes::GetOpcode(bytecodeStart); 34524514f5e3Sopenharmony_ci bytecodeStart += BytecodeInstruction::Size(opcode); 34534514f5e3Sopenharmony_ci } 34544514f5e3Sopenharmony_ci // Since the nativePc is returnAddress, we need to take the previous bytecode 34554514f5e3Sopenharmony_ci bytecodeStart -= BytecodeInstruction::Size(opcode); 34564514f5e3Sopenharmony_ci if (nativePcEnd < nativePc) { 34574514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << 34584514f5e3Sopenharmony_ci "invalid nativePc or pcOffsetTable for getting bytecode pc in baseline code, the nativePcEnd is " << 34594514f5e3Sopenharmony_ci std::hex << nativePcEnd; 34604514f5e3Sopenharmony_ci } 34614514f5e3Sopenharmony_ci if (bytecodeStart > bytecodeEnd) { 34624514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << 34634514f5e3Sopenharmony_ci "out of bytecodeArray range for getting bytecode pc in baseline code, the bytecodePc is " << 34644514f5e3Sopenharmony_ci reinterpret_cast<uintptr_t>(bytecodeStart); 34654514f5e3Sopenharmony_ci } 34664514f5e3Sopenharmony_ci auto bytecodePcOffset = static_cast<uint32_t>(bytecodeStart - thisMethod->GetBytecodeArray()); 34674514f5e3Sopenharmony_ci LOG_BASELINEJIT(DEBUG) << "current bytecodePc offset: " << bytecodePcOffset; 34684514f5e3Sopenharmony_ci return bytecodePcOffset; 34694514f5e3Sopenharmony_ci} 34704514f5e3Sopenharmony_ci} // namespace panda::ecmascript 34714514f5e3Sopenharmony_ci#endif // ECMASCRIPT_STUBS_RUNTIME_STUBS_INL_H 3472