• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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/stubs/runtime_stubs.h"
20 
21 #include "ecmascript/builtins/builtins_regexp.h"
22 #include "ecmascript/compiler/aot_file/aot_file_manager.h"
23 #include "ecmascript/ecma_string_table.h"
24 #include "ecmascript/global_dictionary-inl.h"
25 #include "ecmascript/global_env.h"
26 #include "ecmascript/ic/profile_type_info.h"
27 #include "ecmascript/interpreter/frame_handler.h"
28 #include "ecmascript/jobs/micro_job_queue.h"
29 #include "ecmascript/js_arguments.h"
30 #include "ecmascript/js_async_function.h"
31 #include "ecmascript/js_async_generator_object.h"
32 #include "ecmascript/js_for_in_iterator.h"
33 #include "ecmascript/js_generator_object.h"
34 #include "ecmascript/js_iterator.h"
35 #include "ecmascript/js_promise.h"
36 #include "ecmascript/jspandafile/class_info_extractor.h"
37 #include "ecmascript/jspandafile/literal_data_extractor.h"
38 #include "ecmascript/jspandafile/scope_info_extractor.h"
39 #include "ecmascript/module/js_module_manager.h"
40 #include "ecmascript/module/js_module_source_text.h"
41 #include "ecmascript/platform/file.h"
42 #include "ecmascript/stackmap/llvm_stackmap_parser.h"
43 #include "ecmascript/template_string.h"
44 #include "ecmascript/ts_types/ts_manager.h"
45 
46 namespace panda::ecmascript {
RuntimeInc(JSThread * thread,const JSHandle<JSTaggedValue> & value)47 JSTaggedValue RuntimeStubs::RuntimeInc(JSThread *thread, const JSHandle<JSTaggedValue> &value)
48 {
49     JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value);
50     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
51     if (inputVal->IsBigInt()) {
52         JSHandle<BigInt> bigValue(inputVal);
53         return BigInt::BigintAddOne(thread, bigValue).GetTaggedValue();
54     }
55     JSTaggedNumber number(inputVal.GetTaggedValue());
56     return JSTaggedValue(++number);
57 }
58 
RuntimeDec(JSThread * thread,const JSHandle<JSTaggedValue> & value)59 JSTaggedValue RuntimeStubs::RuntimeDec(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::BigintSubOne(thread, bigValue).GetTaggedValue();
66     }
67     JSTaggedNumber number(inputVal.GetTaggedValue());
68     return JSTaggedValue(--number);
69 }
70 
RuntimeExp(JSThread * thread,JSTaggedValue base,JSTaggedValue exponent)71 JSTaggedValue RuntimeStubs::RuntimeExp(JSThread *thread, JSTaggedValue base, JSTaggedValue exponent)
72 {
73     JSHandle<JSTaggedValue> baseTag(thread, base);
74     JSHandle<JSTaggedValue> exponentTag(thread, exponent);
75     JSHandle<JSTaggedValue> valBase = JSTaggedValue::ToNumeric(thread, baseTag);
76     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
77     JSHandle<JSTaggedValue> valExponent = JSTaggedValue::ToNumeric(thread, exponentTag);
78     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
79     if (valBase->IsBigInt() || valExponent->IsBigInt()) {
80         if (valBase->IsBigInt() && valExponent->IsBigInt()) {
81             JSHandle<BigInt> bigBaseVale(valBase);
82             JSHandle<BigInt> bigExponentValue(valExponent);
83             return BigInt::Exponentiate(thread, bigBaseVale, bigExponentValue).GetTaggedValue();
84         }
85         THROW_TYPE_ERROR_AND_RETURN(thread, "Cannot mix BigInt and other types, use explicit conversions",
86                                     JSTaggedValue::Exception());
87     }
88     double doubleBase = valBase->GetNumber();
89     double doubleExponent = valExponent->GetNumber();
90     if (std::abs(doubleBase) == 1 && std::isinf(doubleExponent)) {
91         return JSTaggedValue(base::NAN_VALUE);
92     }
93     if (((doubleBase == 0) &&
94         ((base::bit_cast<uint64_t>(doubleBase)) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) &&
95         std::isfinite(doubleExponent) && base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent &&
96         base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF == (doubleExponent / 2)) {  // 2: half
97         if (doubleExponent > 0) {
98             return JSTaggedValue(-0.0);
99         }
100         if (doubleExponent < 0) {
101             return JSTaggedValue(-base::POSITIVE_INFINITY);
102         }
103     }
104     return JSTaggedValue(std::pow(doubleBase, doubleExponent));
105 }
106 
RuntimeIsIn(JSThread * thread,const JSHandle<JSTaggedValue> & prop,const JSHandle<JSTaggedValue> & obj)107 JSTaggedValue RuntimeStubs::RuntimeIsIn(JSThread *thread, const JSHandle<JSTaggedValue> &prop,
108                                         const JSHandle<JSTaggedValue> &obj)
109 {
110     if (!obj->IsECMAObject()) {
111         return RuntimeThrowTypeError(thread, "Cannot use 'in' operator in Non-Object");
112     }
113     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop);
114     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
115     bool ret = JSTaggedValue::HasProperty(thread, obj, propKey);
116     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
117     return JSTaggedValue(ret);
118 }
119 
RuntimeInstanceof(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & target)120 JSTaggedValue RuntimeStubs::RuntimeInstanceof(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
121                                               const JSHandle<JSTaggedValue> &target)
122 {
123     bool ret = JSObject::InstanceOf(thread, obj, target);
124     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
125     return JSTaggedValue(ret);
126 }
127 
RuntimeInstanceofByHandler(JSThread * thread,JSHandle<JSTaggedValue> target,JSHandle<JSTaggedValue> object,JSHandle<JSTaggedValue> instOfHandler)128 JSTaggedValue RuntimeStubs::RuntimeInstanceofByHandler(JSThread *thread, JSHandle<JSTaggedValue> target,
129                                                        JSHandle<JSTaggedValue> object,
130                                                        JSHandle<JSTaggedValue> instOfHandler)
131 {
132     // 3. ReturnIfAbrupt(instOfHandler).
133     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
134     // 4. If instOfHandler is not undefined, then
135     if (!instOfHandler->IsUndefined()) {
136         // a. Return ! ToBoolean(? Call(instOfHandler, target, «object»)).
137         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
138         JSTaggedValue function = env->GetTaggedHasInstanceFunction();
139         JSTaggedValue instOf = instOfHandler.GetTaggedValue();
140         // slowpath
141         if (function != instOf) {
142             JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
143             EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, instOfHandler, target,
144                                                                             undefined, 1);
145             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
146             info->SetCallArg(object.GetTaggedValue());
147             JSTaggedValue tagged = JSFunction::Call(info);
148 
149             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
150             return tagged;
151         }
152     }
153     // 5. If IsCallable(target) is false, throw a TypeError exception.
154     if (!target->IsCallable()) {
155         THROW_TYPE_ERROR_AND_RETURN(thread, "InstanceOf error when target is not Callable", JSTaggedValue::Exception());
156     }
157     // fastpath
158     // 6. Return ? OrdinaryHasInstance(target, object).
159     bool res = JSFunction::OrdinaryHasInstance(thread, target, object);
160     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
161     return JSTaggedValue(res);
162 }
163 
RuntimeCreateGeneratorObj(JSThread * thread,const JSHandle<JSTaggedValue> & genFunc)164 JSTaggedValue RuntimeStubs::RuntimeCreateGeneratorObj(JSThread *thread, const JSHandle<JSTaggedValue> &genFunc)
165 {
166     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
167     JSHandle<JSGeneratorObject> obj = factory->NewJSGeneratorObject(genFunc);
168     JSHandle<GeneratorContext> context = factory->NewGeneratorContext();
169     context->SetGeneratorObject(thread, obj.GetTaggedValue());
170 
171     // change state to SUSPENDED_START
172     obj->SetGeneratorState(JSGeneratorState::SUSPENDED_START);
173     obj->SetGeneratorContext(thread, context);
174 
175     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
176     return obj.GetTaggedValue();
177 }
178 
RuntimeCreateAsyncGeneratorObj(JSThread * thread,const JSHandle<JSTaggedValue> & genFunc)179 JSTaggedValue RuntimeStubs::RuntimeCreateAsyncGeneratorObj(JSThread *thread, const JSHandle<JSTaggedValue> &genFunc)
180 {
181     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
182     JSHandle<JSAsyncGeneratorObject> obj = factory->NewJSAsyncGeneratorObject(genFunc);
183     JSHandle<GeneratorContext> context = factory->NewGeneratorContext();
184     context->SetGeneratorObject(thread, obj.GetTaggedValue());
185 
186     // change state to SUSPENDED_START
187     obj->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_START);
188     obj->SetGeneratorContext(thread, context);
189 
190     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
191     return obj.GetTaggedValue();
192 }
193 
RuntimeGetTemplateObject(JSThread * thread,const JSHandle<JSTaggedValue> & literal)194 JSTaggedValue RuntimeStubs::RuntimeGetTemplateObject(JSThread *thread, const JSHandle<JSTaggedValue> &literal)
195 {
196     JSHandle<JSTaggedValue> templateObj = TemplateString::GetTemplateObject(thread, literal);
197     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
198     return templateObj.GetTaggedValue();
199 }
200 
RuntimeGetNextPropName(JSThread * thread,const JSHandle<JSTaggedValue> & iter)201 JSTaggedValue RuntimeStubs::RuntimeGetNextPropName(JSThread *thread, const JSHandle<JSTaggedValue> &iter)
202 {
203     ASSERT(iter->IsForinIterator());
204     std::pair<JSTaggedValue, bool> res =
205         JSForInIterator::NextInternal(thread, JSHandle<JSForInIterator>::Cast(iter));
206     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
207     return res.first;
208 }
209 
RuntimeIterNext(JSThread * thread,const JSHandle<JSTaggedValue> & iter)210 JSTaggedValue RuntimeStubs::RuntimeIterNext(JSThread *thread, const JSHandle<JSTaggedValue> &iter)
211 {
212     JSHandle<JSTaggedValue> resultObj = JSIterator::IteratorNext(thread, iter);
213     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
214     return resultObj.GetTaggedValue();
215 }
216 
RuntimeCloseIterator(JSThread * thread,const JSHandle<JSTaggedValue> & iter)217 JSTaggedValue RuntimeStubs::RuntimeCloseIterator(JSThread *thread, const JSHandle<JSTaggedValue> &iter)
218 {
219     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
220     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
221 
222     JSHandle<JSTaggedValue> record;
223     if (thread->HasPendingException()) {
224         record = JSHandle<JSTaggedValue>(factory->NewCompletionRecord(
225             CompletionRecordType::THROW, JSHandle<JSTaggedValue>(thread, thread->GetException())));
226     } else {
227         JSHandle<JSTaggedValue> undefinedVal = globalConst->GetHandledUndefined();
228         record = JSHandle<JSTaggedValue>(factory->NewCompletionRecord(CompletionRecordType::NORMAL, undefinedVal));
229     }
230     JSHandle<JSTaggedValue> result = JSIterator::IteratorClose(thread, iter, record);
231     if (result->IsCompletionRecord()) {
232         return CompletionRecord::Cast(result->GetTaggedObject())->GetValue();
233     }
234     return result.GetTaggedValue();
235 }
236 
RuntimeSuperCallSpread(JSThread * thread,const JSHandle<JSTaggedValue> & func,const JSHandle<JSTaggedValue> & newTarget,const JSHandle<JSTaggedValue> & array)237 JSTaggedValue RuntimeStubs::RuntimeSuperCallSpread(JSThread *thread, const JSHandle<JSTaggedValue> &func,
238                                                    const JSHandle<JSTaggedValue> &newTarget,
239                                                    const JSHandle<JSTaggedValue> &array)
240 {
241     JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func));
242     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
243     ASSERT(superFunc->IsJSFunction());
244 
245     JSHandle<TaggedArray> argv(thread, RuntimeGetCallSpreadArgs(thread, array));
246     const uint32_t argsLength = argv->GetLength();
247     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
248     EcmaRuntimeCallInfo *info =
249         EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, argsLength);
250     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
251     info->SetCallArg(argsLength, argv);
252     JSTaggedValue result = JSFunction::Construct(info);
253     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
254 
255     return result;
256 }
257 
RuntimeDelObjProp(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & prop)258 JSTaggedValue RuntimeStubs::RuntimeDelObjProp(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
259                                               const JSHandle<JSTaggedValue> &prop)
260 {
261     JSHandle<JSTaggedValue> jsObj(JSTaggedValue::ToObject(thread, obj));
262     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
263     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop);
264     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
265     bool ret = JSTaggedValue::DeletePropertyOrThrow(thread, jsObj, propKey);
266     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
267     return JSTaggedValue(ret);
268 }
269 
RuntimeNewObjApply(JSThread * thread,const JSHandle<JSTaggedValue> & func,const JSHandle<JSTaggedValue> & array)270 JSTaggedValue RuntimeStubs::RuntimeNewObjApply(JSThread *thread, const JSHandle<JSTaggedValue> &func,
271                                                const JSHandle<JSTaggedValue> &array)
272 {
273     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
274     if (!array->IsJSArray()) {
275         return RuntimeThrowTypeError(thread, "Cannot Newobjspread");
276     }
277 
278     uint32_t length = JSHandle<JSArray>::Cast(array)->GetArrayLength();
279     JSHandle<TaggedArray> argsArray = factory->NewTaggedArray(length);
280     for (uint32_t i = 0; i < length; ++i) {
281         auto prop = JSTaggedValue::GetProperty(thread, array, i).GetValue();
282         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
283         argsArray->Set(thread, i, prop);
284         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
285     }
286     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
287     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, func, length);
288     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
289     info->SetCallArg(length, argsArray);
290     return NewObject(info);
291 }
292 
RuntimeCreateIterResultObj(JSThread * thread,const JSHandle<JSTaggedValue> & value,JSTaggedValue flag)293 JSTaggedValue RuntimeStubs::RuntimeCreateIterResultObj(JSThread *thread, const JSHandle<JSTaggedValue> &value,
294                                                        JSTaggedValue flag)
295 {
296     ASSERT(flag.IsBoolean());
297     bool done = flag.IsTrue();
298     JSHandle<JSObject> iter = JSIterator::CreateIterResultObject(thread, value, done);
299     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
300     return iter.GetTaggedValue();
301 }
302 
RuntimeAsyncFunctionAwaitUncaught(JSThread * thread,const JSHandle<JSTaggedValue> & asyncFuncObj,const JSHandle<JSTaggedValue> & value)303 JSTaggedValue RuntimeStubs::RuntimeAsyncFunctionAwaitUncaught(JSThread *thread,
304                                                               const JSHandle<JSTaggedValue> &asyncFuncObj,
305                                                               const JSHandle<JSTaggedValue> &value)
306 {
307     JSAsyncFunction::AsyncFunctionAwait(thread, asyncFuncObj, value);
308     if (asyncFuncObj->IsAsyncGeneratorObject()) {
309         JSHandle<JSObject> obj = JSTaggedValue::ToObject(thread, asyncFuncObj);
310         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
311         JSHandle<JSAsyncGeneratorObject> generator = JSHandle<JSAsyncGeneratorObject>::Cast(obj);
312         JSHandle<TaggedQueue> queue(thread, generator->GetAsyncGeneratorQueue());
313         if (queue->Empty()) {
314             return JSTaggedValue::Undefined();
315         }
316         JSHandle<AsyncGeneratorRequest> next(thread, queue->Front());
317         JSHandle<PromiseCapability> completion(thread, next->GetCapability());
318         JSHandle<JSPromise> promise(thread, completion->GetPromise());
319         return promise.GetTaggedValue();
320     }
321     JSHandle<JSAsyncFuncObject> asyncFuncObjHandle(asyncFuncObj);
322     JSHandle<JSPromise> promise(thread, asyncFuncObjHandle->GetPromise());
323 
324     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
325     return promise.GetTaggedValue();
326 }
327 
RuntimeAsyncFunctionResolveOrReject(JSThread * thread,const JSHandle<JSTaggedValue> & asyncFuncObj,const JSHandle<JSTaggedValue> & value,bool is_resolve)328 JSTaggedValue RuntimeStubs::RuntimeAsyncFunctionResolveOrReject(JSThread *thread,
329     const JSHandle<JSTaggedValue> &asyncFuncObj, const JSHandle<JSTaggedValue> &value, bool is_resolve)
330 {
331     JSHandle<JSAsyncFuncObject> asyncFuncObjHandle(asyncFuncObj);
332     JSHandle<JSPromise> promise(thread, asyncFuncObjHandle->GetPromise());
333 
334     // ActivePromise
335     JSHandle<ResolvingFunctionsRecord> reactions = JSPromise::CreateResolvingFunctions(thread, promise);
336     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
337     JSHandle<JSTaggedValue> thisArg = globalConst->GetHandledUndefined();
338     JSHandle<JSTaggedValue> activeFunc;
339     if (is_resolve) {
340         activeFunc = JSHandle<JSTaggedValue>(thread, reactions->GetResolveFunction());
341     } else {
342         activeFunc = JSHandle<JSTaggedValue>(thread, reactions->GetRejectFunction());
343     }
344     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
345     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, activeFunc, thisArg, undefined, 1);
346     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
347     info->SetCallArg(value.GetTaggedValue());
348     [[maybe_unused]] JSTaggedValue res = JSFunction::Call(info);
349 
350     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
351     return promise.GetTaggedValue();
352 }
353 
RuntimeAsyncGeneratorResolve(JSThread * thread,JSHandle<JSTaggedValue> asyncFuncObj,JSHandle<JSTaggedValue> value,JSTaggedValue flag)354 JSTaggedValue RuntimeStubs::RuntimeAsyncGeneratorResolve(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj,
355                                                          JSHandle<JSTaggedValue> value, JSTaggedValue flag)
356 {
357     [[maybe_unused]] EcmaHandleScope handleScope(thread);
358 
359     JSHandle<JSAsyncGeneratorObject> asyncGeneratorObjHandle(asyncFuncObj);
360     JSHandle<JSTaggedValue> valueHandle(value);
361     JSHandle<GeneratorContext> genContextHandle(thread, asyncGeneratorObjHandle->GetGeneratorContext());
362     // save stack, should copy cur_frame, function execute over will free cur_frame
363     SaveFrameToContext(thread, genContextHandle);
364 
365     ASSERT(flag.IsBoolean());
366     bool done = flag.IsTrue();
367     if (asyncGeneratorObjHandle->GetAsyncGeneratorState() == JSAsyncGeneratorState::COMPLETED &&
368         TaggedQueue::Cast(asyncGeneratorObjHandle->GetAsyncGeneratorQueue().GetTaggedObject())->Empty()) {
369         return JSTaggedValue::Undefined();
370     }
371     return JSAsyncGeneratorObject::AsyncGeneratorResolve(thread, asyncGeneratorObjHandle, valueHandle, done);
372 }
373 
RuntimeAsyncGeneratorReject(JSThread * thread,JSHandle<JSTaggedValue> asyncFuncObj,JSHandle<JSTaggedValue> value)374 JSTaggedValue RuntimeStubs::RuntimeAsyncGeneratorReject(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj,
375                                                         JSHandle<JSTaggedValue> value)
376 {
377     [[maybe_unused]] EcmaHandleScope handleScope(thread);
378 
379     JSHandle<JSAsyncGeneratorObject> asyncGeneratorObjHandle(asyncFuncObj);
380     JSHandle<JSTaggedValue> valueHandle(value);
381 
382     return JSAsyncGeneratorObject::AsyncGeneratorReject(thread, asyncGeneratorObjHandle, valueHandle);
383 }
384 
RuntimeCopyDataProperties(JSThread * thread,const JSHandle<JSTaggedValue> & dst,const JSHandle<JSTaggedValue> & src)385 JSTaggedValue RuntimeStubs::RuntimeCopyDataProperties(JSThread *thread, const JSHandle<JSTaggedValue> &dst,
386                                                       const JSHandle<JSTaggedValue> &src)
387 {
388     if (!src->IsNull() && !src->IsUndefined()) {
389         // 2. Let from be ! ToObject(source).
390         JSHandle<JSTaggedValue> from(JSTaggedValue::ToObject(thread, src));
391         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
392         JSHandle<TaggedArray> keys = JSTaggedValue::GetOwnPropertyKeys(thread, from);
393         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
394 
395         JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
396         uint32_t keysLen = keys->GetLength();
397         for (uint32_t i = 0; i < keysLen; i++) {
398             PropertyDescriptor desc(thread);
399             key.Update(keys->Get(i));
400             bool success = JSTaggedValue::GetOwnProperty(thread, from, key, desc);
401             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
402 
403             if (success && desc.IsEnumerable()) {
404                 JSTaggedValue::DefineOwnProperty(thread, dst, key, desc);
405                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
406             }
407         }
408     }
409     return dst.GetTaggedValue();
410 }
411 
RuntimeStArraySpread(JSThread * thread,const JSHandle<JSTaggedValue> & dst,JSTaggedValue index,const JSHandle<JSTaggedValue> & src)412 JSTaggedValue RuntimeStubs::RuntimeStArraySpread(JSThread *thread, const JSHandle<JSTaggedValue> &dst,
413                                                  JSTaggedValue index, const JSHandle<JSTaggedValue> &src)
414 {
415     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
416     ASSERT(dst->IsJSArray());
417     if (dst->IsJSArray()) {
418         if (src->IsNull() || src->IsUndefined()) {
419             THROW_TYPE_ERROR_AND_RETURN(thread, "src is not iterable", JSTaggedValue::Exception());
420         }
421     } else {
422         THROW_TYPE_ERROR_AND_RETURN(thread, "dst is not iterable", JSTaggedValue::Exception());
423     }
424     if (src->IsString()) {
425         JSHandle<EcmaString> srcString = JSTaggedValue::ToString(thread, src);
426         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
427         JSHandle<EcmaString> srcFlat = JSHandle<EcmaString>(thread,
428             EcmaStringAccessor::Flatten(thread->GetEcmaVM(), srcString));
429         uint32_t dstLen = static_cast<uint32_t>(index.GetInt());
430         uint32_t strLen = EcmaStringAccessor(srcFlat).GetLength();
431         for (uint32_t i = 0; i < strLen; i++) {
432             uint16_t res = EcmaStringAccessor(srcFlat).Get<false>(i);
433             JSHandle<JSTaggedValue> strValue(factory->NewFromUtf16Literal(&res, 1));
434             JSTaggedValue::SetProperty(thread, dst, dstLen + i, strValue, true);
435             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
436         }
437         return JSTaggedValue(dstLen + strLen);
438     }
439 
440     if (index.GetInt() == 0 && src->IsStableJSArray(thread)) {
441         JSHandle<TaggedArray> srcElements(thread, JSHandle<JSObject>::Cast(src)->GetElements());
442         uint32_t length = JSHandle<JSArray>::Cast(src)->GetArrayLength();
443         JSHandle<TaggedArray> dstElements = factory->NewTaggedArray(length);
444         JSHandle<JSArray> dstArray = JSHandle<JSArray>::Cast(dst);
445         dstArray->SetElements(thread, dstElements);
446         dstArray->SetArrayLength(thread, length);
447         TaggedArray::CopyTaggedArrayElement(thread, srcElements, dstElements, length);
448         return JSTaggedValue(length);
449     }
450 
451     JSHandle<JSTaggedValue> iter;
452     auto globalConst = thread->GlobalConstants();
453     if (src->IsJSArrayIterator() || src->IsJSMapIterator() || src->IsJSSetIterator() ||
454         src->IsIterator()) {
455         iter = src;
456     } else if (src->IsJSArray()) {
457         JSHandle<JSTaggedValue> valuesStr = globalConst->GetHandledValuesString();
458         JSHandle<JSTaggedValue> valuesMethod = JSObject::GetMethod(thread, src, valuesStr);
459         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
460         iter = JSIterator::GetIterator(thread, src, valuesMethod);
461         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
462     } else {
463         iter = JSIterator::GetIterator(thread, src);
464         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
465     }
466 
467     JSMutableHandle<JSTaggedValue> indexHandle(thread, index);
468     JSHandle<JSTaggedValue> valueStr = globalConst->GetHandledValueString();
469     PropertyDescriptor desc(thread);
470     JSHandle<JSTaggedValue> iterResult;
471     do {
472         iterResult = JSIterator::IteratorStep(thread, iter);
473         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
474         if (iterResult->IsFalse()) {
475             break;
476         }
477         bool success = JSTaggedValue::GetOwnProperty(thread, iterResult, valueStr, desc);
478         if (success && desc.IsEnumerable()) {
479             JSTaggedValue::DefineOwnProperty(thread, dst, indexHandle, desc);
480             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
481             int tmp = indexHandle->GetInt();
482             indexHandle.Update(JSTaggedValue(tmp + 1));
483         }
484     } while (true);
485 
486     return indexHandle.GetTaggedValue();
487 }
488 
RuntimeGetIteratorNext(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & method)489 JSTaggedValue RuntimeStubs::RuntimeGetIteratorNext(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
490                                                    const JSHandle<JSTaggedValue> &method)
491 {
492     ASSERT(method->IsCallable());
493     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
494     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, method, obj, undefined, 0);
495     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
496     JSTaggedValue ret = JSFunction::Call(info);
497     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
498     if (!ret.IsECMAObject()) {
499         return RuntimeThrowTypeError(thread, "the Iterator is not an ecmaobject.");
500     }
501     return ret;
502 }
503 
RuntimeSetObjectWithProto(JSThread * thread,const JSHandle<JSTaggedValue> & proto,const JSHandle<JSObject> & obj)504 JSTaggedValue RuntimeStubs::RuntimeSetObjectWithProto(JSThread *thread, const JSHandle<JSTaggedValue> &proto,
505                                                       const JSHandle<JSObject> &obj)
506 {
507     if (!proto->IsECMAObject() && !proto->IsNull()) {
508         return JSTaggedValue::False();
509     }
510     JSObject::SetPrototype(thread, obj, proto);
511     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
512     return JSTaggedValue::True();
513 }
514 
RuntimeLdObjByValue(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & prop,bool callGetter,JSTaggedValue receiver)515 JSTaggedValue RuntimeStubs::RuntimeLdObjByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
516                                                 const JSHandle<JSTaggedValue> &prop, bool callGetter,
517                                                 JSTaggedValue receiver)
518 {
519     // Ecma Spec 2015 12.3.2.1
520     // 7. Let bv be RequireObjectCoercible(baseValue).
521     // 8. ReturnIfAbrupt(bv).
522     JSHandle<JSTaggedValue> object =
523         JSTaggedValue::RequireObjectCoercible(thread, obj, "Cannot load property of null or undefined");
524     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
525 
526     JSTaggedValue res;
527     if (callGetter) {
528         res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), object);
529     } else {
530         JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop);
531         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
532         res = JSTaggedValue::GetProperty(thread, object, propKey).GetValue().GetTaggedValue();
533     }
534     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
535     return res;
536 }
537 
RuntimeStObjByValue(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & prop,const JSHandle<JSTaggedValue> & value)538 JSTaggedValue RuntimeStubs::RuntimeStObjByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
539                                                 const JSHandle<JSTaggedValue> &prop,
540                                                 const JSHandle<JSTaggedValue> &value)
541 {
542     // Ecma Spec 2015 12.3.2.1
543     // 7. Let bv be RequireObjectCoercible(baseValue).
544     // 8. ReturnIfAbrupt(bv).
545     JSHandle<JSTaggedValue> object =
546         JSTaggedValue::RequireObjectCoercible(thread, obj, "Cannot store property of null or undefined");
547     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
548 
549     JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, prop));
550     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
551     // strict mode is true
552     JSTaggedValue::SetProperty(thread, object, propKey, value, true);
553     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
554     return JSTaggedValue::True();
555 }
556 
RuntimeStOwnByValue(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & value)557 JSTaggedValue RuntimeStubs::RuntimeStOwnByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
558                                                 const JSHandle<JSTaggedValue> &key,
559                                                 const JSHandle<JSTaggedValue> &value)
560 {
561     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
562 
563     if (obj->IsClassConstructor() &&
564         JSTaggedValue::SameValue(key, globalConst->GetHandledPrototypeString())) {
565         return RuntimeThrowTypeError(thread, "In a class, static property named 'prototype' throw a TypeError");
566     }
567 
568     // property in class is non-enumerable
569     bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor());
570 
571     PropertyDescriptor desc(thread, value, true, enumerable, true);
572     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, key);
573     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
574     bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, propKey, desc);
575     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
576     if (!ret) {
577         return RuntimeThrowTypeError(thread, "StOwnByValue failed");
578     }
579     return JSTaggedValue::True();
580 }
581 
RuntimeLdSuperByValue(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & key,JSTaggedValue thisFunc)582 JSTaggedValue RuntimeStubs::RuntimeLdSuperByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
583                                                   const JSHandle<JSTaggedValue> &key, JSTaggedValue thisFunc)
584 {
585     ASSERT(thisFunc.IsJSFunction());
586     // get Homeobject form function
587     JSHandle<JSTaggedValue> homeObject(thread, JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject());
588 
589     if (obj->IsUndefined()) {
590         return RuntimeThrowReferenceError(thread, obj, "this is uninitialized.");
591     }
592 
593     JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, key));
594     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
595     JSHandle<JSTaggedValue> superBase(thread, JSTaggedValue::GetSuperBase(thread, homeObject));
596     JSTaggedValue::RequireObjectCoercible(thread, superBase);
597     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
598 
599     JSTaggedValue res = JSTaggedValue::GetProperty(thread, superBase, propKey, obj).GetValue().GetTaggedValue();
600     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
601     return res;
602 }
603 
RuntimeStSuperByValue(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & value,JSTaggedValue thisFunc)604 JSTaggedValue RuntimeStubs::RuntimeStSuperByValue(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
605                                                   const JSHandle<JSTaggedValue> &key,
606                                                   const JSHandle<JSTaggedValue> &value, JSTaggedValue thisFunc)
607 {
608     ASSERT(thisFunc.IsJSFunction());
609     // get Homeobject form function
610     JSHandle<JSTaggedValue> homeObject(thread, JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject());
611 
612     if (obj->IsUndefined()) {
613         return RuntimeThrowReferenceError(thread, obj, "this is uninitialized.");
614     }
615 
616     JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, key));
617     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
618     JSHandle<JSTaggedValue> superBase(thread, JSTaggedValue::GetSuperBase(thread, homeObject));
619     JSTaggedValue::RequireObjectCoercible(thread, superBase);
620     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
621 
622     // check may_throw is false?
623     JSTaggedValue::SetProperty(thread, superBase, propKey, value, obj, true);
624     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
625     return JSTaggedValue::True();
626 }
627 
RuntimeLdObjByIndex(JSThread * thread,const JSHandle<JSTaggedValue> & obj,uint32_t idx,bool callGetter,JSTaggedValue receiver)628 JSTaggedValue RuntimeStubs::RuntimeLdObjByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
629                                                 uint32_t idx, bool callGetter, JSTaggedValue receiver)
630 {
631     JSTaggedValue res;
632     if (callGetter) {
633         res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), obj);
634     } else {
635         res = JSTaggedValue::GetProperty(thread, obj, idx).GetValue().GetTaggedValue();
636     }
637     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
638     return res;
639 }
640 
RuntimeLdObjByName(JSThread * thread,JSTaggedValue obj,JSTaggedValue prop,bool callGetter,JSTaggedValue receiver)641 JSTaggedValue RuntimeStubs::RuntimeLdObjByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop,
642                                                bool callGetter, JSTaggedValue receiver)
643 {
644     JSHandle<JSTaggedValue> objHandle(thread, obj);
645     JSTaggedValue res;
646     if (callGetter) {
647         res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), objHandle);
648     } else {
649         JSHandle<JSTaggedValue> propHandle(thread, prop);
650         res = JSTaggedValue::GetProperty(thread, objHandle, propHandle).GetValue().GetTaggedValue();
651     }
652     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
653     return res;
654 }
655 
RuntimeStObjByName(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & prop,const JSHandle<JSTaggedValue> & value)656 JSTaggedValue RuntimeStubs::RuntimeStObjByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
657                                                const JSHandle<JSTaggedValue> &prop,
658                                                const JSHandle<JSTaggedValue> &value)
659 {
660     JSTaggedValue::SetProperty(thread, obj, prop, value, true);
661     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
662     return JSTaggedValue::True();
663 }
664 
RuntimeStObjByIndex(JSThread * thread,const JSHandle<JSTaggedValue> & obj,uint32_t idx,const JSHandle<JSTaggedValue> & value)665 JSTaggedValue RuntimeStubs::RuntimeStObjByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
666                                                 uint32_t idx, const JSHandle<JSTaggedValue> &value)
667 {
668     JSTaggedValue::SetProperty(thread, obj, idx, value, true);
669     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
670     return JSTaggedValue::True();
671 }
672 
RuntimeStOwnByIndex(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & idx,const JSHandle<JSTaggedValue> & value)673 JSTaggedValue RuntimeStubs::RuntimeStOwnByIndex(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
674                                                 const JSHandle<JSTaggedValue> &idx,
675                                                 const JSHandle<JSTaggedValue> &value)
676 {
677     // property in class is non-enumerable
678     bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor());
679 
680     PropertyDescriptor desc(thread, value, true, enumerable, true);
681     bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, idx, desc);
682     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
683     if (!ret) {
684         return RuntimeThrowTypeError(thread, "SetOwnByIndex failed");
685     }
686     return JSTaggedValue::True();
687 }
688 
RuntimeStGlobalRecord(JSThread * thread,const JSHandle<JSTaggedValue> & prop,const JSHandle<JSTaggedValue> & value,bool isConst)689 JSTaggedValue RuntimeStubs::RuntimeStGlobalRecord(JSThread *thread, const JSHandle<JSTaggedValue> &prop,
690                                                   const JSHandle<JSTaggedValue> &value, bool isConst)
691 {
692     EcmaVM *vm = thread->GetEcmaVM();
693     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
694     GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
695 
696     // cross files global record name binding judgment
697     int entry = dict->FindEntry(prop.GetTaggedValue());
698     if (entry != -1) {
699         return RuntimeThrowSyntaxError(thread, "Duplicate identifier");
700     }
701 
702     PropertyAttributes attributes;
703     if (isConst) {
704         attributes.SetIsConstProps(true);
705     }
706     JSHandle<GlobalDictionary> dictHandle(thread, dict);
707 
708     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
709     JSHandle<PropertyBox> box = factory->NewPropertyBox(value);
710     PropertyBoxType boxType = value->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
711     attributes.SetBoxType(boxType);
712 
713     dict = *GlobalDictionary::PutIfAbsent(thread, dictHandle, prop, JSHandle<JSTaggedValue>(box), attributes);
714     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
715     env->SetGlobalRecord(thread, JSTaggedValue(dict));
716     return JSTaggedValue::True();
717 }
718 
RuntimeNeg(JSThread * thread,const JSHandle<JSTaggedValue> & value)719 JSTaggedValue RuntimeStubs::RuntimeNeg(JSThread *thread, const JSHandle<JSTaggedValue> &value)
720 {
721     JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value);
722     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
723     if (inputVal->IsBigInt()) {
724         JSHandle<BigInt> bigValue(inputVal);
725         return BigInt::UnaryMinus(thread, bigValue).GetTaggedValue();
726     }
727     JSTaggedNumber number(inputVal.GetTaggedValue());
728     if (number.IsInt()) {
729         int32_t intValue = number.GetInt();
730         if (intValue == 0) {
731             return JSTaggedValue(-0.0);
732         }
733         if (intValue == INT32_MIN) {
734             return JSTaggedValue(-static_cast<double>(INT32_MIN));
735         }
736         return JSTaggedValue(-intValue);
737     }
738     if (number.IsDouble()) {
739         return JSTaggedValue(-number.GetDouble());
740     }
741     LOG_ECMA(FATAL) << "this branch is unreachable";
742     UNREACHABLE();
743 }
744 
RuntimeNot(JSThread * thread,const JSHandle<JSTaggedValue> & value)745 JSTaggedValue RuntimeStubs::RuntimeNot(JSThread *thread, const JSHandle<JSTaggedValue> &value)
746 {
747     JSHandle<JSTaggedValue> inputVal = JSTaggedValue::ToNumeric(thread, value);
748     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
749     if (inputVal->IsBigInt()) {
750         JSHandle<BigInt> bigValue(inputVal);
751         return BigInt::BitwiseNOT(thread, bigValue).GetTaggedValue();
752     }
753     int32_t number = JSTaggedValue::ToInt32(thread, inputVal);
754     return JSTaggedValue(~number); // NOLINT(hicpp-signed-bitwise)
755 }
756 
RuntimeResolveClass(JSThread * thread,const JSHandle<JSFunction> & ctor,const JSHandle<TaggedArray> & literal,const JSHandle<JSTaggedValue> & base,const JSHandle<JSTaggedValue> & lexenv)757 JSTaggedValue RuntimeStubs::RuntimeResolveClass(JSThread *thread, const JSHandle<JSFunction> &ctor,
758                                                 const JSHandle<TaggedArray> &literal,
759                                                 const JSHandle<JSTaggedValue> &base,
760                                                 const JSHandle<JSTaggedValue> &lexenv)
761 {
762     ASSERT(ctor.GetTaggedValue().IsClassConstructor());
763 
764     FrameHandler frameHandler(thread);
765     JSTaggedValue currentFunc = frameHandler.GetFunction();
766     JSHandle<JSTaggedValue> ecmaModule(thread, JSFunction::Cast(currentFunc.GetTaggedObject())->GetModule());
767 
768     RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(ctor), base);
769     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
770 
771     uint32_t literalBufferLength = literal->GetLength();
772 
773     // only traverse the value of key-value pair
774     for (uint32_t index = 1; index < literalBufferLength - 1; index += 2) {  // 2: key-value pair
775         JSTaggedValue value = literal->Get(index);
776         if (LIKELY(value.IsJSFunction())) {
777             JSFunction *func = JSFunction::Cast(value.GetTaggedObject());
778             func->SetLexicalEnv(thread, lexenv.GetTaggedValue());
779             func->SetModule(thread, ecmaModule);
780         }
781     }
782 
783     return ctor.GetTaggedValue();
784 }
785 
RuntimeCloneClassFromTemplate(JSThread * thread,const JSHandle<JSFunction> & ctor,const JSHandle<JSTaggedValue> & base,const JSHandle<JSTaggedValue> & lexenv)786 JSTaggedValue RuntimeStubs::RuntimeCloneClassFromTemplate(JSThread *thread, const JSHandle<JSFunction> &ctor,
787                                                           const JSHandle<JSTaggedValue> &base,
788                                                           const JSHandle<JSTaggedValue> &lexenv)
789 {
790     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
791     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
792 
793     ASSERT(ctor.GetTaggedValue().IsClassConstructor());
794     JSHandle<JSObject> clsPrototype(thread, ctor->GetFunctionPrototype());
795 
796     bool canShareHClass = false;
797     JSHandle<JSFunction> cloneClass = factory->CloneClassCtor(ctor, lexenv, canShareHClass);
798     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
799     JSHandle<JSObject> cloneClassPrototype = factory->CloneObjectLiteral(JSHandle<JSObject>(clsPrototype), lexenv,
800                                                                          canShareHClass);
801     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
802 
803     // After clone both, reset "constructor" and "prototype" properties.
804     cloneClass->SetFunctionPrototype(thread, cloneClassPrototype.GetTaggedValue());
805     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
806 
807     PropertyDescriptor ctorDesc(thread, JSHandle<JSTaggedValue>(cloneClass), true, false, true);
808     JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(cloneClassPrototype),
809                                          globalConst->GetHandledConstructorString(), ctorDesc);
810     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
811 
812     cloneClass->SetHomeObject(thread, cloneClassPrototype);
813 
814     if (!canShareHClass) {
815         RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cloneClass), base);
816         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
817     }
818 
819     return cloneClass.GetTaggedValue();
820 }
821 
822 // 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)823 JSTaggedValue RuntimeStubs::RuntimeCreateClassWithBuffer(JSThread *thread,
824                                                          const JSHandle<JSTaggedValue> &base,
825                                                          const JSHandle<JSTaggedValue> &lexenv,
826                                                          const JSHandle<JSTaggedValue> &constpool,
827                                                          uint16_t methodId, uint16_t literalId,
828                                                          const JSHandle<JSTaggedValue> &module)
829 {
830     [[maybe_unused]] EcmaHandleScope handleScope(thread);
831     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
832     CString entry = ModuleManager::GetRecordName(module.GetTaggedValue());
833 
834     // For class constructor.
835     auto methodObj = ConstantPool::GetMethodFromCache(thread, constpool.GetTaggedValue(), methodId);
836     JSHandle<JSTaggedValue> method(thread, methodObj);
837     JSHandle<ConstantPool> constpoolHandle = JSHandle<ConstantPool>::Cast(constpool);
838     JSHandle<JSFunction> cls;
839     JSMutableHandle<JSTaggedValue> ihc(thread, JSTaggedValue::Undefined());
840     JSMutableHandle<JSTaggedValue> chc(thread, JSTaggedValue::Undefined());
841 
842     JSTaggedValue val = constpoolHandle->GetObjectFromCache(literalId);
843     if (val.IsAOTLiteralInfo()) {
844         JSHandle<AOTLiteralInfo> aotLiteralInfo(thread, val);
845         ihc.Update(aotLiteralInfo->GetIhc());
846         chc.Update(aotLiteralInfo->GetChc());
847     }
848     auto literalObj = ConstantPool::GetClassLiteralFromCache(thread, constpoolHandle, literalId, entry);
849     JSHandle<ClassLiteral> classLiteral(thread, literalObj);
850     JSHandle<TaggedArray> arrayHandle(thread, classLiteral->GetArray());
851     JSHandle<ClassInfoExtractor> extractor = factory->NewClassInfoExtractor(method);
852     ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(thread, extractor, arrayHandle);
853 
854     if ((ihc->IsUndefined() && chc->IsUndefined()) ||
855         (classLiteral->GetIsAOTUsed())) {
856         cls = ClassHelper::DefineClassFromExtractor(thread, base, extractor, lexenv);
857     } else {
858         classLiteral->SetIsAOTUsed(true);
859         JSHandle<JSHClass> ihclass(ihc);
860         JSHandle<JSHClass> chclass(chc);
861         cls = ClassHelper::DefineClassWithIHClass(thread, extractor,
862                                                   lexenv, ihclass, chclass);
863     }
864 
865     RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cls), base);
866     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
867     return cls.GetTaggedValue();
868 }
869 
RuntimeSetClassInheritanceRelationship(JSThread * thread,const JSHandle<JSTaggedValue> & ctor,const JSHandle<JSTaggedValue> & base)870 JSTaggedValue RuntimeStubs::RuntimeSetClassInheritanceRelationship(JSThread *thread,
871                                                                    const JSHandle<JSTaggedValue> &ctor,
872                                                                    const JSHandle<JSTaggedValue> &base)
873 {
874     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
875     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
876 
877     ASSERT(ctor->IsJSFunction());
878     JSHandle<JSTaggedValue> parent = base;
879 
880     /*
881      *         class A / class A extends null                             class A extends B
882      *                                       a                                                 a
883      *                                       |                                                 |
884      *                                       |  __proto__                                      |  __proto__
885      *                                       |                                                 |
886      *       A            ---->         A.prototype                  A             ---->    A.prototype
887      *       |                               |                       |                         |
888      *       |  __proto__                    |  __proto__            |  __proto__              |  __proto__
889      *       |                               |                       |                         |
890      *   Function.prototype       Object.prototype / null            B             ---->    B.prototype
891      */
892 
893     JSHandle<JSTaggedValue> parentPrototype;
894     // hole means parent is not present
895     Method *method = Method::Cast(JSHandle<JSFunction>::Cast(ctor)->GetMethod().GetTaggedObject());
896     if (parent->IsHole()) {
897         method->SetFunctionKind(FunctionKind::CLASS_CONSTRUCTOR);
898         parentPrototype = env->GetObjectFunctionPrototype();
899         parent = env->GetFunctionPrototype();
900     } else if (parent->IsNull()) {
901         method->SetFunctionKind(FunctionKind::DERIVED_CONSTRUCTOR);
902         parentPrototype = JSHandle<JSTaggedValue>(thread, JSTaggedValue::Null());
903         parent = env->GetFunctionPrototype();
904     } else if (!parent->IsConstructor()) {
905         return RuntimeThrowTypeError(thread, "parent class is not constructor");
906     } else {
907         method->SetFunctionKind(FunctionKind::DERIVED_CONSTRUCTOR);
908         parentPrototype = JSTaggedValue::GetProperty(thread, parent,
909             globalConst->GetHandledPrototypeString()).GetValue();
910         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
911         if (!parentPrototype->IsECMAObject() && !parentPrototype->IsNull()) {
912             return RuntimeThrowTypeError(thread, "parent class have no valid prototype");
913         }
914     }
915 
916     ctor->GetTaggedObject()->GetClass()->SetPrototype(thread, parent);
917 
918     JSHandle<JSObject> clsPrototype(thread, JSHandle<JSFunction>(ctor)->GetFunctionPrototype());
919     clsPrototype->GetClass()->SetPrototype(thread, parentPrototype);
920 
921     // by enableing the ProtoChangeMarker, the IHC generated in the Aot stage
922     // is registered into the listener of its prototype. In this way, it is ensured
923     // that when the prototype changes, the affected IHC can be notified.
924     JSTaggedValue protoOrHClass = JSHandle<JSFunction>(ctor)->GetProtoOrHClass();
925     if (protoOrHClass.IsJSHClass()) {
926         JSHClass *ihc = JSHClass::Cast(protoOrHClass.GetTaggedObject());
927         if (ihc->IsTS()) {
928             JSHandle<JSHClass> ihcHandle(thread, ihc);
929             JSHClass::EnableProtoChangeMarker(thread, ihcHandle);
930         }
931     }
932 
933     return JSTaggedValue::Undefined();
934 }
935 
RuntimeSetClassConstructorLength(JSThread * thread,JSTaggedValue ctor,JSTaggedValue length)936 JSTaggedValue RuntimeStubs::RuntimeSetClassConstructorLength(JSThread *thread, JSTaggedValue ctor,
937                                                              JSTaggedValue length)
938 {
939     ASSERT(ctor.IsClassConstructor());
940 
941     JSFunction* cls = JSFunction::Cast(ctor.GetTaggedObject());
942     if (LIKELY(!cls->GetClass()->IsDictionaryMode())) {
943         cls->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, length);
944     } else {
945         const GlobalEnvConstants *globalConst = thread->GlobalConstants();
946         cls->UpdatePropertyInDictionary(thread, globalConst->GetLengthString(), length);
947     }
948     return JSTaggedValue::Undefined();
949 }
950 
RuntimeNotifyInlineCache(JSThread * thread,const JSHandle<Method> & method,uint32_t icSlotSize)951 JSTaggedValue RuntimeStubs::RuntimeNotifyInlineCache(JSThread *thread, const JSHandle<Method> &method,
952                                                      uint32_t icSlotSize)
953 {
954     if (icSlotSize == 0) {
955         return JSTaggedValue::Undefined();
956     }
957     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
958     JSHandle<ProfileTypeInfo> profileTypeInfo = factory->NewProfileTypeInfo(icSlotSize);
959     // overflow 8bit
960     if (icSlotSize > ProfileTypeInfo::INVALID_SLOT_INDEX) {
961         // set as mega
962         profileTypeInfo->Set(thread, ProfileTypeInfo::INVALID_SLOT_INDEX, JSTaggedValue::Hole());
963         ASSERT(icSlotSize <= ProfileTypeInfo::MAX_SLOT_INDEX + 1);
964     }
965     method->SetProfileTypeInfo(thread, profileTypeInfo.GetTaggedValue());
966     return profileTypeInfo.GetTaggedValue();
967 }
968 
RuntimeStOwnByValueWithNameSet(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & value)969 JSTaggedValue RuntimeStubs::RuntimeStOwnByValueWithNameSet(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
970                                                            const JSHandle<JSTaggedValue> &key,
971                                                            const JSHandle<JSTaggedValue> &value)
972 {
973     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
974 
975     if (obj->IsClassConstructor() &&
976         JSTaggedValue::SameValue(key, globalConst->GetHandledPrototypeString())) {
977         return RuntimeThrowTypeError(thread, "In a class, static property named 'prototype' throw a TypeError");
978     }
979 
980     // property in class is non-enumerable
981     bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor());
982 
983     PropertyDescriptor desc(thread, value, true, enumerable, true);
984     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, key);
985     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
986     bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, propKey, desc);
987     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
988     if (!ret) {
989         return RuntimeThrowTypeError(thread, "StOwnByValueWithNameSet failed");
990     }
991     if (value->IsJSFunction()) {
992         if (propKey->IsNumber()) {
993             propKey = JSHandle<JSTaggedValue>(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()));
994         }
995         JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(value), propKey,
996                                         JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
997     }
998     return JSTaggedValue::True();
999 }
1000 
RuntimeStOwnByName(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & prop,const JSHandle<JSTaggedValue> & value)1001 JSTaggedValue RuntimeStubs::RuntimeStOwnByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
1002                                                const JSHandle<JSTaggedValue> &prop,
1003                                                const JSHandle<JSTaggedValue> &value)
1004 {
1005     ASSERT(prop->IsStringOrSymbol());
1006 
1007     // property in class is non-enumerable
1008     bool enumerable = !(obj->IsClassPrototype() || obj->IsClassConstructor());
1009 
1010     PropertyDescriptor desc(thread, value, true, enumerable, true);
1011     bool ret = JSTaggedValue::DefineOwnProperty(thread, obj, prop, desc);
1012     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1013     if (!ret) {
1014         return RuntimeThrowTypeError(thread, "SetOwnByName failed");
1015     }
1016     return JSTaggedValue::True();
1017 }
1018 
RuntimeStOwnByNameWithNameSet(JSThread * thread,const JSHandle<JSTaggedValue> & objHandle,const JSHandle<JSTaggedValue> & propHandle,const JSHandle<JSTaggedValue> & valueHandle)1019 JSTaggedValue RuntimeStubs::RuntimeStOwnByNameWithNameSet(JSThread *thread,
1020                                                           const JSHandle<JSTaggedValue> &objHandle,
1021                                                           const JSHandle<JSTaggedValue> &propHandle,
1022                                                           const JSHandle<JSTaggedValue> &valueHandle)
1023 {
1024     ASSERT(propHandle->IsStringOrSymbol());
1025     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, propHandle);
1026     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1027     // property in class is non-enumerable
1028     bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor());
1029 
1030     PropertyDescriptor desc(thread, valueHandle, true, enumerable, true);
1031     bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propHandle, desc);
1032     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1033     if (!ret) {
1034         return RuntimeThrowTypeError(thread, "SetOwnByNameWithNameSet failed");
1035     }
1036     JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(valueHandle), propKey,
1037                                     JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1038     return JSTaggedValue::True();
1039 }
1040 
RuntimeSuspendGenerator(JSThread * thread,const JSHandle<JSTaggedValue> & genObj,const JSHandle<JSTaggedValue> & value)1041 JSTaggedValue RuntimeStubs::RuntimeSuspendGenerator(JSThread *thread, const JSHandle<JSTaggedValue> &genObj,
1042                                                     const JSHandle<JSTaggedValue> &value)
1043 {
1044     if (genObj->IsAsyncGeneratorObject()) {
1045         JSHandle<JSAsyncGeneratorObject> generatorObjectHandle(genObj);
1046         JSHandle<GeneratorContext> genContextHandle(thread, generatorObjectHandle->GetGeneratorContext());
1047         // save stack, should copy cur_frame, function execute over will free cur_frame
1048         SaveFrameToContext(thread, genContextHandle);
1049 
1050         // change state to SuspendedYield
1051         if (generatorObjectHandle->IsExecuting()) {
1052             return value.GetTaggedValue();
1053         }
1054         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1055         return generatorObjectHandle.GetTaggedValue();
1056     }
1057 
1058     if (genObj->IsGeneratorObject()) {
1059         JSHandle<JSGeneratorObject> generatorObjectHandle(genObj);
1060         JSHandle<GeneratorContext> genContextHandle(thread, generatorObjectHandle->GetGeneratorContext());
1061         // save stack, should copy cur_frame, function execute over will free cur_frame
1062         SaveFrameToContext(thread, genContextHandle);
1063 
1064         // change state to SuspendedYield
1065         if (generatorObjectHandle->IsExecuting()) {
1066             generatorObjectHandle->SetGeneratorState(JSGeneratorState::SUSPENDED_YIELD);
1067             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1068             return value.GetTaggedValue();
1069         }
1070         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1071         return generatorObjectHandle.GetTaggedValue();
1072     }
1073 
1074     return RuntimeThrowTypeError(thread, "RuntimeSuspendGenerator failed");
1075 }
1076 
RuntimeSetGeneratorState(JSThread * thread,const JSHandle<JSTaggedValue> & genObj,const int32_t index)1077 void RuntimeStubs::RuntimeSetGeneratorState(JSThread *thread, const JSHandle<JSTaggedValue> &genObj,
1078                                             const int32_t index)
1079 {
1080     JSHandle<JSAsyncGeneratorObject> generatorObjectHandle(genObj);
1081     JSHandle<GeneratorContext> genContextHandle(thread, generatorObjectHandle->GetGeneratorContext());
1082 
1083     // change state
1084     switch (index) {
1085         case static_cast<int32_t>(JSAsyncGeneratorState::SUSPENDED_START):
1086             generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_START);
1087             break;
1088         case static_cast<int32_t>(JSAsyncGeneratorState::SUSPENDED_YIELD):
1089             generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::SUSPENDED_YIELD);
1090             break;
1091         case static_cast<int32_t>(JSAsyncGeneratorState::EXECUTING):
1092             generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::EXECUTING);
1093             break;
1094         case static_cast<int32_t>(JSAsyncGeneratorState::COMPLETED):
1095             generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::COMPLETED);
1096             break;
1097         case static_cast<int32_t>(JSAsyncGeneratorState::AWAITING_RETURN):
1098             generatorObjectHandle->SetAsyncGeneratorState(JSAsyncGeneratorState::AWAITING_RETURN);
1099             break;
1100         default:
1101             LOG_ECMA(FATAL) << "this branch is unreachable";
1102             UNREACHABLE();
1103     }
1104 }
1105 
RuntimeGetModuleNamespace(JSThread * thread,int32_t index)1106 JSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, int32_t index)
1107 {
1108     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(index);
1109 }
1110 
RuntimeGetModuleNamespace(JSThread * thread,int32_t index,JSTaggedValue jsFunc)1111 JSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, int32_t index,
1112                                                       JSTaggedValue jsFunc)
1113 {
1114     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(index, jsFunc);
1115 }
1116 
RuntimeGetModuleNamespace(JSThread * thread,JSTaggedValue localName)1117 JSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, JSTaggedValue localName)
1118 {
1119     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(localName);
1120 }
1121 
RuntimeGetModuleNamespace(JSThread * thread,JSTaggedValue localName,JSTaggedValue jsFunc)1122 JSTaggedValue RuntimeStubs::RuntimeGetModuleNamespace(JSThread *thread, JSTaggedValue localName,
1123                                                       JSTaggedValue jsFunc)
1124 {
1125     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleNamespace(localName, jsFunc);
1126 }
1127 
RuntimeStModuleVar(JSThread * thread,int32_t index,JSTaggedValue value)1128 void RuntimeStubs::RuntimeStModuleVar(JSThread *thread, int32_t index, JSTaggedValue value)
1129 {
1130     thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(index, value);
1131 }
1132 
RuntimeStModuleVar(JSThread * thread,int32_t index,JSTaggedValue value,JSTaggedValue jsFunc)1133 void RuntimeStubs::RuntimeStModuleVar(JSThread *thread, int32_t index, JSTaggedValue value,
1134                                       JSTaggedValue jsFunc)
1135 {
1136     thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(index, value, jsFunc);
1137 }
1138 
RuntimeStModuleVar(JSThread * thread,JSTaggedValue key,JSTaggedValue value)1139 void RuntimeStubs::RuntimeStModuleVar(JSThread *thread, JSTaggedValue key, JSTaggedValue value)
1140 {
1141     thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(key, value);
1142 }
1143 
RuntimeStModuleVar(JSThread * thread,JSTaggedValue key,JSTaggedValue value,JSTaggedValue jsFunc)1144 void RuntimeStubs::RuntimeStModuleVar(JSThread *thread, JSTaggedValue key, JSTaggedValue value,
1145                                       JSTaggedValue jsFunc)
1146 {
1147     thread->GetCurrentEcmaContext()->GetModuleManager()->StoreModuleValue(key, value, jsFunc);
1148 }
1149 
RuntimeLdLocalModuleVar(JSThread * thread,int32_t index)1150 JSTaggedValue RuntimeStubs::RuntimeLdLocalModuleVar(JSThread *thread, int32_t index)
1151 {
1152     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(index);
1153 }
1154 
RuntimeLdLocalModuleVar(JSThread * thread,int32_t index,JSTaggedValue jsFunc)1155 JSTaggedValue RuntimeStubs::RuntimeLdLocalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc)
1156 {
1157     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(index, jsFunc);
1158 }
1159 
RuntimeLdExternalModuleVar(JSThread * thread,int32_t index)1160 JSTaggedValue RuntimeStubs::RuntimeLdExternalModuleVar(JSThread *thread, int32_t index)
1161 {
1162     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(index);
1163 }
1164 
RuntimeLdExternalModuleVar(JSThread * thread,int32_t index,JSTaggedValue jsFunc)1165 JSTaggedValue RuntimeStubs::RuntimeLdExternalModuleVar(JSThread *thread, int32_t index, JSTaggedValue jsFunc)
1166 {
1167     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(index, jsFunc);
1168 }
1169 
RuntimeLdModuleVar(JSThread * thread,JSTaggedValue key,bool inner)1170 JSTaggedValue RuntimeStubs::RuntimeLdModuleVar(JSThread *thread, JSTaggedValue key, bool inner)
1171 {
1172     if (inner) {
1173         JSTaggedValue moduleValue = thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(key);
1174         return moduleValue;
1175     }
1176 
1177     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(key);
1178 }
1179 
RuntimeLdModuleVar(JSThread * thread,JSTaggedValue key,bool inner,JSTaggedValue jsFunc)1180 JSTaggedValue RuntimeStubs::RuntimeLdModuleVar(JSThread *thread, JSTaggedValue key, bool inner,
1181                                                JSTaggedValue jsFunc)
1182 {
1183     if (inner) {
1184         JSTaggedValue moduleValue =
1185             thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueInner(key, jsFunc);
1186         return moduleValue;
1187     }
1188 
1189     return thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(key, jsFunc);
1190 }
1191 
RuntimeGetPropIterator(JSThread * thread,const JSHandle<JSTaggedValue> & value)1192 JSTaggedValue RuntimeStubs::RuntimeGetPropIterator(JSThread *thread, const JSHandle<JSTaggedValue> &value)
1193 {
1194     JSHandle<JSForInIterator> iteratorHandle = JSObject::EnumerateObjectProperties(thread, value);
1195     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1196     return iteratorHandle.GetTaggedValue();
1197 }
1198 
RuntimeAsyncFunctionEnter(JSThread * thread)1199 JSTaggedValue RuntimeStubs::RuntimeAsyncFunctionEnter(JSThread *thread)
1200 {
1201     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1202     // 1. create promise
1203     JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
1204     JSHandle<JSFunction> promiseFunc(globalEnv->GetPromiseFunction());
1205 
1206     JSHandle<JSPromise> promiseObject(factory->NewJSObjectByConstructor(promiseFunc));
1207     promiseObject->SetPromiseState(PromiseState::PENDING);
1208     // 2. create asyncfuncobj
1209     JSHandle<JSAsyncFuncObject> asyncFuncObj = factory->NewJSAsyncFuncObject();
1210     asyncFuncObj->SetPromise(thread, promiseObject);
1211 
1212     JSHandle<GeneratorContext> context = factory->NewGeneratorContext();
1213     context->SetGeneratorObject(thread, asyncFuncObj);
1214 
1215     // change state to EXECUTING
1216     asyncFuncObj->SetGeneratorState(JSGeneratorState::EXECUTING);
1217     asyncFuncObj->SetGeneratorContext(thread, context);
1218 
1219     // 3. return asyncfuncobj
1220     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1221     return asyncFuncObj.GetTaggedValue();
1222 }
1223 
RuntimeGetIterator(JSThread * thread,const JSHandle<JSTaggedValue> & obj)1224 JSTaggedValue RuntimeStubs::RuntimeGetIterator(JSThread *thread, const JSHandle<JSTaggedValue> &obj)
1225 {
1226     EcmaVM *vm = thread->GetEcmaVM();
1227     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1228     JSHandle<JSTaggedValue> valuesFunc =
1229         JSTaggedValue::GetProperty(thread, obj, env->GetIteratorSymbol()).GetValue();
1230     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1231     if (!valuesFunc->IsCallable()) {
1232         return valuesFunc.GetTaggedValue();
1233     }
1234 
1235     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1236     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, valuesFunc, obj, undefined, 0);
1237     return EcmaInterpreter::Execute(info);
1238 }
1239 
RuntimeGetAsyncIterator(JSThread * thread,const JSHandle<JSTaggedValue> & obj)1240 JSTaggedValue RuntimeStubs::RuntimeGetAsyncIterator(JSThread *thread, const JSHandle<JSTaggedValue> &obj)
1241 {
1242     JSHandle<JSTaggedValue> asyncit = JSIterator::GetAsyncIterator(thread, obj);
1243     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1244     return asyncit.GetTaggedValue();
1245 }
1246 
RuntimeThrow(JSThread * thread,JSTaggedValue value)1247 void RuntimeStubs::RuntimeThrow(JSThread *thread, JSTaggedValue value)
1248 {
1249     thread->SetException(value);
1250 }
1251 
RuntimeThrowThrowNotExists(JSThread * thread)1252 void RuntimeStubs::RuntimeThrowThrowNotExists(JSThread *thread)
1253 {
1254     THROW_TYPE_ERROR(thread, "Throw method is not defined");
1255 }
1256 
RuntimeThrowPatternNonCoercible(JSThread * thread)1257 void RuntimeStubs::RuntimeThrowPatternNonCoercible(JSThread *thread)
1258 {
1259     JSHandle<EcmaString> msg(thread->GlobalConstants()->GetHandledObjNotCoercibleString());
1260     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1261     THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::TYPE_ERROR, msg).GetTaggedValue());
1262 }
1263 
RuntimeThrowDeleteSuperProperty(JSThread * thread)1264 void RuntimeStubs::RuntimeThrowDeleteSuperProperty(JSThread *thread)
1265 {
1266     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1267     JSHandle<EcmaString> info = factory->NewFromASCII("Can not delete super property");
1268     JSHandle<JSObject> errorObj = factory->NewJSError(base::ErrorType::REFERENCE_ERROR, info);
1269     THROW_NEW_ERROR_AND_RETURN(thread, errorObj.GetTaggedValue());
1270 }
1271 
RuntimeThrowUndefinedIfHole(JSThread * thread,const JSHandle<EcmaString> & obj)1272 void RuntimeStubs::RuntimeThrowUndefinedIfHole(JSThread *thread, const JSHandle<EcmaString> &obj)
1273 {
1274     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1275     JSHandle<EcmaString> info = factory->NewFromASCII(" is not initialized");
1276 
1277     JSHandle<EcmaString> msg = factory->ConcatFromString(obj, info);
1278     THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::REFERENCE_ERROR, msg).GetTaggedValue());
1279 }
1280 
RuntimeThrowIfNotObject(JSThread * thread)1281 void RuntimeStubs::RuntimeThrowIfNotObject(JSThread *thread)
1282 {
1283     THROW_TYPE_ERROR(thread, "Inner return result is not object");
1284 }
1285 
RuntimeThrowConstAssignment(JSThread * thread,const JSHandle<EcmaString> & value)1286 void RuntimeStubs::RuntimeThrowConstAssignment(JSThread *thread, const JSHandle<EcmaString> &value)
1287 {
1288     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1289 
1290     JSHandle<EcmaString> info = factory->NewFromASCII("Assignment to const variable ");
1291 
1292     JSHandle<EcmaString> msg = factory->ConcatFromString(info, value);
1293     THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::TYPE_ERROR, msg).GetTaggedValue());
1294 }
1295 
RuntimeLdGlobalRecord(JSThread * thread,JSTaggedValue key)1296 JSTaggedValue RuntimeStubs::RuntimeLdGlobalRecord(JSThread *thread, JSTaggedValue key)
1297 {
1298     EcmaVM *vm = thread->GetEcmaVM();
1299     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1300     GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
1301     int entry = dict->FindEntry(key);
1302     if (entry != -1) {
1303         return JSTaggedValue(dict->GetBox(entry));
1304     }
1305     return JSTaggedValue::Undefined();
1306 }
1307 
RuntimeTryLdGlobalByName(JSThread * thread,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & prop)1308 JSTaggedValue RuntimeStubs::RuntimeTryLdGlobalByName(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
1309                                                      const JSHandle<JSTaggedValue> &prop)
1310 {
1311     OperationResult res = JSTaggedValue::GetProperty(thread, obj, prop);
1312     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1313     if (!res.GetPropertyMetaData().IsFound()) {
1314         return RuntimeThrowReferenceError(thread, prop, " is not defined");
1315     }
1316     return res.GetValue().GetTaggedValue();
1317 }
1318 
RuntimeTryUpdateGlobalRecord(JSThread * thread,JSTaggedValue prop,JSTaggedValue value)1319 JSTaggedValue RuntimeStubs::RuntimeTryUpdateGlobalRecord(JSThread *thread, JSTaggedValue prop,
1320                                                          JSTaggedValue value)
1321 {
1322     EcmaVM *vm = thread->GetEcmaVM();
1323     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1324     GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
1325     int entry = dict->FindEntry(prop);
1326     ASSERT(entry != -1);
1327 
1328     if (dict->GetAttributes(entry).IsConstProps()) {
1329         return RuntimeThrowTypeError(thread, "const variable can not be modified");
1330     }
1331 
1332     PropertyBox *box = dict->GetBox(entry);
1333     box->SetValue(thread, value);
1334     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1335     return JSTaggedValue::True();
1336 }
1337 
RuntimeThrowReferenceError(JSThread * thread,const JSHandle<JSTaggedValue> & prop,const char * desc)1338 JSTaggedValue RuntimeStubs::RuntimeThrowReferenceError(JSThread *thread, const JSHandle<JSTaggedValue> &prop,
1339                                                        const char *desc)
1340 {
1341     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1342     JSHandle<EcmaString> propName = JSTaggedValue::ToString(thread, prop);
1343     ASSERT_NO_ABRUPT_COMPLETION(thread);
1344     JSHandle<EcmaString> info = factory->NewFromUtf8(desc);
1345     JSHandle<EcmaString> msg = factory->ConcatFromString(propName, info);
1346     THROW_NEW_ERROR_AND_RETURN_VALUE(thread,
1347                                      factory->NewJSError(base::ErrorType::REFERENCE_ERROR, msg).GetTaggedValue(),
1348                                      JSTaggedValue::Exception());
1349 }
1350 
RuntimeLdGlobalVarFromProto(JSThread * thread,const JSHandle<JSTaggedValue> & globalObj,const JSHandle<JSTaggedValue> & prop)1351 JSTaggedValue RuntimeStubs::RuntimeLdGlobalVarFromProto(JSThread *thread, const JSHandle<JSTaggedValue> &globalObj,
1352                                                         const JSHandle<JSTaggedValue> &prop)
1353 {
1354     ASSERT(globalObj->IsJSGlobalObject());
1355     JSHandle<JSObject> global(globalObj);
1356     JSHandle<JSTaggedValue> obj(thread, JSObject::GetPrototype(global));
1357     OperationResult res = JSTaggedValue::GetProperty(thread, obj, prop);
1358     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1359     return res.GetValue().GetTaggedValue();
1360 }
1361 
RuntimeStGlobalVar(JSThread * thread,const JSHandle<JSTaggedValue> & prop,const JSHandle<JSTaggedValue> & value)1362 JSTaggedValue RuntimeStubs::RuntimeStGlobalVar(JSThread *thread, const JSHandle<JSTaggedValue> &prop,
1363                                                const JSHandle<JSTaggedValue> &value)
1364 {
1365     JSHandle<JSTaggedValue> global(thread, thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject());
1366 
1367     JSObject::GlobalSetProperty(thread, prop, value, true);
1368     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1369     return JSTaggedValue::True();
1370 }
1371 
RuntimeToNumber(JSThread * thread,const JSHandle<JSTaggedValue> & value)1372 JSTaggedValue RuntimeStubs::RuntimeToNumber(JSThread *thread, const JSHandle<JSTaggedValue> &value)
1373 {
1374     return JSTaggedValue::ToNumber(thread, value);
1375 }
1376 
RuntimeToNumeric(JSThread * thread,const JSHandle<JSTaggedValue> & value)1377 JSTaggedValue RuntimeStubs::RuntimeToNumeric(JSThread *thread, const JSHandle<JSTaggedValue> &value)
1378 {
1379     return JSTaggedValue::ToNumeric(thread, value).GetTaggedValue();
1380 }
1381 
RuntimeDynamicImport(JSThread * thread,const JSHandle<JSTaggedValue> & specifier,const JSHandle<JSTaggedValue> & func)1382 JSTaggedValue RuntimeStubs::RuntimeDynamicImport(JSThread *thread, const JSHandle<JSTaggedValue> &specifier,
1383     const JSHandle<JSTaggedValue> &func)
1384 {
1385     EcmaVM *ecmaVm = thread->GetEcmaVM();
1386     JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
1387     ObjectFactory *factory = ecmaVm->GetFactory();
1388 
1389     // get current filename
1390     Method *method = JSFunction::Cast(func->GetTaggedObject())->GetCallTarget();
1391     const JSPandaFile *jsPandaFile = method->GetJSPandaFile();
1392     CString currentfilename = jsPandaFile->GetJSPandaFileDesc();
1393 
1394     JSMutableHandle<JSTaggedValue> dirPath(thread, thread->GlobalConstants()->GetUndefined());
1395     JSMutableHandle<JSTaggedValue> recordName(thread, thread->GlobalConstants()->GetUndefined());
1396     if (jsPandaFile->IsBundlePack()) {
1397         dirPath.Update(factory->NewFromUtf8(currentfilename).GetTaggedValue());
1398     } else {
1399         JSFunction *function = JSFunction::Cast(func.GetTaggedValue().GetTaggedObject());
1400         recordName.Update(function->GetRecordName());
1401         dirPath.Update(factory->NewFromUtf8(currentfilename).GetTaggedValue());
1402     }
1403 
1404     // 4. Let promiseCapability be !NewPromiseCapability(%Promise%).
1405     JSHandle<JSTaggedValue> promiseFunc = env->GetPromiseFunction();
1406     JSHandle<PromiseCapability> promiseCapability = JSPromise::NewPromiseCapability(thread, promiseFunc);
1407     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1408     JSHandle<job::MicroJobQueue> job = thread->GetCurrentEcmaContext()->GetMicroJobQueue();
1409 
1410     JSHandle<TaggedArray> argv = factory->NewTaggedArray(5); // 5: 5 means parameters stored in array
1411     argv->Set(thread, 0, promiseCapability->GetResolve());
1412     argv->Set(thread, 1, promiseCapability->GetReject());    // 1 : reject method
1413     argv->Set(thread, 2, dirPath);                           // 2 : current file path(containing file name)
1414     argv->Set(thread, 3, specifier);                         // 3 : request module's path
1415     argv->Set(thread, 4, recordName);                        // 4 : js recordName or undefined
1416 
1417     JSHandle<JSFunction> dynamicImportJob(env->GetDynamicImportJob());
1418     job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, dynamicImportJob, argv);
1419 
1420     return promiseCapability->GetPromise();
1421 }
1422 
RuntimeEq(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1423 JSTaggedValue RuntimeStubs::RuntimeEq(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1424                                          const JSHandle<JSTaggedValue> &right)
1425 {
1426     bool ret = JSTaggedValue::Equal(thread, left, right);
1427     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1428     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
1429 }
1430 
RuntimeNotEq(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1431 JSTaggedValue RuntimeStubs::RuntimeNotEq(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1432                                             const JSHandle<JSTaggedValue> &right)
1433 {
1434     bool ret = JSTaggedValue::Equal(thread, left, right);
1435     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1436     return (ret ? JSTaggedValue::False() : JSTaggedValue::True());
1437 }
1438 
RuntimeLess(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1439 JSTaggedValue RuntimeStubs::RuntimeLess(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1440                                            const JSHandle<JSTaggedValue> &right)
1441 {
1442     bool ret = JSTaggedValue::Compare(thread, left, right) == ComparisonResult::LESS;
1443     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1444     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
1445 }
1446 
RuntimeLessEq(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1447 JSTaggedValue RuntimeStubs::RuntimeLessEq(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1448                                              const JSHandle<JSTaggedValue> &right)
1449 {
1450     bool ret = JSTaggedValue::Compare(thread, left, right) <= ComparisonResult::EQUAL;
1451     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1452     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
1453 }
1454 
RuntimeGreater(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1455 JSTaggedValue RuntimeStubs::RuntimeGreater(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1456                                               const JSHandle<JSTaggedValue> &right)
1457 {
1458     bool ret = JSTaggedValue::Compare(thread, left, right) == ComparisonResult::GREAT;
1459     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1460     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
1461 }
1462 
RuntimeGreaterEq(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1463 JSTaggedValue RuntimeStubs::RuntimeGreaterEq(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1464                                                 const JSHandle<JSTaggedValue> &right)
1465 {
1466     ComparisonResult comparison = JSTaggedValue::Compare(thread, left, right);
1467     bool ret = (comparison == ComparisonResult::GREAT) || (comparison == ComparisonResult::EQUAL);
1468     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1469     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
1470 }
1471 
RuntimeAdd2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1472 JSTaggedValue RuntimeStubs::RuntimeAdd2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1473                                            const JSHandle<JSTaggedValue> &right)
1474 {
1475     if (left->IsString() && right->IsString()) {
1476         EcmaString *resultStr = EcmaStringAccessor::Concat(
1477             thread->GetEcmaVM(), JSHandle<EcmaString>(left), JSHandle<EcmaString>(right));
1478         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1479         return JSTaggedValue(resultStr);
1480     }
1481     JSHandle<JSTaggedValue> primitiveA0(thread, JSTaggedValue::ToPrimitive(thread, left));
1482     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1483     JSHandle<JSTaggedValue> primitiveA1(thread, JSTaggedValue::ToPrimitive(thread, right));
1484     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1485     // contain string
1486     if (primitiveA0->IsString() || primitiveA1->IsString()) {
1487         JSHandle<EcmaString> stringA0 = JSTaggedValue::ToString(thread, primitiveA0);
1488         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1489         JSHandle<EcmaString> stringA1 = JSTaggedValue::ToString(thread, primitiveA1);
1490         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1491         EcmaString *resultStr = EcmaStringAccessor::Concat(thread->GetEcmaVM(), stringA0, stringA1);
1492         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1493         return JSTaggedValue(resultStr);
1494     }
1495     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, primitiveA0);
1496     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1497     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, primitiveA1);
1498     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1499     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1500         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1501             JSHandle<BigInt> bigLeft(valLeft);
1502             JSHandle<BigInt> bigRight(valRight);
1503             return BigInt::Add(thread, bigLeft, bigRight).GetTaggedValue();
1504         }
1505         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1506     }
1507     double doubleA0 = valLeft->GetNumber();
1508     double doubleA1 = valRight->GetNumber();
1509     return JSTaggedValue(doubleA0 + doubleA1);
1510 }
1511 
RuntimeShl2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1512 JSTaggedValue RuntimeStubs::RuntimeShl2(JSThread *thread,
1513                                         const JSHandle<JSTaggedValue> &left,
1514                                         const JSHandle<JSTaggedValue> &right)
1515 {
1516     JSHandle<JSTaggedValue> leftValue = JSTaggedValue::ToNumeric(thread, left);
1517     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1518     JSHandle<JSTaggedValue> rightValue = JSTaggedValue::ToNumeric(thread, right);
1519     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1520     if (leftValue->IsBigInt() || rightValue->IsBigInt()) {
1521         if (leftValue->IsBigInt() && rightValue->IsBigInt()) {
1522             JSHandle<BigInt> leftBigint(leftValue);
1523             JSHandle<BigInt> rightBigint(rightValue);
1524             return BigInt::LeftShift(thread, leftBigint, rightBigint).GetTaggedValue();
1525         }
1526         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1527     }
1528     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, leftValue);
1529     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1530     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, rightValue);
1531     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1532     int32_t opNumber0 = taggedNumber0.GetInt();
1533     int32_t opNumber1 = taggedNumber1.GetInt();
1534     uint32_t shift =
1535             static_cast<uint32_t>(opNumber1) & 0x1f;  // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1536     using unsigned_type = std::make_unsigned_t<int32_t>;
1537     auto ret =
1538             static_cast<int32_t>(static_cast<unsigned_type>(opNumber0) << shift);  // NOLINT(hicpp-signed-bitwise)
1539     return JSTaggedValue(ret);
1540 }
1541 
RuntimeShr2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1542 JSTaggedValue RuntimeStubs::RuntimeShr2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1543                                         const JSHandle<JSTaggedValue> &right)
1544 {
1545     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1546     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1547     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1548     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1549     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1550         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1551             return BigInt::UnsignedRightShift(thread);
1552         }
1553         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1554     }
1555     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft);
1556     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1557     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight);
1558     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1559     int32_t opNumber0 = taggedNumber0.GetInt();
1560     int32_t opNumber1 = taggedNumber1.GetInt();
1561     uint32_t shift = static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1562     using unsigned_type = std::make_unsigned_t<uint32_t>;
1563     auto ret =
1564             static_cast<uint32_t>(static_cast<unsigned_type>(opNumber0) >> shift); // NOLINT(hicpp-signed-bitwise)
1565     return JSTaggedValue(ret);
1566 }
1567 
RuntimeSub2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1568 JSTaggedValue RuntimeStubs::RuntimeSub2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1569                                         const JSHandle<JSTaggedValue> &right)
1570 {
1571     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1572     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1573     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1574     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1575     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1576         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1577             JSHandle<BigInt> bigLeft(valLeft);
1578             JSHandle<BigInt> bigRight(valRight);
1579             return BigInt::Subtract(thread, bigLeft, bigRight).GetTaggedValue();
1580         }
1581         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1582     }
1583     JSTaggedNumber number0(valLeft.GetTaggedValue());
1584     JSTaggedNumber number1(valRight.GetTaggedValue());
1585     return number0 - number1;
1586 }
1587 
RuntimeMul2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1588 JSTaggedValue RuntimeStubs::RuntimeMul2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1589                                         const JSHandle<JSTaggedValue> &right)
1590 {
1591     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1592     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1593     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1594     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1595     // 9. ReturnIfAbrupt(rnum).
1596     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1597         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1598             JSHandle<BigInt> bigLeft(valLeft);
1599             JSHandle<BigInt> bigRight(valRight);
1600             return BigInt::Multiply(thread, bigLeft, bigRight).GetTaggedValue();
1601         }
1602         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1603     }
1604     // 12.6.3.1 Applying the * Operator
1605     JSTaggedNumber number0(valLeft.GetTaggedValue());
1606     JSTaggedNumber number1(valRight.GetTaggedValue());
1607     return number0 * number1;
1608 }
1609 
RuntimeDiv2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1610 JSTaggedValue RuntimeStubs::RuntimeDiv2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1611                                         const JSHandle<JSTaggedValue> &right)
1612 {
1613     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1614     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1615     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1616     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1617     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1618         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1619             JSHandle<BigInt> bigLeft(valLeft);
1620             JSHandle<BigInt> bigRight(valRight);
1621             return BigInt::Divide(thread, bigLeft, bigRight).GetTaggedValue();
1622         }
1623         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1624     }
1625     double dLeft = valLeft->GetNumber();
1626     double dRight = valRight->GetNumber();
1627     if (dRight == 0) {
1628         if (dLeft == 0 || std::isnan(dLeft)) {
1629             return JSTaggedValue(base::NAN_VALUE);
1630         }
1631         bool positive = (((base::bit_cast<uint64_t>(dRight)) & base::DOUBLE_SIGN_MASK) ==
1632                          ((base::bit_cast<uint64_t>(dLeft)) & base::DOUBLE_SIGN_MASK));
1633         return JSTaggedValue(positive ? base::POSITIVE_INFINITY : -base::POSITIVE_INFINITY);
1634     }
1635     return JSTaggedValue(dLeft / dRight);
1636 }
1637 
RuntimeMod2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1638 JSTaggedValue RuntimeStubs::RuntimeMod2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1639                                         const JSHandle<JSTaggedValue> &right)
1640 {
1641     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1642     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1643     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1644     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1645 
1646     // 12.6.3.3 Applying the % Operator
1647     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1648         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1649             JSHandle<BigInt> leftBigint(valLeft);
1650             JSHandle<BigInt> rightBigint(valRight);
1651             return BigInt::Remainder(thread, leftBigint, rightBigint).GetTaggedValue();
1652         }
1653         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1654     }
1655     double dLeft = valLeft->GetNumber();
1656     double dRight = valRight->GetNumber();
1657     // 12.6.3.3 Applying the % Operator
1658     if ((dRight == 0.0) || std::isnan(dRight) || std::isnan(dLeft) || std::isinf(dLeft)) {
1659         return JSTaggedValue(base::NAN_VALUE);
1660     }
1661     if ((dLeft == 0.0) || std::isinf(dRight)) {
1662         return JSTaggedValue(dLeft);
1663     }
1664     return JSTaggedValue(std::fmod(dLeft, dRight));
1665 }
1666 
RuntimeAshr2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1667 JSTaggedValue RuntimeStubs::RuntimeAshr2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1668                                          const JSHandle<JSTaggedValue> &right)
1669 {
1670     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1671     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1672     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1673     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1674     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1675         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1676             JSHandle<BigInt> bigLeft(valLeft);
1677             JSHandle<BigInt> bigRight(valRight);
1678             return BigInt::SignedRightShift(thread, bigLeft, bigRight).GetTaggedValue();
1679         }
1680         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1681     }
1682     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft);
1683     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1684     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight);
1685     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1686     int32_t opNumber0 = taggedNumber0.GetInt();
1687     int32_t opNumber1 = taggedNumber1.GetInt();
1688     uint32_t shift = static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1689     auto ret = static_cast<int32_t>(opNumber0 >> shift); // NOLINT(hicpp-signed-bitwise)
1690     return JSTaggedValue(ret);
1691 }
1692 
RuntimeAnd2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1693 JSTaggedValue RuntimeStubs::RuntimeAnd2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1694                                         const JSHandle<JSTaggedValue> &right)
1695 {
1696     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1697     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1698     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1699     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1700     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1701         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1702             JSHandle<BigInt> leftBigint(valLeft);
1703             JSHandle<BigInt> rightBigint(valRight);
1704             return BigInt::BitwiseAND(thread, leftBigint, rightBigint).GetTaggedValue();
1705         }
1706         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1707     }
1708     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft);
1709     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1710     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight);
1711     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1712     int32_t opNumber0 = taggedNumber0.GetInt();
1713     int32_t opNumber1 = taggedNumber1.GetInt();
1714     // NOLINT(hicpp-signed-bitwise)
1715     auto ret = static_cast<uint32_t>(opNumber0) & static_cast<uint32_t>(opNumber1);
1716     return JSTaggedValue(static_cast<int32_t>(ret));
1717 }
1718 
RuntimeOr2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1719 JSTaggedValue RuntimeStubs::RuntimeOr2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1720                                        const JSHandle<JSTaggedValue> &right)
1721 {
1722     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1723     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1724     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1725     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1726     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1727         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1728             JSHandle<BigInt> leftBigint(valLeft);
1729             JSHandle<BigInt> rightBigint(valRight);
1730             return BigInt::BitwiseOR(thread, leftBigint, rightBigint).GetTaggedValue();
1731         }
1732         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1733     }
1734     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft);
1735     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1736     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight);
1737     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1738     int32_t opNumber0 = taggedNumber0.GetInt();
1739     int32_t opNumber1 = taggedNumber1.GetInt();
1740     // NOLINT(hicpp-signed-bitwise)
1741     auto ret = static_cast<uint32_t>(opNumber0) | static_cast<uint32_t>(opNumber1);
1742     return JSTaggedValue(static_cast<int32_t>(ret));
1743 }
1744 
RuntimeXor2(JSThread * thread,const JSHandle<JSTaggedValue> & left,const JSHandle<JSTaggedValue> & right)1745 JSTaggedValue RuntimeStubs::RuntimeXor2(JSThread *thread, const JSHandle<JSTaggedValue> &left,
1746                                         const JSHandle<JSTaggedValue> &right)
1747 {
1748     JSHandle<JSTaggedValue> valLeft = JSTaggedValue::ToNumeric(thread, left);
1749     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1750     JSHandle<JSTaggedValue> valRight = JSTaggedValue::ToNumeric(thread, right);
1751     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1752     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
1753         if (valLeft->IsBigInt() && valRight->IsBigInt()) {
1754             JSHandle<BigInt> leftBigint(valLeft);
1755             JSHandle<BigInt> rightBigint(valRight);
1756             return BigInt::BitwiseXOR(thread, leftBigint, rightBigint).GetTaggedValue();
1757         }
1758         return RuntimeThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
1759     }
1760     JSTaggedValue taggedNumber0 = RuntimeToJSTaggedValueWithInt32(thread, valLeft);
1761     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1762     JSTaggedValue taggedNumber1 = RuntimeToJSTaggedValueWithInt32(thread, valRight);
1763     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1764     int32_t opNumber0 = taggedNumber0.GetInt();
1765     int32_t opNumber1 = taggedNumber1.GetInt();
1766     // NOLINT(hicpp-signed-bitwise)
1767     auto ret = static_cast<uint32_t>(opNumber0) ^ static_cast<uint32_t>(opNumber1);
1768     return JSTaggedValue(static_cast<int32_t>(ret));
1769 }
1770 
RuntimeToJSTaggedValueWithInt32(JSThread * thread,const JSHandle<JSTaggedValue> & value)1771 JSTaggedValue RuntimeStubs::RuntimeToJSTaggedValueWithInt32(JSThread *thread,
1772                                                             const JSHandle<JSTaggedValue> &value)
1773 {
1774     int32_t res = JSTaggedValue::ToInt32(thread, value);
1775     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1776     return JSTaggedValue(res);
1777 }
1778 
RuntimeToJSTaggedValueWithUint32(JSThread * thread,const JSHandle<JSTaggedValue> & value)1779 JSTaggedValue RuntimeStubs::RuntimeToJSTaggedValueWithUint32(JSThread *thread, const JSHandle<JSTaggedValue> &value)
1780 {
1781     uint32_t res = JSTaggedValue::ToUint32(thread, value);
1782     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1783     return JSTaggedValue(res);
1784 }
1785 
RuntimeCreateEmptyObject(JSThread * thread,ObjectFactory * factory,JSHandle<GlobalEnv> globalEnv)1786 JSTaggedValue RuntimeStubs::RuntimeCreateEmptyObject([[maybe_unused]] JSThread *thread, ObjectFactory *factory,
1787                                                      JSHandle<GlobalEnv> globalEnv)
1788 {
1789     JSHandle<JSFunction> builtinObj(globalEnv->GetObjectFunction());
1790     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(builtinObj);
1791     return obj.GetTaggedValue();
1792 }
1793 
RuntimeCreateEmptyArray(JSThread * thread,ObjectFactory * factory,JSHandle<GlobalEnv> globalEnv)1794 JSTaggedValue RuntimeStubs::RuntimeCreateEmptyArray([[maybe_unused]] JSThread *thread, ObjectFactory *factory,
1795                                                     JSHandle<GlobalEnv> globalEnv)
1796 {
1797     JSHandle<JSFunction> builtinObj(globalEnv->GetArrayFunction());
1798     JSHandle<JSObject> arr = factory->NewJSObjectByConstructor(builtinObj);
1799     return arr.GetTaggedValue();
1800 }
1801 
RuntimeGetUnmapedArgs(JSThread * thread,JSTaggedType * sp,uint32_t actualNumArgs,uint32_t startIdx)1802 JSTaggedValue RuntimeStubs::RuntimeGetUnmapedArgs(JSThread *thread, JSTaggedType *sp, uint32_t actualNumArgs,
1803                                                   uint32_t startIdx)
1804 {
1805     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1806     JSHandle<TaggedArray> argumentsList = factory->NewTaggedArray(actualNumArgs);
1807     for (uint32_t i = 0; i < actualNumArgs; ++i) {
1808         argumentsList->Set(thread, i,
1809                            JSTaggedValue(sp[startIdx + i]));  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1810     }
1811     return RuntimeGetUnmapedJSArgumentObj(thread, argumentsList);
1812 }
1813 
RuntimeCopyRestArgs(JSThread * thread,JSTaggedType * sp,uint32_t restNumArgs,uint32_t startIdx)1814 JSTaggedValue RuntimeStubs::RuntimeCopyRestArgs(JSThread *thread, JSTaggedType *sp, uint32_t restNumArgs,
1815                                                 uint32_t startIdx)
1816 {
1817     JSHandle<JSTaggedValue> restArray = JSArray::ArrayCreate(thread, JSTaggedNumber(restNumArgs));
1818 
1819     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1820     JSMutableHandle<JSTaggedValue> element(thread, JSTaggedValue::Undefined());
1821     for (uint32_t i = 0; i < restNumArgs; ++i) {
1822         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1823         element.Update(JSTaggedValue(sp[startIdx + i]));
1824         JSObject::SetProperty(thread, restArray, i, element, true);
1825     }
1826     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1827     return restArray.GetTaggedValue();
1828 }
1829 
RuntimeCreateArrayWithBuffer(JSThread * thread,ObjectFactory * factory,const JSHandle<JSTaggedValue> & literal)1830 JSTaggedValue RuntimeStubs::RuntimeCreateArrayWithBuffer(JSThread *thread, ObjectFactory *factory,
1831                                                          const JSHandle<JSTaggedValue> &literal)
1832 {
1833     JSHandle<JSArray> array(literal);
1834     JSHandle<JSArray> arrLiteral = factory->CloneArrayLiteral(array);
1835     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1836 
1837     return arrLiteral.GetTaggedValue();
1838 }
1839 
RuntimeCreateObjectWithBuffer(JSThread * thread,ObjectFactory * factory,const JSHandle<JSObject> & literal)1840 JSTaggedValue RuntimeStubs::RuntimeCreateObjectWithBuffer(JSThread *thread, ObjectFactory *factory,
1841                                                           const JSHandle<JSObject> &literal)
1842 {
1843     JSHandle<JSObject> objLiteral = factory->CloneObjectLiteral(literal);
1844     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1845 
1846     return objLiteral.GetTaggedValue();
1847 }
1848 
RuntimeNewLexicalEnv(JSThread * thread,uint16_t numVars)1849 JSTaggedValue RuntimeStubs::RuntimeNewLexicalEnv(JSThread *thread, uint16_t numVars)
1850 {
1851     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1852     JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars);
1853 
1854     JSTaggedValue currentLexenv = thread->GetCurrentLexenv();
1855     newEnv->SetParentEnv(thread, currentLexenv);
1856     newEnv->SetScopeInfo(thread, JSTaggedValue::Hole());
1857     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1858     return newEnv.GetTaggedValue();
1859 }
1860 
RuntimeNewObjRange(JSThread * thread,const JSHandle<JSTaggedValue> & func,const JSHandle<JSTaggedValue> & newTarget,uint16_t firstArgIdx,uint16_t length)1861 JSTaggedValue RuntimeStubs::RuntimeNewObjRange(JSThread *thread, const JSHandle<JSTaggedValue> &func,
1862     const JSHandle<JSTaggedValue> &newTarget, uint16_t firstArgIdx, uint16_t length)
1863 {
1864     JSHandle<JSTaggedValue> preArgs(thread, JSTaggedValue::Undefined());
1865     JSHandle<TaggedArray> args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(length);
1866     FrameHandler frameHandler(thread);
1867     for (uint16_t i = 0; i < length; ++i) {
1868         JSTaggedValue value = frameHandler.GetVRegValue(firstArgIdx + i);
1869         args->Set(thread, i, value);
1870     }
1871     auto tagged = RuntimeOptConstruct(thread, func, newTarget, preArgs, args);
1872     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1873     return tagged;
1874 }
1875 
RuntimeDefinefunc(JSThread * thread,const JSHandle<Method> & methodHandle)1876 JSTaggedValue RuntimeStubs::RuntimeDefinefunc(JSThread *thread, const JSHandle<Method> &methodHandle)
1877 {
1878     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1879     return factory->NewJSFunction(methodHandle).GetTaggedValue();
1880 }
1881 
RuntimeCreateRegExpWithLiteral(JSThread * thread,const JSHandle<JSTaggedValue> & pattern,uint8_t flags)1882 JSTaggedValue RuntimeStubs::RuntimeCreateRegExpWithLiteral(JSThread *thread,
1883                                                            const JSHandle<JSTaggedValue> &pattern, uint8_t flags)
1884 {
1885     JSHandle<JSTaggedValue> flagsHandle(thread, JSTaggedValue(flags));
1886     return builtins::BuiltinsRegExp::RegExpCreate(thread, pattern, flagsHandle);
1887 }
1888 
RuntimeThrowIfSuperNotCorrectCall(JSThread * thread,uint16_t index,JSTaggedValue thisValue)1889 JSTaggedValue RuntimeStubs::RuntimeThrowIfSuperNotCorrectCall(JSThread *thread, uint16_t index,
1890                                                               JSTaggedValue thisValue)
1891 {
1892     if (index == 0 && (thisValue.IsUndefined() || thisValue.IsHole())) {
1893         return RuntimeThrowReferenceError(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1894                                        "sub-class must call super before use 'this'");
1895     }
1896     if (index == 1 && !thisValue.IsUndefined() && !thisValue.IsHole()) {
1897         return RuntimeThrowReferenceError(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()),
1898                                        "super() forbidden re-bind 'this'");
1899     }
1900     return JSTaggedValue::True();
1901 }
1902 
RuntimeCreateObjectHavingMethod(JSThread * thread,ObjectFactory * factory,const JSHandle<JSObject> & literal,const JSHandle<JSTaggedValue> & env)1903 JSTaggedValue RuntimeStubs::RuntimeCreateObjectHavingMethod(JSThread *thread, ObjectFactory *factory,
1904                                                             const JSHandle<JSObject> &literal,
1905                                                             const JSHandle<JSTaggedValue> &env)
1906 {
1907     JSHandle<JSObject> objLiteral = factory->CloneObjectLiteral(literal, env);
1908     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1909 
1910     return objLiteral.GetTaggedValue();
1911 }
1912 
CommonCreateObjectWithExcludedKeys(JSThread * thread,const JSHandle<JSTaggedValue> & objVal,uint32_t numExcludedKeys,JSHandle<TaggedArray> excludedKeys)1913 JSTaggedValue RuntimeStubs::CommonCreateObjectWithExcludedKeys(JSThread *thread,
1914                                                                const JSHandle<JSTaggedValue> &objVal,
1915                                                                uint32_t numExcludedKeys,
1916                                                                JSHandle<TaggedArray> excludedKeys)
1917 {
1918     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1919     JSHandle<JSObject> restObj = factory->NewEmptyJSObject();
1920     if (objVal->IsNull() || objVal->IsUndefined()) {
1921         return restObj.GetTaggedValue();
1922     }
1923     JSHandle<JSObject> obj(JSTaggedValue::ToObject(thread, objVal));
1924     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1925     JSHandle<TaggedArray> allKeys = JSObject::GetOwnPropertyKeys(thread, obj);
1926     uint32_t numAllKeys = allKeys->GetLength();
1927     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1928     for (uint32_t i = 0; i < numAllKeys; i++) {
1929         key.Update(allKeys->Get(i));
1930         bool isExcludedKey = false;
1931         for (uint32_t j = 0; j < numExcludedKeys; j++) {
1932             if (JSTaggedValue::Equal(thread, key, JSHandle<JSTaggedValue>(thread, excludedKeys->Get(j)))) {
1933                 isExcludedKey = true;
1934                 break;
1935             }
1936         }
1937         if (!isExcludedKey) {
1938             PropertyDescriptor desc(thread);
1939             bool success = JSObject::GetOwnProperty(thread, obj, key, desc);
1940             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1941             if (success && desc.IsEnumerable()) {
1942                 JSHandle<JSTaggedValue> value = JSObject::GetProperty(thread, obj, key).GetValue();
1943                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1944                 JSObject::SetProperty(thread, restObj, key, value, true);
1945                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1946             }
1947         }
1948     }
1949     return restObj.GetTaggedValue();
1950 }
1951 
RuntimeOptCreateObjectWithExcludedKeys(JSThread * thread,uint16_t numKeys,const JSHandle<JSTaggedValue> & objVal,uint16_t firstArgRegIdx,uintptr_t argv,uint32_t argc)1952 JSTaggedValue RuntimeStubs::RuntimeOptCreateObjectWithExcludedKeys(JSThread *thread, uint16_t numKeys,
1953                                                                    const JSHandle<JSTaggedValue> &objVal,
1954                                                                    uint16_t firstArgRegIdx,
1955                                                                    uintptr_t argv, uint32_t argc)
1956 {
1957     firstArgRegIdx += 4; // firstArgRegIdx + 4: means the remain parameter
1958     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1959     uint32_t numExcludedKeys = 0;
1960     JSHandle<TaggedArray> excludedKeys = factory->NewTaggedArray(numKeys + 1);
1961     JSTaggedValue excludedKey = GetArg(argv, argc, firstArgRegIdx);
1962     if (!excludedKey.IsUndefined()) {
1963         numExcludedKeys = numKeys + 1;
1964         excludedKeys->Set(thread, 0, excludedKey);
1965         for (uint32_t i = 1; i < numExcludedKeys; i++) {
1966             excludedKey = GetArg(argv, argc, firstArgRegIdx + i);
1967             excludedKeys->Set(thread, i, excludedKey);
1968         }
1969     }
1970     return CommonCreateObjectWithExcludedKeys(thread, objVal, numExcludedKeys, excludedKeys);
1971 }
1972 
RuntimeCreateObjectWithExcludedKeys(JSThread * thread,uint16_t numKeys,const JSHandle<JSTaggedValue> & objVal,uint16_t firstArgRegIdx)1973 JSTaggedValue RuntimeStubs::RuntimeCreateObjectWithExcludedKeys(JSThread *thread, uint16_t numKeys,
1974                                                                 const JSHandle<JSTaggedValue> &objVal,
1975                                                                 uint16_t firstArgRegIdx)
1976 {
1977     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1978     uint32_t numExcludedKeys = 0;
1979     JSHandle<TaggedArray> excludedKeys = factory->NewTaggedArray(numKeys + 1);
1980     FrameHandler frameHandler(thread);
1981     JSTaggedValue excludedKey = frameHandler.GetVRegValue(firstArgRegIdx);
1982     if (!excludedKey.IsUndefined()) {
1983         numExcludedKeys = numKeys + 1;
1984         excludedKeys->Set(thread, 0, excludedKey);
1985         for (uint32_t i = 1; i < numExcludedKeys; i++) {
1986             excludedKey = frameHandler.GetVRegValue(firstArgRegIdx + i);
1987             excludedKeys->Set(thread, i, excludedKey);
1988         }
1989     }
1990 
1991     JSHandle<JSTaggedValue> finalVal = objVal;
1992     if (finalVal->CheckIsJSProxy()) {
1993         JSHandle<JSProxy> proxyVal(thread, finalVal.GetTaggedValue());
1994 
1995         finalVal = proxyVal->GetSourceTarget(thread);
1996     }
1997 
1998     return CommonCreateObjectWithExcludedKeys(thread, finalVal, numExcludedKeys, excludedKeys);
1999 }
2000 
RuntimeDefineMethod(JSThread * thread,const JSHandle<Method> & methodHandle,const JSHandle<JSTaggedValue> & homeObject)2001 JSTaggedValue RuntimeStubs::RuntimeDefineMethod(JSThread *thread, const JSHandle<Method> &methodHandle,
2002                                                 const JSHandle<JSTaggedValue> &homeObject)
2003 {
2004     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2005     return factory->NewJSFunction(methodHandle, homeObject).GetTaggedValue();
2006 }
2007 
RuntimeCallSpread(JSThread * thread,const JSHandle<JSTaggedValue> & func,const JSHandle<JSTaggedValue> & obj,const JSHandle<JSTaggedValue> & array)2008 JSTaggedValue RuntimeStubs::RuntimeCallSpread(JSThread *thread,
2009                                               const JSHandle<JSTaggedValue> &func,
2010                                               const JSHandle<JSTaggedValue> &obj,
2011                                               const JSHandle<JSTaggedValue> &array)
2012 {
2013     if ((!obj->IsUndefined() && !obj->IsECMAObject()) || !func->IsCallable() || !array->IsJSArray()) {
2014         THROW_TYPE_ERROR_AND_RETURN(thread, "cannot Callspread", JSTaggedValue::Exception());
2015     }
2016 
2017     JSHandle<TaggedArray> coretypesArray(thread, RuntimeGetCallSpreadArgs(thread, array));
2018     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2019     uint32_t length = coretypesArray->GetLength();
2020     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
2021     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, func, obj, undefined, length);
2022     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2023     info->SetCallArg(length, coretypesArray);
2024     return EcmaInterpreter::Execute(info);
2025 }
2026 
RuntimeDefineGetterSetterByValue(JSThread * thread,const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & prop,const JSHandle<JSTaggedValue> & getter,const JSHandle<JSTaggedValue> & setter,bool flag)2027 JSTaggedValue RuntimeStubs::RuntimeDefineGetterSetterByValue(JSThread *thread, const JSHandle<JSObject> &obj,
2028                                                              const JSHandle<JSTaggedValue> &prop,
2029                                                              const JSHandle<JSTaggedValue> &getter,
2030                                                              const JSHandle<JSTaggedValue> &setter, bool flag)
2031 {
2032     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, prop);
2033     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2034     auto globalConst = thread->GlobalConstants();
2035     if (obj.GetTaggedValue().IsClassConstructor() &&
2036         JSTaggedValue::SameValue(propKey, globalConst->GetHandledPrototypeString())) {
2037         return RuntimeThrowTypeError(
2038             thread,
2039             "In a class, computed property names for static getter that are named 'prototype' throw a TypeError");
2040     }
2041 
2042     if (flag) {
2043         if (!getter->IsUndefined()) {
2044             if (propKey->IsNumber()) {
2045                 propKey =
2046                     JSHandle<JSTaggedValue>::Cast(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()));
2047             }
2048             JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(getter), propKey,
2049                                             JSHandle<JSTaggedValue>(thread, globalConst->GetGetString()));
2050         }
2051 
2052         if (!setter->IsUndefined()) {
2053             if (propKey->IsNumber()) {
2054                 propKey =
2055                     JSHandle<JSTaggedValue>::Cast(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()));
2056             }
2057             JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(setter), propKey,
2058                                             JSHandle<JSTaggedValue>(thread, globalConst->GetSetString()));
2059         }
2060     }
2061 
2062     // set accessor
2063     bool enumerable =
2064         !(obj.GetTaggedValue().IsClassPrototype() || obj.GetTaggedValue().IsClassConstructor());
2065     PropertyDescriptor desc(thread, true, enumerable, true);
2066     if (!getter->IsUndefined()) {
2067         Method *method = Method::Cast(JSHandle<JSFunction>::Cast(getter)->GetMethod().GetTaggedObject());
2068         method->SetFunctionKind(FunctionKind::GETTER_FUNCTION);
2069         desc.SetGetter(getter);
2070     }
2071     if (!setter->IsUndefined()) {
2072         Method *method = Method::Cast(JSHandle<JSFunction>::Cast(setter)->GetMethod().GetTaggedObject());
2073         method->SetFunctionKind(FunctionKind::SETTER_FUNCTION);
2074         desc.SetSetter(setter);
2075     }
2076     JSObject::DefineOwnProperty(thread, obj, propKey, desc);
2077 
2078     return obj.GetTaggedValue();
2079 }
2080 
RuntimeSuperCall(JSThread * thread,const JSHandle<JSTaggedValue> & func,const JSHandle<JSTaggedValue> & newTarget,uint16_t firstVRegIdx,uint16_t length)2081 JSTaggedValue RuntimeStubs::RuntimeSuperCall(JSThread *thread, const JSHandle<JSTaggedValue> &func,
2082                                              const JSHandle<JSTaggedValue> &newTarget, uint16_t firstVRegIdx,
2083                                              uint16_t length)
2084 {
2085     JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func));
2086     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2087 
2088     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2089     JSHandle<TaggedArray> argv = factory->NewTaggedArray(length);
2090     FrameHandler frameHandler(thread);
2091     for (size_t i = 0; i < length; ++i) {
2092         argv->Set(thread, i, frameHandler.GetVRegValue(firstVRegIdx + i));
2093     }
2094 
2095     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
2096     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, length);
2097     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2098     info->SetCallArg(length, argv);
2099     JSTaggedValue result = JSFunction::Construct(info);
2100     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2101 
2102     return result;
2103 }
2104 
RuntimeOptSuperCall(JSThread * thread,uintptr_t argv,uint32_t argc)2105 JSTaggedValue RuntimeStubs::RuntimeOptSuperCall(JSThread *thread, uintptr_t argv, uint32_t argc)
2106 {
2107     constexpr size_t fixNums = 2;
2108     JSHandle<JSTaggedValue> func = GetHArg<JSTaggedValue>(argv, argc, 0);
2109     JSHandle<JSTaggedValue> newTarget = GetHArg<JSTaggedValue>(argv, argc, 1);
2110     JSHandle<JSTaggedValue> superFunc(thread, JSTaggedValue::GetPrototype(thread, func));
2111     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2112     uint16_t length = argc - fixNums;
2113     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
2114     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, superFunc, undefined, newTarget, length);
2115     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2116     for (size_t i = 0; i < length; ++i) {
2117         JSTaggedType arg = reinterpret_cast<JSTaggedType *>(argv)[i + fixNums];
2118         info->SetCallArg(i, JSTaggedValue(arg));
2119     }
2120     JSTaggedValue result = JSFunction::Construct(info);
2121     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2122 
2123     return result;
2124 }
2125 
RuntimeThrowTypeError(JSThread * thread,const char * message)2126 JSTaggedValue RuntimeStubs::RuntimeThrowTypeError(JSThread *thread, const char *message)
2127 {
2128     ASSERT_NO_ABRUPT_COMPLETION(thread);
2129     THROW_TYPE_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception());
2130 }
2131 
RuntimeGetCallSpreadArgs(JSThread * thread,const JSHandle<JSTaggedValue> & jsArray)2132 JSTaggedValue RuntimeStubs::RuntimeGetCallSpreadArgs(JSThread *thread, const JSHandle<JSTaggedValue> &jsArray)
2133 {
2134     uint32_t argvMayMaxLength = JSHandle<JSArray>::Cast(jsArray)->GetArrayLength();
2135 
2136     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2137     JSHandle<TaggedArray> argv = factory->NewTaggedArray(argvMayMaxLength);
2138     JSHandle<JSTaggedValue> itor = JSIterator::GetIterator(thread, jsArray);
2139     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2140     JSMutableHandle<JSTaggedValue> next(thread, JSTaggedValue::Undefined());
2141     JSMutableHandle<JSTaggedValue> nextArg(thread, JSTaggedValue::Undefined());
2142     size_t argvIndex = 0;
2143     while (true) {
2144         next.Update(JSIterator::IteratorStep(thread, itor).GetTaggedValue());
2145         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2146         if (JSTaggedValue::SameValue(next.GetTaggedValue(), JSTaggedValue::False())) {
2147             break;
2148         }
2149         nextArg.Update(JSIterator::IteratorValue(thread, next).GetTaggedValue());
2150         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2151         if (UNLIKELY(argvIndex + 1 >= argvMayMaxLength)) {
2152             argvMayMaxLength = argvMayMaxLength + (argvMayMaxLength >> 1U) + 1U;
2153             argv = argv->SetCapacity(thread, argv, argvMayMaxLength);
2154         }
2155         argv->Set(thread, argvIndex++, nextArg);
2156     }
2157     argv = factory->CopyArray(argv, argvMayMaxLength, argvIndex);
2158     return argv.GetTaggedValue();
2159 }
2160 
RuntimeThrowSyntaxError(JSThread * thread,const char * message)2161 JSTaggedValue RuntimeStubs::RuntimeThrowSyntaxError(JSThread *thread, const char *message)
2162 {
2163     ASSERT_NO_ABRUPT_COMPLETION(thread);
2164     THROW_SYNTAX_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception());
2165 }
2166 
RuntimeLdBigInt(JSThread * thread,const JSHandle<JSTaggedValue> & numberBigInt)2167 JSTaggedValue RuntimeStubs::RuntimeLdBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &numberBigInt)
2168 {
2169     return JSTaggedValue::ToBigInt(thread, numberBigInt);
2170 }
2171 
RuntimeNewLexicalEnvWithName(JSThread * thread,uint16_t numVars,uint16_t scopeId)2172 JSTaggedValue RuntimeStubs::RuntimeNewLexicalEnvWithName(JSThread *thread, uint16_t numVars, uint16_t scopeId)
2173 {
2174     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2175     JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars);
2176 
2177     JSTaggedValue currentLexenv = thread->GetCurrentLexenv();
2178     newEnv->SetParentEnv(thread, currentLexenv);
2179     JSTaggedValue scopeInfo = ScopeInfoExtractor::GenerateScopeInfo(thread, scopeId);
2180     newEnv->SetScopeInfo(thread, scopeInfo);
2181     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2182     return newEnv.GetTaggedValue();
2183 }
2184 
RuntimeOptGetUnmapedArgs(JSThread * thread,uint32_t actualNumArgs)2185 JSTaggedValue RuntimeStubs::RuntimeOptGetUnmapedArgs(JSThread *thread, uint32_t actualNumArgs)
2186 {
2187     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2188     JSHandle<TaggedArray> argumentsList = factory->NewTaggedArray(actualNumArgs - NUM_MANDATORY_JSFUNC_ARGS);
2189 
2190     auto argv = GetActualArgvFromStub(thread);
2191     int idx = 0;
2192     for (uint32_t i = NUM_MANDATORY_JSFUNC_ARGS; i < actualNumArgs; ++i) {
2193         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2194         JSTaggedType arg = reinterpret_cast<JSTaggedType *>(argv)[i];
2195         JSTaggedValue args = JSTaggedValue(arg);
2196         argumentsList->Set(thread, idx++, args);
2197     }
2198     return RuntimeGetUnmapedJSArgumentObj(thread, argumentsList);
2199 }
2200 
RuntimeGetUnmapedJSArgumentObj(JSThread * thread,const JSHandle<TaggedArray> & argumentsList)2201 JSTaggedValue RuntimeStubs::RuntimeGetUnmapedJSArgumentObj(JSThread *thread, const JSHandle<TaggedArray> &argumentsList)
2202 {
2203     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2204     JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
2205     // 1. Let len be the number of elements in argumentsList
2206     uint32_t len = argumentsList->GetLength();
2207     // 2. Let obj be ObjectCreate(%ObjectPrototype%, «[[ParameterMap]]»).
2208     // 3. Set obj’s [[ParameterMap]] internal slot to undefined.
2209     // [[ParameterMap]] setted as undifined.
2210     JSHandle<JSArguments> obj = factory->NewJSArguments();
2211     // 4. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor{[[Value]]: len, [[Writable]]: true,
2212     // [[Enumerable]]: false, [[Configurable]]: true}).
2213     obj->SetPropertyInlinedProps(thread, JSArguments::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(len));
2214     // 5. Let index be 0.
2215     // 6. Repeat while index < len,
2216     //    a. Let val be argumentsList[index].
2217     //    b. Perform CreateDataProperty(obj, ToString(index), val).
2218     //    c. Let index be index + 1
2219     obj->SetElements(thread, argumentsList.GetTaggedValue());
2220     // 7. Perform DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor
2221     // {[[Value]]:%ArrayProto_values%,
2222     // [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}).
2223     obj->SetPropertyInlinedProps(thread, JSArguments::ITERATOR_INLINE_PROPERTY_INDEX,
2224                                  globalEnv->GetArrayProtoValuesFunction().GetTaggedValue());
2225     // 8. Perform DefinePropertyOrThrow(obj, "caller", PropertyDescriptor {[[Get]]: %ThrowTypeError%,
2226     // [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}).
2227     JSHandle<JSTaggedValue> accessorCaller = globalEnv->GetArgumentsCallerAccessor();
2228     obj->SetPropertyInlinedProps(thread, JSArguments::CALLER_INLINE_PROPERTY_INDEX, accessorCaller.GetTaggedValue());
2229     // 9. Perform DefinePropertyOrThrow(obj, "callee", PropertyDescriptor {[[Get]]: %ThrowTypeError%,
2230     // [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}).
2231     JSHandle<JSTaggedValue> accessorCallee = globalEnv->GetArgumentsCalleeAccessor();
2232     obj->SetPropertyInlinedProps(thread, JSArguments::CALLEE_INLINE_PROPERTY_INDEX, accessorCallee.GetTaggedValue());
2233     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2234     // 11. Return obj
2235     return obj.GetTaggedValue();
2236 }
2237 
RuntimeOptNewLexicalEnvWithName(JSThread * thread,uint16_t numVars,uint16_t scopeId,JSHandle<JSTaggedValue> & currentLexEnv,JSHandle<JSTaggedValue> & func)2238 JSTaggedValue RuntimeStubs::RuntimeOptNewLexicalEnvWithName(JSThread *thread, uint16_t numVars, uint16_t scopeId,
2239                                                             JSHandle<JSTaggedValue> &currentLexEnv,
2240                                                             JSHandle<JSTaggedValue> &func)
2241 {
2242     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2243     JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars);
2244 
2245     newEnv->SetParentEnv(thread, currentLexEnv.GetTaggedValue());
2246     JSTaggedValue scopeInfo = RuntimeOptGenerateScopeInfo(thread, scopeId, func.GetTaggedValue());
2247     newEnv->SetScopeInfo(thread, scopeInfo);
2248     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2249     JSTaggedValue taggedEnv = newEnv.GetTaggedValue();
2250     return taggedEnv;
2251 }
2252 
RuntimeOptCopyRestArgs(JSThread * thread,uint32_t actualArgc,uint32_t restIndex)2253 JSTaggedValue RuntimeStubs::RuntimeOptCopyRestArgs(JSThread *thread, uint32_t actualArgc, uint32_t restIndex)
2254 {
2255     // when only have three fixed args, restIndex in bytecode maybe not zero, but it actually should be zero.
2256     uint32_t actualRestNum = 0;
2257     if (actualArgc > NUM_MANDATORY_JSFUNC_ARGS + restIndex) {
2258         actualRestNum = actualArgc - NUM_MANDATORY_JSFUNC_ARGS - restIndex;
2259     }
2260     JSHandle<JSTaggedValue> restArray = JSArray::ArrayCreate(thread, JSTaggedNumber(actualRestNum));
2261 
2262     auto argv = GetActualArgv(thread);
2263     int idx = 0;
2264     JSMutableHandle<JSTaggedValue> element(thread, JSTaggedValue::Undefined());
2265 
2266     for (uint32_t i = NUM_MANDATORY_JSFUNC_ARGS + restIndex; i < actualArgc; ++i) {
2267         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2268         JSTaggedType arg = reinterpret_cast<JSTaggedType *>(argv)[i];
2269         element.Update(JSTaggedValue(arg));
2270         JSObject::SetProperty(thread, restArray, idx++, element, true);
2271     }
2272     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2273     return restArray.GetTaggedValue();
2274 }
2275 
RuntimeOptSuspendGenerator(JSThread * thread,const JSHandle<JSTaggedValue> & genObj,const JSHandle<JSTaggedValue> & value)2276 JSTaggedValue RuntimeStubs::RuntimeOptSuspendGenerator(JSThread *thread, const JSHandle<JSTaggedValue> &genObj,
2277                                                        const JSHandle<JSTaggedValue> &value)
2278 {
2279     if (genObj->IsAsyncGeneratorObject()) {
2280         JSHandle<JSAsyncGeneratorObject> generatorObjectHandle(genObj);
2281         // change state to SuspendedYield
2282         if (generatorObjectHandle->IsExecuting()) {
2283             return value.GetTaggedValue();
2284         }
2285         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2286         return generatorObjectHandle.GetTaggedValue();
2287     }
2288 
2289     if (genObj->IsGeneratorObject()) {
2290         JSHandle<JSGeneratorObject> generatorObjectHandle(genObj);
2291         // change state to SuspendedYield
2292         if (generatorObjectHandle->IsExecuting()) {
2293             generatorObjectHandle->SetGeneratorState(JSGeneratorState::SUSPENDED_YIELD);
2294             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2295             return value.GetTaggedValue();
2296         }
2297         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2298         return generatorObjectHandle.GetTaggedValue();
2299     }
2300 
2301     return RuntimeThrowTypeError(thread, "RuntimeSuspendGenerator failed");
2302 }
2303 
RuntimeOptAsyncGeneratorResolve(JSThread * thread,JSHandle<JSTaggedValue> asyncFuncObj,JSHandle<JSTaggedValue> value,JSTaggedValue flag)2304 JSTaggedValue RuntimeStubs::RuntimeOptAsyncGeneratorResolve(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj,
2305                                                             JSHandle<JSTaggedValue> value, JSTaggedValue flag)
2306 {
2307     [[maybe_unused]] EcmaHandleScope handleScope(thread);
2308 
2309     JSHandle<JSAsyncGeneratorObject> asyncGeneratorObjHandle(asyncFuncObj);
2310     JSHandle<JSTaggedValue> valueHandle(value);
2311     JSHandle<GeneratorContext> genContextHandle(thread, asyncGeneratorObjHandle->GetGeneratorContext());
2312     ASSERT(flag.IsBoolean());
2313     bool done = flag.IsTrue();
2314     return JSAsyncGeneratorObject::AsyncGeneratorResolve(thread, asyncGeneratorObjHandle, valueHandle, done);
2315 }
2316 
RuntimeOptConstruct(JSThread * thread,JSHandle<JSTaggedValue> ctor,JSHandle<JSTaggedValue> newTarget,JSHandle<JSTaggedValue> preArgs,JSHandle<TaggedArray> args)2317 JSTaggedValue RuntimeStubs::RuntimeOptConstruct(JSThread *thread, JSHandle<JSTaggedValue> ctor,
2318                                                 JSHandle<JSTaggedValue> newTarget, JSHandle<JSTaggedValue> preArgs,
2319                                                 JSHandle<TaggedArray> args)
2320 {
2321     if (newTarget->IsUndefined()) {
2322         newTarget = ctor;
2323     }
2324 
2325     if (!(newTarget->IsConstructor() && ctor->IsConstructor())) {
2326         THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor is false", JSTaggedValue::Exception());
2327     }
2328 
2329     if (ctor->IsJSFunction()) {
2330         return RuntimeOptConstructGeneric(thread, JSHandle<JSFunction>::Cast(ctor), newTarget, preArgs, args);
2331     }
2332     if (ctor->IsBoundFunction()) {
2333         return RuntimeOptConstructBoundFunction(
2334             thread, JSHandle<JSBoundFunction>::Cast(ctor), newTarget, preArgs, args);
2335     }
2336     if (ctor->IsJSProxy()) {
2337         return RuntimeOptConstructProxy(thread, JSHandle<JSProxy>::Cast(ctor), newTarget, preArgs, args);
2338     }
2339     THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor NonConstructor", JSTaggedValue::Exception());
2340 }
2341 
RuntimeOptConstructProxy(JSThread * thread,JSHandle<JSProxy> ctor,JSHandle<JSTaggedValue> newTgt,JSHandle<JSTaggedValue> preArgs,JSHandle<TaggedArray> args)2342 JSTaggedValue RuntimeStubs::RuntimeOptConstructProxy(JSThread *thread, JSHandle<JSProxy> ctor,
2343                                                      JSHandle<JSTaggedValue> newTgt, JSHandle<JSTaggedValue> preArgs,
2344                                                      JSHandle<TaggedArray> args)
2345 {
2346     // step 1 ~ 4 get ProxyHandler and ProxyTarget
2347     JSHandle<JSTaggedValue> handler(thread, ctor->GetHandler());
2348     if (handler->IsNull()) {
2349         THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor: handler is null", JSTaggedValue::Exception());
2350     }
2351     ASSERT(handler->IsJSObject());
2352     JSHandle<JSTaggedValue> target(thread, ctor->GetTarget());
2353 
2354     // 5.Let trap be GetMethod(handler, "construct").
2355     JSHandle<JSTaggedValue> key(thread->GlobalConstants()->GetHandledProxyConstructString());
2356     JSHandle<JSTaggedValue> method = JSObject::GetMethod(thread, handler, key);
2357 
2358     // 6.ReturnIfAbrupt(trap).
2359     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2360     // 7.If trap is undefined, then
2361     //   a.Assert: target has a [[Construct]] internal method.
2362     //   b.Return Construct(target, argumentsList, newTarget).
2363     if (method->IsUndefined()) {
2364         ASSERT(target->IsConstructor());
2365         return RuntimeOptConstruct(thread, target, newTgt, preArgs, args);
2366     }
2367 
2368     // 8.Let argArray be CreateArrayFromList(argumentsList).
2369     uint32_t preArgsSize = preArgs->IsUndefined() ? 0 : JSHandle<TaggedArray>::Cast(preArgs)->GetLength();
2370     const uint32_t argsCount = args->GetLength();
2371     const uint32_t size = preArgsSize + argsCount;
2372     JSHandle<TaggedArray> arr = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(size);
2373     if (preArgsSize > 0) {
2374         JSHandle<TaggedArray> tgaPreArgs = JSHandle<TaggedArray>::Cast(preArgs);
2375         for (uint32_t i = 0; i < preArgsSize; ++i) {
2376             JSTaggedValue value = tgaPreArgs->Get(i);
2377             arr->Set(thread, i, value);
2378         }
2379     }
2380 
2381     for (uint32_t i = 0; i < argsCount; ++i) {
2382         JSTaggedValue value = args->Get(i);
2383         arr->Set(thread, i + preArgsSize, value);
2384     }
2385 
2386     // step 8 ~ 9 Call(trap, handler, «target, argArray, newTarget »).
2387     const uint32_t argsLength = 3;  // 3: «target, argArray, newTarget »
2388     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
2389     EcmaRuntimeCallInfo *info = EcmaInterpreter::NewRuntimeCallInfo(thread, method, handler, undefined, argsLength);
2390     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2391     info->SetCallArg(target.GetTaggedValue(), arr.GetTaggedValue(), newTgt.GetTaggedValue());
2392     JSTaggedValue newObjValue = JSFunction::Call(info);
2393     // 10.ReturnIfAbrupt(newObj).
2394     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2395     // 11.If Type(newObj) is not Object, throw a TypeError exception.
2396     if (!newObjValue.IsECMAObject()) {
2397         THROW_TYPE_ERROR_AND_RETURN(thread, "new object is not object", JSTaggedValue::Exception());
2398     }
2399     // 12.Return newObj.
2400     return newObjValue;
2401 }
2402 
RuntimeOptConstructBoundFunction(JSThread * thread,JSHandle<JSBoundFunction> ctor,JSHandle<JSTaggedValue> newTgt,JSHandle<JSTaggedValue> preArgs,JSHandle<TaggedArray> args)2403 JSTaggedValue RuntimeStubs::RuntimeOptConstructBoundFunction(JSThread *thread, JSHandle<JSBoundFunction> ctor,
2404                                                              JSHandle<JSTaggedValue> newTgt,
2405                                                              JSHandle<JSTaggedValue> preArgs,
2406                                                              JSHandle<TaggedArray> args)
2407 {
2408     JSHandle<JSTaggedValue> target(thread, ctor->GetBoundTarget());
2409     ASSERT(target->IsConstructor());
2410 
2411     JSHandle<TaggedArray> boundArgs(thread, ctor->GetBoundArguments());
2412     JSMutableHandle<JSTaggedValue> newPreArgs(thread, preArgs.GetTaggedValue());
2413     if (newPreArgs->IsUndefined()) {
2414         newPreArgs.Update(boundArgs.GetTaggedValue());
2415     } else {
2416         newPreArgs.Update(
2417             TaggedArray::Append(thread, boundArgs, JSHandle<TaggedArray>::Cast(preArgs)).GetTaggedValue());
2418     }
2419     JSMutableHandle<JSTaggedValue> newTargetMutable(thread, newTgt.GetTaggedValue());
2420     if (JSTaggedValue::SameValue(ctor.GetTaggedValue(), newTgt.GetTaggedValue())) {
2421         newTargetMutable.Update(target.GetTaggedValue());
2422     }
2423     return RuntimeOptConstruct(thread, target, newTargetMutable, newPreArgs, args);
2424 }
2425 
RuntimeOptConstructGeneric(JSThread * thread,JSHandle<JSFunction> ctor,JSHandle<JSTaggedValue> newTgt,JSHandle<JSTaggedValue> preArgs,JSHandle<TaggedArray> args)2426 JSTaggedValue RuntimeStubs::RuntimeOptConstructGeneric(JSThread *thread, JSHandle<JSFunction> ctor,
2427                                                        JSHandle<JSTaggedValue> newTgt,
2428                                                        JSHandle<JSTaggedValue> preArgs, JSHandle<TaggedArray> args)
2429 {
2430     if (!ctor->IsConstructor()) {
2431         THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor is false", JSTaggedValue::Exception());
2432     }
2433 
2434     JSHandle<JSTaggedValue> obj(thread, JSTaggedValue::Undefined());
2435     if (ctor->IsBase()) {
2436         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2437         obj = JSHandle<JSTaggedValue>(factory->NewJSObjectByConstructor(ctor, newTgt));
2438     }
2439 
2440     uint32_t preArgsSize = preArgs->IsUndefined() ? 0 : JSHandle<TaggedArray>::Cast(preArgs)->GetLength();
2441     const uint32_t argsCount = args->GetLength();
2442     uint32_t size = preArgsSize + argsCount;
2443     CVector<JSTaggedType> values;
2444     Method *method = ctor->GetCallTarget();
2445     bool isAotMethod = method->IsAotWithCallField();
2446     if (isAotMethod && ctor->IsClassConstructor()) {
2447         if (method->IsFastCall()) {
2448             values.reserve(size + NUM_MANDATORY_JSFUNC_ARGS - 1);
2449             values.emplace_back(ctor.GetTaggedValue().GetRawData());
2450             values.emplace_back(obj.GetTaggedValue().GetRawData());
2451         } else {
2452             values.reserve(size + NUM_MANDATORY_JSFUNC_ARGS);
2453             values.emplace_back(ctor.GetTaggedValue().GetRawData());
2454             values.emplace_back(newTgt.GetTaggedValue().GetRawData());
2455             values.emplace_back(obj.GetTaggedValue().GetRawData());
2456         }
2457     } else {
2458         values.reserve(size);
2459     }
2460 
2461     if (preArgsSize > 0) {
2462         JSHandle<TaggedArray> tgaPreArgs = JSHandle<TaggedArray>::Cast(preArgs);
2463         for (uint32_t i = 0; i < preArgsSize; ++i) {
2464             JSTaggedValue value = tgaPreArgs->Get(i);
2465             values.emplace_back(value.GetRawData());
2466         }
2467         for (uint32_t i = 0; i < argsCount; ++i) {
2468             values.emplace_back(args->Get(i).GetRawData());
2469         }
2470     } else {
2471         for (uint32_t i = 0; i < argsCount; ++i) {
2472             values.emplace_back(args->Get(i).GetRawData());
2473         }
2474     }
2475     JSTaggedValue resultValue;
2476     if (isAotMethod && ctor->IsClassConstructor()) {
2477         uint32_t numArgs = ctor->GetCallTarget()->GetNumArgsWithCallField();
2478         bool needPushUndefined = numArgs > size;
2479         const JSTaggedType *prevFp = thread->GetLastLeaveFrame();
2480         if (ctor->GetCallTarget()->IsFastCall()) {
2481             if (needPushUndefined) {
2482                 values.reserve(numArgs + NUM_MANDATORY_JSFUNC_ARGS - 1);
2483                 for (uint32_t i = size; i < numArgs; i++) {
2484                     values.emplace_back(JSTaggedValue::VALUE_UNDEFINED);
2485                 }
2486                 size = numArgs;
2487             }
2488             resultValue = thread->GetEcmaVM()->FastCallAot(size, values.data(), prevFp);
2489         } else {
2490             resultValue = thread->GetCurrentEcmaContext()->ExecuteAot(size, values.data(), prevFp, needPushUndefined);
2491         }
2492     } else {
2493         ctor->GetCallTarget()->SetAotCodeBit(false); // if Construct is not ClassConstructor, don't run aot
2494         EcmaRuntimeCallInfo *info =
2495             EcmaInterpreter::NewRuntimeCallInfo(thread, JSHandle<JSTaggedValue>(ctor), obj, newTgt, size);
2496         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2497         info->SetCallArg(size, values.data());
2498         resultValue = EcmaInterpreter::Execute(info);
2499     }
2500     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2501     // 9.3.2 [[Construct]] (argumentsList, newTarget)
2502     if (resultValue.IsECMAObject()) {
2503         return resultValue;
2504     }
2505 
2506     if (ctor->IsBase()) {
2507         return obj.GetTaggedValue();
2508     }
2509     if (!resultValue.IsUndefined()) {
2510         THROW_TYPE_ERROR_AND_RETURN(thread, "function is non-constructor", JSTaggedValue::Exception());
2511     }
2512     return obj.GetTaggedValue();
2513 }
2514 
RuntimeOptNewObjRange(JSThread * thread,uintptr_t argv,uint32_t argc)2515 JSTaggedValue RuntimeStubs::RuntimeOptNewObjRange(JSThread *thread, uintptr_t argv, uint32_t argc)
2516 {
2517     JSHandle<JSTaggedValue> ctor = GetHArg<JSTaggedValue>(argv, argc, 0);
2518     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
2519     const size_t firstArgOffset = 1;
2520     size_t arrLength = argc - firstArgOffset;
2521     JSHandle<TaggedArray> args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(arrLength);
2522     for (size_t i = 0; i < arrLength; ++i) {
2523         args->Set(thread, i, GetArg(argv, argc, i + firstArgOffset));
2524     }
2525     JSTaggedValue object = RuntimeOptConstruct(thread, ctor, ctor, undefined, args);
2526     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2527     if (!object.IsUndefined() && !object.IsECMAObject() && !JSHandle<JSFunction>(ctor)->IsBase()) {
2528         THROW_TYPE_ERROR_AND_RETURN(thread, "Derived constructor must return object or undefined",
2529                                     JSTaggedValue::Exception());
2530     }
2531     return object;
2532 }
2533 
RuntimeOptGenerateScopeInfo(JSThread * thread,uint16_t scopeId,JSTaggedValue func)2534 JSTaggedValue RuntimeStubs::RuntimeOptGenerateScopeInfo(JSThread *thread, uint16_t scopeId, JSTaggedValue func)
2535 {
2536     EcmaVM *ecmaVm = thread->GetEcmaVM();
2537     ObjectFactory *factory = ecmaVm->GetFactory();
2538     Method *method = ECMAObject::Cast(func.GetTaggedObject())->GetCallTarget();
2539     const JSPandaFile *jsPandaFile = method->GetJSPandaFile();
2540     JSHandle<ConstantPool> constpool(thread, method->GetConstantPool());
2541     panda_file::File::EntityId id = constpool->GetEntityId(scopeId);
2542     JSHandle<TaggedArray> elementsLiteral =
2543         LiteralDataExtractor::GetDatasIgnoreType(thread, jsPandaFile, id, constpool);
2544 
2545     ASSERT(elementsLiteral->GetLength() > 0);
2546 
2547     auto *scopeDebugInfo = ecmaVm->GetNativeAreaAllocator()->New<ScopeDebugInfo>();
2548     if (scopeDebugInfo == nullptr) {
2549         return JSTaggedValue::Hole();
2550     }
2551 
2552     size_t length = elementsLiteral->GetLength();
2553     for (size_t i = 1; i < length; i += 2) {  // 2: Each literal buffer contains a pair of key-value.
2554         JSTaggedValue val = elementsLiteral->Get(i);
2555         ASSERT(val.IsString());
2556         CString name = ConvertToString(EcmaString::Cast(val.GetTaggedObject()));
2557         int32_t slot = elementsLiteral->Get(i + 1).GetInt();
2558         scopeDebugInfo->scopeInfo.emplace(name, slot);
2559     }
2560 
2561     JSHandle<JSNativePointer> pointer = factory->NewJSNativePointer(
2562         scopeDebugInfo, NativeAreaAllocator::FreeObjectFunc<ScopeDebugInfo>, ecmaVm->GetNativeAreaAllocator());
2563     return pointer.GetTaggedValue();
2564 }
2565 
GetActualArgv(JSThread * thread)2566 JSTaggedType *RuntimeStubs::GetActualArgv(JSThread *thread)
2567 {
2568     JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
2569     FrameIterator it(current, thread);
2570     ASSERT(it.IsLeaveFrame());
2571     it.Advance<GCVisitedFlag::VISITED>();
2572     ASSERT(it.IsOptimizedJSFunctionFrame());
2573     auto optimizedJSFunctionFrame = it.GetFrame<OptimizedJSFunctionFrame>();
2574     return optimizedJSFunctionFrame->GetArgv(it);
2575 }
2576 
GetActualArgvFromStub(JSThread * thread)2577 JSTaggedType *RuntimeStubs::GetActualArgvFromStub(JSThread *thread)
2578 {
2579     JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
2580     FrameIterator it(current, thread);
2581     ASSERT(it.IsLeaveFrame());
2582     it.Advance<GCVisitedFlag::VISITED>();
2583     ASSERT(it.IsOptimizedFrame());
2584     it.Advance<GCVisitedFlag::VISITED>();
2585     ASSERT(it.IsOptimizedJSFunctionFrame());
2586     auto optimizedJSFunctionFrame = it.GetFrame<OptimizedJSFunctionFrame>();
2587     return optimizedJSFunctionFrame->GetArgv(it);
2588 }
2589 
GetOptimizedJSFunctionFrame(JSThread * thread)2590 OptimizedJSFunctionFrame *RuntimeStubs::GetOptimizedJSFunctionFrame(JSThread *thread)
2591 {
2592     JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
2593     FrameIterator it(current, thread);
2594     ASSERT(it.IsLeaveFrame());
2595     it.Advance();
2596     ASSERT(it.IsOptimizedJSFunctionFrame());
2597     return it.GetFrame<OptimizedJSFunctionFrame>();
2598 }
2599 
GetOptimizedJSFunctionFrameNoGC(JSThread * thread)2600 OptimizedJSFunctionFrame *RuntimeStubs::GetOptimizedJSFunctionFrameNoGC(JSThread *thread)
2601 {
2602     JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
2603     FrameIterator it(current, thread);
2604     ASSERT(it.IsOptimizedFrame());
2605     it.Advance();
2606     ASSERT(it.IsOptimizedJSFunctionFrame());
2607     return it.GetFrame<OptimizedJSFunctionFrame>();
2608 }
2609 
RuntimeLdPatchVar(JSThread * thread,uint32_t index)2610 JSTaggedValue RuntimeStubs::RuntimeLdPatchVar(JSThread *thread, uint32_t index)
2611 {
2612     JSHandle<TaggedArray> globalPatch =
2613         JSHandle<TaggedArray>::Cast(thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalPatch());
2614 
2615     return globalPatch->Get(thread, index);
2616 }
2617 
RuntimeStPatchVar(JSThread * thread,uint32_t index,const JSHandle<JSTaggedValue> & value)2618 JSTaggedValue RuntimeStubs::RuntimeStPatchVar(JSThread *thread, uint32_t index, const JSHandle<JSTaggedValue> &value)
2619 {
2620     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
2621 
2622     JSHandle<TaggedArray> globalPatch = JSHandle<TaggedArray>::Cast(env->GetGlobalPatch());
2623     if (index >= globalPatch->GetLength()) {
2624         globalPatch = TaggedArray::SetCapacity(thread, globalPatch, index + 1);
2625     }
2626     globalPatch->Set(thread, index, value);
2627     env->SetGlobalPatch(thread, globalPatch.GetTaggedValue());
2628     return JSTaggedValue::True();
2629 }
2630 
RuntimeNotifyConcurrentResult(JSThread * thread,JSTaggedValue result,JSTaggedValue hint)2631 JSTaggedValue RuntimeStubs::RuntimeNotifyConcurrentResult(JSThread *thread, JSTaggedValue result, JSTaggedValue hint)
2632 {
2633     thread->GetEcmaVM()->TriggerConcurrentCallback(result, hint);
2634     return JSTaggedValue::Undefined();
2635 }
2636 
RuntimeNotifyDebuggerStatement(JSThread * thread)2637 JSTaggedValue RuntimeStubs::RuntimeNotifyDebuggerStatement(JSThread *thread)
2638 {
2639     FrameHandler frameHandler(thread);
2640     for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
2641         if (frameHandler.IsEntryFrame() || frameHandler.IsBuiltinFrame()) {
2642             continue;
2643         }
2644         Method *method = frameHandler.GetMethod();
2645         if (method->IsNativeWithCallField()) {
2646             continue;
2647         }
2648         auto bcOffset = frameHandler.GetBytecodeOffset();
2649         auto *debuggerMgr = thread->GetEcmaVM()->GetJsDebuggerManager();
2650         debuggerMgr->GetNotificationManager()->DebuggerStmtEvent(thread, method, bcOffset);
2651         return JSTaggedValue::Hole();
2652     }
2653     return JSTaggedValue::Hole();
2654 }
2655 }  // namespace panda::ecmascript
2656 #endif  // ECMASCRIPT_STUBS_RUNTIME_STUBS_INL_H
2657