1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ECMASCRIPT_STUBS_RUNTIME_STUBS_INL_H
17 #define ECMASCRIPT_STUBS_RUNTIME_STUBS_INL_H
18 
19 #include "ecmascript/ecma_macros.h"
20 #include "ecmascript/js_tagged_value.h"
21 #include "ecmascript/stubs/runtime_stubs.h"
22 
23 #include "ecmascript/base/array_helper.h"
24 #include "ecmascript/builtins/builtins_regexp.h"
25 #include "ecmascript/compiler/aot_file/aot_file_manager.h"
26 #include "ecmascript/debugger/js_debugger_manager.h"
27 #include "ecmascript/ecma_string_table.h"
28 #include "ecmascript/global_dictionary-inl.h"
29 #include "ecmascript/global_env.h"
30 #include "ecmascript/ic/profile_type_info.h"
31 #include "ecmascript/interpreter/frame_handler.h"
32 #include "ecmascript/interpreter/interpreter.h"
33 #include "ecmascript/jobs/micro_job_queue.h"
34 #include "ecmascript/js_arguments.h"
35 #include "ecmascript/js_async_function.h"
36 #include "ecmascript/js_async_generator_object.h"
37 #include "ecmascript/js_bigint.h"
38 #include "ecmascript/js_for_in_iterator.h"
39 #include "ecmascript/js_generator_object.h"
40 #include "ecmascript/js_iterator.h"
41 #include "ecmascript/js_promise.h"
42 #include "ecmascript/jspandafile/class_info_extractor.h"
43 #include "ecmascript/jspandafile/literal_data_extractor.h"
44 #include "ecmascript/jspandafile/program_object.h"
45 #include "ecmascript/jspandafile/scope_info_extractor.h"
46 #include "ecmascript/message_string.h"
47 #include "ecmascript/module/js_module_manager.h"
48 #include "ecmascript/module/js_module_source_text.h"
49 #include "ecmascript/object_factory-inl.h"
50 #include "ecmascript/patch/quick_fix_helper.h"
51 #include "ecmascript/platform/file.h"
52 #include "ecmascript/runtime.h"
53 #include "ecmascript/stackmap/llvm/llvm_stackmap_parser.h"
54 #include "ecmascript/sendable_env.h"
55 #include "ecmascript/template_string.h"
56 
57 namespace panda::ecmascript {
58 using ArrayHelper = base::ArrayHelper;
RuntimeInc(JSThread *thread, const JSHandle<JSTaggedValue> &value)59 JSTaggedValue RuntimeStubs::RuntimeInc(JSThread *thread, const JSHandle<JSTaggedValue> &value)
60 {
61     JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value);
62     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
63     if (inputVal->IsBigInt()) {
64         JSHandle<BigInt> bigValue(inputVal);
65         return BigInt::BigintAddOne(thread, bigValue).GetTaggedValue();
66     }
67     JSTaggedNumber number(inputVal.GetTaggedValue());
68     return JSTaggedValue(++number);
69 }
70 
RuntimeDec(JSThread *thread, const JSHandle<JSTaggedValue> &value)71 JSTaggedValue RuntimeStubs::RuntimeDec(JSThread *thread, const JSHandle<JSTaggedValue> &value)
72 {
73     JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value);
74     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
75     if (inputVal->IsBigInt()) {
76         JSHandle<BigInt> bigValue(inputVal);
77         return BigInt::BigintSubOne(thread, bigValue).GetTaggedValue();
78     }
79     JSTaggedNumber number(inputVal.GetTaggedValue());
80     return JSTaggedValue(--number);
81 }
82 
RuntimeExp(JSThread *thread, JSTaggedValue base, JSTaggedValue exponent)83 JSTaggedValue RuntimeStubs::RuntimeExp(JSThread *thread, JSTaggedValue base, JSTaggedValue exponent)
84 {
85     JSHandle<JSTaggedValue> baseTag(thread, base);
86     JSHandle<JSTaggedValue> exponentTag(thread, exponent);
87     JSHandle<JSTaggedValue> valBase = JSTaggedValue::ToNumeric(thread, baseTag);
88     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
89     JSHandle<JSTaggedValue> valExponent = JSTaggedValue::ToNumeric(thread, exponentTag);
90     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
91     if (valBase->IsBigInt() || valExponent->IsBigInt()) {
92         if (valBase->IsBigInt() && valExponent->IsBigInt()) {
93             JSHandle<BigInt> bigBaseVale(valBase);
94             JSHandle<BigInt> bigExponentValue(valExponent);
95             return BigInt::Exponentiate(thread, bigBaseVale, bigExponentValue).GetTaggedValue();
96         }
97         THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot mix BigInt and other types, use explicit conversions",
98                                     JSTaggedValue::Exception());
99     }
100     double doubleBase = valBase->GetNumber();
101     double doubleExponent = valExponent->GetNumber();
102     if (std::abs(doubleBase) == 1 && std::isinf(doubleExponent)) {
103         return JSTaggedValue(base::NAN_VALUE);
104     }
105     if (((doubleBase == 0) &&
106         ((base::bit_cast<uint64_t>(doubleBase)) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) &&
107         std::isfinite(doubleExponent) && base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent &&
108         base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF == (doubleExponent / 2)) {  // 2: half
109         if (doubleExponent > 0) {
110             return JSTaggedValue(-0.0);
111         }
112         if (doubleExponent < 0) {
113             return JSTaggedValue(-base::POSITIVE_INFINITY);
114         }
115     }
116     return JSTaggedValue(std::pow(doubleBase, doubleExponent));
117 }
118 
RuntimeIsIn(JSThread *thread, const JSHandle<JSTaggedValue> &prop, const JSHandle<JSTaggedValue> &obj)119 JSTaggedValue RuntimeStubs::RuntimeIsIn(JSThread *thread, const JSHandle<JSTaggedValue> &prop,
120                                         const JSHandle<JSTaggedValue> &obj)
121 {
122     if (!obj->IsECMAObject()) {
123         return RuntimeThrowTypeError(thread, "Cannot use 'in' operator in Non-Object");
124     }
125     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop);
126     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
127     bool ret = JSTaggedValue::HasProperty(thread, obj, propKey);
128     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
129     return JSTaggedValue(ret);
130 }
131 
RuntimeInstanceof(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &target)132 JSTaggedValue RuntimeStubs::RuntimeInstanceof(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
133                                               const JSHandle<JSTaggedValue> &target)
134 {
135     bool ret = JSObject::InstanceOf(thread, obj, target);
136     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
137     return JSTaggedValue(ret);
138 }
139 
RuntimeInstanceofByHandler(JSThread *thread, JSHandle<JSTaggedValue> target, JSHandle<JSTaggedValue> object, JSHandle<JSTaggedValue> instOfHandler)140 JSTaggedValue RuntimeStubs::RuntimeInstanceofByHandler(JSThread *thread, JSHandle<JSTaggedValue> target,
141                                                        JSHandle<JSTaggedValue> object,
142                                                        JSHandle<JSTaggedValue> instOfHandler)
143 {
144     // 3. ReturnIfAbrupt(instOfHandler).
145     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
146     // 4. If instOfHandler is not undefined, then
147     if (!instOfHandler->IsUndefined()) {
148         // a. Return ! ToBoolean(? Call(instOfHandler, target, «object»)).
149         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
150         JSTaggedValue function = env->GetTaggedHasInstanceFunction();
151         JSTaggedValue instOf = instOfHandler.GetTaggedValue();
152         // slowpath
153         if (function != instOf) {
154             JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
155             EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, instOfHandler, target,
156                                                                             undefined, 1);
157             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
158             info->SetCallArg(object.GetTaggedValue());
159             JSTaggedValue tagged = JSFunction::Call(info);
160 
161             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
162             return tagged;
163         }
164     }
165     // 5. If IsCallable(target) is false, throw a TypeError exception.
166     if (!target->IsCallable()) {
167         THROW_TYPE_ERROR_AND_RETURN(thread, "InstanceOf error when target is not Callable", JSTaggedValue::Exception());
168     }
169     // fastpath
170     // 6. Return ? OrdinaryHasInstance(target, object).
171     bool res = JSFunction::OrdinaryHasInstance(thread, target, object);
172     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
173     return JSTaggedValue(res);
174 }
175 
RuntimeCreateGeneratorObj(JSThread *thread, const JSHandle<JSTaggedValue> &genFunc)176 JSTaggedValue RuntimeStubs::RuntimeCreateGeneratorObj(JSThread *thread, const JSHandle<JSTaggedValue> &genFunc)
177 {
178     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
179     JSHandle<JSGeneratorObject> obj = factory->NewJSGeneratorObject(genFunc);
180     JSHandle<GeneratorContext> context = factory->NewGeneratorContext();
181     context->SetGeneratorObject(thread, obj.GetTaggedValue());
182 
183     // change state to SUSPENDED_START
184     obj->SetGeneratorState(JSGeneratorState::SUSPENDED_START);
185     obj->SetGeneratorContext(thread, context);
186 
187     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
188     return obj.GetTaggedValue();
189 }
190 
RuntimeCreateAsyncGeneratorObj(JSThread *thread, const JSHandle<JSTaggedValue> &genFunc)191 JSTaggedValue RuntimeStubs::RuntimeCreateAsyncGeneratorObj(JSThread *thread, const JSHandle<JSTaggedValue> &genFunc)
192 {
193     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
194     JSHandle<JSAsyncGeneratorObject> obj = factory->NewJSAsyncGeneratorObject(genFunc);
195     JSHandle<GeneratorContext> context = factory->NewGeneratorContext();
196     context->SetGeneratorObject(thread, obj.GetTaggedValue());
197 
198     // change state to SUSPENDED_START
199     obj->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_START);
200     obj->SetGeneratorContext(thread, context);
201 
202     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
203     return obj.GetTaggedValue();
204 }
205 
RuntimeGetTemplateObject(JSThread *thread, const JSHandle<JSTaggedValue> &literal)206 JSTaggedValue RuntimeStubs::RuntimeGetTemplateObject(JSThread *thread, const JSHandle<JSTaggedValue> &literal)
207 {
208     JSHandle<JSTaggedValue> templateObj = TemplateString::GetTemplateObject(thread, literal);
209     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
210     return templateObj.GetTaggedValue();
211 }
212 
RuntimeGetNextPropName(JSThread *thread, const JSHandle<JSTaggedValue> &iter)213 JSTaggedValue RuntimeStubs::RuntimeGetNextPropName(JSThread *thread, const JSHandle<JSTaggedValue> &iter)
214 {
215     ASSERT(iter->IsForinIterator());
216     JSTaggedValue res = JSForInIterator::NextInternal(thread, JSHandle<JSForInIterator>::Cast(iter));
217     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
218     return res;
219 }
220 
RuntimeIterNext(JSThread *thread, const JSHandle<JSTaggedValue> &iter)221 JSTaggedValue RuntimeStubs::RuntimeIterNext(JSThread *thread, const JSHandle<JSTaggedValue> &iter)
222 {
223     JSHandle<JSTaggedValue> resultObj = JSIterator::IteratorNext(thread, iter);
224     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
225     return resultObj.GetTaggedValue();
226 }
227 
RuntimeCloseIterator(JSThread *thread, const JSHandle<JSTaggedValue> &iter)228 JSTaggedValue RuntimeStubs::RuntimeCloseIterator(JSThread *thread, const JSHandle<JSTaggedValue> &iter)
229 {
230     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
231     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
232 
233     JSHandle<JSTaggedValue> record;
234     if (thread->HasPendingException()) {
235         record = JSHandle<JSTaggedValue>(factory->NewCompletionRecord(
236             CompletionRecordType::THROW, JSHandle<JSTaggedValue>(thread, thread->GetException())));
237     } else {
238         JSHandle<JSTaggedValue> undefinedVal = globalConst->GetHandledUndefined();
239         record = JSHandle<JSTaggedValue>(factory->NewCompletionRecord(CompletionRecordType::NORMAL, undefinedVal));
240     }
241     JSHandle<JSTaggedValue> result = JSIterator::IteratorClose(thread, iter, record);
242     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
243     if (result->IsCompletionRecord()) {
244         return CompletionRecord::Cast(result->GetTaggedObject())->GetValue();
245     }
246     return result.GetTaggedValue();
247 }
248 
RuntimeSuperCallSpread(JSThread *thread, const JSHandle<JSTaggedValue> &func, const JSHandle<JSTaggedValue> &newTarget, const JSHandle<JSTaggedValue> &array)249 JSTaggedValue RuntimeStubs::RuntimeSuperCallSpread(JSThread *thread, const JSHandle<JSTaggedValue> &func,
250                                                    const JSHandle<JSTaggedValue> &newTarget,
251                                                    const JSHandle<JSTaggedValue> &array)
252 {
253     JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func));
254     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
255     if (!superFunc->IsJSFunction()) {
256         THROW_TYPE_ERROR_AND_RETURN(thread, "Super constructor is not JSFunction", JSTaggedValue::Exception());
257     }
258 
259     JSHandle<TaggedArray> argv(thread, RuntimeGetCallSpreadArgs(thread, array));
260     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
261     const uint32_t argsLength = argv->GetLength();
262     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
263     EcmaRuntimeCallInfo *info =
264         EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, argsLength);
265     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
266     info->SetCallArg(argsLength, argv);
267     JSTaggedValue result = JSFunction::Construct(info);
268     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
269 
270     return result;
271 }
272 
RuntimeOptSuperCallSpread(JSThread *thread, const JSHandle<JSTaggedValue> &func, const JSHandle<JSTaggedValue> &newTarget, const JSHandle<JSTaggedValue> &taggedArray)273 JSTaggedValue RuntimeStubs::RuntimeOptSuperCallSpread(JSThread *thread, const JSHandle<JSTaggedValue> &func,
274                                                       const JSHandle<JSTaggedValue> &newTarget,
275                                                       const JSHandle<JSTaggedValue> &taggedArray)
276 {
277     JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func));
278     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
279     if (!superFunc->IsJSFunction()) {
280         THROW_TYPE_ERROR_AND_RETURN(thread, "Super constructor is not JSFunction", JSTaggedValue::Exception());
281     }
282 
283     JSHandle<TaggedArray> argv(thread, taggedArray.GetTaggedValue());
284     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
285     const uint32_t argsLength = argv->GetLength();
286     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
287     EcmaRuntimeCallInfo *info =
288         EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, argsLength);
289     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
290     info->SetCallArg(argsLength, argv);
291     JSTaggedValue result = JSFunction::Construct(info);
292     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
293 
294     return result;
295 }
296 
RuntimeSuperCallForwardAllArgs(JSThread *thread, JSTaggedType *sp, const JSHandle<JSTaggedValue> &superFunc, const JSHandle<JSTaggedValue> &newTarget, uint32_t restNumArgs, uint32_t startIdx)297 JSTaggedValue RuntimeStubs::RuntimeSuperCallForwardAllArgs(JSThread *thread, JSTaggedType *sp,
298                                                            const JSHandle<JSTaggedValue> &superFunc,
299                                                            const JSHandle<JSTaggedValue> &newTarget,
300                                                            uint32_t restNumArgs, uint32_t startIdx)
301 {
302     if (!superFunc->IsConstructor()) {
303         THROW_TYPE_ERROR_AND_RETURN(thread, "Super constructor is not a constructor", JSTaggedValue::Exception());
304     }
305 
306     // prepare callinfo
307     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
308     EcmaRuntimeCallInfo *info =
309         EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, restNumArgs);
310     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
311     // set args for callinfo
312     for (uint32_t i = 0; i < restNumArgs; ++i) {
313         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
314         info->SetCallArg(i, JSTaggedValue(sp[startIdx + i]));
315     }
316     // execute super ctor with call info
317     JSTaggedValue res = JSFunction::Construct(info);
318     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
319     return res;
320 }
321 
RuntimeDelObjProp(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &prop)322 JSTaggedValue RuntimeStubs::RuntimeDelObjProp(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
323                                               const JSHandle<JSTaggedValue> &prop)
324 {
325     JSHandle<JSTaggedValue> jsObj(JSTaggedValue::ToObject(thread, obj));
326     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
327     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop);
328     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
329     bool ret = JSTaggedValue::DeletePropertyOrThrow(thread, jsObj, propKey);
330     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
331     return JSTaggedValue(ret);
332 }
333 
RuntimeNewObjApply(JSThread *thread, const JSHandle<JSTaggedValue> &func, const JSHandle<JSTaggedValue> &array)334 JSTaggedValue RuntimeStubs::RuntimeNewObjApply(JSThread *thread, const JSHandle<JSTaggedValue> &func,
335                                                const JSHandle<JSTaggedValue> &array)
336 {
337     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
338     if (!array->IsJSArray()) {
339         return RuntimeThrowTypeError(thread, "Cannot Newobjspread");
340     }
341 
342     uint32_t length = JSHandle<JSArray>::Cast(array)->GetArrayLength();
343     JSHandle<TaggedArray> argsArray = factory->NewTaggedArray(length);
344     for (uint32_t i = 0; i < length; ++i) {
345         auto prop = JSTaggedValue::GetProperty(thread, array, i).GetValue();
346         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
347         argsArray->Set(thread, i, prop);
348         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
349     }
350     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
351     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, func, length);
352     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
353     info->SetCallArg(length, argsArray);
354     return NewObject(info);
355 }
356 
RuntimeCreateIterResultObj(JSThread *thread, const JSHandle<JSTaggedValue> &value, JSTaggedValue flag)357 JSTaggedValue RuntimeStubs::RuntimeCreateIterResultObj(JSThread *thread, const JSHandle<JSTaggedValue> &value,
358                                                        JSTaggedValue flag)
359 {
360     ASSERT(flag.IsBoolean());
361     bool done = flag.IsTrue();
362     JSHandle<JSObject> iter = JSIterator::CreateIterResultObject(thread, value, done);
363     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
364     return iter.GetTaggedValue();
365 }
366 
RuntimeAsyncFunctionAwaitUncaught(JSThread *thread, const JSHandle<JSTaggedValue> &asyncFuncObj, const JSHandle<JSTaggedValue> &value)367 JSTaggedValue RuntimeStubs::RuntimeAsyncFunctionAwaitUncaught(JSThread *thread,
368                                                               const JSHandle<JSTaggedValue> &asyncFuncObj,
369                                                               const JSHandle<JSTaggedValue> &value)
370 {
371     JSAsyncFunction::AsyncFunctionAwait(thread, asyncFuncObj, value);
372     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
373     if (asyncFuncObj->IsAsyncGeneratorObject()) {
374         JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, asyncFuncObj);
375         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
376         JSHandle<JSAsyncGeneratorObject> generator = JSHandle<JSAsyncGeneratorObject>::Cast(obj);
377         JSHandle<TaggedQueue> queue(thread, generator->GetAsyncGeneratorQueue());
378         if (queue->Empty()) {
379             return JSTaggedValue::Undefined();
380         }
381         JSHandle<AsyncGeneratorRequest> next(thread, queue->Front());
382         JSHandle<PromiseCapability> completion(thread, next->GetCapability());
383         JSHandle<JSPromise> promise(thread, completion->GetPromise());
384         return promise.GetTaggedValue();
385     }
386     JSHandle<JSAsyncFuncObject> asyncFuncObjHandle(asyncFuncObj);
387     JSHandle<JSPromise> promise(thread, asyncFuncObjHandle->GetPromise());
388 
389     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
390     return promise.GetTaggedValue();
391 }
392 
RuntimeAsyncFunctionResolveOrReject(JSThread *thread, const JSHandle<JSTaggedValue> &asyncFuncObj, const JSHandle<JSTaggedValue> &value, bool is_resolve)393 JSTaggedValue RuntimeStubs::RuntimeAsyncFunctionResolveOrReject(JSThread *thread,
394     const JSHandle<JSTaggedValue> &asyncFuncObj, const JSHandle<JSTaggedValue> &value, bool is_resolve)
395 {
396     JSHandle<JSAsyncFuncObject> asyncFuncObjHandle(asyncFuncObj);
397     JSHandle<JSPromise> promise(thread, asyncFuncObjHandle->GetPromise());
398 
399     // ActivePromise
400     JSHandle<ResolvingFunctionsRecord> reactions = JSPromise::CreateResolvingFunctions(thread, promise);
401     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
402     JSHandle<JSTaggedValue> thisArg = globalConst->GetHandledUndefined();
403     JSHandle<JSTaggedValue> activeFunc;
404     if (is_resolve) {
405         activeFunc = JSHandle<JSTaggedValue>(thread, reactions->GetResolveFunction());
406     } else {
407         activeFunc = JSHandle<JSTaggedValue>(thread, reactions->GetRejectFunction());
408     }
409     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
410     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, activeFunc, thisArg, undefined, 1);
411     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
412     info->SetCallArg(value.GetTaggedValue());
413     [[maybe_unused]] JSTaggedValue res = JSFunction::Call(info);
414 
415     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
416     return promise.GetTaggedValue();
417 }
418 
RuntimeAsyncGeneratorResolve(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj, JSHandle<JSTaggedValue> value, JSTaggedValue flag)419 JSTaggedValue RuntimeStubs::RuntimeAsyncGeneratorResolve(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj,
420                                                          JSHandle<JSTaggedValue> value, JSTaggedValue flag)
421 {
422     [[maybe_unused]] EcmaHandleScope handleScope(thread);
423 
424     JSHandle<JSAsyncGeneratorObject> asyncGeneratorObjHandle(asyncFuncObj);
425     JSHandle<JSTaggedValue> valueHandle(value);
426     JSHandle<GeneratorContext> genContextHandle(thread, asyncGeneratorObjHandle->GetGeneratorContext());
427     // save stack, should copy cur_frame, function execute over will free cur_frame
428     SaveFrameToContext(thread, genContextHandle);
429 
430     ASSERT(flag.IsBoolean());
431     bool done = flag.IsTrue();
432 
433     return JSAsyncGeneratorObject::AsyncGeneratorResolve(thread, asyncGeneratorObjHandle, valueHandle, done);
434 }
435 
RuntimeAsyncGeneratorReject(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj, JSHandle<JSTaggedValue> value)436 JSTaggedValue RuntimeStubs::RuntimeAsyncGeneratorReject(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj,
437                                                         JSHandle<JSTaggedValue> value)
438 {
439     [[maybe_unused]] EcmaHandleScope handleScope(thread);
440 
441     JSHandle<JSAsyncGeneratorObject> asyncGeneratorObjHandle(asyncFuncObj);
442     JSHandle<JSTaggedValue> valueHandle(value);
443 
444     return JSAsyncGeneratorObject::AsyncGeneratorReject(thread, asyncGeneratorObjHandle, valueHandle);
445 }
446 
RuntimeCopyDataProperties(JSThread *thread, const JSHandle<JSTaggedValue> &dst, const JSHandle<JSTaggedValue> &src)447 JSTaggedValue RuntimeStubs::RuntimeCopyDataProperties(JSThread *thread, const JSHandle<JSTaggedValue> &dst,
448                                                       const JSHandle<JSTaggedValue> &src)
449 {
450     if (!src->IsNull() && !src->IsUndefined()) {
451         // 2. Let from be ! ToObject(source).
452         JSHandle<JSTaggedValue> from(JSTaggedValue::ToObject(thread, src));
453         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
454         JSHandle<TaggedArray> keys = JSTaggedValue::GetOwnPropertyKeys(thread, from);
455         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
456 
457         JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
458         uint32_t keysLen = keys->GetLength();
459         for (uint32_t i = 0; i < keysLen; i++) {
460             PropertyDescriptor desc(thread);
461             key.Update(keys->Get(i));
462             bool success = JSTaggedValue::GetOwnProperty(thread, from, key, desc);
463             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
464 
465             if (success && desc.IsEnumerable()) {
466                 desc.SetWritable(true);
467                 desc.SetConfigurable(true);
468                 JSTaggedValue::DefineOwnProperty(thread, dst, key, desc);
469                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
470             }
471         }
472     }
473     return dst.GetTaggedValue();
474 }
475 
RuntimeStArraySpread(JSThread *thread, const JSHandle<JSTaggedValue> &dst, JSTaggedValue index, const JSHandle<JSTaggedValue> &src)476 JSTaggedValue RuntimeStubs::RuntimeStArraySpread(JSThread *thread, const JSHandle<JSTaggedValue> &dst,
477                                                  JSTaggedValue index, const JSHandle<JSTaggedValue> &src)
478 {
479     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
480     JSHandle<JSTaggedValue> undefinedHandle(thread, JSTaggedValue::Undefined());
481     ASSERT(dst->IsJSArray());
482     if (dst->IsJSArray()) {
483         if (src->IsNull() || src->IsUndefined()) {
484             THROW_TYPE_ERROR_AND_RETURN(thread, "src is not iterable", JSTaggedValue::Exception());
485         }
486     } else {
487         THROW_TYPE_ERROR_AND_RETURN(thread, "dst is not iterable", JSTaggedValue::Exception());
488     }
489     if (src->IsString()) {
490         JSHandle<EcmaString> srcString = JSTaggedValue::ToString(thread, src);
491         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
492         JSHandle<EcmaString> srcFlat = JSHandle<EcmaString>(thread,
493             EcmaStringAccessor::Flatten(thread->GetEcmaVM(), srcString));
494         uint32_t dstLen = static_cast<uint32_t>(index.GetInt());
495         uint32_t strLen = EcmaStringAccessor(srcFlat).GetLength();
496         for (uint32_t i = 0; i < strLen; i++) {
497             uint16_t res = EcmaStringAccessor(srcFlat).Get<false>(i);
498             JSHandle<JSTaggedValue> strValue(factory->NewFromUtf16Literal(&res, 1));
499             JSTaggedValue::SetProperty(thread, dst, dstLen + i, strValue, true);
500             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
501         }
502         JSHandle<JSTaggedValue> length(thread, JSTaggedValue(dstLen + strLen));
503         if (strLen == 0U) {
504             JSHandle<JSTaggedValue> lengthKey = thread->GlobalConstants()->GetHandledLengthString();
505             JSTaggedValue::SetProperty(thread, dst, lengthKey, length);
506         }
507         return length.GetTaggedValue();
508     }
509 
510     if (index.GetInt() == 0 && src->IsStableJSArray(thread)) {
511         JSHandle<TaggedArray> srcElements(thread, JSHandle<JSObject>::Cast(src)->GetElements());
512         uint32_t length = JSHandle<JSArray>::Cast(src)->GetArrayLength();
513         JSHandle<TaggedArray> dstElements = factory->NewTaggedArray(length);
514         JSHandle<JSArray> dstArray = JSHandle<JSArray>::Cast(dst);
515         dstArray->SetElements(thread, dstElements);
516         dstArray->SetArrayLength(thread, length);
517         JSHandle<JSObject> srcObj(src);
518         JSHandle<JSObject> dstObj(dst);
519         ElementAccessor::CopyJSArrayObject(thread, srcObj, dstObj, length);
520         for (uint32_t i = 0; i < length; i++) {
521             JSHandle<JSTaggedValue> reg(thread, ElementAccessor::Get(srcObj, i));
522             if (reg->IsHole()) {
523                 JSHandle<JSTaggedValue> reg2(thread, JSArray::FastGetPropertyByValue(thread, src, i).GetTaggedValue());
524                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
525                 if (reg2->IsHole()) {
526                     ElementAccessor::Set(thread, dstObj, i, undefinedHandle, true);
527                 } else {
528                     ElementAccessor::Set(thread, dstObj, i, reg2, true);
529                 }
530             } else {
531                 ElementAccessor::Set(thread, dstObj, i, reg, true);
532             }
533         }
534         return JSTaggedValue(length);
535     }
536 
537     JSHandle<JSTaggedValue> iter;
538     auto globalConst = thread->GlobalConstants();
539     if (src->IsJSArrayIterator() || src->IsJSMapIterator() || src->IsJSSetIterator() ||
540         src->IsIterator()) {
541         iter = src;
542     } else if (src->IsJSArray()) {
543         JSHandle<JSTaggedValue> valuesStr = globalConst->GetHandledValuesString();
544         JSHandle<JSTaggedValue> valuesMethod = JSObject::GetMethod(thread, src, valuesStr);
545         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
546         iter = JSIterator::GetIterator(thread, src, valuesMethod);
547         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
548     } else {
549         iter = JSIterator::GetIterator(thread, src);
550         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
551     }
552 
553     JSMutableHandle<JSTaggedValue> indexHandle(thread, index);
554     JSHandle<JSTaggedValue> valueStr = globalConst->GetHandledValueString();
555     PropertyDescriptor desc(thread);
556     JSHandle<JSTaggedValue> iterResult;
557     uint32_t srcLen = 0U;
558     do {
559         iterResult = JSIterator::IteratorStep(thread, iter);
560         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
561         if (iterResult->IsFalse()) {
562             break;
563         }
564         bool success = JSTaggedValue::GetOwnProperty(thread, iterResult, valueStr, desc);
565         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
566         if (success && desc.IsEnumerable()) {
567             JSTaggedValue::DefineOwnProperty(thread, dst, indexHandle, desc);
568             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
569             int tmp = indexHandle->GetInt();
570             indexHandle.Update(JSTaggedValue(tmp + 1));
571             ++srcLen;
572         }
573     } while (true);
574     if (srcLen == 0U) {
575         JSHandle<JSTaggedValue> lengthKey = thread->GlobalConstants()->GetHandledLengthString();
576         JSTaggedValue::SetProperty(thread, dst, lengthKey, indexHandle);
577     }
578     return indexHandle.GetTaggedValue();
579 }
580 
RuntimeGetIteratorNext(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &method)581 JSTaggedValue RuntimeStubs::RuntimeGetIteratorNext(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
582                                                    const JSHandle<JSTaggedValue> &method)
583 {
584     ASSERT(method->IsCallable());
585     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
586     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, method, obj, undefined, 0);
587     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
588     JSTaggedValue ret = JSFunction::Call(info);
589     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
590     if (!ret.IsECMAObject()) {
591         return RuntimeThrowTypeError(thread, "the Iterator is not an ecmaobject.");
592     }
593     return ret;
594 }
595 
RuntimeSetObjectWithProto(JSThread *thread, const JSHandle<JSTaggedValue> &proto, const JSHandle<JSObject> &obj)596 JSTaggedValue RuntimeStubs::RuntimeSetObjectWithProto(JSThread *thread, const JSHandle<JSTaggedValue> &proto,
597                                                       const JSHandle<JSObject> &obj)
598 {
599     if (!proto->IsECMAObject() && !proto->IsNull()) {
600         return JSTaggedValue::False();
601     }
602     if (UNLIKELY(proto->IsJSShared())) {
603         THROW_TYPE_ERROR_AND_RETURN(thread, GET_MESSAGE_STRING(SetProtoWithSendable), JSTaggedValue::Exception());
604     }
605     JSObject::SetPrototype(thread, obj, proto);
606     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
607     return JSTaggedValue::True();
608 }
609 
RuntimeLdObjByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &prop, bool callGetter, JSTaggedValue receiver)610 JSTaggedValue RuntimeStubs::RuntimeLdObjByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
611                                                 const JSHandle<JSTaggedValue> &prop, bool callGetter,
612                                                 JSTaggedValue receiver)
613 {
614     // Ecma Spec 2015 12.3.2.1
615     // 7. Let bv be RequireObjectCoercible(baseValue).
616     // 8. ReturnIfAbrupt(bv).
617     JSHandle<JSTaggedValue> object =
618         JSTaggedValue::RequireObjectCoercible(thread, obj, "Cannot load property of null or undefined");
619     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
620 
621     JSTaggedValue res;
622     if (callGetter) {
623         res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), object);
624         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
625     } else {
626         JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop);
627         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
628         res = JSTaggedValue::GetProperty(thread, object, propKey).GetValue().GetTaggedValue();
629     }
630     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
631     return res;
632 }
633 
RuntimeStObjByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &prop, const JSHandle<JSTaggedValue> &value)634 JSTaggedValue RuntimeStubs::RuntimeStObjByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
635                                                 const JSHandle<JSTaggedValue> &prop,
636                                                 const JSHandle<JSTaggedValue> &value)
637 {
638     // Ecma Spec 2015 12.3.2.1
639     // 7. Let bv be RequireObjectCoercible(baseValue).
640     // 8. ReturnIfAbrupt(bv).
641     JSHandle<JSTaggedValue> object =
642         JSTaggedValue::RequireObjectCoercible(thread, obj, "Cannot store property of null or undefined");
643     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
644 
645     JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, prop));
646     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
647     // strict mode is true
648     JSTaggedValue::SetProperty(thread, object, propKey, value, true);
649     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
650     return JSTaggedValue::True();
651 }
652 
RuntimeStOwnByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value)653 JSTaggedValue RuntimeStubs::RuntimeStOwnByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
654                                                 const JSHandle<JSTaggedValue> &key,
655                                                 const JSHandle<JSTaggedValue> &value)
656 {
657     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
658 
659     if (obj->IsClassConstructor() &&
660         JSTaggedValue::SameValue(key, globalConst->GetHandledPrototypeString())) {
661         return RuntimeThrowTypeError(thread, "In a class, static property named 'prototype' throw a TypeError");
662     }
663 
664     // property in class is non-enumerable
665     bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor());
666 
667     PropertyDescriptor desc(thread, value, true, enumerable, true);
668     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, key);
669     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
670     bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, propKey, desc);
671     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
672     if (!ret) {
673         return RuntimeThrowTypeError(thread, "StOwnByValue failed");
674     }
675     return JSTaggedValue::True();
676 }
677 
RuntimeLdSuperByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &key, JSTaggedValue thisFunc)678 JSTaggedValue RuntimeStubs::RuntimeLdSuperByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
679                                                   const JSHandle<JSTaggedValue> &key, JSTaggedValue thisFunc)
680 {
681     ASSERT(thisFunc.IsJSFunction());
682     // get Homeobject form function
683     JSHandle<JSTaggedValue> homeObject(thread, JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject());
684     JSHandle<JSTaggedValue> superBase(thread, JSTaggedValue::GetSuperBase(thread, homeObject));
685     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
686     JSTaggedValue::RequireObjectCoercible(thread, superBase);
687     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
688     JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, key));
689     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
690 
691     JSTaggedValue res = JSTaggedValue::GetProperty(thread, superBase, propKey, obj).GetValue().GetTaggedValue();
692     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
693     return res;
694 }
695 
RuntimeStSuperByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value, JSTaggedValue thisFunc)696 JSTaggedValue RuntimeStubs::RuntimeStSuperByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
697                                                   const JSHandle<JSTaggedValue> &key,
698                                                   const JSHandle<JSTaggedValue> &value, JSTaggedValue thisFunc)
699 {
700     ASSERT(thisFunc.IsJSFunction());
701     // get Homeobject form function
702     JSHandle<JSTaggedValue> homeObject(thread, JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject());
703     JSHandle<JSTaggedValue> superBase(thread, JSTaggedValue::GetSuperBase(thread, homeObject));
704     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
705     JSTaggedValue::RequireObjectCoercible(thread, superBase);
706     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
707     JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, key));
708     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
709 
710     // check may_throw is false?
711     JSTaggedValue::SetProperty(thread, superBase, propKey, value, obj, true);
712     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
713     return JSTaggedValue::True();
714 }
715 
RuntimeLdObjByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj, uint32_t idx, bool callGetter, JSTaggedValue receiver)716 JSTaggedValue RuntimeStubs::RuntimeLdObjByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
717                                                 uint32_t idx, bool callGetter, JSTaggedValue receiver)
718 {
719     JSTaggedValue res;
720     if (callGetter) {
721         res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), obj);
722     } else {
723         res = JSTaggedValue::GetProperty(thread, obj, idx).GetValue().GetTaggedValue();
724     }
725     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
726     return res;
727 }
728 
RuntimeLdObjByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, bool callGetter, JSTaggedValue receiver)729 JSTaggedValue RuntimeStubs::RuntimeLdObjByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop,
730                                                bool callGetter, JSTaggedValue receiver)
731 {
732     JSHandle<JSTaggedValue> objHandle(thread, obj);
733     JSTaggedValue res;
734     if (callGetter) {
735         res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), objHandle);
736     } else {
737         JSHandle<JSTaggedValue> propHandle(thread, prop);
738         res = JSTaggedValue::GetProperty(thread, objHandle, propHandle).GetValue().GetTaggedValue();
739     }
740     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
741     return res;
742 }
743 
RuntimeStObjByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &prop, const JSHandle<JSTaggedValue> &value)744 JSTaggedValue RuntimeStubs::RuntimeStObjByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
745                                                const JSHandle<JSTaggedValue> &prop,
746                                                const JSHandle<JSTaggedValue> &value)
747 {
748     JSTaggedValue::SetProperty(thread, obj, prop, value, true);
749     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
750     return JSTaggedValue::True();
751 }
752 
RuntimeStObjByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj, uint32_t idx, const JSHandle<JSTaggedValue> &value)753 JSTaggedValue RuntimeStubs::RuntimeStObjByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
754                                                 uint32_t idx, const JSHandle<JSTaggedValue> &value)
755 {
756     JSTaggedValue::SetProperty(thread, obj, idx, value, true);
757     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
758     return JSTaggedValue::True();
759 }
760 
RuntimeStOwnByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &idx, const JSHandle<JSTaggedValue> &value)761 JSTaggedValue RuntimeStubs::RuntimeStOwnByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
762                                                 const JSHandle<JSTaggedValue> &idx,
763                                                 const JSHandle<JSTaggedValue> &value)
764 {
765     // property in class is non-enumerable
766     bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor());
767 
768     PropertyDescriptor desc(thread, value, true, enumerable, true);
769     bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, idx, desc);
770     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
771     if (!ret) {
772         return RuntimeThrowTypeError(thread, "SetOwnByIndex failed");
773     }
774     return JSTaggedValue::True();
775 }
776 
RuntimeStGlobalRecord(JSThread *thread, const JSHandle<JSTaggedValue> &prop, const JSHandle<JSTaggedValue> &value, bool isConst)777 JSTaggedValue RuntimeStubs::RuntimeStGlobalRecord(JSThread *thread, const JSHandle<JSTaggedValue> &prop,
778                                                   const JSHandle<JSTaggedValue> &value, bool isConst)
779 {
780     ObjectFactory* factory = thread->GetEcmaVM()->GetFactory();
781     if (thread->GetEcmaVM()->GetJSOptions().IsEnableLoweringBuiltin()) {
782         BuiltinIndex& builtinIndex = BuiltinIndex::GetInstance();
783         auto index = builtinIndex.GetBuiltinIndex(prop.GetTaggedValue());
784         if (index != BuiltinIndex::NOT_FOUND) {
785             auto box = factory->NewPropertyBox(JSHandle<JSTaggedValue>(thread, JSTaggedValue::Hole()));
786             thread->GetBuiltinEntriesPointer()->ClearByIndex(index, box.GetTaggedValue());
787         }
788     }
789 
790     EcmaVM *vm = thread->GetEcmaVM();
791     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
792     GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
793 
794     // cross files global record name binding judgment
795     int entry = dict->FindEntry(prop.GetTaggedValue());
796     if (entry != -1) {
797         return RuntimeThrowSyntaxError(thread, "Duplicate identifier");
798     }
799 
800     PropertyAttributes attributes;
801     if (isConst) {
802         attributes.SetIsConstProps(true);
803     }
804     JSHandle<GlobalDictionary> dictHandle(thread, dict);
805     JSHandle<PropertyBox> box = factory->NewPropertyBox(value);
806     PropertyBoxType boxType = value->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
807     attributes.SetBoxType(boxType);
808 
809     dict = *GlobalDictionary::PutIfAbsent(thread, dictHandle, prop, JSHandle<JSTaggedValue>(box), attributes);
810     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
811     env->SetGlobalRecord(thread, JSTaggedValue(dict));
812     return JSTaggedValue::True();
813 }
814 
RuntimeNeg(JSThread *thread, const JSHandle<JSTaggedValue> &value)815 JSTaggedValue RuntimeStubs::RuntimeNeg(JSThread *thread, const JSHandle<JSTaggedValue> &value)
816 {
817     JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value);
818     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
819     if (inputVal->IsBigInt()) {
820         JSHandle<BigInt> bigValue(inputVal);
821         return BigInt::UnaryMinus(thread, bigValue).GetTaggedValue();
822     }
823     JSTaggedNumber number(inputVal.GetTaggedValue());
824     if (number.IsInt()) {
825         int32_t intValue = number.GetInt();
826         if (intValue == 0) {
827             return JSTaggedValue(-0.0);
828         }
829         if (intValue == INT32_MIN) {
830             return JSTaggedValue(-static_cast<double>(INT32_MIN));
831         }
832         return JSTaggedValue(-intValue);
833     }
834     if (number.IsDouble()) {
835         return JSTaggedValue(-number.GetDouble());
836     }
837     LOG_ECMA(FATAL) << "this branch is unreachable";
838     UNREACHABLE();
839 }
840 
RuntimeNot(JSThread *thread, const JSHandle<JSTaggedValue> &value)841 JSTaggedValue RuntimeStubs::RuntimeNot(JSThread *thread, const JSHandle<JSTaggedValue> &value)
842 {
843     JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value);
844     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
845     if (inputVal->IsBigInt()) {
846         JSHandle<BigInt> bigValue(inputVal);
847         return BigInt::BitwiseNOT(thread, bigValue).GetTaggedValue();
848     }
849     int32_t number = JSTaggedValue::ToInt32(thread, inputVal);
850     return JSTaggedValue(~number); // NOLINT(hicpp-signed-bitwise)
851 }
852 
RuntimeResolveClass(JSThread *thread, const JSHandle<JSFunction> &ctor, const JSHandle<TaggedArray> &literal, const JSHandle<JSTaggedValue> &base, const JSHandle<JSTaggedValue> &lexenv)853 JSTaggedValue RuntimeStubs::RuntimeResolveClass(JSThread *thread, const JSHandle<JSFunction> &ctor,
854                                                 const JSHandle<TaggedArray> &literal,
855                                                 const JSHandle<JSTaggedValue> &base,
856                                                 const JSHandle<JSTaggedValue> &lexenv)
857 {
858     ASSERT(ctor.GetTaggedValue().IsClassConstructor());
859 
860     FrameHandler frameHandler(thread);
861     JSTaggedValue currentFunc = frameHandler.GetFunction();
862     JSHandle<JSTaggedValue> ecmaModule(thread, JSFunction::Cast(currentFunc.GetTaggedObject())->GetModule());
863 
864     RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(ctor), base);
865     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
866 
867     uint32_t literalBufferLength = literal->GetLength();
868     ASSERT(literalBufferLength > 0);
869 
870     // only traverse the value of key-value pair
871     for (uint32_t index = 1; index < literalBufferLength - 1; index += 2) {  // 2: key-value pair
872         JSTaggedValue value = literal->Get(index);
873         if (LIKELY(value.IsJSFunction())) {
874             JSFunction *func = JSFunction::Cast(value.GetTaggedObject());
875             func->SetLexicalEnv(thread, lexenv.GetTaggedValue());
876             func->SetModule(thread, ecmaModule);
877         }
878     }
879 
880     return ctor.GetTaggedValue();
881 }
882 
RuntimeCloneClassFromTemplate(JSThread *thread, const JSHandle<JSFunction> &ctor, const JSHandle<JSTaggedValue> &base, const JSHandle<JSTaggedValue> &lexenv)883 JSTaggedValue RuntimeStubs::RuntimeCloneClassFromTemplate(JSThread *thread, const JSHandle<JSFunction> &ctor,
884                                                           const JSHandle<JSTaggedValue> &base,
885                                                           const JSHandle<JSTaggedValue> &lexenv)
886 {
887     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
888     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
889 
890     ASSERT(ctor.GetTaggedValue().IsClassConstructor());
891     JSHandle<JSObject> clsPrototype(thread, ctor->GetFunctionPrototype());
892 
893     bool canShareHClass = false;
894     JSHandle<JSFunction> cloneClass = factory->CloneClassCtor(ctor, lexenv, canShareHClass);
895     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
896     JSHandle<JSObject> cloneClassPrototype = factory->CloneObjectLiteral(JSHandle<JSObject>(clsPrototype), lexenv,
897                                                                          canShareHClass);
898     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
899 
900     // After clone both, reset "constructor" and "prototype" properties.
901     JSFunction::SetFunctionPrototypeOrInstanceHClass(thread, cloneClass, cloneClassPrototype.GetTaggedValue());
902     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
903 
904     PropertyDescriptor ctorDesc(thread, JSHandle<JSTaggedValue>(cloneClass), true, false, true);
905     JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(cloneClassPrototype),
906                                          globalConst->GetHandledConstructorString(), ctorDesc);
907     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
908 
909     cloneClass->SetHomeObject(thread, cloneClassPrototype);
910 
911     if (!canShareHClass) {
912         RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cloneClass), base);
913         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
914     }
915 
916     return cloneClass.GetTaggedValue();
917 }
918 
ShouldUseAOTHClass(const JSHandle<JSTaggedValue> &ihc, const JSHandle<JSTaggedValue> &chc, const JSHandle<ClassLiteral> &classLiteral)919 bool RuntimeStubs::ShouldUseAOTHClass(const JSHandle<JSTaggedValue> &ihc,
920                                       const JSHandle<JSTaggedValue> &chc,
921                                       const JSHandle<ClassLiteral> &classLiteral)
922 {
923     // In the case of incomplete data collection in PGO, AOT may not create ihc and chc at the same time.
924     // Therefore, there is no need to check for the existence of both at this point.
925     return (!ihc->IsUndefined() || !chc->IsUndefined()) && !classLiteral->GetIsAOTUsed();
926 }
927 // clone class may need re-set inheritance relationship due to extends may be a variable.
RuntimeCreateClassWithBuffer(JSThread *thread, const JSHandle<JSTaggedValue> &base, const JSHandle<JSTaggedValue> &lexenv, const JSHandle<JSTaggedValue> &constpool, uint16_t methodId, uint16_t literalId, const JSHandle<JSTaggedValue> &module, const JSHandle<JSTaggedValue> &length)928 JSTaggedValue RuntimeStubs::RuntimeCreateClassWithBuffer(JSThread *thread,
929                                                          const JSHandle<JSTaggedValue> &base,
930                                                          const JSHandle<JSTaggedValue> &lexenv,
931                                                          const JSHandle<JSTaggedValue> &constpool,
932                                                          uint16_t methodId, uint16_t literalId,
933                                                          const JSHandle<JSTaggedValue> &module,
934                                                          const JSHandle<JSTaggedValue> &length)
935 {
936     if (base->IsJSShared()) {
937         THROW_TYPE_ERROR_AND_RETURN(thread, GET_MESSAGE_STRING(NotSendableSubClass), JSTaggedValue::Exception());
938     }
939     [[maybe_unused]] EcmaHandleScope handleScope(thread);
940     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
941     CString entry = ModuleManager::GetRecordName(module.GetTaggedValue());
942 
943     // For class constructor.
944     auto methodObj = ConstantPool::GetMethodFromCache(thread, constpool.GetTaggedValue(), methodId);
945     JSHandle<JSTaggedValue> method(thread, methodObj);
946     JSHandle<ConstantPool> constpoolHandle = JSHandle<ConstantPool>::Cast(constpool);
947     JSHandle<JSFunction> cls;
948     JSMutableHandle<JSTaggedValue> ihc(thread, JSTaggedValue::Undefined());
949     JSMutableHandle<JSTaggedValue> chc(thread, JSTaggedValue::Undefined());
950 
951     JSHandle<ConstantPool> cp(thread,
952         thread->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(constpoolHandle.GetTaggedValue()));
953     JSTaggedValue val = cp->GetObjectFromCache(literalId);
954     if (val.IsAOTLiteralInfo()) {
955         JSHandle<AOTLiteralInfo> aotLiteralInfo(thread, val);
956         ihc.Update(aotLiteralInfo->GetIhc());
957         chc.Update(aotLiteralInfo->GetChc());
958     }
959 
960     JSHandle<JSTaggedValue> sendableEnv(thread, JSTaggedValue::Undefined());
961     if (module->GetTaggedObject()->GetClass()->IsSourceTextModule()) {
962         JSHandle<SourceTextModule> moduleRecord = JSHandle<SourceTextModule>::Cast(module);
963         sendableEnv = JSHandle<JSTaggedValue>(thread, moduleRecord->GetSendableEnv());
964     }
965     JSTaggedValue literalObj = ConstantPool::GetClassLiteralFromCache(thread, cp, literalId, entry, sendableEnv);
966 
967     JSHandle<ClassLiteral> classLiteral(thread, literalObj);
968     JSHandle<TaggedArray> arrayHandle(thread, classLiteral->GetArray());
969     JSHandle<ClassInfoExtractor> extractor = factory->NewClassInfoExtractor(method);
970     auto literalLength = arrayHandle->GetLength();
971     ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(thread, extractor, arrayHandle, literalLength);
972 
973     if (ShouldUseAOTHClass(ihc, chc, classLiteral)) {
974         classLiteral->SetIsAOTUsed(true);
975         cls = ClassHelper::DefineClassWithIHClass(thread, base, extractor, lexenv, ihc, chc);
976     } else {
977         cls = ClassHelper::DefineClassFromExtractor(thread, base, extractor, lexenv);
978     }
979 
980     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
981     RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cls), base);
982     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
983 
984     cls->SetLexicalEnv(thread, lexenv.GetTaggedValue());
985     cls->SetModule(thread, module.GetTaggedValue());
986     RuntimeSetClassConstructorLength(thread, cls.GetTaggedValue(), length.GetTaggedValue());
987     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
988 
989     return cls.GetTaggedValue();
990 }
991 
SetProfileTypeInfoCellToFunction(JSThread *thread, const JSHandle<JSFunction> &jsFunc, const JSHandle<JSFunction> &definedFunc, uint16_t slotId)992 void RuntimeStubs::SetProfileTypeInfoCellToFunction(JSThread *thread, const JSHandle<JSFunction> &jsFunc,
993                                                     const JSHandle<JSFunction> &definedFunc, uint16_t slotId)
994 {
995     if (slotId == ProfileTypeInfo::INVALID_SLOT_INDEX) {  // do nothing for invalid slotId
996         return;
997     }
998 
999     ASSERT(definedFunc->IsJSFunction());
1000     ASSERT(!definedFunc->IsSharedFunction());
1001     ASSERT(jsFunc->IsJSFunction());
1002     ASSERT(!jsFunc->IsSharedFunction());
1003 
1004     auto profileTypeInfo = jsFunc->GetProfileTypeInfo();
1005     if (profileTypeInfo.IsUndefined()) {
1006         JSHandle<Method> method(thread, jsFunc->GetMethod());
1007         uint32_t slotSize = method->GetSlotSize();
1008         profileTypeInfo = RuntimeNotifyInlineCache(thread, jsFunc, slotSize);
1009     }
1010 
1011     ASSERT(!profileTypeInfo.IsUndefined());
1012 
1013     JSHandle<ProfileTypeInfo> profileTypeArray(thread, profileTypeInfo);
1014     JSTaggedValue slotValue = profileTypeArray->Get(slotId);
1015     if (slotValue.IsUndefined()) {
1016         JSHandle<JSTaggedValue> handleUndefined(thread, JSTaggedValue::Undefined());
1017         JSHandle<ProfileTypeInfoCell> newProfileTypeInfoCell =
1018             thread->GetEcmaVM()->GetFactory()->NewProfileTypeInfoCell(handleUndefined);
1019         profileTypeArray->Set(thread, slotId, newProfileTypeInfoCell);
1020         definedFunc->SetRawProfileTypeInfo(thread, newProfileTypeInfoCell);
1021     } else {
1022         auto cellPtr = ProfileTypeInfoCell::Cast(slotValue.GetTaggedObject());
1023         cellPtr->UpdateProfileTypeInfoCellType(thread);
1024         definedFunc->SetRawProfileTypeInfo(thread, slotValue);
1025     }
1026 }
1027 
RuntimeCreateSharedClass(JSThread *thread, const JSHandle<JSTaggedValue> &base, const JSHandle<JSTaggedValue> &constpool, uint16_t methodId, uint16_t literalId, uint16_t length, const JSHandle<JSTaggedValue> &module)1028 JSTaggedValue RuntimeStubs::RuntimeCreateSharedClass(JSThread *thread,
1029                                                      const JSHandle<JSTaggedValue> &base,
1030                                                      const JSHandle<JSTaggedValue> &constpool,
1031                                                      uint16_t methodId, uint16_t literalId,
1032                                                      uint16_t length, const JSHandle<JSTaggedValue> &module)
1033 {
1034     if (!base->IsJSShared() && !base->IsHole()) {
1035         THROW_TYPE_ERROR_AND_RETURN(thread, GET_MESSAGE_STRING(ClassNotDerivedFromShared), JSTaggedValue::Exception());
1036     }
1037     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1038     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1039     CString entry = ModuleManager::GetRecordName(module.GetTaggedValue());
1040 
1041     auto methodObj = ConstantPool::GetMethodFromCache(thread, constpool.GetTaggedValue(), methodId);
1042     JSHandle<JSTaggedValue> method(thread, methodObj);
1043     JSHandle<Method>(method)->SetIsSendable(true);
1044     JSHandle<ConstantPool> constpoolHandle = JSHandle<ConstantPool>::Cast(constpool);
1045 
1046     JSHandle<JSTaggedValue> sendableEnv(thread, JSTaggedValue::Undefined());
1047     if (module->IsSourceTextModule()) {
1048         JSHandle<SourceTextModule> moduleRecord = JSHandle<SourceTextModule>::Cast(module);
1049         sendableEnv = JSHandle<JSTaggedValue>(thread, moduleRecord->GetSendableEnv());
1050     }
1051     auto literalObj = ConstantPool::GetClassLiteralFromCache(
1052         thread, constpoolHandle, literalId, entry, sendableEnv, ClassKind::SENDABLE);
1053     JSHandle<ClassLiteral> classLiteral(thread, literalObj);
1054     JSHandle<TaggedArray> arrayHandle(thread, classLiteral->GetArray());
1055     auto literalLength = arrayHandle->GetLength();
1056     ASSERT(literalLength > 0);
1057     // fieldTypeId is the last element in literal buffer
1058     auto fieldTypeId = static_cast<uint32_t>(arrayHandle->Get(literalLength - 1).GetInt());
1059     // Don't trim array, because define class maybe called on muilt-time in the same vm or diferrent vm
1060     JSHandle<ClassInfoExtractor> extractor = factory->NewClassInfoExtractor(method);
1061     ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(thread, extractor, arrayHandle,
1062                                                            literalLength - 1, ClassKind::SENDABLE);
1063 
1064     JSHandle<TaggedArray> fieldTypeArray = ConstantPool::GetFieldLiteral(thread, constpoolHandle, fieldTypeId, entry);
1065     JSHandle<TaggedArray> staticFieldArray = SendableClassDefiner::ExtractStaticFieldTypeArray(thread, fieldTypeArray);
1066     JSHandle<JSFunction> cls =
1067         SendableClassDefiner::DefineSendableClassFromExtractor(thread, extractor, staticFieldArray);
1068     ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
1069     JSHandle<JSTaggedValue> sendableClsModule = moduleManager->GenerateSendableFuncModule(module);
1070     if (sendableClsModule->IsSourceTextModule()) {
1071         JSHandle<SourceTextModule> sendableClsModuleRecord(sendableClsModule);
1072         sendableClsModuleRecord->SetSendableEnv(thread, sendableEnv);
1073     }
1074     cls->SetModule(thread, sendableClsModule.GetTaggedValue());
1075     RuntimeSetClassConstructorLength(thread, cls.GetTaggedValue(), JSTaggedValue(length));
1076     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1077     RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cls), base, ClassKind::SENDABLE);
1078     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1079 
1080     uint32_t arrayLength = fieldTypeArray->GetLength();
1081     ASSERT(arrayLength > 0);
1082     auto instanceFieldNums = static_cast<uint32_t>(fieldTypeArray->Get(arrayLength - 1).GetInt());
1083     // Don't trim array, because define class maybe called on muilt-time in the same vm or diferrent vm
1084     uint32_t instanceLength = instanceFieldNums * 2;  // 2: key and value
1085     ASSERT(instanceLength < arrayLength);
1086     SendableClassDefiner::DefineSendableInstanceHClass(thread, fieldTypeArray, instanceLength, cls, base);
1087     return cls.GetTaggedValue();
1088 }
1089 
1090 JSTaggedValue RuntimeStubs::RuntimeSetClassInheritanceRelationship(JSThread *thread,
1091                                                                    const JSHandle<JSTaggedValue> &ctor,
1092                                                                    const JSHandle<JSTaggedValue> &base,
1093                                                                    ClassKind kind)
1094 {
1095     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1096     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1097 
1098     ASSERT(ctor->IsJSFunction());
1099     JSHandle<JSTaggedValue> parent = base;
1100 
1101     /*
1102      *         class A / class A extends null                             class A extends B
1103      *                                       a                                                 a
1104      *                                       |                                                 |
1105      *                                       |  __proto__                                      |  __proto__
1106      *                                       |                                                 |
1107      *       A            ---->         A.prototype                  A             ---->    A.prototype
1108      *       |                               |                       |                         |
1109      *       |  __proto__                    |  __proto__            |  __proto__              |  __proto__
1110      *       |                               |                       |                         |
1111      *   Function.prototype       Object.prototype / null            B             ---->    B.prototype
1112      */
1113 
1114     JSHandle<JSTaggedValue> parentPrototype;
1115     // hole means parent is not present
1116     Method *method = Method::Cast(JSHandle<JSFunction>::Cast(ctor)->GetMethod().GetTaggedObject());
1117     if (parent->IsHole()) {
1118         method->SetFunctionKind(FunctionKind::CLASS_CONSTRUCTOR);
1119         parentPrototype =
1120             (kind == ClassKind::SENDABLE) ? env->GetSObjectFunctionPrototype() : env->GetObjectFunctionPrototype();
1121         parent = (kind == ClassKind::SENDABLE) ? env->GetSFunctionPrototype() : env->GetFunctionPrototype();
1122     } else if (parent->IsNull()) {
1123         method->SetFunctionKind(FunctionKind::DERIVED_CONSTRUCTOR);
1124         parentPrototype = JSHandle<JSTaggedValue>(thread, JSTaggedValue::Null());
1125         parent = (kind == ClassKind::SENDABLE) ? env->GetSFunctionPrototype() : env->GetFunctionPrototype();
1126     } else if (!parent->IsConstructor()) {
1127         return RuntimeThrowTypeError(thread, "parent class is not constructor");
1128     } else {
1129         method->SetFunctionKind(FunctionKind::DERIVED_CONSTRUCTOR);
1130         parentPrototype = JSTaggedValue::GetProperty(thread, parent,
1131             globalConst->GetHandledPrototypeString()).GetValue();
1132         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1133         if (!parentPrototype->IsECMAObject() && !parentPrototype->IsNull()) {
1134             return RuntimeThrowTypeError(thread, "parent class have no valid prototype");
1135         }
1136     }
1137 
1138     ctor->GetTaggedObject()->GetClass()->SetPrototype(thread, parent); // __proto__
1139 
1140     JSHandle<JSObject> clsPrototype(thread, JSHandle<JSFunction>(ctor)->GetFunctionPrototype());
1141     clsPrototype->GetClass()->SetPrototype(thread, parentPrototype);
1142 
1143     // ctor -> hclass -> EnableProtoChangeMarker
1144     auto constructor = JSFunction::Cast(ctor.GetTaggedValue().GetTaggedObject());
1145     if (constructor->GetClass()->IsTS()) {
1146         JSHClass::EnableProtoChangeMarker(thread, JSHandle<JSHClass>(thread, constructor->GetClass()));
1147         // prototype -> hclass -> EnableProtoChangeMarker
1148         JSHClass::EnableProtoChangeMarker(thread,
1149             JSHandle<JSHClass>(thread, constructor->GetFunctionPrototype().GetTaggedObject()->GetClass()));
1150     }
1151 
1152     // by enableing the ProtoChangeMarker, the IHC generated in the Aot stage
1153     // is registered into the listener of its prototype. In this way, it is ensured
1154     // that when the prototype changes, the affected IHC can be notified.
1155     JSTaggedValue protoOrHClass = JSHandle<JSFunction>(ctor)->GetProtoOrHClass();
1156     if (protoOrHClass.IsJSHClass()) {
1157         JSHClass *ihc = JSHClass::Cast(protoOrHClass.GetTaggedObject());
1158         if (ihc->IsTS()) {
1159             JSHandle<JSHClass> ihcHandle(thread, ihc);
1160             JSHClass::EnableProtoChangeMarker(thread, ihcHandle);
1161         }
1162     } else {
1163         JSHandle<JSObject> protoHandle(thread, protoOrHClass);
1164         if (protoHandle->GetJSHClass()->IsTS()) {
1165             JSHClass::EnablePHCProtoChangeMarker(thread, JSHandle<JSHClass>(thread, protoHandle->GetJSHClass()));
1166         }
1167     }
1168 
1169     return JSTaggedValue::Undefined();
1170 }
1171 
RuntimeSetClassConstructorLength(JSThread *thread, JSTaggedValue ctor, JSTaggedValue length)1172 JSTaggedValue RuntimeStubs::RuntimeSetClassConstructorLength(JSThread *thread, JSTaggedValue ctor,
1173                                                              JSTaggedValue length)
1174 {
1175     ASSERT(ctor.IsClassConstructor());
1176 
1177     JSFunction* cls = JSFunction::Cast(ctor.GetTaggedObject());
1178     if (LIKELY(!cls->GetClass()->IsDictionaryMode())) {
1179         cls->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, length);
1180     } else {
1181         const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1182         cls->UpdatePropertyInDictionary(thread, globalConst->GetLengthString(), length);
1183     }
1184     return JSTaggedValue::Undefined();
1185 }
1186 
RuntimeNotifyInlineCache(JSThread *thread, const JSHandle<JSFunction> &function, uint32_t icSlotSize)1187 JSTaggedValue RuntimeStubs::RuntimeNotifyInlineCache(JSThread *thread, const JSHandle<JSFunction> &function,
1188                                                      uint32_t icSlotSize)
1189 {
1190     // max ic slot index is 0xffff, the size of ic slot could extend more
1191     ASSERT(icSlotSize <= ProfileTypeInfo::MAX_SLOT_INDEX + MethodLiteral::EXTEND_SLOT_SIZE);
1192     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1193     JSHandle<ProfileTypeInfo> profileTypeInfo;
1194     if (function->IsSharedFunction()) {
1195         return JSTaggedValue::Undefined();
1196     } else {
1197         profileTypeInfo = factory->NewProfileTypeInfo(icSlotSize);
1198     }
1199     Method* method = Method::Cast(function->GetMethod());
1200     auto codeSize = method->GetCodeSize();
1201     if (pgo::PGOProfilerManager::GetInstance()->IsBigMethod(codeSize)) {
1202         LOG_ECMA(DEBUG) << "method size is too large, skip pgo. code size: " << codeSize
1203                         << ", max code size: " << pgo::PGOProfilerManager::GetInstance()->GetMaxAotMethodSize();
1204         profileTypeInfo->SetBigMethodPeriodIndex();
1205     }
1206     JSFunction::SetProfileTypeInfo(thread, function, JSHandle<JSTaggedValue>::Cast(profileTypeInfo));
1207     return profileTypeInfo.GetTaggedValue();
1208 }
1209 
RuntimeStOwnByValueWithNameSet(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value)1210 JSTaggedValue RuntimeStubs::RuntimeStOwnByValueWithNameSet(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
1211                                                            const JSHandle<JSTaggedValue> &key,
1212                                                            const JSHandle<JSTaggedValue> &value)
1213 {
1214     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1215 
1216     if (obj->IsClassConstructor() &&
1217         JSTaggedValue::SameValue(key, globalConst->GetHandledPrototypeString())) {
1218         return RuntimeThrowTypeError(thread, "In a class, static property named 'prototype' throw a TypeError");
1219     }
1220 
1221     // property in class is non-enumerable
1222     bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor());
1223 
1224     PropertyDescriptor desc(thread, value, true, enumerable, true);
1225     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, key);
1226     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1227     bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, propKey, desc);
1228     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1229     if (!ret) {
1230         return RuntimeThrowTypeError(thread, "StOwnByValueWithNameSet failed");
1231     }
1232     if (value->IsJSFunction()) {
1233         if (propKey->IsNumber()) {
1234             propKey = JSHandle<JSTaggedValue>(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()));
1235         }
1236         JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(value), propKey,
1237                                         JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1238     }
1239     return JSTaggedValue::True();
1240 }
1241 
RuntimeStOwnByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &prop, const JSHandle<JSTaggedValue> &value)1242 JSTaggedValue RuntimeStubs::RuntimeStOwnByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
1243                                                const JSHandle<JSTaggedValue> &prop,
1244                                                const JSHandle<JSTaggedValue> &value)
1245 {
1246     ASSERT(prop->IsStringOrSymbol());
1247 
1248     // property in class is non-enumerable
1249     bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor());
1250 
1251     PropertyDescriptor desc(thread, value, true, enumerable, true);
1252     bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, prop, desc);
1253     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1254     if (!ret) {
1255         return RuntimeThrowTypeError(thread, "SetOwnByName failed");
1256     }
1257     return JSTaggedValue::True();
1258 }
1259 
RuntimeStOwnByNameWithNameSet(JSThread *thread, const JSHandle<JSTaggedValue> &objHandle, const JSHandle<JSTaggedValue> &propHandle, const JSHandle<JSTaggedValue> &valueHandle)1260 JSTaggedValue RuntimeStubs::RuntimeStOwnByNameWithNameSet(JSThread *thread,
1261                                                           const JSHandle<JSTaggedValue> &objHandle,
1262                                                           const JSHandle<JSTaggedValue> &propHandle,
1263                                                           const JSHandle<JSTaggedValue> &valueHandle)
1264 {
1265     ASSERT(propHandle->IsStringOrSymbol());
1266     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, propHandle);
1267     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1268     // property in class is non-enumerable
1269     bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor());
1270 
1271     PropertyDescriptor desc(thread, valueHandle, true, enumerable, true);
1272     bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propHandle, desc);
1273     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1274     if (!ret) {
1275         return RuntimeThrowTypeError(thread, "SetOwnByNameWithNameSet failed");
1276     }
1277     JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(valueHandle), propKey,
1278                                     JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1279     return JSTaggedValue::True();
1280 }
1281 
RuntimeSuspendGenerator(JSThread *thread, const JSHandle<JSTaggedValue> &genObj, const JSHandle<JSTaggedValue> &value)1282 JSTaggedValue RuntimeStubs::RuntimeSuspendGenerator(JSThread *thread, const JSHandle<JSTaggedValue> &genObj,
1283                                                     const JSHandle<JSTaggedValue> &value)
1284 {
1285     if (genObj->IsAsyncGeneratorObject()) {
1286         JSHandle<JSAsyncGeneratorObject> generatorObjectHandle(genObj);
1287         JSHandle<GeneratorContext> genContextHandle(thread, generatorObjectHandle->GetGeneratorContext());
1288         // save stack, should copy cur_frame, function execute over will free cur_frame
1289         SaveFrameToContext(thread, genContextHandle);
1290 
1291         // change state to SuspendedYield
1292         if (generatorObjectHandle->IsExecuting()) {
1293             return value.GetTaggedValue();
1294         }
1295         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1296         return generatorObjectHandle.GetTaggedValue();
1297     }
1298 
1299     if (genObj->IsGeneratorObject()) {
1300         JSHandle<JSGeneratorObject> generatorObjectHandle(genObj);
1301         JSHandle<GeneratorContext> genContextHandle(thread, generatorObjectHandle->GetGeneratorContext());
1302         // set TaskInfo for TaskPool
1303         generatorObjectHandle->SetTaskInfo(thread->GetTaskInfo());
1304         // save stack, should copy cur_frame, function execute over will free cur_frame
1305         SaveFrameToContext(thread, genContextHandle);
1306 
1307         // change state to SuspendedYield
1308         if (generatorObjectHandle->IsExecuting()) {
1309             generatorObjectHandle->SetGeneratorState(JSGeneratorState::SUSPENDED_YIELD);
1310             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1311             return value.GetTaggedValue();
1312         }
1313         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1314         return generatorObjectHandle.GetTaggedValue();
1315     }
1316 
1317     return RuntimeThrowTypeError(thread, "RuntimeSuspendGenerator failed");
1318 }
1319 
RuntimeSetGeneratorState(JSThread *thread, const JSHandle<JSTaggedValue> &genObj, const int32_t index)1320 void RuntimeStubs::RuntimeSetGeneratorState(JSThread *thread, const JSHandle<JSTaggedValue> &genObj,
1321                                             const int32_t index)
1322 {
1323     JSHandle<JSAsyncGeneratorObject> generatorObjectHandle(genObj);
1324     JSHandle<GeneratorContext> genContextHandle(thread, generatorObjectHandle->GetGeneratorContext());
1325 
1326     // change state
1327     switch (index) {
1328         case static_cast<int32_t>(JSAsyncGeneratorState::SUSPENDED_START):
1329             generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_START);
1330             break;
1331         case static_cast<int32_t>(JSAsyncGeneratorState::SUSPENDED_YIELD):
1332             generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_YIELD);
1333             break;
1334         case static_cast<int32_t>(JSAsyncGeneratorState::EXECUTING):
1335             generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::EXECUTING);
1336             break;
1337         case static_cast<int32_t>(JSAsyncGeneratorState::COMPLETED):
1338             generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::COMPLETED);
1339             break;
1340         case static_cast<int32_t>(JSAsyncGeneratorState::AWAITING_RETURN):
1341             generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::AWAITING_RETURN);
1342             break;
1343         default:
1344             LOG_ECMA(FATAL) << "this branch is unreachable";
1345             UNREACHABLE();
1346     }
1347 }
1348 
RuntimeGetModuleNamespace(JSThread *thread, int32_t index)1349 JSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, int32_t index)
1350 {
1351     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(index);
1352 }
1353 
RuntimeGetModuleNamespace(JSThread *thread, int32_t index, JSTaggedValue jsFunc)1354 JSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, int32_t index,
1355                                                       JSTaggedValue jsFunc)
1356 {
1357     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(index, jsFunc);
1358 }
1359 
RuntimeGetModuleNamespace(JSThread *thread, JSTaggedValue localName)1360 JSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, JSTaggedValue localName)
1361 {
1362     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(localName);
1363 }
1364 
RuntimeGetModuleNamespace(JSThread *thread, JSTaggedValue localName, JSTaggedValue jsFunc)1365 JSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, JSTaggedValue localName,
1366                                                       JSTaggedValue jsFunc)
1367 {
1368     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(localName, jsFunc);
1369 }
1370 
RuntimeStModuleVar(JSThread *thread, int32_t index, JSTaggedValue value)1371 void RuntimeStubs::RuntimeStModuleVar(JSThread *thread, int32_t index, JSTaggedValue value)
1372 {
1373     thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(index, value);
1374 }
1375 
RuntimeStModuleVar(JSThread *thread, int32_t index, JSTaggedValue value, JSTaggedValue jsFunc)1376 void RuntimeStubs::RuntimeStModuleVar(JSThread *thread, int32_t index, JSTaggedValue value,
1377                                       JSTaggedValue jsFunc)
1378 {
1379     thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(index, value, jsFunc);
1380 }
1381 
RuntimeStModuleVar(JSThread *thread, JSTaggedValue key, JSTaggedValue value)1382 void RuntimeStubs::RuntimeStModuleVar(JSThread *thread, JSTaggedValue key, JSTaggedValue value)
1383 {
1384     thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(key, value);
1385 }
1386 
RuntimeStModuleVar(JSThread *thread, JSTaggedValue key, JSTaggedValue value, JSTaggedValue jsFunc)1387 void RuntimeStubs::RuntimeStModuleVar(JSThread *thread, JSTaggedValue key, JSTaggedValue value,
1388                                       JSTaggedValue jsFunc)
1389 {
1390     thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(key, value, jsFunc);
1391 }
1392 
RuntimeLdLocalModuleVar(JSThread *thread, int32_t index)1393 JSTaggedValue RuntimeStubs::RuntimeLdLocalModuleVar(JSThread *thread, int32_t index)
1394 {
1395     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(index);
1396 }
1397 
RuntimeLdLocalModuleVarWithModule(JSThread* thread, int32_t index, JSHandle<JSTaggedValue> moduleHdl)1398 inline JSTaggedValue RuntimeStubs::RuntimeLdLocalModuleVarWithModule(JSThread* thread, int32_t index,
1399     JSHandle<JSTaggedValue> moduleHdl)
1400 {
1401     JSTaggedValue module = moduleHdl.GetTaggedValue();
1402     ModuleManager* mmgr = thread->GetCurrentEcmaContext()->GetModuleManager();
1403     if (SourceTextModule::IsSendableFunctionModule(module)) {
1404         const CString recordNameStr = SourceTextModule::GetModuleName(module);
1405         module = mmgr->HostGetImportedModule(recordNameStr).GetTaggedValue();
1406     }
1407     return SourceTextModule::Cast(module)->GetModuleValue(thread, index, false);
1408 }
1409 
RuntimeLdLocalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc)1410 JSTaggedValue RuntimeStubs::RuntimeLdLocalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc)
1411 {
1412     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(index, jsFunc);
1413 }
1414 
RuntimeLdExternalModuleVar(JSThread *thread, int32_t index)1415 JSTaggedValue RuntimeStubs::RuntimeLdExternalModuleVar(JSThread *thread, int32_t index)
1416 {
1417     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(index);
1418 }
1419 
RuntimeLdExternalModuleVarWithModule(JSThread* thread, int32_t index, JSHandle<JSTaggedValue> moduleHdl)1420 inline JSTaggedValue RuntimeStubs::RuntimeLdExternalModuleVarWithModule(JSThread* thread, int32_t index,
1421     JSHandle<JSTaggedValue> moduleHdl)
1422 {
1423     JSTaggedValue module = moduleHdl.GetTaggedValue();
1424     ModuleManager* mmgr = thread->GetCurrentEcmaContext()->GetModuleManager();
1425     if (SourceTextModule::IsSendableFunctionModule(module)) {
1426         const CString recordNameStr = SourceTextModule::GetModuleName(module);
1427         module = mmgr->HostGetImportedModule(recordNameStr).GetTaggedValue();
1428         moduleHdl = JSHandle<JSTaggedValue>(thread, module);
1429     }
1430     return mmgr->GetModuleValueOutter(index, moduleHdl);
1431 }
1432 
RuntimeLdSendableExternalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc)1433 JSTaggedValue RuntimeStubs::RuntimeLdSendableExternalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc)
1434 {
1435     return SharedModuleManager::GetInstance()->GetSendableModuleValue(thread, index, jsFunc);
1436 }
1437 
RuntimeLdExternalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc)1438 JSTaggedValue RuntimeStubs::RuntimeLdExternalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc)
1439 {
1440     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(index, jsFunc);
1441 }
1442 
RuntimeLdLazyExternalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc)1443 JSTaggedValue RuntimeStubs::RuntimeLdLazyExternalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc)
1444 {
1445     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetLazyModuleValueOutter(index, jsFunc);
1446 }
1447 
RuntimeLdLazySendableExternalModuleVar( JSThread *thread, int32_t index, JSTaggedValue jsFunc)1448 JSTaggedValue RuntimeStubs::RuntimeLdLazySendableExternalModuleVar(
1449     JSThread *thread, int32_t index, JSTaggedValue jsFunc)
1450 {
1451     return SharedModuleManager::GetInstance()->GetLazySendableModuleValue(thread, index, jsFunc);
1452 }
1453 
RuntimeLdModuleVar(JSThread *thread, JSTaggedValue key, bool inner)1454 JSTaggedValue RuntimeStubs::RuntimeLdModuleVar(JSThread *thread, JSTaggedValue key, bool inner)
1455 {
1456     if (inner) {
1457         JSTaggedValue moduleValue = thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(key);
1458         return moduleValue;
1459     }
1460 
1461     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(key);
1462 }
1463 
RuntimeLdModuleVar(JSThread *thread, JSTaggedValue key, bool inner, JSTaggedValue jsFunc)1464 JSTaggedValue RuntimeStubs::RuntimeLdModuleVar(JSThread *thread, JSTaggedValue key, bool inner,
1465                                                JSTaggedValue jsFunc)
1466 {
1467     if (inner) {
1468         JSTaggedValue moduleValue =
1469             thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(key, jsFunc);
1470         return moduleValue;
1471     }
1472 
1473     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(key, jsFunc);
1474 }
1475 
RuntimeGetPropIterator(JSThread *thread, const JSHandle<JSTaggedValue> &value)1476 JSTaggedValue RuntimeStubs::RuntimeGetPropIterator(JSThread *thread, const JSHandle<JSTaggedValue> &value)
1477 {
1478     JSHandle<JSForInIterator> iteratorHandle = JSObject::EnumerateObjectProperties(thread, value);
1479     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1480     return iteratorHandle.GetTaggedValue();
1481 }
1482 
RuntimeAsyncFunctionEnter(JSThread *thread)1483 JSTaggedValue RuntimeStubs::RuntimeAsyncFunctionEnter(JSThread *thread)
1484 {
1485     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1486     // 1. create promise
1487     JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
1488     JSHandle<JSFunction> promiseFunc(globalEnv->GetPromiseFunction());
1489 
1490     JSHandle<JSPromise> promiseObject(factory->NewJSObjectByConstructor(promiseFunc));
1491     promiseObject->SetPromiseState(PromiseState::PENDING);
1492     // 2. create asyncfuncobj
1493     JSHandle<JSAsyncFuncObject> asyncFuncObj = factory->NewJSAsyncFuncObject();
1494     asyncFuncObj->SetPromise(thread, promiseObject);
1495 
1496     JSHandle<GeneratorContext> context = factory->NewGeneratorContext();
1497     context->SetGeneratorObject(thread, asyncFuncObj);
1498 
1499     // change state to EXECUTING
1500     asyncFuncObj->SetGeneratorState(JSGeneratorState::EXECUTING);
1501     asyncFuncObj->SetGeneratorContext(thread, context);
1502 
1503     // 3. return asyncfuncobj
1504     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1505     return asyncFuncObj.GetTaggedValue();
1506 }
1507 
RuntimeGetIterator(JSThread *thread, const JSHandle<JSTaggedValue> &obj)1508 JSTaggedValue RuntimeStubs::RuntimeGetIterator(JSThread *thread, const JSHandle<JSTaggedValue> &obj)
1509 {
1510     EcmaVM *vm = thread->GetEcmaVM();
1511     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1512     JSHandle<JSTaggedValue> valuesFunc =
1513         JSTaggedValue::GetProperty(thread, obj, env->GetIteratorSymbol()).GetValue();
1514     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1515     if (!valuesFunc->IsCallable()) {
1516         return valuesFunc.GetTaggedValue();
1517     }
1518 
1519     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1520     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, valuesFunc, obj, undefined, 0);
1521     return EcmaInterpreter::Execute(info);
1522 }
1523 
RuntimeGetAsyncIterator(JSThread *thread, const JSHandle<JSTaggedValue> &obj)1524 JSTaggedValue RuntimeStubs::RuntimeGetAsyncIterator(JSThread *thread, const JSHandle<JSTaggedValue> &obj)
1525 {
1526     JSHandle<JSTaggedValue> asyncit = JSIterator::GetAsyncIterator(thread, obj);
1527     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1528     return asyncit.GetTaggedValue();
1529 }
1530 
RuntimeLdPrivateProperty(JSThread *thread, JSTaggedValue lexicalEnv, uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj)1531 JSTaggedValue RuntimeStubs::RuntimeLdPrivateProperty(JSThread *thread, JSTaggedValue lexicalEnv,
1532     uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj)
1533 {
1534     JSTaggedValue currentLexicalEnv = lexicalEnv;
1535     for (uint32_t i = 0; i < levelIndex; i++) {
1536         currentLexicalEnv = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetParentEnv();
1537         ASSERT(!currentLexicalEnv.IsUndefined());
1538     }
1539     JSTaggedValue key = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetProperties(slotIndex);
1540     // private property is invisible for proxy
1541     JSHandle<JSTaggedValue> handleObj(thread, obj.IsJSProxy() ? JSProxy::Cast(obj)->GetPrivateField() : obj);
1542     JSHandle<JSTaggedValue> handleKey(thread, key);
1543     if (handleKey->IsJSFunction()) {  // getter
1544         JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1545         // 0: getter has 0 arg
1546         EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, handleKey, handleObj, undefined, 0);
1547         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1548         JSTaggedValue resGetter = JSFunction::Call(info);
1549         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1550         return resGetter;
1551     }
1552     PropertyDescriptor desc(thread);
1553     if (!JSTaggedValue::IsPropertyKey(handleKey) ||
1554         !JSTaggedValue::GetOwnProperty(thread, handleObj, handleKey, desc)) {
1555         THROW_TYPE_ERROR_AND_RETURN(thread, "invalid or cannot find private key", JSTaggedValue::Exception());
1556     }
1557     JSTaggedValue res = desc.GetValue().GetTaggedValue();
1558     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1559     return res;
1560 }
1561 
RuntimeStPrivateProperty(JSThread *thread, JSTaggedValue lexicalEnv, uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj, JSTaggedValue value)1562 JSTaggedValue RuntimeStubs::RuntimeStPrivateProperty(JSThread *thread, JSTaggedValue lexicalEnv,
1563     uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj, JSTaggedValue value)
1564 {
1565     JSTaggedValue currentLexicalEnv = lexicalEnv;
1566     for (uint32_t i = 0; i < levelIndex; i++) {
1567         currentLexicalEnv = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetParentEnv();
1568         ASSERT(!currentLexicalEnv.IsUndefined());
1569     }
1570     JSTaggedValue key = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetProperties(slotIndex);
1571     // private property is invisible for proxy
1572     JSHandle<JSTaggedValue> handleObj(thread, obj.IsJSProxy() ? JSProxy::Cast(obj)->GetPrivateField() : obj);
1573     JSHandle<JSTaggedValue> handleKey(thread, key);
1574     JSHandle<JSTaggedValue> handleValue(thread, value);
1575     if (handleKey->IsJSFunction()) {  // setter
1576         JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1577         // 1: setter has 1 arg
1578         EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, handleKey, handleObj, undefined, 1);
1579         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1580         info->SetCallArg(handleValue.GetTaggedValue());
1581         JSTaggedValue resSetter = JSFunction::Call(info);
1582         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1583         return resSetter;
1584     }
1585     PropertyDescriptor desc(thread);
1586     if (!JSTaggedValue::IsPropertyKey(handleKey) ||
1587         !JSTaggedValue::GetOwnProperty(thread, handleObj, handleKey, desc)) {
1588         THROW_TYPE_ERROR_AND_RETURN(thread, "invalid or cannot find private key", JSTaggedValue::Exception());
1589     }
1590     desc.SetValue(handleValue);
1591     bool res = JSTaggedValue::DefineOwnProperty(thread, handleObj, handleKey, desc);
1592     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1593     return JSTaggedValue(res);
1594 }
1595 
RuntimeTestIn(JSThread *thread, JSTaggedValue lexicalEnv, uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj)1596 JSTaggedValue RuntimeStubs::RuntimeTestIn(JSThread *thread, JSTaggedValue lexicalEnv,
1597     uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj)
1598 {
1599     if (!obj.IsECMAObject()) {
1600         THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot use 'in' operator in Non-Object", JSTaggedValue::Exception());
1601     }
1602     JSTaggedValue currentLexicalEnv = lexicalEnv;
1603     for (uint32_t i = 0; i < levelIndex; i++) {
1604         currentLexicalEnv = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetParentEnv();
1605         ASSERT(!currentLexicalEnv.IsUndefined());
1606     }
1607     JSTaggedValue key = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetProperties(slotIndex);
1608     JSHandle<JSTaggedValue> handleObj(thread, obj.IsJSProxy() ? JSProxy::Cast(obj)->GetPrivateField() : obj);
1609     JSHandle<JSTaggedValue> handleKey(thread, key);
1610     bool res = JSTaggedValue::IsPropertyKey(handleKey) && JSTaggedValue::HasProperty(thread, handleObj, handleKey);
1611     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1612     return JSTaggedValue(res);
1613 }
1614 
RuntimeThrow(JSThread *thread, JSTaggedValue value)1615 void RuntimeStubs::RuntimeThrow(JSThread *thread, JSTaggedValue value)
1616 {
1617     thread->SetException(value);
1618 }
1619 
RuntimeThrowThrowNotExists(JSThread *thread)1620 void RuntimeStubs::RuntimeThrowThrowNotExists(JSThread *thread)
1621 {
1622     THROW_TYPE_ERROR(thread, "Throw method is not defined");
1623 }
1624 
RuntimeThrowPatternNonCoercible(JSThread *thread)1625 void RuntimeStubs::RuntimeThrowPatternNonCoercible(JSThread *thread)
1626 {
1627     JSHandle<EcmaString> msg(thread->GlobalConstants()->GetHandledObjNotCoercibleString());
1628     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1629     THROW_NEW_ERROR_AND_RETURN(thread,
1630         factory->NewJSError(base::ErrorType::TYPE_ERROR, msg, StackCheck::NO).GetTaggedValue());
1631 }
1632 
RuntimeThrowDeleteSuperProperty(JSThread *thread)1633 void RuntimeStubs::RuntimeThrowDeleteSuperProperty(JSThread *thread)
1634 {
1635     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1636     JSHandle<EcmaString> info = factory->NewFromASCII("Can not delete super property");
1637     JSHandle<JSObject> errorObj = factory->NewJSError(base::ErrorType::REFERENCE_ERROR, info,  StackCheck::NO);
1638     THROW_NEW_ERROR_AND_RETURN(thread, errorObj.GetTaggedValue());
1639 }
1640 
RuntimeThrowUndefinedIfHole(JSThread *thread, const JSHandle<EcmaString> &obj)1641 void RuntimeStubs::RuntimeThrowUndefinedIfHole(JSThread *thread, const JSHandle<EcmaString> &obj)
1642 {
1643     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1644     JSHandle<EcmaString> info = factory->NewFromASCII(" is not initialized");
1645 
1646     JSHandle<EcmaString> msg = factory->ConcatFromString(obj, info);
1647     THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::REFERENCE_ERROR,
1648         msg, StackCheck::NO).GetTaggedValue());
1649 }
1650 
RuntimeThrowIfNotObject(JSThread *thread)1651 void RuntimeStubs::RuntimeThrowIfNotObject(JSThread *thread)
1652 {
1653     THROW_TYPE_ERROR(thread, "Inner return result is not object");
1654 }
1655 
RuntimeThrowConstAssignment(JSThread *thread, const JSHandle<EcmaString> &value)1656 void RuntimeStubs::RuntimeThrowConstAssignment(JSThread *thread, const JSHandle<EcmaString> &value)
1657 {
1658     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1659 
1660     JSHandle<EcmaString> info = factory->NewFromASCII("Assignment to const variable ");
1661 
1662     JSHandle<EcmaString> msg = factory->ConcatFromString(info, value);
1663     THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::TYPE_ERROR,
1664                                                            msg, StackCheck::NO).GetTaggedValue());
1665 }
1666 
RuntimeLdGlobalRecord(JSThread *thread, JSTaggedValue key)1667 JSTaggedValue RuntimeStubs::RuntimeLdGlobalRecord(JSThread *thread, JSTaggedValue key)
1668 {
1669     EcmaVM *vm = thread->GetEcmaVM();
1670     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1671     GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
1672     int entry = dict->FindEntry(key);
1673     if (entry != -1) {
1674         return JSTaggedValue(dict->GetBox(entry));
1675     }
1676     return JSTaggedValue::Undefined();
1677 }
1678 
RuntimeTryLdGlobalByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> &prop)1679 JSTaggedValue RuntimeStubs::RuntimeTryLdGlobalByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
1680                                                      const JSHandle<JSTaggedValue> &prop)
1681 {
1682     OperationResult res = JSTaggedValue::GetProperty(thread, obj, prop);
1683     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1684     if (!res.GetPropertyMetaData().IsFound()) {
1685         return RuntimeThrowReferenceError(thread, prop, " is not defined");
1686     }
1687     return res.GetValue().GetTaggedValue();
1688 }
1689 
RuntimeTryUpdateGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value)1690 JSTaggedValue RuntimeStubs::RuntimeTryUpdateGlobalRecord(JSThread *thread, JSTaggedValue prop,
1691                                                          JSTaggedValue value)
1692 {
1693     EcmaVM *vm = thread->GetEcmaVM();
1694     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1695     GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
1696     int entry = dict->FindEntry(prop);
1697     ASSERT(entry != -1);
1698 
1699     if (dict->GetAttributes(entry).IsConstProps()) {
1700         return RuntimeThrowTypeError(thread, "const variable can not be modified");
1701     }
1702 
1703     PropertyBox *box = dict->GetBox(entry);
1704     box->SetValue(thread, value);
1705     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1706     return JSTaggedValue::True();
1707 }
1708 
RuntimeThrowReferenceError(JSThread *thread, const JSHandle<JSTaggedValue> &prop, const char *desc)1709 JSTaggedValue RuntimeStubs::RuntimeThrowReferenceError(JSThread *thread, const JSHandle<JSTaggedValue> &prop,
1710                                                        const char *desc)
1711 {
1712     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1713     JSHandle<EcmaString> propName = JSTaggedValue::ToString(thread, prop);
1714     ASSERT_NO_ABRUPT_COMPLETION(thread);
1715     JSHandle<EcmaString> info = factory->NewFromUtf8(desc);
1716     JSHandle<EcmaString> msg = factory->ConcatFromString(propName, info);
1717     THROW_NEW_ERROR_AND_RETURN_VALUE(thread,
1718         factory->NewJSError(base::ErrorType::REFERENCE_ERROR, msg, StackCheck::NO).GetTaggedValue(),
1719         JSTaggedValue::Exception());
1720 }
1721 
RuntimeLdGlobalVarFromProto(JSThread *thread, const JSHandle<JSTaggedValue> &globalObj, const JSHandle<JSTaggedValue> &prop)1722 JSTaggedValue RuntimeStubs::RuntimeLdGlobalVarFromProto(JSThread *thread, const JSHandle<JSTaggedValue> &globalObj,
1723                                                         const JSHandle<JSTaggedValue> &prop)
1724 {
1725     ASSERT(globalObj->IsJSGlobalObject());
1726     JSHandle<JSObject> global(globalObj);
1727     JSHandle<JSTaggedValue> obj(thread, JSObject::GetPrototype(global));
1728     OperationResult res = JSTaggedValue::GetProperty(thread, obj, prop);
1729     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1730     return res.GetValue().GetTaggedValue();
1731 }
1732 
RuntimeStGlobalVar(JSThread *thread, const JSHandle<JSTaggedValue> &prop, const JSHandle<JSTaggedValue> &value)1733 JSTaggedValue RuntimeStubs::RuntimeStGlobalVar(JSThread *thread, const JSHandle<JSTaggedValue> &prop,
1734                                                const JSHandle<JSTaggedValue> &value)
1735 {
1736     JSHandle<JSTaggedValue> global(thread, thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject());
1737 
1738     JSObject::GlobalSetProperty(thread, prop, value, true);
1739     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1740     return JSTaggedValue::True();
1741 }
1742 
RuntimeToNumber(JSThread *thread, const JSHandle<JSTaggedValue> &value)1743 JSTaggedValue RuntimeStubs::RuntimeToNumber(JSThread *thread, const JSHandle<JSTaggedValue> &value)
1744 {
1745     return JSTaggedValue::ToNumber(thread, value);
1746 }
1747 
RuntimeToNumeric(JSThread *thread, const JSHandle<JSTaggedValue> &value)1748 JSTaggedValue RuntimeStubs::RuntimeToNumeric(JSThread *thread, const JSHandle<JSTaggedValue> &value)
1749 {
1750     return JSTaggedValue::ToNumeric(thread, value).GetTaggedValue();
1751 }
1752 
RuntimeDynamicImport(JSThread *thread, const JSHandle<JSTaggedValue> &specifier, const JSHandle<JSTaggedValue> &func)1753 JSTaggedValue RuntimeStubs::RuntimeDynamicImport(JSThread *thread, const JSHandle<JSTaggedValue> &specifier,
1754     const JSHandle<JSTaggedValue> &func)
1755 {
1756     EcmaVM *ecmaVm = thread->GetEcmaVM();
1757     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
1758     ObjectFactory *factory = ecmaVm->GetFactory();
1759 
1760     // get current filename
1761     JSFunction *function = JSFunction::Cast(func->GetTaggedObject());
1762     const JSPandaFile *jsPandaFile = function->GetCallTarget()->GetJSPandaFile();
1763     ASSERT(jsPandaFile != nullptr);
1764     CString currentfilename = jsPandaFile->GetJSPandaFileDesc();
1765 
1766     JSMutableHandle<JSTaggedValue> dirPath(thread, thread->GlobalConstants()->GetUndefined());
1767     JSMutableHandle<JSTaggedValue> recordName(thread, thread->GlobalConstants()->GetUndefined());
1768     if (jsPandaFile->IsBundlePack()) {
1769         dirPath.Update(factory->NewFromUtf8(currentfilename).GetTaggedValue());
1770     } else {
1771         recordName.Update(factory->NewFromUtf8(function->GetRecordName()));
1772         dirPath.Update(factory->NewFromUtf8(currentfilename).GetTaggedValue());
1773     }
1774 
1775     // 4. Let promiseCapability be !NewPromiseCapability(%Promise%).
1776     JSHandle<JSTaggedValue> promiseFunc = env->GetPromiseFunction();
1777     JSHandle<PromiseCapability> promiseCapability = JSPromise::NewPromiseCapability(thread, promiseFunc);
1778     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1779     JSHandle<job::MicroJobQueue> job = thread->GetCurrentEcmaContext()->GetMicroJobQueue();
1780 
1781     JSHandle<TaggedArray> argv = factory->NewTaggedArray(5); // 5: 5 means parameters stored in array
1782     argv->Set(thread, 0, promiseCapability->GetResolve());
1783     argv->Set(thread, 1, promiseCapability->GetReject());    // 1 : reject method
1784     argv->Set(thread, 2, dirPath);                           // 2 : current file path(containing file name)
1785     argv->Set(thread, 3, specifier);                         // 3 : request module's path
1786     argv->Set(thread, 4, recordName);                        // 4 : js recordName or undefined
1787 
1788     JSHandle<JSFunction> dynamicImportJob(env->GetDynamicImportJob());
1789     job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, dynamicImportJob, argv);
1790 
1791     return promiseCapability->GetPromise();
1792 }
1793 
RuntimeEq(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1794 JSTaggedValue RuntimeStubs::RuntimeEq(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1795                                       const JSHandle<JSTaggedValue> &right)
1796 {
1797     bool ret = JSTaggedValue::Equal(thread, left, right);
1798     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1799     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
1800 }
1801 
RuntimeNotEq(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1802 JSTaggedValue RuntimeStubs::RuntimeNotEq(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1803                                          const JSHandle<JSTaggedValue> &right)
1804 {
1805     bool ret = JSTaggedValue::Equal(thread, left, right);
1806     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1807     return (ret ? JSTaggedValue::False() : JSTaggedValue::True());
1808 }
1809 
RuntimeLess(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1810 JSTaggedValue RuntimeStubs::RuntimeLess(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1811                                         const JSHandle<JSTaggedValue> &right)
1812 {
1813     bool ret = JSTaggedValue::Compare(thread, left, right) == ComparisonResult::LESS;
1814     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1815     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
1816 }
1817 
RuntimeLessEq(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1818 JSTaggedValue RuntimeStubs::RuntimeLessEq(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1819                                           const JSHandle<JSTaggedValue> &right)
1820 {
1821     bool ret = JSTaggedValue::Compare(thread, left, right) <= ComparisonResult::EQUAL;
1822     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1823     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
1824 }
1825 
RuntimeGreater(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1826 JSTaggedValue RuntimeStubs::RuntimeGreater(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1827                                            const JSHandle<JSTaggedValue> &right)
1828 {
1829     bool ret = JSTaggedValue::Compare(thread, left, right) == ComparisonResult::GREAT;
1830     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1831     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
1832 }
1833 
RuntimeGreaterEq(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1834 JSTaggedValue RuntimeStubs::RuntimeGreaterEq(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1835                                              const JSHandle<JSTaggedValue> &right)
1836 {
1837     ComparisonResult comparison = JSTaggedValue::Compare(thread, left, right);
1838     bool ret = (comparison == ComparisonResult::GREAT) || (comparison == ComparisonResult::EQUAL);
1839     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1840     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
1841 }
1842 
RuntimeAdd2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1843 JSTaggedValue RuntimeStubs::RuntimeAdd2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1844                                         const JSHandle<JSTaggedValue> &right)
1845 {
1846     if (left->IsString() && right->IsString()) {
1847         EcmaString *resultStr = EcmaStringAccessor::Concat(
1848             thread->GetEcmaVM(), JSHandle<EcmaString>(left), JSHandle<EcmaString>(right));
1849         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1850         return JSTaggedValue(resultStr);
1851     }
1852     JSHandle<JSTaggedValue> primitiveA0(thread, JSTaggedValue::ToPrimitive(thread, left));
1853     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1854     JSHandle<JSTaggedValue> primitiveA1(thread, JSTaggedValue::ToPrimitive(thread, right));
1855     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1856     // contain string
1857     if (primitiveA0->IsString() || primitiveA1->IsString()) {
1858         JSHandle<EcmaString> stringA0 = JSTaggedValue::ToString(thread, primitiveA0);
1859         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1860         JSHandle<EcmaString> stringA1 = JSTaggedValue::ToString(thread, primitiveA1);
1861         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1862         EcmaString *resultStr = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1);
1863         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1864         return JSTaggedValue(resultStr);
1865     }
1866     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, primitiveA0);
1867     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1868     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, primitiveA1);
1869     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1870     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1871         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1872             JSHandle<BigInt> bigLeft(valLeft);
1873             JSHandle<BigInt> bigRight(valRight);
1874             return BigInt::Add(thread, bigLeft, bigRight).GetTaggedValue();
1875         }
1876         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1877     }
1878     double doubleA0 = valLeft->GetNumber();
1879     double doubleA1 = valRight->GetNumber();
1880     return JSTaggedValue(doubleA0 + doubleA1);
1881 }
1882 
RuntimeShl2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1883 JSTaggedValue RuntimeStubs::RuntimeShl2(JSThread *thread,
1884                                         const JSHandle<JSTaggedValue> &left,
1885                                         const JSHandle<JSTaggedValue> &right)
1886 {
1887     JSHandle<JSTaggedValue> leftValue = JSTaggedValue::ToNumeric(thread, left);
1888     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1889     JSHandle<JSTaggedValue> rightValue = JSTaggedValue::ToNumeric(thread, right);
1890     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1891     if (leftValue->IsBigInt() || rightValue->IsBigInt()) {
1892         if (leftValue->IsBigInt() && rightValue->IsBigInt()) {
1893             JSHandle<BigInt> leftBigint(leftValue);
1894             JSHandle<BigInt> rightBigint(rightValue);
1895             return BigInt::LeftShift(thread, leftBigint, rightBigint).GetTaggedValue();
1896         }
1897         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1898     }
1899     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, leftValue);
1900     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1901     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, rightValue);
1902     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1903     int32_t opNumber0 = taggedNumber0.GetInt();
1904     int32_t opNumber1 = taggedNumber1.GetInt();
1905     uint32_t shift =
1906             static_cast<uint32_t>(opNumber1) & 0x1f;  // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1907     using unsigned_type = std::make_unsigned_t<int32_t>;
1908     auto ret =
1909             static_cast<int32_t>(static_cast<unsigned_type>(opNumber0) << shift);  // NOLINT(hicpp-signed-bitwise)
1910     return JSTaggedValue(ret);
1911 }
1912 
RuntimeShr2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1913 JSTaggedValue RuntimeStubs::RuntimeShr2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1914                                         const JSHandle<JSTaggedValue> &right)
1915 {
1916     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1917     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1918     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1919     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1920     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1921         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1922             return BigInt::UnsignedRightShift(thread);
1923         }
1924         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1925     }
1926     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft);
1927     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1928     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight);
1929     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1930     int32_t opNumber0 = taggedNumber0.GetInt();
1931     int32_t opNumber1 = taggedNumber1.GetInt();
1932     uint32_t shift = static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1933     using unsigned_type = std::make_unsigned_t<uint32_t>;
1934     auto ret =
1935             static_cast<uint32_t>(static_cast<unsigned_type>(opNumber0) >> shift); // NOLINT(hicpp-signed-bitwise)
1936     return JSTaggedValue(ret);
1937 }
1938 
RuntimeSub2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1939 JSTaggedValue RuntimeStubs::RuntimeSub2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1940                                         const JSHandle<JSTaggedValue> &right)
1941 {
1942     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1943     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1944     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1945     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1946     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1947         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1948             JSHandle<BigInt> bigLeft(valLeft);
1949             JSHandle<BigInt> bigRight(valRight);
1950             return BigInt::Subtract(thread, bigLeft, bigRight).GetTaggedValue();
1951         }
1952         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1953     }
1954     JSTaggedNumber number0(valLeft.GetTaggedValue());
1955     JSTaggedNumber number1(valRight.GetTaggedValue());
1956     return number0 - number1;
1957 }
1958 
RuntimeMul2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1959 JSTaggedValue RuntimeStubs::RuntimeMul2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1960                                         const JSHandle<JSTaggedValue> &right)
1961 {
1962     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1963     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1964     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1965     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1966     // 9. ReturnIfAbrupt(rnum).
1967     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1968         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1969             JSHandle<BigInt> bigLeft(valLeft);
1970             JSHandle<BigInt> bigRight(valRight);
1971             return BigInt::Multiply(thread, bigLeft, bigRight).GetTaggedValue();
1972         }
1973         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1974     }
1975     // 12.6.3.1 Applying the * Operator
1976     JSTaggedNumber number0(valLeft.GetTaggedValue());
1977     JSTaggedNumber number1(valRight.GetTaggedValue());
1978     return number0 * number1;
1979 }
1980 
RuntimeDiv2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)1981 JSTaggedValue RuntimeStubs::RuntimeDiv2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1982                                         const JSHandle<JSTaggedValue> &right)
1983 {
1984     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1985     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1986     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1987     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1988     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1989         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1990             JSHandle<BigInt> bigLeft(valLeft);
1991             JSHandle<BigInt> bigRight(valRight);
1992             return BigInt::Divide(thread, bigLeft, bigRight).GetTaggedValue();
1993         }
1994         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1995     }
1996     double dLeft = valLeft->GetNumber();
1997     double dRight = valRight->GetNumber();
1998     if (dRight == 0) {
1999         if (dLeft == 0 || std::isnan(dLeft)) {
2000             return JSTaggedValue(base::NAN_VALUE);
2001         }
2002         bool positive = (((base::bit_cast<uint64_t>(dRight)) & base::DOUBLE_SIGN_MASK) ==
2003                          ((base::bit_cast<uint64_t>(dLeft)) & base::DOUBLE_SIGN_MASK));
2004         return JSTaggedValue(positive ? base::POSITIVE_INFINITY : -base::POSITIVE_INFINITY);
2005     }
2006     return JSTaggedValue(dLeft / dRight);
2007 }
2008 
RuntimeMod2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)2009 JSTaggedValue RuntimeStubs::RuntimeMod2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
2010                                         const JSHandle<JSTaggedValue> &right)
2011 {
2012     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
2013     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2014     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
2015     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2016 
2017     // 12.6.3.3 Applying the % Operator
2018     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
2019         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
2020             JSHandle<BigInt> leftBigint(valLeft);
2021             JSHandle<BigInt> rightBigint(valRight);
2022             return BigInt::Remainder(thread, leftBigint, rightBigint).GetTaggedValue();
2023         }
2024         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
2025     }
2026     double dLeft = valLeft->GetNumber();
2027     double dRight = valRight->GetNumber();
2028     // 12.6.3.3 Applying the % Operator
2029     if ((dRight == 0.0) || std::isnan(dRight) || std::isnan(dLeft) || std::isinf(dLeft)) {
2030         return JSTaggedValue(base::NAN_VALUE);
2031     }
2032     if ((dLeft == 0.0) || std::isinf(dRight)) {
2033         return JSTaggedValue(dLeft);
2034     }
2035     return JSTaggedValue(std::fmod(dLeft, dRight));
2036 }
2037 
RuntimeAshr2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)2038 JSTaggedValue RuntimeStubs::RuntimeAshr2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
2039                                          const JSHandle<JSTaggedValue> &right)
2040 {
2041     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
2042     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2043     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
2044     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2045     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
2046         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
2047             JSHandle<BigInt> bigLeft(valLeft);
2048             JSHandle<BigInt> bigRight(valRight);
2049             return BigInt::SignedRightShift(thread, bigLeft, bigRight).GetTaggedValue();
2050         }
2051         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
2052     }
2053     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft);
2054     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2055     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight);
2056     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2057     int32_t opNumber0 = taggedNumber0.GetInt();
2058     int32_t opNumber1 = taggedNumber1.GetInt();
2059     uint32_t shift = static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
2060     auto ret = static_cast<int32_t>(opNumber0 >> shift); // NOLINT(hicpp-signed-bitwise)
2061     return JSTaggedValue(ret);
2062 }
2063 
RuntimeAnd2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)2064 JSTaggedValue RuntimeStubs::RuntimeAnd2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
2065                                         const JSHandle<JSTaggedValue> &right)
2066 {
2067     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
2068     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2069     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
2070     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2071     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
2072         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
2073             JSHandle<BigInt> leftBigint(valLeft);
2074             JSHandle<BigInt> rightBigint(valRight);
2075             return BigInt::BitwiseAND(thread, leftBigint, rightBigint).GetTaggedValue();
2076         }
2077         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
2078     }
2079     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft);
2080     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2081     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight);
2082     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2083     int32_t opNumber0 = taggedNumber0.GetInt();
2084     int32_t opNumber1 = taggedNumber1.GetInt();
2085     // NOLINT(hicpp-signed-bitwise)
2086     auto ret = static_cast<uint32_t>(opNumber0) & static_cast<uint32_t>(opNumber1);
2087     return JSTaggedValue(static_cast<int32_t>(ret));
2088 }
2089 
RuntimeOr2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)2090 JSTaggedValue RuntimeStubs::RuntimeOr2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
2091                                        const JSHandle<JSTaggedValue> &right)
2092 {
2093     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
2094     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2095     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
2096     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2097     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
2098         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
2099             JSHandle<BigInt> leftBigint(valLeft);
2100             JSHandle<BigInt> rightBigint(valRight);
2101             return BigInt::BitwiseOR(thread, leftBigint, rightBigint).GetTaggedValue();
2102         }
2103         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
2104     }
2105     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft);
2106     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2107     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight);
2108     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2109     int32_t opNumber0 = taggedNumber0.GetInt();
2110     int32_t opNumber1 = taggedNumber1.GetInt();
2111     // NOLINT(hicpp-signed-bitwise)
2112     auto ret = static_cast<uint32_t>(opNumber0) | static_cast<uint32_t>(opNumber1);
2113     return JSTaggedValue(static_cast<int32_t>(ret));
2114 }
2115 
RuntimeXor2(JSThread *thread, const JSHandle<JSTaggedValue> &left, const JSHandle<JSTaggedValue> &right)2116 JSTaggedValue RuntimeStubs::RuntimeXor2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
2117                                         const JSHandle<JSTaggedValue> &right)
2118 {
2119     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
2120     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2121     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
2122     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2123     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
2124         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
2125             JSHandle<BigInt> leftBigint(valLeft);
2126             JSHandle<BigInt> rightBigint(valRight);
2127             return BigInt::BitwiseXOR(thread, leftBigint, rightBigint).GetTaggedValue();
2128         }
2129         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
2130     }
2131     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft);
2132     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2133     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight);
2134     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2135     int32_t opNumber0 = taggedNumber0.GetInt();
2136     int32_t opNumber1 = taggedNumber1.GetInt();
2137     // NOLINT(hicpp-signed-bitwise)
2138     auto ret = static_cast<uint32_t>(opNumber0) ^ static_cast<uint32_t>(opNumber1);
2139     return JSTaggedValue(static_cast<int32_t>(ret));
2140 }
2141 
RuntimeToJSTaggedValueWithInt32(JSThread *thread, const JSHandle<JSTaggedValue> &value)2142 JSTaggedValue RuntimeStubs::RuntimeToJSTaggedValueWithInt32(JSThread *thread,
2143                                                             const JSHandle<JSTaggedValue> &value)
2144 {
2145     int32_t res = JSTaggedValue::ToInt32(thread, value);
2146     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2147     return JSTaggedValue(res);
2148 }
2149 
RuntimeToJSTaggedValueWithUint32(JSThread *thread, const JSHandle<JSTaggedValue> &value)2150 JSTaggedValue RuntimeStubs::RuntimeToJSTaggedValueWithUint32(JSThread *thread, const JSHandle<JSTaggedValue> &value)
2151 {
2152     uint32_t res = JSTaggedValue::ToUint32(thread, value);
2153     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2154     return JSTaggedValue(res);
2155 }
2156 
RuntimeCreateEmptyObject([[maybe_unused]] JSThread *thread, ObjectFactory *factory, JSHandle<GlobalEnv> globalEnv)2157 JSTaggedValue RuntimeStubs::RuntimeCreateEmptyObject([[maybe_unused]] JSThread *thread, ObjectFactory *factory,
2158                                                      JSHandle<GlobalEnv> globalEnv)
2159 {
2160     JSHandle<JSFunction> builtinObj(globalEnv->GetObjectFunction());
2161     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(builtinObj);
2162     return obj.GetTaggedValue();
2163 }
2164 
RuntimeCreateEmptyArray([[maybe_unused]] JSThread *thread, ObjectFactory *factory, JSHandle<GlobalEnv> globalEnv)2165 JSTaggedValue RuntimeStubs::RuntimeCreateEmptyArray([[maybe_unused]] JSThread *thread, ObjectFactory *factory,
2166                                                     JSHandle<GlobalEnv> globalEnv)
2167 {
2168     JSHandle<JSFunction> builtinObj(globalEnv->GetArrayFunction());
2169     JSHandle<JSObject> arr = factory->NewJSObjectByConstructor(builtinObj);
2170     return arr.GetTaggedValue();
2171 }
2172 
RuntimeGetUnmapedArgs(JSThread *thread, JSTaggedType *sp, uint32_t actualNumArgs, uint32_t startIdx)2173 JSTaggedValue RuntimeStubs::RuntimeGetUnmapedArgs(JSThread *thread, JSTaggedType *sp, uint32_t actualNumArgs,
2174                                                   uint32_t startIdx)
2175 {
2176     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2177     JSHandle<TaggedArray> argumentsList = factory->NewTaggedArray(actualNumArgs);
2178     for (uint32_t i = 0; i < actualNumArgs; ++i) {
2179         argumentsList->Set(thread, i,
2180                            JSTaggedValue(sp[startIdx + i]));  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2181     }
2182     return RuntimeGetUnmapedJSArgumentObj(thread, argumentsList);
2183 }
2184 
RuntimeCopyRestArgs(JSThread *thread, JSTaggedType *sp, uint32_t restNumArgs, uint32_t startIdx)2185 JSTaggedValue RuntimeStubs::RuntimeCopyRestArgs(JSThread *thread, JSTaggedType *sp, uint32_t restNumArgs,
2186                                                 uint32_t startIdx)
2187 {
2188     return JSArray::ArrayCreateWithInit(
2189         thread, restNumArgs, [thread, sp, startIdx] (const JSHandle<TaggedArray> &newElements, uint32_t length) {
2190         for (uint32_t i = 0; i < length; ++i) {
2191             // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2192             newElements->Set(thread, i, JSTaggedValue(sp[startIdx + i]));
2193         }
2194     });
2195 }
2196 
2197 JSTaggedValue RuntimeStubs::RuntimeCreateArrayWithBuffer(JSThread *thread, ObjectFactory *factory,
2198                                                          const JSHandle<JSTaggedValue> &literal)
2199 {
2200     JSHandle<JSArray> array(literal);
2201     JSHandle<JSArray> arrLiteral = factory->CloneArrayLiteral(array);
2202     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2203 
2204     return arrLiteral.GetTaggedValue();
2205 }
2206 
2207 JSTaggedValue RuntimeStubs::RuntimeCreateObjectWithBuffer(JSThread *thread, ObjectFactory *factory,
2208                                                           const JSHandle<JSObject> &literal)
2209 {
2210     JSHandle<JSObject> objLiteral = factory->CloneObjectLiteral(literal);
2211     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2212 
2213     return objLiteral.GetTaggedValue();
2214 }
2215 
2216 JSTaggedValue RuntimeStubs::RuntimeNewLexicalEnv(JSThread *thread, uint16_t numVars)
2217 {
2218     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2219     JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars);
2220 
2221     JSTaggedValue currentLexenv = thread->GetCurrentLexenv();
2222     newEnv->SetParentEnv(thread, currentLexenv);
2223     newEnv->SetScopeInfo(thread, JSTaggedValue::Hole());
2224     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2225     return newEnv.GetTaggedValue();
2226 }
2227 
2228 JSTaggedValue RuntimeStubs::RuntimeNewSendableEnv(JSThread *thread, uint16_t numVars)
2229 {
2230     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2231     JSHandle<SendableEnv> newEnv = factory->NewSendableEnv(numVars);
2232 
2233     JSTaggedValue module = JSFunction::Cast(thread->GetCurrentFunction())->GetModule();
2234     JSHandle<SourceTextModule> moduleHandle(thread, module);
2235     newEnv->SetParentEnv(thread, moduleHandle->GetSendableEnv());
2236     newEnv->SetScopeInfo(thread, JSTaggedValue::Hole());
2237     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2238     return newEnv.GetTaggedValue();
2239 }
2240 
2241 JSTaggedValue RuntimeStubs::RuntimeNewObjRange(JSThread *thread, const JSHandle<JSTaggedValue> &func,
2242     const JSHandle<JSTaggedValue> &newTarget, uint16_t firstArgIdx, uint16_t length)
2243 {
2244     JSHandle<JSTaggedValue> preArgs(thread, JSTaggedValue::Undefined());
2245     JSHandle<TaggedArray> args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(length);
2246     FrameHandler frameHandler(thread);
2247     for (uint16_t i = 0; i < length; ++i) {
2248         JSTaggedValue value = frameHandler.GetVRegValue(firstArgIdx + i);
2249         args->Set(thread, i, value);
2250     }
2251     auto tagged = RuntimeOptConstruct(thread, func, newTarget, preArgs, args);
2252     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2253     return tagged;
2254 }
2255 
2256 void RuntimeStubs::DefineFuncTryUseAOTHClass(JSThread* thread,
2257                                              const JSHandle<JSFunction>& func,
2258                                              const JSHandle<JSTaggedValue>& ihc,
2259                                              const JSHandle<AOTLiteralInfo>& aotLiteralInfo)
2260 {
2261     FunctionKind kind = Method::Cast(func->GetMethod())->GetFunctionKind();
2262     // The HClass of AOT comes from .ai deserialization
2263     if (!ihc->IsUndefined() && kind == FunctionKind::BASE_CONSTRUCTOR) {
2264         ASSERT(!aotLiteralInfo.GetTaggedValue().IsHole());
2265         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
2266         const GlobalEnvConstants *globalConst = thread->GlobalConstants();
2267         func->SetProtoOrHClass(thread, ihc);
2268 
2269         // build inheritance
2270         JSHandle<JSTaggedValue> parentPrototype = env->GetObjectFunctionPrototype();
2271         JSHandle<JSObject> clsPrototype(thread, func->GetFunctionPrototype());
2272         clsPrototype->GetClass()->SetPrototype(thread, parentPrototype);
2273 
2274         // set "constructor" in prototype
2275         JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
2276         PropertyDescriptor descriptor(thread, JSHandle<JSTaggedValue>::Cast(func), true, false, true);
2277         JSObject::DefineOwnProperty(thread, clsPrototype, constructorKey, descriptor);
2278 
2279         // enable prototype change marker
2280         JSHClass::EnablePHCProtoChangeMarker(thread,
2281             JSHandle<JSHClass>(thread, parentPrototype->GetTaggedObject()->GetClass()));
2282         if (ihc->IsJSHClass()) {
2283             JSHClass::EnableProtoChangeMarker(thread, JSHandle<JSHClass>(ihc));
2284         } else {
2285             JSHClass::EnablePHCProtoChangeMarker(thread, JSHandle<JSHClass>(thread, clsPrototype->GetClass()));
2286         }
2287         //avoid one thread uses ihc twice or more times
2288         aotLiteralInfo->SetIhc(JSTaggedValue::Undefined());
2289     }
2290 }
2291 
2292 JSTaggedValue RuntimeStubs::RuntimeDefinefunc(JSThread *thread, const JSHandle<JSTaggedValue> &constpool,
2293                                               uint16_t methodId, const JSHandle<JSTaggedValue> &module,
2294                                               uint16_t length, const JSHandle<JSTaggedValue> &envHandle,
2295                                               const JSHandle<JSTaggedValue> &homeObject)
2296 {
2297     JSHandle<ConstantPool> constpoolHandle = JSHandle<ConstantPool>::Cast(constpool);
2298     JSMutableHandle<JSTaggedValue> ihc(thread, JSTaggedValue::Undefined());
2299     JSMutableHandle<AOTLiteralInfo> aotLiteralInfo(thread, JSTaggedValue::Hole());
2300     //AOT ihc infos always in unshareConstpool
2301     //If is runing on AOT,unshareConstpool is definitely not a hole
2302     //So wo can skip if unshareConstpool is hole
2303     JSTaggedValue unsharedCp = thread->GetCurrentEcmaContext()->FindUnsharedConstpool(constpoolHandle.GetTaggedValue());
2304     if (!unsharedCp.IsHole()) {
2305         JSHandle<ConstantPool> unsharedCpHandle(thread, unsharedCp);
2306         JSTaggedValue val = unsharedCpHandle->GetObjectFromCache(methodId);
2307         if (val.IsAOTLiteralInfo()) {
2308             aotLiteralInfo.Update(val);
2309             ihc.Update(aotLiteralInfo->GetIhc());
2310         }
2311     }
2312     JSTaggedValue method = ConstantPool::GetMethodFromCache(thread, constpoolHandle.GetTaggedValue(), methodId);
2313     const JSHandle<Method> methodHandle(thread, method);
2314     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2315     JSHandle<JSFunction> result;
2316     if (methodHandle->IsSendableMethod()) {
2317         result = factory->NewJSSendableFunction(methodHandle);
2318         ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
2319         JSHandle<JSTaggedValue> sendableFuncModule = moduleManager->GenerateSendableFuncModule(module);
2320         if (module->IsSourceTextModule()) {
2321             JSHandle<SourceTextModule> sendableFuncModuleRecord(sendableFuncModule);
2322             sendableFuncModuleRecord->SetSendableEnv(
2323                 thread, JSHandle<SourceTextModule>::Cast(module)->GetSendableEnv());
2324         }
2325         result->SetModule(thread, sendableFuncModule.GetTaggedValue());
2326     } else {
2327         result = factory->NewJSFunction(methodHandle);
2328         result->SetModule(thread, module.GetTaggedValue());
2329         result->SetLexicalEnv(thread, envHandle.GetTaggedValue());
2330         result->SetHomeObject(thread, homeObject.GetTaggedValue());
2331     }
2332     DefineFuncTryUseAOTHClass(thread, result, ihc, aotLiteralInfo);
2333 
2334     result->SetLength(length);
2335     return result.GetTaggedValue();
2336 }
2337 
2338 JSTaggedValue RuntimeStubs::RuntimeCreateRegExpWithLiteral(JSThread *thread,
2339                                                            const JSHandle<JSTaggedValue> &pattern, uint8_t flags)
2340 {
2341     JSHandle<JSTaggedValue> flagsHandle(thread, JSTaggedValue(flags));
2342     return builtins::BuiltinsRegExp::RegExpCreate(thread, pattern, flagsHandle);
2343 }
2344 
2345 JSTaggedValue RuntimeStubs::RuntimeThrowIfSuperNotCorrectCall(JSThread *thread, uint16_t index,
2346                                                               JSTaggedValue thisValue)
2347 {
2348     if (index == 0 && (thisValue.IsUndefined() || thisValue.IsHole())) {
2349         return RuntimeThrowReferenceError(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2350                                        "sub-class must call super before use 'this'");
2351     }
2352     if (index == 1 && !thisValue.IsUndefined() && !thisValue.IsHole()) {
2353         return RuntimeThrowReferenceError(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
2354                                        "super() forbidden re-bind 'this'");
2355     }
2356     return JSTaggedValue::True();
2357 }
2358 
2359 JSTaggedValue RuntimeStubs::RuntimeCreateObjectHavingMethod(JSThread *thread, ObjectFactory *factory,
2360                                                             const JSHandle<JSObject> &literal,
2361                                                             const JSHandle<JSTaggedValue> &env)
2362 {
2363     JSHandle<JSObject> objLiteral = factory->CloneObjectLiteral(literal, env);
2364     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2365 
2366     return objLiteral.GetTaggedValue();
2367 }
2368 
2369 JSTaggedValue RuntimeStubs::CommonCreateObjectWithExcludedKeys(JSThread *thread,
2370                                                                const JSHandle<JSTaggedValue> &objVal,
2371                                                                uint32_t numExcludedKeys,
2372                                                                JSHandle<TaggedArray> excludedKeys)
2373 {
2374     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2375     JSHandle<JSObject> restObj = factory->NewEmptyJSObject();
2376     if (objVal->IsNull() || objVal->IsUndefined()) {
2377         return restObj.GetTaggedValue();
2378     }
2379     JSHandle<JSObject> obj(JSTaggedValue::ToObject(thread, objVal));
2380     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2381     JSHandle<TaggedArray> allKeys = JSObject::GetOwnPropertyKeys(thread, obj);
2382     uint32_t numAllKeys = allKeys->GetLength();
2383     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
2384     for (uint32_t i = 0; i < numAllKeys; i++) {
2385         key.Update(allKeys->Get(i));
2386         bool isExcludedKey = false;
2387         for (uint32_t j = 0; j < numExcludedKeys; j++) {
2388             if (JSTaggedValue::Equal(thread, key, JSHandle<JSTaggedValue>(thread, excludedKeys->Get(j)))) {
2389                 isExcludedKey = true;
2390                 break;
2391             }
2392         }
2393         if (!isExcludedKey) {
2394             PropertyDescriptor desc(thread);
2395             bool success = JSObject::GetOwnProperty(thread, obj, key, desc);
2396             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2397             if (success && desc.IsEnumerable()) {
2398                 JSHandle<JSTaggedValue> value = JSObject::GetProperty(thread, obj, key).GetValue();
2399                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2400                 JSObject::SetProperty(thread, restObj, key, value, true);
2401                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2402             }
2403         }
2404     }
2405     return restObj.GetTaggedValue();
2406 }
2407 
2408 JSTaggedValue RuntimeStubs::RuntimeOptCreateObjectWithExcludedKeys(JSThread *thread, uintptr_t argv, uint32_t argc)
2409 {
2410     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2411     const JSHandle<JSTaggedValue> &objVal = GetHArg<JSTaggedValue>(argv, argc, 0); // 0: means the objVal
2412     uint32_t firstArgRegIdx = 1; // 1: means the firstArgRegIdx
2413     uint32_t numExcludedKeys = 0;
2414     uint32_t numKeys = argc - 1;
2415     JSHandle<TaggedArray> excludedKeys = factory->NewTaggedArray(numKeys);
2416     JSTaggedValue excludedKey = GetArg(argv, argc, firstArgRegIdx);
2417     if (!excludedKey.IsUndefined()) {
2418         numExcludedKeys = numKeys;
2419         excludedKeys->Set(thread, 0, excludedKey);
2420         for (uint32_t i = 1; i < numExcludedKeys; i++) {
2421             excludedKey = GetArg(argv, argc, firstArgRegIdx + i);
2422             excludedKeys->Set(thread, i, excludedKey);
2423         }
2424     }
2425     return CommonCreateObjectWithExcludedKeys(thread, objVal, numExcludedKeys, excludedKeys);
2426 }
2427 
2428 JSTaggedValue RuntimeStubs::RuntimeCreateObjectWithExcludedKeys(JSThread *thread, uint16_t numKeys,
2429                                                                 const JSHandle<JSTaggedValue> &objVal,
2430                                                                 uint16_t firstArgRegIdx)
2431 {
2432     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2433     uint32_t numExcludedKeys = 0;
2434     JSHandle<TaggedArray> excludedKeys = factory->NewTaggedArray(numKeys + 1);
2435     FrameHandler frameHandler(thread);
2436     JSTaggedValue excludedKey = frameHandler.GetVRegValue(firstArgRegIdx);
2437     if (!excludedKey.IsUndefined()) {
2438         numExcludedKeys = numKeys + 1;
2439         excludedKeys->Set(thread, 0, excludedKey);
2440         for (uint32_t i = 1; i < numExcludedKeys; i++) {
2441             excludedKey = frameHandler.GetVRegValue(firstArgRegIdx + i);
2442             excludedKeys->Set(thread, i, excludedKey);
2443         }
2444     }
2445 
2446     JSHandle<JSTaggedValue> finalVal = objVal;
2447     if (finalVal->CheckIsJSProxy()) {
2448         JSHandle<JSProxy> proxyVal(thread, finalVal.GetTaggedValue());
2449         finalVal = proxyVal->GetSourceTarget(thread);
2450     }
2451 
2452     return CommonCreateObjectWithExcludedKeys(thread, finalVal, numExcludedKeys, excludedKeys);
2453 }
2454 
2455 JSTaggedValue RuntimeStubs::RuntimeDefineMethod(JSThread *thread, const JSHandle<Method> &methodHandle,
2456                                                 const JSHandle<JSTaggedValue> &homeObject, uint16_t length,
2457                                                 const JSHandle<JSTaggedValue> &env,
2458                                                 const JSHandle<JSTaggedValue> &module)
2459 {
2460     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2461     JSHandle<JSFunction> func = factory->NewJSFunction(methodHandle, homeObject);
2462     func->SetLength(length);
2463     func->SetLexicalEnv(thread, env);
2464     func->SetModule(thread, module);
2465     return func.GetTaggedValue();
2466 }
2467 
2468 JSTaggedValue RuntimeStubs::RuntimeLdSendableClass(const JSHandle<JSTaggedValue> &env, uint16_t level)
2469 {
2470     JSTaggedValue currentEnv(env.GetTaggedValue());
2471     for (uint32_t i = 0; i < level; i++) {
2472         ASSERT(currentEnv.IsLexicalEnv());
2473         currentEnv = LexicalEnv::Cast(currentEnv.GetTaggedObject())->GetParentEnv();
2474     }
2475     ASSERT(currentEnv.IsJSSharedFunction());
2476     return currentEnv;
2477 }
2478 
2479 JSTaggedValue RuntimeStubs::RuntimeCallSpread(JSThread *thread,
2480                                               const JSHandle<JSTaggedValue> &func,
2481                                               const JSHandle<JSTaggedValue> &obj,
2482                                               const JSHandle<JSTaggedValue> &array)
2483 {
2484     if ((!obj->IsUndefined() && !obj->IsECMAObject()) || !func->IsCallable() || !array->IsJSArray()) {
2485         THROW_TYPE_ERROR_AND_RETURN(thread, "cannot Callspread", JSTaggedValue::Exception());
2486     }
2487 
2488     JSHandle<TaggedArray> coretypesArray(thread, RuntimeGetCallSpreadArgs(thread, array));
2489     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2490     uint32_t length = coretypesArray->GetLength();
2491     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
2492     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, func, obj, undefined, length);
2493     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2494     info->SetCallArg(length, coretypesArray);
2495     return EcmaInterpreter::Execute(info);
2496 }
2497 
2498 void RuntimeStubs::RuntimeSetPatchModule(JSThread *thread, const JSHandle<JSFunction> &func)
2499 {
2500     JSHandle<Method> methodHandle(thread, Method::Cast(func->GetMethod()));
2501     const JSHandle<JSTaggedValue> coldReloadRecordName =
2502             thread->GetCurrentEcmaContext()->FindPatchModule(MethodLiteral::GetRecordName(
2503                 methodHandle->GetJSPandaFile(), methodHandle->GetMethodId()));
2504     if (!coldReloadRecordName->IsHole()) {
2505         func->SetModule(thread, coldReloadRecordName.GetTaggedValue());
2506     }
2507 }
2508 
2509 JSTaggedValue RuntimeStubs::RuntimeDefineGetterSetterByValue(JSThread *thread, const JSHandle<JSObject> &obj,
2510                                                              const JSHandle<JSTaggedValue> &prop,
2511                                                              const JSHandle<JSTaggedValue> &getter,
2512                                                              const JSHandle<JSTaggedValue> &setter, bool flag,
2513                                                              const JSHandle<JSTaggedValue> &func,
2514                                                              int32_t pcOffset)
2515 {
2516     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop);
2517     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2518     auto globalConst = thread->GlobalConstants();
2519     if (obj.GetTaggedValue().IsClassConstructor() &&
2520         JSTaggedValue::SameValue(propKey, globalConst->GetHandledPrototypeString())) {
2521         return RuntimeThrowTypeError(
2522             thread,
2523             "In a class, computed property names for static getter that are named 'prototype' throw a TypeError");
2524     }
2525 
2526     auto receiverHClass = obj->GetJSHClass();
2527 
2528     if (flag) {
2529         if (!getter->IsUndefined()) {
2530             if (propKey->IsNumber()) {
2531                 propKey =
2532                     JSHandle<JSTaggedValue>::Cast(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()));
2533             }
2534             JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(getter), propKey,
2535                                             JSHandle<JSTaggedValue>(thread, globalConst->GetGetString()));
2536         }
2537 
2538         if (!setter->IsUndefined()) {
2539             if (propKey->IsNumber()) {
2540                 propKey =
2541                     JSHandle<JSTaggedValue>::Cast(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()));
2542             }
2543             JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(setter), propKey,
2544                                             JSHandle<JSTaggedValue>(thread, globalConst->GetSetString()));
2545         }
2546     }
2547 
2548     // set accessor
2549     bool enumerable =
2550         !(obj.GetTaggedValue().IsClassPrototype() || obj.GetTaggedValue().IsClassConstructor());
2551     PropertyDescriptor desc(thread, true, enumerable, true);
2552     if (!getter->IsUndefined()) {
2553         Method *method = Method::Cast(JSHandle<JSFunction>::Cast(getter)->GetMethod().GetTaggedObject());
2554         method->SetFunctionKind(FunctionKind::GETTER_FUNCTION);
2555         desc.SetGetter(getter);
2556     }
2557     if (!setter->IsUndefined()) {
2558         Method *method = Method::Cast(JSHandle<JSFunction>::Cast(setter)->GetMethod().GetTaggedObject());
2559         method->SetFunctionKind(FunctionKind::SETTER_FUNCTION);
2560         desc.SetSetter(setter);
2561     }
2562 
2563     JSObject::DefineOwnProperty(thread, obj, propKey, desc);
2564     auto holderTraHClass = obj->GetJSHClass();
2565     if (receiverHClass != holderTraHClass) {
2566         if (holderTraHClass->IsTS()) {
2567             JSHandle<JSHClass> phcHandle(thread, holderTraHClass);
2568             JSHClass::EnablePHCProtoChangeMarker(thread, phcHandle);
2569         }
2570         if (thread->GetEcmaVM()->IsEnablePGOProfiler()) {
2571             if (!func->IsUndefined()) {
2572                 thread->GetEcmaVM()->GetPGOProfiler()->ProfileDefineGetterSetter(
2573                     receiverHClass, holderTraHClass, func, pcOffset);
2574             }
2575         }
2576     }
2577     return obj.GetTaggedValue();
2578 }
2579 
2580 JSTaggedValue RuntimeStubs::RuntimeSuperCall(JSThread *thread, const JSHandle<JSTaggedValue> &func,
2581                                              const JSHandle<JSTaggedValue> &newTarget, uint16_t firstVRegIdx,
2582                                              uint16_t length)
2583 {
2584     JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func));
2585     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2586 
2587     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2588     JSHandle<TaggedArray> argv = factory->NewTaggedArray(length);
2589     FrameHandler frameHandler(thread);
2590     for (size_t i = 0; i < length; ++i) {
2591         argv->Set(thread, i, frameHandler.GetVRegValue(firstVRegIdx + i));
2592     }
2593 
2594     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
2595     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, length);
2596     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2597     info->SetCallArg(length, argv);
2598     JSTaggedValue result = JSFunction::Construct(info);
2599     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2600 
2601     return result;
2602 }
2603 
2604 JSTaggedValue RuntimeStubs::RuntimeOptSuperCall(JSThread *thread, const JSHandle<JSTaggedValue> &func,
2605                                                 const JSHandle<JSTaggedValue> &newTarget,
2606                                                 const JSHandle<TaggedArray> &argv,
2607                                                 uint16_t length)
2608 {
2609     JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func));
2610     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2611     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
2612     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, length);
2613     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2614     info->SetCallArg(length, argv);
2615     JSTaggedValue result = JSFunction::Construct(info);
2616     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2617     return result;
2618 }
2619 
2620 JSTaggedValue RuntimeStubs::RuntimeThrowTypeError(JSThread *thread, const char *message)
2621 {
2622     ASSERT_NO_ABRUPT_COMPLETION(thread);
2623     THROW_TYPE_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception());
2624 }
2625 
2626 JSTaggedValue RuntimeStubs::RuntimeGetCallSpreadArgs(JSThread *thread, const JSHandle<JSTaggedValue> &jsArray)
2627 {
2628     uint32_t argvMayMaxLength = JSHandle<JSArray>::Cast(jsArray)->GetArrayLength();
2629 
2630     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2631     JSHandle<TaggedArray> argv = factory->NewTaggedArray(argvMayMaxLength);
2632     JSHandle<JSTaggedValue> itor = JSIterator::GetIterator(thread, jsArray);
2633     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2634 
2635     // Fast path when array is stablearray and Iterator not change.
2636     if (jsArray->IsStableJSArray(thread) && itor->IsJSArrayIterator()) {
2637         JSHandle<JSObject> jsArrayObj(jsArray);
2638         ElementAccessor::CopyJSArrayToTaggedArray(thread, jsArrayObj, argv, argvMayMaxLength);
2639         return argv.GetTaggedValue();
2640     }
2641 
2642     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2643     JSMutableHandle<JSTaggedValue> next(thread, JSTaggedValue::Undefined());
2644     JSMutableHandle<JSTaggedValue> nextArg(thread, JSTaggedValue::Undefined());
2645     size_t argvIndex = 0;
2646     while (true) {
2647         next.Update(JSIterator::IteratorStep(thread, itor).GetTaggedValue());
2648         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2649         if (JSTaggedValue::SameValue(next.GetTaggedValue(), JSTaggedValue::False())) {
2650             break;
2651         }
2652         nextArg.Update(JSIterator::IteratorValue(thread, next).GetTaggedValue());
2653         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2654         if (UNLIKELY(argvIndex + 1 >= argvMayMaxLength)) {
2655             argvMayMaxLength = argvMayMaxLength + (argvMayMaxLength >> 1U) + 1U;
2656             argv = argv->SetCapacity(thread, argv, argvMayMaxLength);
2657         }
2658         argv->Set(thread, argvIndex++, nextArg);
2659     }
2660     argv = factory->CopyArray(argv, argvMayMaxLength, argvIndex);
2661     return argv.GetTaggedValue();
2662 }
2663 
2664 JSTaggedValue RuntimeStubs::RuntimeThrowSyntaxError(JSThread *thread, const char *message)
2665 {
2666     ASSERT_NO_ABRUPT_COMPLETION(thread);
2667     THROW_SYNTAX_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception());
2668 }
2669 
2670 JSTaggedValue RuntimeStubs::RuntimeLdBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &numberBigInt)
2671 {
2672     return JSTaggedValue::ToBigInt(thread, numberBigInt);
2673 }
2674 
2675 JSTaggedValue RuntimeStubs::RuntimeCallBigIntAsIntN(JSThread *thread, JSTaggedValue bits, JSTaggedValue bigint)
2676 {
2677     auto biginteger = JSHandle<BigInt>(thread, bigint);
2678     JSTaggedNumber bitness = JSTaggedValue::ToNumber(thread, bits);
2679     return BigInt::AsintN(thread, bitness, biginteger);
2680 }
2681 
2682 JSTaggedValue RuntimeStubs::RuntimeCallBigIntAsUintN(JSThread *thread, JSTaggedValue bits, JSTaggedValue bigint)
2683 {
2684     auto biginteger = JSHandle<BigInt>(thread, bigint);
2685     JSTaggedNumber bitness = JSTaggedValue::ToNumber(thread, bits);
2686     return BigInt::AsUintN(thread, bitness, biginteger);
2687 }
2688 
2689 JSTaggedValue RuntimeStubs::RuntimeNewLexicalEnvWithName(JSThread *thread, uint16_t numVars, uint16_t scopeId)
2690 {
2691     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2692     JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars);
2693 
2694     JSTaggedValue currentLexenv = thread->GetCurrentLexenv();
2695     newEnv->SetParentEnv(thread, currentLexenv);
2696     JSTaggedValue scopeInfo = ScopeInfoExtractor::GenerateScopeInfo(thread, scopeId);
2697     newEnv->SetScopeInfo(thread, scopeInfo);
2698     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2699     return newEnv.GetTaggedValue();
2700 }
2701 
2702 JSTaggedValue RuntimeStubs::RuntimeOptGetUnmapedArgs(JSThread *thread, uint32_t actualNumArgs)
2703 {
2704     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2705     JSHandle<TaggedArray> argumentsList = factory->NewTaggedArray(actualNumArgs - NUM_MANDATORY_JSFUNC_ARGS);
2706 
2707     auto argv = GetActualArgvFromStub(thread);
2708     int idx = 0;
2709     for (uint32_t i = NUM_MANDATORY_JSFUNC_ARGS; i < actualNumArgs; ++i) {
2710         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2711         JSTaggedType arg = reinterpret_cast<JSTaggedType *>(argv)[i];
2712         JSTaggedValue args = JSTaggedValue(arg);
2713         argumentsList->Set(thread, idx++, args);
2714     }
2715     return RuntimeGetUnmapedJSArgumentObj(thread, argumentsList);
2716 }
2717 
2718 JSTaggedValue RuntimeStubs::RuntimeGetUnmapedJSArgumentObj(JSThread *thread, const JSHandle<TaggedArray> &argumentsList)
2719 {
2720     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2721     JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
2722     // 1. Let len be the number of elements in argumentsList
2723     uint32_t len = argumentsList->GetLength();
2724     // 2. Let obj be ObjectCreate(%ObjectPrototype%, «[[ParameterMap]]»).
2725     // 3. Set obj’s [[ParameterMap]] internal slot to undefined.
2726     // [[ParameterMap]] setted as undifined.
2727     JSHandle<JSArguments> obj = factory->NewJSArguments();
2728     // 4. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor{[[Value]]: len, [[Writable]]: true,
2729     // [[Enumerable]]: false, [[Configurable]]: true}).
2730     obj->SetPropertyInlinedProps(thread, JSArguments::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(len));
2731     // 5. Let index be 0.
2732     // 6. Repeat while index < len,
2733     //    a. Let val be argumentsList[index].
2734     //    b. Perform CreateDataProperty(obj, ToString(index), val).
2735     //    c. Let index be index + 1
2736     obj->SetElements(thread, argumentsList.GetTaggedValue());
2737     // 7. Perform DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor
2738     // {[[Value]]:%ArrayProto_values%,
2739     // [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}).
2740     obj->SetPropertyInlinedProps(thread, JSArguments::ITERATOR_INLINE_PROPERTY_INDEX,
2741                                  globalEnv->GetArrayProtoValuesFunction().GetTaggedValue());
2742     // 8. Perform DefinePropertyOrThrow(obj, "caller", PropertyDescriptor {[[Get]]: %ThrowTypeError%,
2743     // [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}).
2744     JSHandle<JSTaggedValue> accessorCaller = globalEnv->GetArgumentsCallerAccessor();
2745     obj->SetPropertyInlinedProps(thread, JSArguments::CALLER_INLINE_PROPERTY_INDEX, accessorCaller.GetTaggedValue());
2746     // 9. Perform DefinePropertyOrThrow(obj, "callee", PropertyDescriptor {[[Get]]: %ThrowTypeError%,
2747     // [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}).
2748     JSHandle<JSTaggedValue> accessorCallee = globalEnv->GetArgumentsCalleeAccessor();
2749     obj->SetPropertyInlinedProps(thread, JSArguments::CALLEE_INLINE_PROPERTY_INDEX, accessorCallee.GetTaggedValue());
2750     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2751     // 11. Return obj
2752     return obj.GetTaggedValue();
2753 }
2754 
2755 JSTaggedValue RuntimeStubs::RuntimeOptNewLexicalEnvWithName(JSThread *thread, uint16_t numVars, uint16_t scopeId,
2756                                                             JSHandle<JSTaggedValue> &currentLexEnv,
2757                                                             JSHandle<JSTaggedValue> &func)
2758 {
2759     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2760     JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars);
2761 
2762     newEnv->SetParentEnv(thread, currentLexEnv.GetTaggedValue());
2763     JSTaggedValue scopeInfo = RuntimeOptGenerateScopeInfo(thread, scopeId, func.GetTaggedValue());
2764     newEnv->SetScopeInfo(thread, scopeInfo);
2765     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2766     JSTaggedValue taggedEnv = newEnv.GetTaggedValue();
2767     return taggedEnv;
2768 }
2769 
2770 JSTaggedValue RuntimeStubs::RuntimeOptCopyRestArgs(JSThread *thread, uint32_t actualArgc, uint32_t restIndex)
2771 {
2772     // when only have three fixed args, restIndex in bytecode maybe not zero, but it actually should be zero.
2773     uint32_t actualRestNum = 0;
2774     if (actualArgc > NUM_MANDATORY_JSFUNC_ARGS + restIndex) {
2775         actualRestNum = actualArgc - NUM_MANDATORY_JSFUNC_ARGS - restIndex;
2776     }
2777     JSHandle<JSTaggedValue> restArray = JSArray::ArrayCreate(thread, JSTaggedNumber(actualRestNum));
2778 
2779     auto argv = GetActualArgv(thread);
2780     int idx = 0;
2781     JSMutableHandle<JSTaggedValue> element(thread, JSTaggedValue::Undefined());
2782 
2783     for (uint32_t i = NUM_MANDATORY_JSFUNC_ARGS + restIndex; i < actualArgc; ++i) {
2784         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2785         JSTaggedType arg = reinterpret_cast<JSTaggedType *>(argv)[i];
2786         element.Update(JSTaggedValue(arg));
2787         JSObject::SetProperty(thread, restArray, idx++, element, true);
2788     }
2789     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2790     return restArray.GetTaggedValue();
2791 }
2792 
2793 JSTaggedValue RuntimeStubs::RuntimeOptSuspendGenerator(JSThread *thread, const JSHandle<JSTaggedValue> &genObj,
2794                                                        const JSHandle<JSTaggedValue> &value)
2795 {
2796     if (genObj->IsAsyncGeneratorObject()) {
2797         JSHandle<JSAsyncGeneratorObject> generatorObjectHandle(genObj);
2798         // change state to SuspendedYield
2799         if (generatorObjectHandle->IsExecuting()) {
2800             return value.GetTaggedValue();
2801         }
2802         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2803         return generatorObjectHandle.GetTaggedValue();
2804     }
2805 
2806     if (genObj->IsGeneratorObject()) {
2807         JSHandle<JSGeneratorObject> generatorObjectHandle(genObj);
2808         // set TaskInfo for TaskPool
2809         generatorObjectHandle->SetTaskInfo(thread->GetTaskInfo());
2810         // change state to SuspendedYield
2811         if (generatorObjectHandle->IsExecuting()) {
2812             generatorObjectHandle->SetGeneratorState(JSGeneratorState::SUSPENDED_YIELD);
2813             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2814             return value.GetTaggedValue();
2815         }
2816         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2817         return generatorObjectHandle.GetTaggedValue();
2818     }
2819 
2820     return RuntimeThrowTypeError(thread, "RuntimeSuspendGenerator failed");
2821 }
2822 
2823 JSTaggedValue RuntimeStubs::RuntimeOptAsyncGeneratorResolve(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj,
2824                                                             JSHandle<JSTaggedValue> value, JSTaggedValue flag)
2825 {
2826     [[maybe_unused]] EcmaHandleScope handleScope(thread);
2827 
2828     JSHandle<JSAsyncGeneratorObject> asyncGeneratorObjHandle(asyncFuncObj);
2829     JSHandle<JSTaggedValue> valueHandle(value);
2830     JSHandle<GeneratorContext> genContextHandle(thread, asyncGeneratorObjHandle->GetGeneratorContext());
2831     ASSERT(flag.IsBoolean());
2832     bool done = flag.IsTrue();
2833     return JSAsyncGeneratorObject::AsyncGeneratorResolve(thread, asyncGeneratorObjHandle, valueHandle, done);
2834 }
2835 
2836 JSTaggedValue RuntimeStubs::RuntimeOptConstruct(JSThread *thread, JSHandle<JSTaggedValue> ctor,
2837                                                 JSHandle<JSTaggedValue> newTarget, JSHandle<JSTaggedValue> preArgs,
2838                                                 JSHandle<TaggedArray> args)
2839 {
2840     if (newTarget->IsUndefined()) {
2841         newTarget = ctor;
2842     }
2843 
2844     if (!(newTarget->IsConstructor() && ctor->IsConstructor())) {
2845         THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor is false", JSTaggedValue::Exception());
2846     }
2847 
2848     if (ctor->IsJSFunction()) {
2849         return RuntimeOptConstructGeneric(thread, JSHandle<JSFunction>::Cast(ctor), newTarget, preArgs, args);
2850     }
2851     if (ctor->IsBoundFunction()) {
2852         return RuntimeOptConstructBoundFunction(
2853             thread, JSHandle<JSBoundFunction>::Cast(ctor), newTarget, preArgs, args);
2854     }
2855     if (ctor->IsJSProxy()) {
2856         return RuntimeOptConstructProxy(thread, JSHandle<JSProxy>::Cast(ctor), newTarget, preArgs, args);
2857     }
2858     THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor NonConstructor", JSTaggedValue::Exception());
2859 }
2860 
2861 JSTaggedValue RuntimeStubs::RuntimeOptConstructProxy(JSThread *thread, JSHandle<JSProxy> ctor,
2862                                                      JSHandle<JSTaggedValue> newTgt, JSHandle<JSTaggedValue> preArgs,
2863                                                      JSHandle<TaggedArray> args)
2864 {
2865     // step 1 ~ 4 get ProxyHandler and ProxyTarget
2866     JSHandle<JSTaggedValue> handler(thread, ctor->GetHandler());
2867     if (handler->IsNull()) {
2868         THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor: handler is null", JSTaggedValue::Exception());
2869     }
2870     ASSERT(handler->IsECMAObject());
2871     JSHandle<JSTaggedValue> target(thread, ctor->GetTarget());
2872 
2873     // 5.Let trap be GetMethod(handler, "construct").
2874     JSHandle<JSTaggedValue> key(thread->GlobalConstants()->GetHandledProxyConstructString());
2875     JSHandle<JSTaggedValue> method = JSObject::GetMethod(thread, handler, key);
2876 
2877     // 6.ReturnIfAbrupt(trap).
2878     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2879     // 7.If trap is undefined, then
2880     //   a.Assert: target has a [[Construct]] internal method.
2881     //   b.Return Construct(target, argumentsList, newTarget).
2882     if (method->IsUndefined()) {
2883         ASSERT(target->IsConstructor());
2884         return RuntimeOptConstruct(thread, target, newTgt, preArgs, args);
2885     }
2886 
2887     // 8.Let argArray be CreateArrayFromList(argumentsList).
2888     uint32_t preArgsSize = preArgs->IsUndefined() ? 0 : JSHandle<TaggedArray>::Cast(preArgs)->GetLength();
2889     const uint32_t argsCount = args->GetLength();
2890     const uint32_t size = preArgsSize + argsCount;
2891     JSHandle<TaggedArray> arr = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(size);
2892     if (preArgsSize > 0) {
2893         JSHandle<TaggedArray> tgaPreArgs = JSHandle<TaggedArray>::Cast(preArgs);
2894         for (uint32_t i = 0; i < preArgsSize; ++i) {
2895             JSTaggedValue value = tgaPreArgs->Get(i);
2896             arr->Set(thread, i, value);
2897         }
2898     }
2899 
2900     for (uint32_t i = 0; i < argsCount; ++i) {
2901         JSTaggedValue value = args->Get(i);
2902         arr->Set(thread, i + preArgsSize, value);
2903     }
2904     JSHandle<JSArray> newArr = JSArray::CreateArrayFromList(thread, arr);
2905 
2906     // step 8 ~ 9 Call(trap, handler, «target, argArray, newTarget »).
2907     const uint32_t argsLength = 3;  // 3: «target, argArray, newTarget »
2908     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
2909     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, method, handler, undefined, argsLength);
2910     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2911     info->SetCallArg(target.GetTaggedValue(), newArr.GetTaggedValue(), newTgt.GetTaggedValue());
2912     JSTaggedValue newObjValue = JSFunction::Call(info);
2913     // 10.ReturnIfAbrupt(newObj).
2914     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2915     // 11.If Type(newObj) is not Object, throw a TypeError exception.
2916     if (!newObjValue.IsECMAObject()) {
2917         THROW_TYPE_ERROR_AND_RETURN(thread, "new object is not object", JSTaggedValue::Exception());
2918     }
2919     // 12.Return newObj.
2920     return newObjValue;
2921 }
2922 
2923 JSTaggedValue RuntimeStubs::RuntimeOptConstructBoundFunction(JSThread *thread, JSHandle<JSBoundFunction> ctor,
2924                                                              JSHandle<JSTaggedValue> newTgt,
2925                                                              JSHandle<JSTaggedValue> preArgs,
2926                                                              JSHandle<TaggedArray> args)
2927 {
2928     JSHandle<JSTaggedValue> target(thread, ctor->GetBoundTarget());
2929     if (!target->IsConstructor()) {
2930         THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor is false", JSTaggedValue::Exception());
2931     }
2932 
2933     JSHandle<TaggedArray> boundArgs(thread, ctor->GetBoundArguments());
2934     JSMutableHandle<JSTaggedValue> newPreArgs(thread, preArgs.GetTaggedValue());
2935     if (newPreArgs->IsUndefined()) {
2936         newPreArgs.Update(boundArgs.GetTaggedValue());
2937     } else {
2938         newPreArgs.Update(
2939             TaggedArray::Append(thread, boundArgs, JSHandle<TaggedArray>::Cast(preArgs)).GetTaggedValue());
2940     }
2941     JSMutableHandle<JSTaggedValue> newTargetMutable(thread, newTgt.GetTaggedValue());
2942     if (JSTaggedValue::SameValue(ctor.GetTaggedValue(), newTgt.GetTaggedValue())) {
2943         newTargetMutable.Update(target.GetTaggedValue());
2944     }
2945     return RuntimeOptConstruct(thread, target, newTargetMutable, newPreArgs, args);
2946 }
2947 
2948 JSTaggedValue RuntimeStubs::GetResultValue(JSThread *thread, bool isAotMethod, JSHandle<JSFunction> ctor,
2949     CVector<JSTaggedType> &values, JSHandle<JSTaggedValue> newTgt, uint32_t &size, JSHandle<JSTaggedValue> obj)
2950 {
2951     JSTaggedValue resultValue;
2952     if (isAotMethod) {
2953         uint32_t numArgs = ctor->GetCallTarget()->GetNumArgsWithCallField();
2954         bool needPushArgv = numArgs != size;
2955         const JSTaggedType *prevFp = thread->GetLastLeaveFrame();
2956         if (ctor->IsCompiledFastCall()) {
2957             if (needPushArgv) {
2958                 values.reserve(numArgs + NUM_MANDATORY_JSFUNC_ARGS - 1);
2959                 for (uint32_t i = size; i < numArgs; i++) {
2960                     values.emplace_back(JSTaggedValue::VALUE_UNDEFINED);
2961                 }
2962                 size = numArgs;
2963             }
2964             resultValue = thread->GetEcmaVM()->FastCallAot(size, values.data(), prevFp);
2965         } else {
2966             resultValue = thread->GetCurrentEcmaContext()->ExecuteAot(size, values.data(), prevFp, needPushArgv);
2967         }
2968     } else {
2969         EcmaRuntimeCallInfo *info =
2970             EcmaInterpreter::NewRuntimeCallInfo(thread, JSHandle<JSTaggedValue>(ctor), obj, newTgt, size);
2971         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2972         info->SetCallArg(size, values.data());
2973         resultValue = EcmaInterpreter::Execute(info);
2974     }
2975     return resultValue;
2976 }
2977 
2978 JSTaggedValue RuntimeStubs::RuntimeOptConstructGeneric(JSThread *thread, JSHandle<JSFunction> ctor,
2979                                                        JSHandle<JSTaggedValue> newTgt,
2980                                                        JSHandle<JSTaggedValue> preArgs, JSHandle<TaggedArray> args)
2981 {
2982     if (!ctor->IsConstructor()) {
2983         THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor is false", JSTaggedValue::Exception());
2984     }
2985 
2986     JSHandle<JSTaggedValue> obj(thread, JSTaggedValue::Undefined());
2987     if (ctor->IsBase()) {
2988         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2989         obj = JSHandle<JSTaggedValue>(factory->NewJSObjectByConstructor(ctor, newTgt));
2990         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2991     }
2992 
2993     uint32_t preArgsSize = preArgs->IsUndefined() ? 0 : JSHandle<TaggedArray>::Cast(preArgs)->GetLength();
2994     const uint32_t argsCount = args->GetLength();
2995     uint32_t size = preArgsSize + argsCount;
2996     CVector<JSTaggedType> values;
2997     bool isCompiledCode = ctor->IsCompiledCode();
2998     if (isCompiledCode) {
2999         if (ctor->IsCompiledFastCall()) {
3000             values.reserve(size + NUM_MANDATORY_JSFUNC_ARGS - 1);
3001             values.emplace_back(ctor.GetTaggedValue().GetRawData());
3002             values.emplace_back(obj.GetTaggedValue().GetRawData());
3003         } else {
3004             values.reserve(size + NUM_MANDATORY_JSFUNC_ARGS);
3005             values.emplace_back(ctor.GetTaggedValue().GetRawData());
3006             values.emplace_back(newTgt.GetTaggedValue().GetRawData());
3007             values.emplace_back(obj.GetTaggedValue().GetRawData());
3008         }
3009     } else {
3010         values.reserve(size);
3011     }
3012 
3013     if (preArgsSize > 0) {
3014         JSHandle<TaggedArray> tgaPreArgs = JSHandle<TaggedArray>::Cast(preArgs);
3015         for (uint32_t i = 0; i < preArgsSize; ++i) {
3016             JSTaggedValue value = tgaPreArgs->Get(i);
3017             values.emplace_back(value.GetRawData());
3018         }
3019         for (uint32_t i = 0; i < argsCount; ++i) {
3020             values.emplace_back(args->Get(i).GetRawData());
3021         }
3022     } else {
3023         for (uint32_t i = 0; i < argsCount; ++i) {
3024             values.emplace_back(args->Get(i).GetRawData());
3025         }
3026     }
3027     JSTaggedValue resultValue = RuntimeStubs::GetResultValue(thread, isCompiledCode, ctor, values, newTgt, size, obj);
3028     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3029     // 9.3.2 [[Construct]] (argumentsList, newTarget)
3030     if (resultValue.IsECMAObject()) {
3031         if (resultValue.IsJSShared()) {
3032             JSObject::Cast(resultValue.GetTaggedObject())->GetJSHClass()->SetExtensible(false);
3033         }
3034         return resultValue;
3035     }
3036 
3037     if (ctor->IsBase()) {
3038         return obj.GetTaggedValue();
3039     }
3040     if (!resultValue.IsUndefined()) {
3041         THROW_TYPE_ERROR_AND_RETURN(thread, "function is non-constructor", JSTaggedValue::Exception());
3042     }
3043     return obj.GetTaggedValue();
3044 }
3045 
3046 JSTaggedValue RuntimeStubs::RuntimeOptNewObjRange(JSThread *thread, uintptr_t argv, uint32_t argc)
3047 {
3048     JSHandle<JSTaggedValue> ctor = GetHArg<JSTaggedValue>(argv, argc, 0);
3049     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
3050     const size_t firstArgOffset = 1;
3051     ASSERT(argc > 0);
3052     size_t arrLength = argc - firstArgOffset;
3053     JSHandle<TaggedArray> args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(arrLength);
3054     for (size_t i = 0; i < arrLength; ++i) {
3055         args->Set(thread, i, GetArg(argv, argc, i + firstArgOffset));
3056     }
3057     JSTaggedValue object = RuntimeOptConstruct(thread, ctor, ctor, undefined, args);
3058     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3059     if (!object.IsUndefined() && !object.IsECMAObject() && !JSHandle<JSFunction>(ctor)->IsBase()) {
3060         THROW_TYPE_ERROR_AND_RETURN(thread, "Derived constructor must return object or undefined",
3061                                     JSTaggedValue::Exception());
3062     }
3063     return object;
3064 }
3065 
3066 JSTaggedValue RuntimeStubs::RuntimeOptGenerateScopeInfo(JSThread *thread, uint16_t scopeId, JSTaggedValue func)
3067 {
3068     EcmaVM *ecmaVm = thread->GetEcmaVM();
3069     ObjectFactory *factory = ecmaVm->GetFactory();
3070     Method *method = ECMAObject::Cast(func.GetTaggedObject())->GetCallTarget();
3071     const JSPandaFile *jsPandaFile = method->GetJSPandaFile();
3072     JSHandle<ConstantPool> constpool(thread, method->GetConstantPool());
3073     panda_file::File::EntityId id = constpool->GetEntityId(scopeId);
3074     JSHandle<TaggedArray> elementsLiteral =
3075         LiteralDataExtractor::GetDatasIgnoreType(thread, jsPandaFile, id, constpool);
3076 
3077     ASSERT(elementsLiteral->GetLength() > 0);
3078 
3079     auto *scopeDebugInfo = ecmaVm->GetNativeAreaAllocator()->New<ScopeDebugInfo>();
3080     if (scopeDebugInfo == nullptr) {
3081         return JSTaggedValue::Hole();
3082     }
3083 
3084     size_t length = elementsLiteral->GetLength();
3085     for (size_t i = 1; i < length; i += 2) {  // 2: Each literal buffer contains a pair of key-value.
3086         JSTaggedValue val = elementsLiteral->Get(i);
3087         ASSERT(val.IsString());
3088         CString name = ConvertToString(EcmaString::Cast(val.GetTaggedObject()));
3089         int32_t slot = elementsLiteral->Get(i + 1).GetInt();
3090         scopeDebugInfo->scopeInfo.emplace(name, slot);
3091     }
3092 
3093     JSHandle<JSNativePointer> pointer = factory->NewJSNativePointer(
3094         scopeDebugInfo, NativeAreaAllocator::FreeObjectFunc<ScopeDebugInfo>, ecmaVm->GetNativeAreaAllocator());
3095     return pointer.GetTaggedValue();
3096 }
3097 
3098 JSTaggedType *RuntimeStubs::GetActualArgv(JSThread *thread)
3099 {
3100     JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
3101     FrameIterator it(current, thread);
3102     ASSERT(it.IsLeaveFrame());
3103     it.Advance<GCVisitedFlag::VISITED>();
3104     ASSERT(it.IsAotOrJitFunctionFrame());
3105     if (it.IsFastJitFunctionFrame()) {
3106         auto optimizedJSJITFunctionFrame = it.GetFrame<FASTJITFunctionFrame>();
3107         return optimizedJSJITFunctionFrame->GetArgv(it);
3108     } else {
3109         auto optimizedJSFunctionFrame = it.GetFrame<OptimizedJSFunctionFrame>();
3110         return optimizedJSFunctionFrame->GetArgv(it);
3111     }
3112 }
3113 
3114 JSTaggedType *RuntimeStubs::GetActualArgvFromStub(JSThread *thread)
3115 {
3116     JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
3117     FrameIterator it(current, thread);
3118     ASSERT(it.IsLeaveFrame());
3119     it.Advance<GCVisitedFlag::VISITED>();
3120     ASSERT(it.IsOptimizedFrame());
3121     it.Advance<GCVisitedFlag::VISITED>();
3122     ASSERT(it.IsAotOrJitFunctionFrame());
3123     if (it.IsFastJitFunctionFrame()) {
3124         auto optimizedJSJITFunctionFrame = it.GetFrame<FASTJITFunctionFrame>();
3125         return optimizedJSJITFunctionFrame->GetArgv(it);
3126     }
3127     auto optimizedJSFunctionFrame = it.GetFrame<OptimizedJSFunctionFrame>();
3128     return optimizedJSFunctionFrame->GetArgv(it);
3129 }
3130 
3131 OptimizedJSFunctionFrame *RuntimeStubs::GetOptimizedJSFunctionFrame(JSThread *thread)
3132 {
3133     JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
3134     FrameIterator it(current, thread);
3135     ASSERT(it.IsLeaveFrame());
3136     it.Advance();
3137     ASSERT(it.IsOptimizedJSFunctionFrame());
3138     return it.GetFrame<OptimizedJSFunctionFrame>();
3139 }
3140 
3141 OptimizedJSFunctionFrame *RuntimeStubs::GetOptimizedJSFunctionFrameNoGC(JSThread *thread)
3142 {
3143     JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
3144     FrameIterator it(current, thread);
3145     ASSERT(it.IsOptimizedFrame());
3146     it.Advance();
3147     ASSERT(it.IsOptimizedJSFunctionFrame());
3148     return it.GetFrame<OptimizedJSFunctionFrame>();
3149 }
3150 
3151 JSTaggedValue RuntimeStubs::RuntimeLdPatchVar(JSThread *thread, uint32_t index)
3152 {
3153     JSHandle<TaggedArray> globalPatch =
3154         JSHandle<TaggedArray>::Cast(thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalPatch());
3155 
3156     return globalPatch->Get(thread, index);
3157 }
3158 
3159 JSTaggedValue RuntimeStubs::RuntimeStPatchVar(JSThread *thread, uint32_t index, const JSHandle<JSTaggedValue> &value)
3160 {
3161     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
3162 
3163     JSHandle<TaggedArray> globalPatch = JSHandle<TaggedArray>::Cast(env->GetGlobalPatch());
3164     if (index >= globalPatch->GetLength()) {
3165         globalPatch = TaggedArray::SetCapacity(thread, globalPatch, index + 1);
3166     }
3167     globalPatch->Set(thread, index, value);
3168     env->SetGlobalPatch(thread, globalPatch.GetTaggedValue());
3169     return JSTaggedValue::True();
3170 }
3171 
3172 JSTaggedValue RuntimeStubs::RuntimeNotifyConcurrentResult(JSThread *thread, JSTaggedValue result, JSTaggedValue hint)
3173 {
3174     thread->GetEcmaVM()->TriggerConcurrentCallback(result, hint);
3175     return JSTaggedValue::Undefined();
3176 }
3177 
3178 JSTaggedValue RuntimeStubs::RuntimeUpdateAOTHClass(JSThread *thread,
3179     const JSHandle<JSHClass> &oldhclass, const JSHandle<JSHClass> &newhclass, JSTaggedValue key)
3180 {
3181 #if ECMASCRIPT_ENABLE_IC
3182     if (JSHClass::IsNeedNotifyHclassChangedForAotTransition(thread, oldhclass, key)) {
3183         JSHClass::NotifyHclassChanged(thread, oldhclass, newhclass, key);
3184     } else {
3185         JSHClass::RefreshUsers(thread, oldhclass, newhclass);
3186     }
3187     JSHClass::EnablePHCProtoChangeMarker(thread, newhclass);
3188 #endif
3189     return JSTaggedValue::Undefined();
3190 }
3191 
3192 JSTaggedValue RuntimeStubs::RuntimeDefineField(JSThread *thread, JSTaggedValue obj,
3193                                                JSTaggedValue propKey, JSTaggedValue value)
3194 {
3195     // Do the same thing as Object.defineProperty(obj, propKey, {value: value,
3196     //                                                           writable:true, enumerable: true, configurable: true})
3197     if (!obj.IsECMAObject()) {
3198         THROW_TYPE_ERROR_AND_RETURN(thread, "DefineField: obj is not Object", JSTaggedValue::Exception());
3199     }
3200     JSHandle<JSObject> handleObj(thread, obj);
3201     JSHandle<JSTaggedValue> handleValue(thread, value);
3202     JSHandle<JSTaggedValue> handleKey = JSTaggedValue::ToPropertyKey(thread, JSHandle<JSTaggedValue>(thread, propKey));
3203     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3204 
3205     JSObject::CreateDataPropertyOrThrow(thread, handleObj, handleKey, handleValue, SCheckMode::CHECK);
3206     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3207 
3208     return JSTaggedValue::Undefined();
3209 }
3210 
3211 JSTaggedValue RuntimeStubs::RuntimeCreatePrivateProperty(JSThread *thread, JSTaggedValue lexicalEnv,
3212     uint32_t count, JSTaggedValue constpool, uint32_t literalId, JSTaggedValue module)
3213 {
3214     ObjectFactory* factory = thread->GetEcmaVM()->GetFactory();
3215     JSHandle<LexicalEnv> handleLexicalEnv(thread, lexicalEnv);
3216     JSHandle<ConstantPool> handleConstpool(thread, constpool);
3217     JSHandle<JSTaggedValue> handleModule(thread, module);
3218     JSHandle<ConstantPool> unsharedConstpoolHandle(
3219         thread, thread->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(constpool));
3220     CString entry = ModuleManager::GetRecordName(handleModule.GetTaggedValue());
3221     uint32_t length = handleLexicalEnv->GetLength() - LexicalEnv::RESERVED_ENV_LENGTH;
3222     uint32_t startIndex = 0;
3223     while (startIndex < length && !handleLexicalEnv->GetProperties(startIndex).IsHole()) {
3224         startIndex++;
3225     }
3226 
3227     JSTaggedValue aotSymbolInfo = unsharedConstpoolHandle->GetAotSymbolInfo();
3228     JSHandle<TaggedArray> aotSymbolInfoHandle(thread, aotSymbolInfo);
3229     FrameHandler frameHandler(thread);
3230     uint32_t abcId = frameHandler.GetAbcId();
3231     ASSERT(startIndex + count <= length);
3232     for (uint32_t i = 0; i < count; i++) {
3233         auto index = startIndex + i;
3234         uint64_t id = JSSymbol::GeneratePrivateId(abcId, literalId, index);
3235         JSHandle<JSSymbol> symbolHandle;
3236         JSTaggedValue symbol = ConstantPool::GetSymbolFromSymbolInfo(aotSymbolInfoHandle, id);
3237         if (ConstantPool::IsAotSymbolInfoExist(aotSymbolInfoHandle, symbol)) {
3238             symbolHandle = JSHandle<JSSymbol>(thread, symbol);
3239         } else {
3240             symbolHandle = factory->NewJSSymbol();
3241             symbolHandle->SetPrivateId(id);
3242             symbolHandle->SetPrivate();
3243         }
3244         handleLexicalEnv->SetProperties(thread, index, symbolHandle.GetTaggedValue());
3245     }
3246 
3247     JSTaggedValue literalObj =
3248         ConstantPool::GetClassLiteralFromCache(thread, unsharedConstpoolHandle, literalId, entry);
3249     JSHandle<ClassLiteral> classLiteral(thread, literalObj);
3250     JSHandle<TaggedArray> literalBuffer(thread, classLiteral->GetArray());
3251     uint32_t literalBufferLength = literalBuffer->GetLength();
3252     if (literalBufferLength == 0) {
3253         return JSTaggedValue::Undefined();
3254     }
3255     // instace property number is hidden in the last index of literal buffer
3256     uint32_t instacePropertyCount = static_cast<uint32_t>(literalBuffer->Get(literalBufferLength - 1).GetInt());
3257     ASSERT(startIndex + count + literalBufferLength - (instacePropertyCount == 0) <= length);
3258 
3259     JSMutableHandle<JSTaggedValue> literalValue(thread, JSTaggedValue::Undefined());
3260     for (uint32_t i = 0; i < literalBufferLength - 1; i++) {
3261         literalValue.Update(literalBuffer->Get(i));
3262         if (LIKELY(literalValue->IsFunctionTemplate())) {
3263             auto literalFunc = JSHandle<FunctionTemplate>::Cast(literalValue);
3264             JSHandle<JSFunction> func = factory->CreateJSFunctionFromTemplate(literalFunc);
3265             func->SetLexicalEnv(thread, handleLexicalEnv.GetTaggedValue());
3266             func->SetModule(thread, handleModule.GetTaggedValue());
3267             literalValue.Update(func);
3268         }
3269         handleLexicalEnv->SetProperties(thread, startIndex + count + i, literalValue.GetTaggedValue());
3270     }
3271     if (instacePropertyCount > 0) {
3272         auto index = startIndex + count + literalBufferLength - 1;
3273         uint64_t id = JSSymbol::GeneratePrivateId(abcId, literalId, index);
3274         JSHandle<JSSymbol> symbolHandle;
3275         JSTaggedValue symbol = ConstantPool::GetSymbolFromSymbolInfo(aotSymbolInfoHandle, id);
3276         if (ConstantPool::IsAotSymbolInfoExist(aotSymbolInfoHandle, symbol)) {
3277             symbolHandle = JSHandle<JSSymbol>(thread, symbol);
3278         } else {
3279             symbolHandle = factory->NewPublicSymbolWithChar("method");
3280             symbolHandle->SetPrivateId(id);
3281             symbolHandle->SetPrivate();
3282         }
3283         handleLexicalEnv->SetProperties(thread, index, symbolHandle.GetTaggedValue());
3284     }
3285     return JSTaggedValue::Undefined();
3286 }
3287 
3288 JSTaggedValue RuntimeStubs::RuntimeDefinePrivateProperty(JSThread *thread, JSTaggedValue lexicalEnv,
3289     uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj, JSTaggedValue value)
3290 {
3291     JSTaggedValue currentLexicalEnv = lexicalEnv;
3292     for (uint32_t i = 0; i < levelIndex; i++) {
3293         currentLexicalEnv = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetParentEnv();
3294         ASSERT(!currentLexicalEnv.IsUndefined());
3295     }
3296     JSTaggedValue key = LexicalEnv::Cast(currentLexicalEnv.GetTaggedObject())->GetProperties(slotIndex);
3297     // private property is invisible for proxy
3298     JSHandle<JSTaggedValue> handleObj(thread, obj.IsJSProxy() ? JSProxy::Cast(obj)->GetPrivateField() : obj);
3299     JSHandle<JSTaggedValue> handleKey(thread, key);
3300     JSHandle<JSTaggedValue> handleValue(thread, value);
3301     PropertyDescriptor desc(thread);
3302     if (!JSTaggedValue::IsPropertyKey(handleKey) &&
3303         JSTaggedValue::GetOwnProperty(thread, handleObj, handleKey, desc)) {
3304         THROW_TYPE_ERROR_AND_RETURN(thread, "invalid private key or already exists", JSTaggedValue::Exception());
3305     }
3306     bool extensible = handleObj->IsExtensible(thread);
3307     if (handleObj->IsUndefined()) {
3308         THROW_TYPE_ERROR_AND_RETURN(thread, "DefinePrivateProperty obj is undefined", JSTaggedValue::Exception());
3309     }
3310     if (handleObj->IsJSShared()) {
3311         THROW_TYPE_ERROR_AND_RETURN(thread, "shared obj cannot use # to define private property",
3312                                     JSTaggedValue::Exception());
3313     }
3314     if (!extensible) {
3315         // private key should be always extensible
3316         handleObj->GetTaggedObject()->GetClass()->SetExtensible(true);
3317     }
3318     bool result = JSObject::CreateDataPropertyOrThrow(thread, JSHandle<JSObject>::Cast(handleObj),
3319                                                       handleKey, handleValue);
3320     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3321     if (!extensible) {
3322         handleObj->GetTaggedObject()->GetClass()->SetExtensible(false);
3323     }
3324     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3325     return JSTaggedValue(result);
3326 }
3327 
3328 JSTaggedValue RuntimeStubs::RuntimeNotifyDebuggerStatement(JSThread *thread)
3329 {
3330     FrameHandler frameHandler(thread);
3331     for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
3332         if (frameHandler.IsEntryFrame() || frameHandler.IsBuiltinFrame()) {
3333             continue;
3334         }
3335         Method *method = frameHandler.GetMethod();
3336         if (method->IsNativeWithCallField()) {
3337             continue;
3338         }
3339         auto bcOffset = frameHandler.GetBytecodeOffset();
3340         auto *debuggerMgr = thread->GetEcmaVM()->GetJsDebuggerManager();
3341         debuggerMgr->GetNotificationManager()->DebuggerStmtEvent(thread, method, bcOffset);
3342         return JSTaggedValue::Hole();
3343     }
3344     return JSTaggedValue::Hole();
3345 }
3346 
3347 bool RuntimeStubs::CheckElementsNumber(JSHandle<TaggedArray> elements, uint32_t len)
3348 {
3349     ASSERT(len <= elements->GetLength());
3350     for (uint32_t i = 0; i < len; i++) {
3351         if (!elements->Get(i).IsNumber()) {
3352             return false;
3353         }
3354     }
3355     return true;
3356 }
3357 
3358 JSHandle<JSTaggedValue> RuntimeStubs::GetOrCreateNumberString(JSThread *thread, JSHandle<JSTaggedValue> presentValue,
3359                                                               std::map<uint64_t, JSHandle<JSTaggedValue>> &cachedString)
3360 {
3361     JSMutableHandle<JSTaggedValue> presentString(thread, JSTaggedValue::Undefined());
3362     auto iter = cachedString.find(presentValue->GetRawData());
3363     if (iter != cachedString.end()) {
3364         presentString.Update(iter->second);
3365     } else {
3366         presentString.Update(JSTaggedValue::ToString(thread, presentValue).GetTaggedValue());
3367         cachedString[presentValue->GetRawData()] = presentString;
3368     }
3369     return presentString;
3370 }
3371 
3372 JSTaggedValue RuntimeStubs::TryCopyCOWArray(JSThread *thread, JSHandle<JSArray> holderHandler, bool &isCOWArray)
3373 {
3374     if (isCOWArray) {
3375         JSArray::CheckAndCopyArray(thread, holderHandler);
3376         isCOWArray = false;
3377     }
3378     return holderHandler->GetElements();
3379 }
3380 
3381 JSTaggedValue RuntimeStubs::ArrayNumberSort(JSThread *thread, JSHandle<JSObject> thisObj, uint32_t len)
3382 {
3383     JSMutableHandle<JSTaggedValue> presentValue(thread, JSTaggedValue::Undefined());
3384     JSMutableHandle<JSTaggedValue> middleValue(thread, JSTaggedValue::Undefined());
3385     JSMutableHandle<JSTaggedValue> previousValue(thread, JSTaggedValue::Undefined());
3386     bool isCOWArray = JSHandle<JSTaggedValue>(thisObj)->IsJSCOWArray();
3387     JSMutableHandle<TaggedArray> elements(thread, thisObj->GetElements());
3388     std::map<uint64_t, JSHandle<JSTaggedValue>> cachedString;
3389     for (uint32_t i = 1; i < len; i++) {
3390         uint32_t beginIndex = 0;
3391         uint32_t endIndex = i;
3392         presentValue.Update(elements->Get(i));
3393         JSHandle<JSTaggedValue> presentString = GetOrCreateNumberString(thread, presentValue, cachedString);
3394         while (beginIndex < endIndex) {
3395             uint32_t middleIndex = beginIndex + (endIndex - beginIndex) / 2; // 2 : half
3396             middleValue.Update(elements->Get(middleIndex));
3397             JSHandle<JSTaggedValue> middleString = GetOrCreateNumberString(thread, middleValue, cachedString);
3398             double compareResult = ArrayHelper::StringSortCompare(thread, middleString, presentString);
3399             RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
3400             if (compareResult > 0) {
3401                 endIndex = middleIndex;
3402             } else {
3403                 beginIndex = middleIndex + 1;
3404             }
3405         }
3406         if (endIndex >= 0 && endIndex < i) {
3407             for (uint32_t j = i; j > endIndex; j--) {
3408                 previousValue.Update(elements->Get(j - 1));
3409                 elements.Update(TryCopyCOWArray(thread, JSHandle<JSArray>(thisObj), isCOWArray));
3410                 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
3411                 elements->Set(thread, j, previousValue);
3412             }
3413             elements.Update(TryCopyCOWArray(thread, JSHandle<JSArray>(thisObj), isCOWArray));
3414             RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
3415             elements->Set(thread, endIndex, presentValue);
3416         }
3417     }
3418     return thisObj.GetTaggedValue();
3419 }
3420 
3421 JSTaggedType RuntimeStubs::RuntimeTryGetInternString(uintptr_t argGlue, const JSHandle<EcmaString> &string)
3422 {
3423     auto thread = JSThread::GlueToJSThread(argGlue);
3424     EcmaString *str =
3425         thread->GetEcmaVM()->GetEcmaStringTable()->TryGetInternString(thread, string);
3426     if (str == nullptr) {
3427         return JSTaggedValue::Hole().GetRawData();
3428     }
3429     return JSTaggedValue::Cast(static_cast<void *>(str));
3430 }
3431 
3432 uint32_t RuntimeStubs::RuntimeGetBytecodePcOfstForBaseline(const JSHandle<JSFunction> &func, uintptr_t nativePc)
3433 {
3434     // Compute current bytecodePc according to nativePc of returnAddress
3435     LOG_BASELINEJIT(DEBUG) << "nativePc address: " << std::hex << nativePc;
3436     const MachineCode *machineCode = MachineCode::Cast(func->GetBaselineCode().GetTaggedObject());
3437     const uintptr_t nativePcStart = machineCode->GetFuncAddr();
3438     LOG_BASELINEJIT(DEBUG) << "baselineCode nativeStart address: " << std::hex << nativePcStart;
3439     const Method *thisMethod = Method::Cast(func->GetMethod().GetTaggedObject());
3440     const uint8_t *bytecodeStart = thisMethod->GetBytecodeArray();
3441     const uint8_t *bytecodeEnd = bytecodeStart + thisMethod->GetCodeSize();
3442     LOG_BASELINEJIT(DEBUG) << "bytecodePc start: " << reinterpret_cast<uintptr_t>(bytecodeStart);
3443     LOG_BASELINEJIT(DEBUG) << "bytecodePc end: " << reinterpret_cast<uintptr_t>(bytecodeEnd);
3444     const uint8_t *offsetTableAddr = machineCode->GetStackMapOrOffsetTableAddress();
3445     const uint32_t offsetTableSize = machineCode->GetStackMapOrOffsetTableSize();
3446     uintptr_t nativePcEnd = nativePcStart;
3447     uint32_t pcOffsetIndex = 0;
3448     auto opcode = kungfu::Bytecodes::GetOpcode(bytecodeStart);
3449     while (nativePcEnd < nativePc && pcOffsetIndex < offsetTableSize) {
3450         nativePcEnd += static_cast<uintptr_t>(offsetTableAddr[pcOffsetIndex++]);
3451         opcode = kungfu::Bytecodes::GetOpcode(bytecodeStart);
3452         bytecodeStart += BytecodeInstruction::Size(opcode);
3453     }
3454     // Since the nativePc is returnAddress, we need to take the previous bytecode
3455     bytecodeStart -= BytecodeInstruction::Size(opcode);
3456     if (nativePcEnd < nativePc) {
3457         LOG_ECMA(FATAL) <<
3458             "invalid nativePc or pcOffsetTable for getting bytecode pc in baseline code, the nativePcEnd is " <<
3459             std::hex << nativePcEnd;
3460     }
3461     if (bytecodeStart > bytecodeEnd) {
3462         LOG_ECMA(FATAL) <<
3463             "out of bytecodeArray range for getting bytecode pc in baseline code, the bytecodePc is " <<
3464             reinterpret_cast<uintptr_t>(bytecodeStart);
3465     }
3466     auto bytecodePcOffset = static_cast<uint32_t>(bytecodeStart - thisMethod->GetBytecodeArray());
3467     LOG_BASELINEJIT(DEBUG) << "current bytecodePc offset: " << bytecodePcOffset;
3468     return bytecodePcOffset;
3469 }
3470 }  // namespace panda::ecmascript
3471 #endif  // ECMASCRIPT_STUBS_RUNTIME_STUBS_INL_H
3472