• 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 #include "ecmascript/interpreter/slow_runtime_stub.h"
17 
18 #include "ecmascript/base/number_helper.h"
19 #include "ecmascript/builtins/builtins_regexp.h"
20 #include "ecmascript/jspandafile/program_object-inl.h"
21 #include "ecmascript/ecma_module.h"
22 #include "ecmascript/global_dictionary-inl.h"
23 #include "ecmascript/ic/profile_type_info.h"
24 #include "ecmascript/internal_call_params.h"
25 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
26 #include "ecmascript/interpreter/frame_handler.h"
27 #include "ecmascript/interpreter/slow_runtime_helper.h"
28 #include "ecmascript/js_arguments.h"
29 #include "ecmascript/js_array.h"
30 #include "ecmascript/js_array_iterator.h"
31 #include "ecmascript/js_async_function.h"
32 #include "ecmascript/js_for_in_iterator.h"
33 #include "ecmascript/js_function.h"
34 #include "ecmascript/js_generator_object.h"
35 #include "ecmascript/js_hclass-inl.h"
36 #include "ecmascript/js_invoker.h"
37 #include "ecmascript/js_iterator.h"
38 #include "ecmascript/js_promise.h"
39 #include "ecmascript/js_proxy.h"
40 #include "ecmascript/js_tagged_value-inl.h"
41 #include "ecmascript/js_thread.h"
42 #include "ecmascript/jspandafile/scope_info_extractor.h"
43 #include "ecmascript/tagged_dictionary.h"
44 #include "ecmascript/runtime_call_id.h"
45 #include "ecmascript/template_string.h"
46 
47 namespace panda::ecmascript {
CallSpreadDyn(JSThread * thread,JSTaggedValue func,JSTaggedValue obj,JSTaggedValue array)48 JSTaggedValue SlowRuntimeStub::CallSpreadDyn(JSThread *thread, JSTaggedValue func, JSTaggedValue obj,
49                                              JSTaggedValue array)
50 {
51     INTERPRETER_TRACE(thread, CallSpreadDyn);
52     if ((!obj.IsUndefined() && !obj.IsECMAObject()) || !func.IsJSFunction() || !array.IsJSArray()) {
53         THROW_TYPE_ERROR_AND_RETURN(thread, "cannot Callspread", JSTaggedValue::Exception());
54     }
55     [[maybe_unused]] EcmaHandleScope handleScope(thread);
56 
57     JSHandle<JSFunction> jsFunc(thread, func);
58     JSHandle<JSTaggedValue> jsArray(thread, array);
59     JSHandle<JSTaggedValue> taggedObj(thread, obj);
60 
61     JSHandle<TaggedArray> coretypesArray(thread, GetCallSpreadArgs(thread, jsArray.GetTaggedValue()));
62     InternalCallParams *params = thread->GetInternalCallParams();
63     params->MakeArgList(*coretypesArray);
64     JSHandle<JSTaggedValue> newTarget(thread, JSTaggedValue::Undefined());
65     JSTaggedValue res = InvokeJsFunction(thread, jsFunc, taggedObj, newTarget, params);
66 
67     return res;
68 }
69 
NegDyn(JSThread * thread,JSTaggedValue value)70 JSTaggedValue SlowRuntimeStub::NegDyn(JSThread *thread, JSTaggedValue value)
71 {
72     INTERPRETER_TRACE(thread, NegDyn);
73     [[maybe_unused]] EcmaHandleScope handleScope(thread);
74 
75     JSHandle<JSTaggedValue> input(thread, value);
76     JSHandle<JSTaggedValue> inputVal(thread, JSTaggedValue::ToNumeric(thread, input));
77     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
78     if (inputVal->IsBigInt()) {
79         JSHandle<BigInt> bigValue(inputVal);
80         return BigInt::UnaryMinus(thread, bigValue).GetTaggedValue();
81     }
82     JSTaggedNumber number(inputVal.GetTaggedValue());
83     if (number.IsInt()) {
84         int32_t intValue = number.GetInt();
85         if (intValue == 0) {
86             return JSTaggedValue(-0.0);
87         }
88         return JSTaggedValue(-intValue);
89     }
90     if (number.IsDouble()) {
91         return JSTaggedValue(-number.GetDouble());
92     }
93     UNREACHABLE();
94 }
95 
AsyncFunctionEnter(JSThread * thread)96 JSTaggedValue SlowRuntimeStub::AsyncFunctionEnter(JSThread *thread)
97 {
98     INTERPRETER_TRACE(thread, AsyncFunctionEnter);
99     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
100     [[maybe_unused]] EcmaHandleScope handleScope(thread);
101     // 1. create promise
102     JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
103     JSHandle<JSTaggedValue> promiseFunc = globalEnv->GetPromiseFunction();
104 
105     JSHandle<JSPromise> promiseObject =
106         JSHandle<JSPromise>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(promiseFunc), promiseFunc));
107     promiseObject->SetPromiseState(PromiseState::PENDING);
108     // 2. create asyncfuncobj
109     JSHandle<JSAsyncFuncObject> asyncFuncObj = factory->NewJSAsyncFuncObject();
110     asyncFuncObj->SetPromise(thread, promiseObject);
111 
112     JSHandle<GeneratorContext> context = factory->NewGeneratorContext();
113     context->SetGeneratorObject(thread, asyncFuncObj);
114 
115     // change state to EXECUTING
116     asyncFuncObj->SetGeneratorState(JSGeneratorState::EXECUTING);
117     asyncFuncObj->SetGeneratorContext(thread, context);
118 
119     // 3. return asyncfuncobj
120     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
121     return asyncFuncObj.GetTaggedValue();
122 }
123 
ToNumber(JSThread * thread,JSTaggedValue value)124 JSTaggedValue SlowRuntimeStub::ToNumber(JSThread *thread, JSTaggedValue value)
125 {
126     INTERPRETER_TRACE(thread, Tonumber);
127     [[maybe_unused]] EcmaHandleScope handleScope(thread);
128 
129     JSHandle<JSTaggedValue> number(thread, value);
130     // may return exception
131     return JSTaggedValue::ToNumeric(thread, number);
132 }
133 
NotDyn(JSThread * thread,JSTaggedValue value)134 JSTaggedValue SlowRuntimeStub::NotDyn(JSThread *thread, JSTaggedValue value)
135 {
136     INTERPRETER_TRACE(thread, NotDyn);
137     [[maybe_unused]] EcmaHandleScope handleScope(thread);
138     JSHandle<JSTaggedValue> input(thread, value);
139     JSHandle<JSTaggedValue> inputVal(thread, JSTaggedValue::ToNumeric(thread, input));
140     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
141     if (inputVal->IsBigInt()) {
142         JSHandle<BigInt> bigValue(inputVal);
143         return BigInt::BitwiseNOT(thread, bigValue).GetTaggedValue();
144     }
145     int32_t number = JSTaggedValue::ToInt32(thread, inputVal);
146     return JSTaggedValue(~number); // NOLINT(hicpp-signed-bitwise)
147 }
148 
IncDyn(JSThread * thread,JSTaggedValue value)149 JSTaggedValue SlowRuntimeStub::IncDyn(JSThread *thread, JSTaggedValue value)
150 {
151     INTERPRETER_TRACE(thread, IncDyn);
152     [[maybe_unused]] EcmaHandleScope handleScope(thread);
153 
154     JSHandle<JSTaggedValue> input(thread, value);
155     JSHandle<JSTaggedValue> inputVal(thread, JSTaggedValue::ToNumeric(thread, input));
156     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
157     if (inputVal->IsBigInt()) {
158         JSHandle<BigInt> bigValue(inputVal);
159         return BigInt::BigintAddOne(thread, bigValue).GetTaggedValue();
160     }
161     JSTaggedNumber number(inputVal.GetTaggedValue());
162     return JSTaggedValue(++number);
163 }
164 
DecDyn(JSThread * thread,JSTaggedValue value)165 JSTaggedValue SlowRuntimeStub::DecDyn(JSThread *thread, JSTaggedValue value)
166 {
167     INTERPRETER_TRACE(thread, DecDyn);
168     [[maybe_unused]] EcmaHandleScope handleScope(thread);
169 
170     JSHandle<JSTaggedValue> input(thread, value);
171     JSHandle<JSTaggedValue> inputVal(thread, JSTaggedValue::ToNumeric(thread, input));
172     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
173     if (inputVal->IsBigInt()) {
174         JSHandle<BigInt> bigValue(inputVal);
175         return BigInt::BigintSubOne(thread, bigValue).GetTaggedValue();
176     }
177     JSTaggedNumber number(inputVal.GetTaggedValue());
178     return JSTaggedValue(--number);
179 }
180 
ThrowDyn(JSThread * thread,JSTaggedValue value)181 void SlowRuntimeStub::ThrowDyn(JSThread *thread, JSTaggedValue value)
182 {
183     INTERPRETER_TRACE(thread, ThrowDyn);
184     thread->SetException(value);
185 }
186 
GetPropIterator(JSThread * thread,JSTaggedValue value)187 JSTaggedValue SlowRuntimeStub::GetPropIterator(JSThread *thread, JSTaggedValue value)
188 {
189     INTERPRETER_TRACE(thread, GetPropIterator);
190     [[maybe_unused]] EcmaHandleScope handleScope(thread);
191 
192     JSHandle<JSTaggedValue> objHandle(thread, value);
193     JSHandle<JSForInIterator> iteratorHandle = JSObject::EnumerateObjectProperties(thread, objHandle);
194     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
195     return iteratorHandle.GetTaggedValue();
196 }
197 
ThrowConstAssignment(JSThread * thread,JSTaggedValue value)198 void SlowRuntimeStub::ThrowConstAssignment(JSThread *thread, JSTaggedValue value)
199 {
200     INTERPRETER_TRACE(thread, ThrowConstAssignment);
201     [[maybe_unused]] EcmaHandleScope handleScope(thread);
202 
203     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
204 
205     JSHandle<EcmaString> name(thread, value.GetTaggedObject());
206     JSHandle<EcmaString> info = factory->NewFromCanBeCompressString("Assignment to const variable ");
207 
208     JSHandle<EcmaString> msg = factory->ConcatFromString(info, name);
209     THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::TYPE_ERROR, msg).GetTaggedValue());
210 }
211 
Add2Dyn(JSThread * thread,EcmaVM * ecma_vm,JSTaggedValue left,JSTaggedValue right)212 JSTaggedValue SlowRuntimeStub::Add2Dyn(JSThread *thread, EcmaVM *ecma_vm, JSTaggedValue left, JSTaggedValue right)
213 {
214     INTERPRETER_TRACE(thread, Add2Dyn);
215     [[maybe_unused]] EcmaHandleScope handleScope(thread);
216 
217     JSHandle<JSTaggedValue> leftValue(thread, left);
218     JSHandle<JSTaggedValue> rightValue(thread, right);
219     if (leftValue->IsString() && rightValue->IsString()) {
220         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
221         JSHandle<EcmaString> newString =
222             factory->ConcatFromString(JSHandle<EcmaString>(leftValue), JSHandle<EcmaString>(rightValue));
223         return newString.GetTaggedValue();
224     }
225     JSHandle<JSTaggedValue> primitiveA0(thread, JSTaggedValue::ToPrimitive(thread, leftValue));
226     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
227     JSHandle<JSTaggedValue> primitiveA1(thread, JSTaggedValue::ToPrimitive(thread, rightValue));
228     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
229     // contain string
230     if (primitiveA0->IsString() || primitiveA1->IsString()) {
231         JSHandle<EcmaString> stringA0 = JSTaggedValue::ToString(thread, primitiveA0);
232         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
233         JSHandle<EcmaString> stringA1 = JSTaggedValue::ToString(thread, primitiveA1);
234         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
235         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
236         JSHandle<EcmaString> newString = factory->ConcatFromString(stringA0, stringA1);
237         return newString.GetTaggedValue();
238     }
239     JSHandle<JSTaggedValue> valLeft(thread, JSTaggedValue::ToNumeric(thread, primitiveA0));
240     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
241     JSHandle<JSTaggedValue> valRight(thread, JSTaggedValue::ToNumeric(thread, primitiveA1));
242     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
243     if (valLeft->IsBigInt() && valRight->IsBigInt()) {
244         JSHandle<BigInt> bigLeft(valLeft);
245         JSHandle<BigInt> bigRight(valRight);
246         return BigInt::Add(thread, bigLeft, bigRight).GetTaggedValue();
247     }
248     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
249         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
250     }
251     double a0Double = valLeft->GetNumber();
252     double a1Double = valRight->GetNumber();
253     return JSTaggedValue(a0Double + a1Double);
254 }
255 
Sub2Dyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)256 JSTaggedValue SlowRuntimeStub::Sub2Dyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
257 {
258     INTERPRETER_TRACE(thread, Sub2Dyn);
259     [[maybe_unused]] EcmaHandleScope handleScope(thread);
260 
261     JSHandle<JSTaggedValue> leftHandle(thread, left);
262     JSHandle<JSTaggedValue> rightHandle(thread, right);
263     JSHandle<JSTaggedValue> valLeft(thread, JSTaggedValue::ToNumeric(thread, leftHandle));
264     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
265     JSHandle<JSTaggedValue> valRight(thread, JSTaggedValue::ToNumeric(thread, rightHandle));
266     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
267     if (valLeft->IsBigInt() && valRight->IsBigInt()) {
268         JSHandle<BigInt> bigLeft(valLeft);
269         JSHandle<BigInt> bigRight(valRight);
270         return BigInt::Subtract(thread, bigLeft, bigRight).GetTaggedValue();
271     }
272     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
273         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
274     }
275     JSTaggedNumber number0(valLeft.GetTaggedValue());
276     JSTaggedNumber number1(valRight.GetTaggedValue());
277     return number0 - number1;
278 }
279 
Mul2Dyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)280 JSTaggedValue SlowRuntimeStub::Mul2Dyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
281 {
282     INTERPRETER_TRACE(thread, Mul2Dyn);
283     [[maybe_unused]] EcmaHandleScope handleScope(thread);
284 
285     JSHandle<JSTaggedValue> leftHandle(thread, left);
286     JSHandle<JSTaggedValue> rightHandle(thread, right);
287     JSHandle<JSTaggedValue> valLeft(thread, JSTaggedValue::ToNumeric(thread, leftHandle));
288     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
289     JSHandle<JSTaggedValue> valRight(thread, JSTaggedValue::ToNumeric(thread, rightHandle));
290     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
291     // 9. ReturnIfAbrupt(rnum).
292     if (valLeft->IsBigInt() && valRight->IsBigInt()) {
293         JSHandle<BigInt> bigLeft(valLeft);
294         JSHandle<BigInt> bigRight(valRight);
295         return BigInt::Multiply(thread, bigLeft, bigRight).GetTaggedValue();
296     }
297     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
298         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
299     }
300     // 12.6.3.1 Applying the * Operator
301     JSTaggedNumber number0(valLeft.GetTaggedValue());
302     JSTaggedNumber number1(valRight.GetTaggedValue());
303     return number0 * number1;
304 }
305 
Div2Dyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)306 JSTaggedValue SlowRuntimeStub::Div2Dyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
307 {
308     INTERPRETER_TRACE(thread, Div2Dyn);
309     [[maybe_unused]] EcmaHandleScope handleScope(thread);
310 
311     JSHandle<JSTaggedValue> leftHandle(thread, left);
312     JSHandle<JSTaggedValue> rightHandle(thread, right);
313     JSHandle<JSTaggedValue> valLeft(thread, JSTaggedValue::ToNumeric(thread, leftHandle));
314     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
315     JSHandle<JSTaggedValue> valRight(thread, JSTaggedValue::ToNumeric(thread, rightHandle));
316     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
317     if (valLeft->IsBigInt() && valRight->IsBigInt()) {
318         JSHandle<BigInt> bigLeft(valLeft);
319         JSHandle<BigInt> bigRight(valRight);
320         return BigInt::Divide(thread, bigLeft, bigRight).GetTaggedValue();
321     }
322     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
323         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
324     }
325     double dLeft = valLeft->GetNumber();
326     double dRight = valRight->GetNumber();
327     if (dRight == 0) {
328         if (dLeft == 0 || std::isnan(dLeft)) {
329             return JSTaggedValue(base::NAN_VALUE);
330         }
331         bool positive = (((bit_cast<uint64_t>(dRight)) & base::DOUBLE_SIGN_MASK) ==
332                          ((bit_cast<uint64_t>(dLeft)) & base::DOUBLE_SIGN_MASK));
333         return JSTaggedValue(positive ? base::POSITIVE_INFINITY : -base::POSITIVE_INFINITY);
334     }
335     return JSTaggedValue(dLeft / dRight);
336 }
337 
Mod2Dyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)338 JSTaggedValue SlowRuntimeStub::Mod2Dyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
339 {
340     INTERPRETER_TRACE(thread, Mod2Dyn);
341     [[maybe_unused]] EcmaHandleScope handleScope(thread);
342 
343     JSHandle<JSTaggedValue> leftHandle(thread, left);
344     JSHandle<JSTaggedValue> rightHandle(thread, right);
345     JSHandle<JSTaggedValue> valLeft(thread, JSTaggedValue::ToNumeric(thread, leftHandle));
346     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
347     JSHandle<JSTaggedValue> valRight(thread, JSTaggedValue::ToNumeric(thread, rightHandle));
348     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
349 
350     // 12.6.3.3 Applying the % Operator
351     if (valLeft->IsBigInt() && valRight->IsBigInt()) {
352         JSHandle<BigInt> leftBigint(valLeft);
353         JSHandle<BigInt> rightBigint(valRight);
354         return BigInt::Remainder(thread, leftBigint, rightBigint).GetTaggedValue();
355     }
356     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
357         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
358     }
359     double dLeft = valLeft->GetNumber();
360     double dRight = valRight->GetNumber();
361     // 12.6.3.3 Applying the % Operator
362     if ((dRight == 0.0) || std::isnan(dRight) || std::isnan(dLeft) || std::isinf(dLeft)) {
363         return JSTaggedValue(base::NAN_VALUE);
364     }
365     if ((dLeft == 0.0) || std::isinf(dRight)) {
366         return JSTaggedValue(dLeft);
367     }
368     return JSTaggedValue(std::fmod(dLeft, dRight));
369 }
370 
EqDyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)371 JSTaggedValue SlowRuntimeStub::EqDyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
372 {
373     INTERPRETER_TRACE(thread, EqDyn);
374     [[maybe_unused]] EcmaHandleScope handleScope(thread);
375 
376     JSHandle<JSTaggedValue> leftValue(thread, left);
377     JSHandle<JSTaggedValue> rightValue(thread, right);
378     bool ret = JSTaggedValue::Equal(thread, leftValue, rightValue);
379     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
380     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
381 }
382 
NotEqDyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)383 JSTaggedValue SlowRuntimeStub::NotEqDyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
384 {
385     INTERPRETER_TRACE(thread, NotEqDyn);
386     [[maybe_unused]] EcmaHandleScope handleScope(thread);
387 
388     JSHandle<JSTaggedValue> leftValue(thread, left);
389     JSHandle<JSTaggedValue> rightValue(thread, right);
390     bool ret = JSTaggedValue::Equal(thread, leftValue, rightValue);
391     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
392     return (ret ? JSTaggedValue::False() : JSTaggedValue::True());
393 }
394 
LessDyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)395 JSTaggedValue SlowRuntimeStub::LessDyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
396 {
397     INTERPRETER_TRACE(thread, LessDyn);
398     [[maybe_unused]] EcmaHandleScope handleScope(thread);
399 
400     JSHandle<JSTaggedValue> leftValue(thread, left);
401     JSHandle<JSTaggedValue> rightValue(thread, right);
402     bool ret = JSTaggedValue::Compare(thread, leftValue, rightValue) == ComparisonResult::LESS;
403     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
404     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
405 }
406 
LessEqDyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)407 JSTaggedValue SlowRuntimeStub::LessEqDyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
408 {
409     INTERPRETER_TRACE(thread, LessEqDyn);
410     [[maybe_unused]] EcmaHandleScope handleScope(thread);
411 
412     JSHandle<JSTaggedValue> leftValue(thread, left);
413     JSHandle<JSTaggedValue> rightValue(thread, right);
414     bool ret = JSTaggedValue::Compare(thread, leftValue, rightValue) <= ComparisonResult::EQUAL;
415     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
416     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
417 }
418 
GreaterDyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)419 JSTaggedValue SlowRuntimeStub::GreaterDyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
420 {
421     INTERPRETER_TRACE(thread, GreaterDyn);
422     [[maybe_unused]] EcmaHandleScope handleScope(thread);
423 
424     JSHandle<JSTaggedValue> leftValue(thread, left);
425     JSHandle<JSTaggedValue> rightValue(thread, right);
426     bool ret = JSTaggedValue::Compare(thread, leftValue, rightValue) == ComparisonResult::GREAT;
427     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
428     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
429 }
430 
GreaterEqDyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)431 JSTaggedValue SlowRuntimeStub::GreaterEqDyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
432 {
433     INTERPRETER_TRACE(thread, GreaterEqDyn);
434     [[maybe_unused]] EcmaHandleScope handleScope(thread);
435 
436     JSHandle<JSTaggedValue> leftValue(thread, left);
437     JSHandle<JSTaggedValue> rightValue(thread, right);
438     ComparisonResult comparison = JSTaggedValue::Compare(thread, leftValue, rightValue);
439     bool ret = (comparison == ComparisonResult::GREAT) || (comparison == ComparisonResult::EQUAL);
440     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
441     return (ret ? JSTaggedValue::True() : JSTaggedValue::False());
442 }
443 
Shl2Dyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)444 JSTaggedValue SlowRuntimeStub::Shl2Dyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
445 {
446     INTERPRETER_TRACE(thread, Shl2Dyn);
447     [[maybe_unused]] EcmaHandleScope handleScope(thread);
448     JSHandle<JSTaggedValue> leftHandle(thread, left);
449     JSHandle<JSTaggedValue> rightHandle(thread, right);
450     JSHandle<JSTaggedValue> leftValue(thread, JSTaggedValue::ToNumeric(thread, leftHandle));
451     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
452     JSHandle<JSTaggedValue> rightValue(thread, JSTaggedValue::ToNumeric(thread, rightHandle));
453     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
454     if (leftValue->IsBigInt() && rightValue->IsBigInt()) {
455         JSHandle<BigInt> leftBigint(leftValue);
456         JSHandle<BigInt> rightBigint(rightValue);
457         return BigInt::LeftShift(thread, leftBigint, rightBigint).GetTaggedValue();
458     }
459     if (leftValue->IsBigInt() || rightValue->IsBigInt()) {
460         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
461     }
462     JSTaggedValue taggedNumber0 = SlowRuntimeStub::ToJSTaggedValueWithInt32(thread, leftValue.GetTaggedValue());
463     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
464     JSTaggedValue taggedNumber1 = SlowRuntimeStub::ToJSTaggedValueWithUint32(thread, rightValue.GetTaggedValue());
465     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
466     int32_t opNumber0 = taggedNumber0.GetInt();
467     int32_t opNumber1 = taggedNumber1.GetInt();
468     uint32_t shift =
469         static_cast<uint32_t>(opNumber1) & 0x1f;  // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
470     using unsigned_type = std::make_unsigned_t<int32_t>;
471     auto ret =
472         static_cast<int32_t>(static_cast<unsigned_type>(opNumber0) << shift);  // NOLINT(hicpp-signed-bitwise)
473     return JSTaggedValue(ret);
474 }
475 
Shr2Dyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)476 JSTaggedValue SlowRuntimeStub::Shr2Dyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
477 {
478     INTERPRETER_TRACE(thread, Shr2Dyn);
479     [[maybe_unused]] EcmaHandleScope handleScope(thread);
480 
481     JSHandle<JSTaggedValue> leftHandle(thread, left);
482     JSHandle<JSTaggedValue> rightHandle(thread, right);
483     JSHandle<JSTaggedValue> valLeft(thread, JSTaggedValue::ToNumeric(thread, leftHandle));
484     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
485     JSHandle<JSTaggedValue> valRight(thread, JSTaggedValue::ToNumeric(thread, rightHandle));
486     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
487     if (valLeft->IsBigInt() && valRight->IsBigInt()) {
488         JSHandle<BigInt> bigLeft(valLeft);
489         JSHandle<BigInt> bigRight(valRight);
490         return BigInt::SignedRightShift(thread, bigLeft, bigRight).GetTaggedValue();
491     }
492     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
493         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
494     }
495     JSTaggedValue taggedNumber0 = SlowRuntimeStub::ToJSTaggedValueWithInt32(thread, valLeft.GetTaggedValue());
496     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
497     JSTaggedValue taggedNumber1 = SlowRuntimeStub::ToJSTaggedValueWithUint32(thread, valRight.GetTaggedValue());
498     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
499     int32_t opNumber0 = taggedNumber0.GetInt();
500     int32_t opNumber1 = taggedNumber1.GetInt();
501     uint32_t shift =
502             static_cast<uint32_t>(opNumber1) & 0x1f;          // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
503     auto ret = static_cast<int32_t>(opNumber0 >> shift);  // NOLINT(hicpp-signed-bitwise)
504     return JSTaggedValue(ret);
505 }
506 
Ashr2Dyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)507 JSTaggedValue SlowRuntimeStub::Ashr2Dyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
508 {
509     INTERPRETER_TRACE(thread, Ashr2Dyn);
510     [[maybe_unused]] EcmaHandleScope handleScope(thread);
511 
512     JSHandle<JSTaggedValue> leftHandle(thread, left);
513     JSHandle<JSTaggedValue> rightHandle(thread, right);
514     JSHandle<JSTaggedValue> valLeft(thread, JSTaggedValue::ToNumeric(thread, leftHandle));
515     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
516     JSHandle<JSTaggedValue> valRight(thread, JSTaggedValue::ToNumeric(thread, rightHandle));
517     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
518     if (valLeft->IsBigInt() && valRight->IsBigInt()) {
519         return BigInt::UnsignedRightShift(thread);
520     }
521     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
522         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
523     }
524     JSTaggedValue taggedNumber0 = SlowRuntimeStub::ToJSTaggedValueWithUint32(thread, valLeft.GetTaggedValue());
525     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
526     JSTaggedValue taggedNumber1 = SlowRuntimeStub::ToJSTaggedValueWithUint32(thread, valRight.GetTaggedValue());
527     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
528     int32_t opNumber0 = taggedNumber0.GetInt();
529     int32_t opNumber1 = taggedNumber1.GetInt();
530     uint32_t shift =
531         static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
532     using unsigned_type = std::make_unsigned_t<uint32_t>;
533     auto ret =
534         static_cast<uint32_t>(static_cast<unsigned_type>(opNumber0) >> shift); // NOLINT(hicpp-signed-bitwise)
535     return JSTaggedValue(ret);
536 }
537 
And2Dyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)538 JSTaggedValue SlowRuntimeStub::And2Dyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
539 {
540     INTERPRETER_TRACE(thread, And2Dyn);
541     [[maybe_unused]] EcmaHandleScope handleScope(thread);
542 
543     JSHandle<JSTaggedValue> leftHandle(thread, left);
544     JSHandle<JSTaggedValue> rightHandle(thread, right);
545     JSHandle<JSTaggedValue> valLeft(thread, JSTaggedValue::ToNumeric(thread, leftHandle));
546     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
547     JSHandle<JSTaggedValue> valRight(thread, JSTaggedValue::ToNumeric(thread, rightHandle));
548     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
549     if (valLeft->IsBigInt() && valRight->IsBigInt()) {
550         JSHandle<BigInt> leftBigint(valLeft);
551         JSHandle<BigInt> rightBigint(valRight);
552         return BigInt::BitwiseAND(thread, leftBigint, rightBigint).GetTaggedValue();
553     }
554     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
555         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
556     }
557     JSTaggedValue taggedNumber0 = SlowRuntimeStub::ToJSTaggedValueWithInt32(thread, valLeft.GetTaggedValue());
558     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
559     JSTaggedValue taggedNumber1 = SlowRuntimeStub::ToJSTaggedValueWithInt32(thread, valRight.GetTaggedValue());
560     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
561     int32_t opNumber0 = taggedNumber0.GetInt();
562     int32_t opNumber1 = taggedNumber1.GetInt();
563     // NOLINT(hicpp-signed-bitwise)
564     auto ret = static_cast<uint32_t>(opNumber0) & static_cast<uint32_t>(opNumber1);
565     return JSTaggedValue(static_cast<int32_t>(ret));
566 }
567 
Or2Dyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)568 JSTaggedValue SlowRuntimeStub::Or2Dyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
569 {
570     INTERPRETER_TRACE(thread, Or2Dyn);
571     [[maybe_unused]] EcmaHandleScope handleScope(thread);
572 
573     JSHandle<JSTaggedValue> leftHandle(thread, left);
574     JSHandle<JSTaggedValue> rightHandle(thread, right);
575     JSHandle<JSTaggedValue> valLeft(thread, JSTaggedValue::ToNumeric(thread, leftHandle));
576     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
577     JSHandle<JSTaggedValue> valRight(thread, JSTaggedValue::ToNumeric(thread, rightHandle));
578     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
579     if (valLeft->IsBigInt() && valRight->IsBigInt()) {
580         JSHandle<BigInt> leftBigint(valLeft);
581         JSHandle<BigInt> rightBigint(valRight);
582         return BigInt::BitwiseOR(thread, leftBigint, rightBigint).GetTaggedValue();
583     }
584     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
585         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
586     }
587     JSTaggedValue taggedNumber0 = SlowRuntimeStub::ToJSTaggedValueWithInt32(thread, valLeft.GetTaggedValue());
588     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
589     JSTaggedValue taggedNumber1 = SlowRuntimeStub::ToJSTaggedValueWithInt32(thread, valRight.GetTaggedValue());
590     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
591     int32_t opNumber0 = taggedNumber0.GetInt();
592     int32_t opNumber1 = taggedNumber1.GetInt();
593     // NOLINT(hicpp-signed-bitwise)
594     auto ret = static_cast<uint32_t>(opNumber0) | static_cast<uint32_t>(opNumber1);
595     return JSTaggedValue(static_cast<int32_t>(ret));
596 }
597 
Xor2Dyn(JSThread * thread,JSTaggedValue left,JSTaggedValue right)598 JSTaggedValue SlowRuntimeStub::Xor2Dyn(JSThread *thread, JSTaggedValue left, JSTaggedValue right)
599 {
600     INTERPRETER_TRACE(thread, Xor2Dyn);
601     [[maybe_unused]] EcmaHandleScope handleScope(thread);
602 
603     JSHandle<JSTaggedValue> leftHandle(thread, left);
604     JSHandle<JSTaggedValue> rightHandle(thread, right);
605     JSHandle<JSTaggedValue> valLeft(thread, JSTaggedValue::ToNumeric(thread, leftHandle));
606     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
607     JSHandle<JSTaggedValue> valRight(thread, JSTaggedValue::ToNumeric(thread, rightHandle));
608     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
609     if (valLeft->IsBigInt() && valRight->IsBigInt()) {
610         JSHandle<BigInt> leftBigint(valLeft);
611         JSHandle<BigInt> rightBigint(valRight);
612         return BigInt::BitwiseXOR(thread, leftBigint, rightBigint).GetTaggedValue();
613     }
614     if (valLeft->IsBigInt() || valRight->IsBigInt()) {
615         return ThrowTypeError(thread, "Cannot mix BigInt and other types, use explicit conversions");
616     }
617     JSTaggedValue taggedNumber0 = SlowRuntimeStub::ToJSTaggedValueWithInt32(thread, valLeft.GetTaggedValue());
618     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
619     JSTaggedValue taggedNumber1 = SlowRuntimeStub::ToJSTaggedValueWithInt32(thread, valRight.GetTaggedValue());
620     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
621     int32_t opNumber0 = taggedNumber0.GetInt();
622     int32_t opNumber1 = taggedNumber1.GetInt();
623     // NOLINT(hicpp-signed-bitwise)
624     auto ret = static_cast<uint32_t>(opNumber0) ^ static_cast<uint32_t>(opNumber1);
625     return JSTaggedValue(static_cast<int32_t>(ret));
626 }
627 
ToJSTaggedValueWithInt32(JSThread * thread,JSTaggedValue value)628 JSTaggedValue SlowRuntimeStub::ToJSTaggedValueWithInt32(JSThread *thread, JSTaggedValue value)
629 {
630     INTERPRETER_TRACE(thread, ToJSTaggedValueWithInt32);
631     [[maybe_unused]] EcmaHandleScope handleScope(thread);
632     JSHandle<JSTaggedValue> valueHandle(thread, value);
633     int32_t res = JSTaggedValue::ToInt32(thread, valueHandle);
634     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
635     return JSTaggedValue(res);
636 }
637 
ToJSTaggedValueWithUint32(JSThread * thread,JSTaggedValue value)638 JSTaggedValue SlowRuntimeStub::ToJSTaggedValueWithUint32(JSThread *thread, JSTaggedValue value)
639 {
640     INTERPRETER_TRACE(thread, ToJSTaggedValueWithUint32);
641     [[maybe_unused]] EcmaHandleScope handleScope(thread);
642     JSHandle<JSTaggedValue> valueHandle(thread, value);
643     int32_t res = JSTaggedValue::ToUint32(thread, valueHandle);
644     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
645     return JSTaggedValue(res);
646 }
647 
DelObjProp(JSThread * thread,JSTaggedValue obj,JSTaggedValue prop)648 JSTaggedValue SlowRuntimeStub::DelObjProp(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop)
649 {
650     INTERPRETER_TRACE(thread, Delobjprop);
651     [[maybe_unused]] EcmaHandleScope handleScope(thread);
652 
653     JSHandle<JSTaggedValue> objHandle(thread, obj);
654     JSHandle<JSTaggedValue> propHandle(thread, prop);
655     JSHandle<JSTaggedValue> jsObj(JSTaggedValue::ToObject(thread, objHandle));
656     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
657     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, propHandle);
658     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
659     bool ret = JSTaggedValue::DeletePropertyOrThrow(thread, jsObj, propKey);
660     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
661     return JSTaggedValue(ret);
662 }
663 
NewObjDynRange(JSThread * thread,JSTaggedValue func,JSTaggedValue newTarget,uint16_t firstArgIdx,uint16_t length)664 JSTaggedValue SlowRuntimeStub::NewObjDynRange(JSThread *thread, JSTaggedValue func, JSTaggedValue newTarget,
665                                               uint16_t firstArgIdx, uint16_t length)
666 {
667     INTERPRETER_TRACE(thread, NewobjDynrange);
668     [[maybe_unused]] EcmaHandleScope handleScope(thread);
669 
670     JSHandle<JSTaggedValue> funcHandle(thread, func);
671     JSHandle<JSTaggedValue> newTargetHandle(thread, newTarget);
672 
673     JSHandle<JSTaggedValue> preArgs(thread, JSTaggedValue::Undefined());
674     auto tagged = SlowRuntimeHelper::Construct(thread, funcHandle, newTargetHandle, preArgs, length, firstArgIdx);
675     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
676     return tagged;
677 }
678 
CreateObjectWithExcludedKeys(JSThread * thread,uint16_t numKeys,JSTaggedValue objVal,uint16_t firstArgRegIdx)679 JSTaggedValue SlowRuntimeStub::CreateObjectWithExcludedKeys(JSThread *thread, uint16_t numKeys, JSTaggedValue objVal,
680                                                             uint16_t firstArgRegIdx)
681 {
682     INTERPRETER_TRACE(thread, CreateObjectWithExcludedKeys);
683     [[maybe_unused]] EcmaHandleScope handleScope(thread);
684 
685     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
686 
687     ASSERT(objVal.IsJSObject());
688     JSHandle<JSObject> obj(thread, objVal);
689     uint32_t numExcludedKeys = 0;
690     JSHandle<TaggedArray> excludedKeys = factory->NewTaggedArray(numKeys + 1);
691     InterpretedFrameHandler frameHandler(thread);
692     JSTaggedValue excludedKey = frameHandler.GetVRegValue(firstArgRegIdx);
693     if (!excludedKey.IsUndefined()) {
694         numExcludedKeys = numKeys + 1;
695         excludedKeys->Set(thread, 0, excludedKey);
696         for (uint32_t i = 1; i < numExcludedKeys; i++) {
697             excludedKey = frameHandler.GetVRegValue(firstArgRegIdx + i);
698             excludedKeys->Set(thread, i, excludedKey);
699         }
700     }
701 
702     uint32_t numAllKeys = obj->GetNumberOfKeys();
703     JSHandle<TaggedArray> allKeys = factory->NewTaggedArray(numAllKeys);
704     JSObject::GetAllKeys(thread, obj, 0, allKeys);
705 
706     JSHandle<JSObject> restObj = factory->NewEmptyJSObject();
707     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
708     for (uint32_t i = 0; i < numAllKeys; i++) {
709         key.Update(allKeys->Get(i));
710         bool isExcludedKey = false;
711         for (uint32_t j = 0; j < numExcludedKeys; j++) {
712             if (JSTaggedValue::Equal(thread, key, JSHandle<JSTaggedValue>(thread, excludedKeys->Get(j)))) {
713                 isExcludedKey = true;
714                 break;
715             }
716         }
717         if (!isExcludedKey) {
718             PropertyDescriptor desc(thread);
719             bool success = JSObject::GetOwnProperty(thread, obj, key, desc);
720             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
721             if (success && desc.IsEnumerable()) {
722                 JSHandle<JSTaggedValue> value = JSObject::GetProperty(thread, obj, key).GetValue();
723                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
724                 JSObject::SetProperty(thread, restObj, key, value, true);
725                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
726             }
727         }
728     }
729     return restObj.GetTaggedValue();
730 }
731 
ExpDyn(JSThread * thread,JSTaggedValue base,JSTaggedValue exponent)732 JSTaggedValue SlowRuntimeStub::ExpDyn(JSThread *thread, JSTaggedValue base, JSTaggedValue exponent)
733 {
734     INTERPRETER_TRACE(thread, ExpDyn);
735     [[maybe_unused]] EcmaHandleScope handleScope(thread);
736 
737     JSTaggedNumber baseNumber = JSTaggedValue::ToNumber(thread, JSHandle<JSTaggedValue>(thread, base));
738     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
739     double doubleBase = baseNumber.GetNumber();
740     JSTaggedNumber exponentNumber = JSTaggedValue::ToNumber(thread, JSHandle<JSTaggedValue>(thread, exponent));
741     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
742     double doubleExponent = exponentNumber.GetNumber();
743     if (std::abs(doubleBase) == 1 && std::isinf(doubleExponent)) {
744         return JSTaggedValue(base::NAN_VALUE);
745     }
746 
747     if (((doubleBase == 0) && ((bit_cast<uint64_t>(doubleBase)) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) &&
748         std::isfinite(doubleExponent) && base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent &&
749         base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF == (doubleExponent / 2)) {  // 2: half
750         if (doubleExponent > 0) {
751             return JSTaggedValue(-0.0);
752         }
753         if (doubleExponent < 0) {
754             return JSTaggedValue(-base::POSITIVE_INFINITY);
755         }
756     }
757     return JSTaggedValue(std::pow(doubleBase, doubleExponent));
758 }
759 
IsInDyn(JSThread * thread,JSTaggedValue prop,JSTaggedValue obj)760 JSTaggedValue SlowRuntimeStub::IsInDyn(JSThread *thread, JSTaggedValue prop, JSTaggedValue obj)
761 {
762     INTERPRETER_TRACE(thread, IsInDyn);
763     [[maybe_unused]] EcmaHandleScope handleScope(thread);
764 
765     JSHandle<JSTaggedValue> propHandle(thread, prop);
766     JSHandle<JSTaggedValue> objHandle(thread, obj);
767     if (!objHandle->IsECMAObject()) {
768         return ThrowTypeError(thread, "Cannot use 'in' operator in Non-Object");
769     }
770     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, propHandle);
771     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
772     bool ret = JSTaggedValue::HasProperty(thread, objHandle, propKey);
773     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
774     return JSTaggedValue(ret);
775 }
776 
InstanceofDyn(JSThread * thread,JSTaggedValue obj,JSTaggedValue target)777 JSTaggedValue SlowRuntimeStub::InstanceofDyn(JSThread *thread, JSTaggedValue obj, JSTaggedValue target)
778 {
779     INTERPRETER_TRACE(thread, InstanceofDyn);
780     [[maybe_unused]] EcmaHandleScope handleScope(thread);
781 
782     JSHandle<JSTaggedValue> objHandle(thread, obj);
783     JSHandle<JSTaggedValue> targetHandle(thread, target);
784     bool ret = JSObject::InstanceOf(thread, objHandle, targetHandle);
785     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
786     return JSTaggedValue(ret);
787 }
788 
NewLexicalEnvDyn(JSThread * thread,uint16_t numVars)789 JSTaggedValue SlowRuntimeStub::NewLexicalEnvDyn(JSThread *thread, uint16_t numVars)
790 {
791     INTERPRETER_TRACE(thread, NewlexenvDyn);
792     [[maybe_unused]] EcmaHandleScope handleScope(thread);
793 
794     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
795     JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars);
796 
797     JSTaggedValue currentLexenv = thread->GetCurrentLexenv();
798     newEnv->SetParentEnv(thread, currentLexenv);
799     newEnv->SetScopeInfo(thread, JSTaggedValue::Hole());
800     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
801     return newEnv.GetTaggedValue();
802 }
803 
NewLexicalEnvWithNameDyn(JSThread * thread,uint16_t numVars,uint16_t scopeId)804 JSTaggedValue SlowRuntimeStub::NewLexicalEnvWithNameDyn(JSThread *thread, uint16_t numVars, uint16_t scopeId)
805 {
806     INTERPRETER_TRACE(thread, NewlexenvwithNameDyn);
807     [[maybe_unused]] EcmaHandleScope handleScope(thread);
808 
809     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
810     JSHandle<LexicalEnv> newEnv = factory->NewLexicalEnv(numVars);
811 
812     JSTaggedValue currentLexenv = thread->GetCurrentLexenv();
813     newEnv->SetParentEnv(thread, currentLexenv);
814     JSTaggedValue scopeInfo = ScopeInfoExtractor::GenerateScopeInfo(thread, scopeId);
815     newEnv->SetScopeInfo(thread, scopeInfo);
816     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
817     return newEnv.GetTaggedValue();
818 }
819 
CreateIterResultObj(JSThread * thread,JSTaggedValue value,JSTaggedValue flag)820 JSTaggedValue SlowRuntimeStub::CreateIterResultObj(JSThread *thread, JSTaggedValue value, JSTaggedValue flag)
821 {
822     INTERPRETER_TRACE(thread, CreateIterResultObj);
823     [[maybe_unused]] EcmaHandleScope handleScope(thread);
824 
825     JSHandle<JSTaggedValue> valueHandle(thread, value);
826     ASSERT(flag.IsBoolean());
827     bool done = flag.IsTrue();
828     JSHandle<JSObject> iter = JSIterator::CreateIterResultObject(thread, valueHandle, done);
829     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
830     return iter.GetTaggedValue();
831 }
832 
CreateGeneratorObj(JSThread * thread,JSTaggedValue genFunc)833 JSTaggedValue SlowRuntimeStub::CreateGeneratorObj(JSThread *thread, JSTaggedValue genFunc)
834 {
835     INTERPRETER_TRACE(thread, CreateGeneratorObj);
836     [[maybe_unused]] EcmaHandleScope handleScope(thread);
837 
838     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
839     JSHandle<JSTaggedValue> generatorFunction(thread, genFunc);
840     JSHandle<JSGeneratorObject> obj = factory->NewJSGeneratorObject(generatorFunction);
841     JSHandle<GeneratorContext> context = factory->NewGeneratorContext();
842     context->SetGeneratorObject(thread, obj.GetTaggedValue());
843 
844     // change state to SUSPENDED_START
845     obj->SetGeneratorState(JSGeneratorState::SUSPENDED_START);
846     obj->SetGeneratorContext(thread, context);
847 
848     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
849     return obj.GetTaggedValue();
850 }
851 
SuspendGenerator(JSThread * thread,JSTaggedValue genObj,JSTaggedValue value)852 JSTaggedValue SlowRuntimeStub::SuspendGenerator(JSThread *thread, JSTaggedValue genObj, JSTaggedValue value)
853 {
854     INTERPRETER_TRACE(thread, SuspendGenerator);
855     [[maybe_unused]] EcmaHandleScope handleScope(thread);
856 
857     JSHandle<JSGeneratorObject> generatorObjectHandle(thread, genObj);
858     JSHandle<GeneratorContext> genContextHandle(thread, generatorObjectHandle->GetGeneratorContext());
859     JSHandle<JSTaggedValue> valueHandle(thread, value);
860     // save stack, should copy cur_frame, function execute over will free cur_frame
861     SlowRuntimeHelper::SaveFrameToContext(thread, genContextHandle);
862 
863     // change state to SuspendedYield
864     if (generatorObjectHandle->IsExecuting()) {
865         generatorObjectHandle->SetGeneratorState(JSGeneratorState::SUSPENDED_YIELD);
866         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
867         return valueHandle.GetTaggedValue();
868     }
869     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
870     return generatorObjectHandle.GetTaggedValue();
871 }
872 
AsyncFunctionAwaitUncaught(JSThread * thread,JSTaggedValue asyncFuncObj,JSTaggedValue value)873 JSTaggedValue SlowRuntimeStub::AsyncFunctionAwaitUncaught(JSThread *thread, JSTaggedValue asyncFuncObj,
874                                                           JSTaggedValue value)
875 {
876     INTERPRETER_TRACE(thread, AsyncFunctionAwaitUncaught);
877     [[maybe_unused]] EcmaHandleScope handleScope(thread);
878 
879     JSHandle<JSAsyncFuncObject> asyncFuncObjHandle(thread, asyncFuncObj);
880     JSHandle<JSTaggedValue> valueHandle(thread, value);
881     JSAsyncFunction::AsyncFunctionAwait(thread, asyncFuncObjHandle, valueHandle);
882     JSHandle<JSPromise> promise(thread, asyncFuncObjHandle->GetPromise());
883 
884     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
885     return promise.GetTaggedValue();
886 }
887 
AsyncFunctionResolveOrReject(JSThread * thread,JSTaggedValue asyncFuncObj,JSTaggedValue value,bool is_resolve)888 JSTaggedValue SlowRuntimeStub::AsyncFunctionResolveOrReject(JSThread *thread, JSTaggedValue asyncFuncObj,
889                                                             JSTaggedValue value, bool is_resolve)
890 {
891     INTERPRETER_TRACE(thread, AsyncFunctionResolveOrReject);
892     [[maybe_unused]] EcmaHandleScope handleScope(thread);
893 
894     JSHandle<JSAsyncFuncObject> asyncFuncObjHandle(thread, asyncFuncObj);
895     JSHandle<JSPromise> promise(thread, asyncFuncObjHandle->GetPromise());
896     JSHandle<JSTaggedValue> valueHandle(thread, value);
897 
898     // ActivePromise
899     JSHandle<ResolvingFunctionsRecord> reactions = JSPromise::CreateResolvingFunctions(thread, promise);
900     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
901     JSHandle<JSTaggedValue> thisArg = globalConst->GetHandledUndefined();
902     JSHandle<JSTaggedValue> activeFunc;
903     if (is_resolve) {
904         activeFunc = JSHandle<JSTaggedValue>(thread, reactions->GetResolveFunction());
905     } else {
906         activeFunc = JSHandle<JSTaggedValue>(thread, reactions->GetRejectFunction());
907     }
908     InternalCallParams *arguments = thread->GetInternalCallParams();
909     arguments->MakeArgv(valueHandle);
910     [[maybe_unused]] JSTaggedValue res = JSFunction::Call(thread, activeFunc, thisArg, 1, arguments->GetArgv());
911 
912     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
913     return promise.GetTaggedValue();
914 }
915 
NewObjSpreadDyn(JSThread * thread,JSTaggedValue func,JSTaggedValue newTarget,JSTaggedValue array)916 JSTaggedValue SlowRuntimeStub::NewObjSpreadDyn(JSThread *thread, JSTaggedValue func, JSTaggedValue newTarget,
917                                                JSTaggedValue array)
918 {
919     INTERPRETER_TRACE(thread, NewobjspreadDyn);
920     [[maybe_unused]] EcmaHandleScope handleScope(thread);
921 
922     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
923     JSHandle<JSTaggedValue> funcHandle(thread, func);
924     JSHandle<JSTaggedValue> newTargetHandle(thread, newTarget);
925     JSHandle<JSTaggedValue> jsArray(thread, array);
926     if (!jsArray->IsJSArray()) {
927         return ThrowTypeError(thread, "Cannot Newobjspread");
928     }
929 
930     uint32_t length = JSHandle<JSArray>::Cast(jsArray)->GetArrayLength();
931     JSHandle<TaggedArray> argsArray = factory->NewTaggedArray(length);
932     for (uint32_t i = 0; i < length; ++i) {
933         auto prop = JSTaggedValue::GetProperty(thread, jsArray, i).GetValue();
934         argsArray->Set(thread, i, prop);
935         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
936     }
937     InternalCallParams *arguments = thread->GetInternalCallParams();
938     arguments->MakeArgList(*argsArray);
939     auto tagged = SlowRuntimeHelper::NewObject(thread, funcHandle, newTargetHandle, length, arguments->GetArgv());
940     return tagged;
941 }
942 
ThrowUndefinedIfHole(JSThread * thread,JSTaggedValue obj)943 void SlowRuntimeStub::ThrowUndefinedIfHole(JSThread *thread, JSTaggedValue obj)
944 {
945     INTERPRETER_TRACE(thread, ThrowUndefinedIfHole);
946     [[maybe_unused]] EcmaHandleScope handleScope(thread);
947 
948     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
949     JSHandle<EcmaString> name(thread, obj);
950     JSHandle<EcmaString> info = factory->NewFromCanBeCompressString(" is not initialized");
951 
952     JSHandle<EcmaString> msg = factory->ConcatFromString(info, name);
953     THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::REFERENCE_ERROR, msg).GetTaggedValue());
954 }
955 
ThrowIfSuperNotCorrectCall(JSThread * thread,uint16_t index,JSTaggedValue thisValue)956 JSTaggedValue SlowRuntimeStub::ThrowIfSuperNotCorrectCall(JSThread *thread, uint16_t index, JSTaggedValue thisValue)
957 {
958     INTERPRETER_TRACE(thread, ThrowIfSuperNotCorrectCall);
959     [[maybe_unused]] EcmaHandleScope handleScope(thread);
960 
961     if (index == 0 && (thisValue.IsUndefined() || thisValue.IsHole())) {
962         return ThrowReferenceError(thread, JSTaggedValue::Undefined(), "sub-class must call super before use 'this'");
963     }
964     if (index == 1 && !thisValue.IsUndefined() && !thisValue.IsHole()) {
965         return ThrowReferenceError(thread, JSTaggedValue::Undefined(), "super() forbidden re-bind 'this'");
966     }
967     return JSTaggedValue::True();
968 }
969 
ThrowIfNotObject(JSThread * thread)970 void SlowRuntimeStub::ThrowIfNotObject(JSThread *thread)
971 {
972     INTERPRETER_TRACE(thread, ThrowIfNotObject);
973     [[maybe_unused]] EcmaHandleScope handleScope(thread);
974 
975     THROW_TYPE_ERROR(thread, "Inner return result is not object");
976 }
977 
ThrowThrowNotExists(JSThread * thread)978 void SlowRuntimeStub::ThrowThrowNotExists(JSThread *thread)
979 {
980     INTERPRETER_TRACE(thread, ThrowThrowNotExists);
981     [[maybe_unused]] EcmaHandleScope handleScope(thread);
982 
983     THROW_TYPE_ERROR(thread, "Throw method is not defined");
984 }
985 
ThrowPatternNonCoercible(JSThread * thread)986 void SlowRuntimeStub::ThrowPatternNonCoercible(JSThread *thread)
987 {
988     INTERPRETER_TRACE(thread, ThrowPatternNonCoercible);
989     [[maybe_unused]] EcmaHandleScope handleScope(thread);
990 
991     JSHandle<EcmaString> msg(thread->GlobalConstants()->GetHandledObjNotCoercibleString());
992     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
993     THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::TYPE_ERROR, msg).GetTaggedValue());
994 }
995 
StOwnByName(JSThread * thread,JSTaggedValue obj,JSTaggedValue prop,JSTaggedValue value)996 JSTaggedValue SlowRuntimeStub::StOwnByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, JSTaggedValue value)
997 {
998     INTERPRETER_TRACE(thread, StOwnByNameDyn);
999     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1000 
1001     JSHandle<JSTaggedValue> objHandle(thread, obj);
1002     JSHandle<JSTaggedValue> propHandle(thread, prop);
1003     JSHandle<JSTaggedValue> valueHandle(thread, value);
1004     ASSERT(propHandle->IsStringOrSymbol());
1005 
1006     // property in class is non-enumerable
1007     bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor());
1008 
1009     PropertyDescriptor desc(thread, valueHandle, true, enumerable, true);
1010     bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propHandle, desc);
1011     if (!ret) {
1012         return ThrowTypeError(thread, "SetOwnByName failed");
1013     }
1014     return JSTaggedValue::True();
1015 }
1016 
StOwnByNameWithNameSet(JSThread * thread,JSTaggedValue obj,JSTaggedValue prop,JSTaggedValue value)1017 JSTaggedValue SlowRuntimeStub::StOwnByNameWithNameSet(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop,
1018                                                       JSTaggedValue value)
1019 {
1020     INTERPRETER_TRACE(thread, StOwnByNameDyn);
1021     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1022 
1023     JSHandle<JSTaggedValue> objHandle(thread, obj);
1024     JSHandle<JSTaggedValue> propHandle(thread, prop);
1025     JSHandle<JSTaggedValue> valueHandle(thread, value);
1026     ASSERT(propHandle->IsStringOrSymbol());
1027 
1028     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, propHandle);
1029 
1030     // property in class is non-enumerable
1031     bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor());
1032 
1033     PropertyDescriptor desc(thread, valueHandle, true, enumerable, true);
1034     bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propHandle, desc);
1035     if (!ret) {
1036         return ThrowTypeError(thread, "SetOwnByNameWithNameSet failed");
1037     }
1038     JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(valueHandle), propKey,
1039                                     JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1040     return JSTaggedValue::True();
1041 }
1042 
StOwnByIndex(JSThread * thread,JSTaggedValue obj,uint32_t idx,JSTaggedValue value)1043 JSTaggedValue SlowRuntimeStub::StOwnByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, JSTaggedValue value)
1044 {
1045     INTERPRETER_TRACE(thread, StOwnByIdDyn);
1046     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1047 
1048     JSHandle<JSTaggedValue> objHandle(thread, obj);
1049     JSHandle<JSTaggedValue> idxHandle(thread, JSTaggedValue(idx));
1050     JSHandle<JSTaggedValue> valueHandle(thread, value);
1051 
1052     // property in class is non-enumerable
1053     bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor());
1054 
1055     PropertyDescriptor desc(thread, valueHandle, true, enumerable, true);
1056     bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, idxHandle, desc);
1057     if (!ret) {
1058         return ThrowTypeError(thread, "SetOwnByIndex failed");
1059     }
1060     return JSTaggedValue::True();
1061 }
1062 
StOwnByValue(JSThread * thread,JSTaggedValue obj,JSTaggedValue key,JSTaggedValue value)1063 JSTaggedValue SlowRuntimeStub::StOwnByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, JSTaggedValue value)
1064 {
1065     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1066 
1067     INTERPRETER_TRACE(thread, StOwnByValueDyn);
1068     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1069     JSHandle<JSTaggedValue> objHandle(thread, obj);
1070     JSHandle<JSTaggedValue> keyHandle(thread, key);
1071     JSHandle<JSTaggedValue> valueHandle(thread, value);
1072 
1073     if (objHandle->IsClassConstructor() &&
1074         JSTaggedValue::SameValue(keyHandle, globalConst->GetHandledPrototypeString())) {
1075         return ThrowTypeError(thread, "In a class, static property named 'prototype' throw a TypeError");
1076     }
1077 
1078     // property in class is non-enumerable
1079     bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor());
1080 
1081     PropertyDescriptor desc(thread, valueHandle, true, enumerable, true);
1082     JSMutableHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, keyHandle));
1083     bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propKey, desc);
1084     if (!ret) {
1085         return ThrowTypeError(thread, "StOwnByValue failed");
1086     }
1087     return JSTaggedValue::True();
1088 }
1089 
StOwnByValueWithNameSet(JSThread * thread,JSTaggedValue obj,JSTaggedValue key,JSTaggedValue value)1090 JSTaggedValue SlowRuntimeStub::StOwnByValueWithNameSet(JSThread *thread, JSTaggedValue obj, JSTaggedValue key,
1091                                                        JSTaggedValue value)
1092 {
1093     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1094     INTERPRETER_TRACE(thread, StOwnByValueDyn);
1095     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1096     JSHandle<JSTaggedValue> objHandle(thread, obj);
1097     JSHandle<JSTaggedValue> keyHandle(thread, key);
1098     JSHandle<JSTaggedValue> valueHandle(thread, value);
1099 
1100     if (objHandle->IsClassConstructor() &&
1101         JSTaggedValue::SameValue(keyHandle, globalConst->GetHandledPrototypeString())) {
1102         return ThrowTypeError(thread, "In a class, static property named 'prototype' throw a TypeError");
1103     }
1104 
1105     // property in class is non-enumerable
1106     bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor());
1107 
1108     PropertyDescriptor desc(thread, valueHandle, true, enumerable, true);
1109     JSMutableHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, keyHandle));
1110     bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propKey, desc);
1111     if (!ret) {
1112         return ThrowTypeError(thread, "StOwnByValueWithNameSet failed");
1113     }
1114     if (valueHandle->IsJSFunction()) {
1115         if (propKey->IsNumber()) {
1116             propKey.Update(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()).GetTaggedValue());
1117         }
1118         JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(valueHandle), propKey,
1119                                         JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
1120     }
1121     return JSTaggedValue::True();
1122 }
1123 
CreateEmptyArray(JSThread * thread,ObjectFactory * factory,JSHandle<GlobalEnv> globalEnv)1124 JSTaggedValue SlowRuntimeStub::CreateEmptyArray(JSThread *thread, ObjectFactory *factory, JSHandle<GlobalEnv> globalEnv)
1125 {
1126     INTERPRETER_TRACE(thread, CreateEmptyArray);
1127     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1128 
1129     JSHandle<JSFunction> builtinObj(globalEnv->GetArrayFunction());
1130     JSHandle<JSObject> arr = factory->NewJSObjectByConstructor(builtinObj, JSHandle<JSTaggedValue>(builtinObj));
1131     return arr.GetTaggedValue();
1132 }
1133 
CreateEmptyObject(JSThread * thread,ObjectFactory * factory,JSHandle<GlobalEnv> globalEnv)1134 JSTaggedValue SlowRuntimeStub::CreateEmptyObject(JSThread *thread, ObjectFactory *factory,
1135                                                  JSHandle<GlobalEnv> globalEnv)
1136 {
1137     INTERPRETER_TRACE(thread, CreateEmptyObject);
1138     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1139 
1140     JSHandle<JSFunction> builtinObj(globalEnv->GetObjectFunction());
1141     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(builtinObj, JSHandle<JSTaggedValue>(builtinObj));
1142     return obj.GetTaggedValue();
1143 }
1144 
CreateObjectWithBuffer(JSThread * thread,ObjectFactory * factory,JSObject * literal)1145 JSTaggedValue SlowRuntimeStub::CreateObjectWithBuffer(JSThread *thread, ObjectFactory *factory, JSObject *literal)
1146 {
1147     INTERPRETER_TRACE(thread, CreateObjectWithBuffer);
1148     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1149 
1150     JSHandle<JSObject> obj(thread, literal);
1151     JSHandle<JSObject> objLiteral = factory->CloneObjectLiteral(obj);
1152     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1153 
1154     return objLiteral.GetTaggedValue();
1155 }
1156 
CreateObjectHavingMethod(JSThread * thread,ObjectFactory * factory,JSObject * literal,JSTaggedValue env,ConstantPool * constpool)1157 JSTaggedValue SlowRuntimeStub::CreateObjectHavingMethod(JSThread *thread, ObjectFactory *factory, JSObject *literal,
1158                                                         JSTaggedValue env, ConstantPool *constpool)
1159 {
1160     INTERPRETER_TRACE(thread, CreateObjectHavingMethod);
1161     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1162 
1163     JSHandle<JSObject> obj(thread, literal);
1164     JSHandle<JSObject> objLiteral = factory->CloneObjectLiteral(
1165         obj, JSHandle<JSTaggedValue>(thread, env), JSHandle<JSTaggedValue>(thread, JSTaggedValue(constpool)));
1166     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1167 
1168     return objLiteral.GetTaggedValue();
1169 }
1170 
SetObjectWithProto(JSThread * thread,JSTaggedValue proto,JSTaggedValue obj)1171 JSTaggedValue SlowRuntimeStub::SetObjectWithProto(JSThread *thread, JSTaggedValue proto, JSTaggedValue obj)
1172 {
1173     INTERPRETER_TRACE(thread, SetObjectWithProto);
1174     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1175 
1176     if (!proto.IsECMAObject() && !proto.IsNull()) {
1177         return JSTaggedValue::False();
1178     }
1179     JSHandle<JSTaggedValue> protoHandle(thread, proto);
1180     JSHandle<JSObject> objHandle(thread, obj);
1181     JSObject::SetPrototype(thread, objHandle, protoHandle);
1182     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1183     return JSTaggedValue::True();
1184 }
1185 
IterNext(JSThread * thread,JSTaggedValue iter)1186 JSTaggedValue SlowRuntimeStub::IterNext(JSThread *thread, JSTaggedValue iter)
1187 {
1188     INTERPRETER_TRACE(thread, IterNext);
1189     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1190 
1191     JSHandle<JSTaggedValue> iterHandle(thread, iter);
1192     JSHandle<JSObject> resultObj = JSIterator::IteratorNext(thread, iterHandle);
1193     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1194     return resultObj.GetTaggedValue();
1195 }
1196 
CloseIterator(JSThread * thread,JSTaggedValue iter)1197 JSTaggedValue SlowRuntimeStub::CloseIterator(JSThread *thread, JSTaggedValue iter)
1198 {
1199     INTERPRETER_TRACE(thread, CloseIterator);
1200     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1201 
1202     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1203     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1204 
1205     JSHandle<JSTaggedValue> iterHandle(thread, iter);
1206     JSHandle<JSTaggedValue> record;
1207     if (thread->HasPendingException()) {
1208         record = JSHandle<JSTaggedValue>(factory->NewCompletionRecord(
1209             CompletionRecordType::THROW, JSHandle<JSTaggedValue>(thread, thread->GetException())));
1210     } else {
1211         JSHandle<JSTaggedValue> undefinedVal = globalConst->GetHandledUndefined();
1212         record = JSHandle<JSTaggedValue>(factory->NewCompletionRecord(CompletionRecordType::NORMAL, undefinedVal));
1213     }
1214     JSHandle<JSTaggedValue> result = JSIterator::IteratorClose(thread, iterHandle, record);
1215     if (result->IsCompletionRecord()) {
1216         return CompletionRecord::Cast(result->GetTaggedObject())->GetValue();
1217     }
1218     return result.GetTaggedValue();
1219 }
1220 
ImportModule(JSThread * thread,JSTaggedValue moduleName)1221 JSTaggedValue SlowRuntimeStub::ImportModule([[maybe_unused]] JSThread *thread,
1222                                             [[maybe_unused]] JSTaggedValue moduleName)
1223 {
1224     INTERPRETER_TRACE(thread, ImportModule);
1225     [[maybe_unused]] EcmaHandleScope scope(thread);
1226     JSHandle<JSTaggedValue> name(thread, moduleName);
1227     JSHandle<JSTaggedValue> module = thread->GetEcmaVM()->GetModuleByName(name);
1228     return module.GetTaggedValue();  // return moduleRef
1229 }
1230 
StModuleVar(JSThread * thread,JSTaggedValue exportName,JSTaggedValue exportObj)1231 void SlowRuntimeStub::StModuleVar([[maybe_unused]] JSThread *thread, [[maybe_unused]] JSTaggedValue exportName,
1232                                   [[maybe_unused]] JSTaggedValue exportObj)
1233 {
1234     INTERPRETER_TRACE(thread, StModuleVar);
1235     [[maybe_unused]] EcmaHandleScope scope(thread);
1236     JSHandle<JSTaggedValue> name(thread, exportName);
1237     JSHandle<JSTaggedValue> value(thread, exportObj);
1238     thread->GetEcmaVM()->GetModuleManager()->AddModuleItem(thread, name, value);
1239 }
1240 
CopyModule(JSThread * thread,JSTaggedValue srcModule)1241 void SlowRuntimeStub::CopyModule(JSThread *thread, JSTaggedValue srcModule)
1242 {
1243     INTERPRETER_TRACE(thread, CopyModule);
1244     [[maybe_unused]] EcmaHandleScope scope(thread);
1245     JSHandle<JSTaggedValue> srcModuleObj(thread, srcModule);
1246     thread->GetEcmaVM()->GetModuleManager()->CopyModule(thread, srcModuleObj);
1247 }
1248 
LdModvarByName(JSThread * thread,JSTaggedValue moduleObj,JSTaggedValue itemName)1249 JSTaggedValue SlowRuntimeStub::LdModvarByName([[maybe_unused]] JSThread *thread,
1250                                               [[maybe_unused]] JSTaggedValue moduleObj,
1251                                               [[maybe_unused]] JSTaggedValue itemName)
1252 {
1253     INTERPRETER_TRACE(thread, LdModvarByName);
1254     [[maybe_unused]] EcmaHandleScope scope(thread);
1255     JSHandle<JSTaggedValue> module(thread, moduleObj);
1256     JSHandle<JSTaggedValue> item(thread, itemName);
1257     JSHandle<JSTaggedValue> moduleVar = thread->GetEcmaVM()->GetModuleManager()->GetModuleItem(thread, module, item);
1258     return moduleVar.GetTaggedValue();
1259 }
1260 
CreateRegExpWithLiteral(JSThread * thread,JSTaggedValue pattern,uint8_t flags)1261 JSTaggedValue SlowRuntimeStub::CreateRegExpWithLiteral(JSThread *thread, JSTaggedValue pattern, uint8_t flags)
1262 {
1263     INTERPRETER_TRACE(thread, CreateRegExpWithLiteral);
1264     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1265 
1266     JSHandle<JSTaggedValue> patternHandle(thread, pattern);
1267     JSHandle<JSTaggedValue> flagsHandle(thread, JSTaggedValue(flags));
1268 
1269     return builtins::BuiltinsRegExp::RegExpCreate(thread, patternHandle, flagsHandle);
1270 }
1271 
CreateArrayWithBuffer(JSThread * thread,ObjectFactory * factory,JSArray * literal)1272 JSTaggedValue SlowRuntimeStub::CreateArrayWithBuffer(JSThread *thread, ObjectFactory *factory, JSArray *literal)
1273 {
1274     INTERPRETER_TRACE(thread, CreateArrayWithBuffer);
1275     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1276 
1277     JSHandle<JSArray> array(thread, literal);
1278     JSHandle<JSArray> arrLiteral = factory->CloneArrayLiteral(array);
1279     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1280 
1281     return arrLiteral.GetTaggedValue();
1282 }
1283 
GetTemplateObject(JSThread * thread,JSTaggedValue literal)1284 JSTaggedValue SlowRuntimeStub::GetTemplateObject(JSThread *thread, JSTaggedValue literal)
1285 {
1286     INTERPRETER_TRACE(thread, GetTemplateObject);
1287     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1288 
1289     JSHandle<JSTaggedValue> templateLiteral(thread, literal);
1290     JSHandle<JSTaggedValue> templateObj = TemplateString::GetTemplateObject(thread, templateLiteral);
1291     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1292     return templateObj.GetTaggedValue();
1293 }
1294 
GetNextPropName(JSThread * thread,JSTaggedValue iter)1295 JSTaggedValue SlowRuntimeStub::GetNextPropName(JSThread *thread, JSTaggedValue iter)
1296 {
1297     INTERPRETER_TRACE(thread, GetNextPropName);
1298     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1299 
1300     JSHandle<JSTaggedValue> iterator(thread, iter);
1301     ASSERT(iterator->IsForinIterator());
1302     std::pair<JSTaggedValue, bool> res =
1303         JSForInIterator::NextInternal(thread, JSHandle<JSForInIterator>::Cast(iterator));
1304     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1305     return res.first;
1306 }
1307 
CopyDataProperties(JSThread * thread,JSTaggedValue dst,JSTaggedValue src)1308 JSTaggedValue SlowRuntimeStub::CopyDataProperties(JSThread *thread, JSTaggedValue dst, JSTaggedValue src)
1309 {
1310     INTERPRETER_TRACE(thread, CopyDataProperties);
1311     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1312 
1313     JSHandle<JSTaggedValue> dstHandle(thread, dst);
1314     JSHandle<JSTaggedValue> srcHandle(thread, src);
1315     if (!srcHandle->IsNull() && !srcHandle->IsUndefined()) {
1316         JSHandle<TaggedArray> keys = JSTaggedValue::GetOwnPropertyKeys(thread, srcHandle);
1317         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1318 
1319         JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1320         uint32_t keysLen = keys->GetLength();
1321         for (uint32_t i = 0; i < keysLen; i++) {
1322             PropertyDescriptor desc(thread);
1323             key.Update(keys->Get(i));
1324             bool success = JSTaggedValue::GetOwnProperty(thread, srcHandle, key, desc);
1325             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1326 
1327             if (success && desc.IsEnumerable()) {
1328                 JSTaggedValue::DefineOwnProperty(thread, dstHandle, key, desc);
1329                 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1330             }
1331         }
1332     }
1333     return dstHandle.GetTaggedValue();
1334 }
1335 
GetIteratorNext(JSThread * thread,JSTaggedValue obj,JSTaggedValue method)1336 JSTaggedValue SlowRuntimeStub::GetIteratorNext(JSThread *thread, JSTaggedValue obj, JSTaggedValue method)
1337 {
1338     INTERPRETER_TRACE(thread, GetIteratorNext);
1339     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1340 
1341     JSHandle<JSTaggedValue> iter(thread, obj);
1342     JSHandle<JSTaggedValue> next(thread, method);
1343 
1344     ASSERT(next->IsCallable());
1345     JSTaggedValue ret = JSFunction::Call(thread, next, iter, 0, nullptr);
1346     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1347     if (!ret.IsECMAObject()) {
1348         return ThrowTypeError(thread, "the Iterator is not an ecmaobject.");
1349     }
1350     return ret;
1351 }
1352 
GetUnmapedArgs(JSThread * thread,JSTaggedType * sp,uint32_t actualNumArgs,uint32_t startIdx)1353 JSTaggedValue SlowRuntimeStub::GetUnmapedArgs(JSThread *thread, JSTaggedType *sp, uint32_t actualNumArgs,
1354                                               uint32_t startIdx)
1355 {
1356     INTERPRETER_TRACE(thread, GetUnmapedArgs);
1357     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1358 
1359     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1360     JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
1361     JSHandle<TaggedArray> argumentsList = factory->NewTaggedArray(actualNumArgs);
1362     for (uint32_t i = 0; i < actualNumArgs; ++i) {
1363         argumentsList->Set(thread, i,
1364                            JSTaggedValue(sp[startIdx + i]));  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1365     }
1366     // 1. Let len be the number of elements in argumentsList
1367     int32_t len = argumentsList->GetLength();
1368     // 2. Let obj be ObjectCreate(%ObjectPrototype%, «[[ParameterMap]]»).
1369     // 3. Set obj’s [[ParameterMap]] internal slot to undefined.
1370     JSHandle<JSArguments> obj = factory->NewJSArguments();
1371     // 4. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor{[[Value]]: len, [[Writable]]: true,
1372     // [[Enumerable]]: false, [[Configurable]]: true}).
1373     obj->SetPropertyInlinedProps(thread, JSArguments::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(len));
1374     // 5. Let index be 0.
1375     // 6. Repeat while index < len,
1376     //    a. Let val be argumentsList[index].
1377     //    b. Perform CreateDataProperty(obj, ToString(index), val).
1378     //    c. Let index be index + 1
1379     obj->SetElements(thread, argumentsList.GetTaggedValue());
1380     // 7. Perform DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor
1381     // {[[Value]]:%ArrayProto_values%,
1382     // [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}).
1383     obj->SetPropertyInlinedProps(thread, JSArguments::ITERATOR_INLINE_PROPERTY_INDEX,
1384                                  globalEnv->GetArrayProtoValuesFunction().GetTaggedValue());
1385     // 8. Perform DefinePropertyOrThrow(obj, "caller", PropertyDescriptor {[[Get]]: %ThrowTypeError%,
1386     // [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}).
1387     JSHandle<JSTaggedValue> throwFunction = globalEnv->GetThrowTypeError();
1388     JSHandle<AccessorData> accessor = factory->NewAccessorData();
1389     accessor->SetGetter(thread, throwFunction);
1390     accessor->SetSetter(thread, throwFunction);
1391     obj->SetPropertyInlinedProps(thread, JSArguments::CALLER_INLINE_PROPERTY_INDEX, accessor.GetTaggedValue());
1392     // 9. Perform DefinePropertyOrThrow(obj, "callee", PropertyDescriptor {[[Get]]: %ThrowTypeError%,
1393     // [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}).
1394     accessor = factory->NewAccessorData();
1395     accessor->SetGetter(thread, throwFunction);
1396     accessor->SetSetter(thread, throwFunction);
1397     obj->SetPropertyInlinedProps(thread, JSArguments::CALLEE_INLINE_PROPERTY_INDEX, accessor.GetTaggedValue());
1398     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1399     // 11. Return obj
1400     return obj.GetTaggedValue();
1401 }
1402 
CopyRestArgs(JSThread * thread,JSTaggedType * sp,uint32_t restNumArgs,uint32_t startIdx)1403 JSTaggedValue SlowRuntimeStub::CopyRestArgs(JSThread *thread, JSTaggedType *sp, uint32_t restNumArgs, uint32_t startIdx)
1404 {
1405     INTERPRETER_TRACE(thread, Copyrestargs);
1406     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1407 
1408     JSHandle<JSTaggedValue> restArray = JSArray::ArrayCreate(thread, JSTaggedNumber(restNumArgs));
1409 
1410     JSMutableHandle<JSTaggedValue> element(thread, JSTaggedValue::Undefined());
1411     for (uint32_t i = 0; i < restNumArgs; ++i) {
1412         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1413         element.Update(JSTaggedValue(sp[startIdx + i]));
1414         JSObject::SetProperty(thread, restArray, i, element, true);
1415     }
1416     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1417     return restArray.GetTaggedValue();
1418 }
1419 
GetIterator(JSThread * thread,JSTaggedValue obj)1420 JSTaggedValue SlowRuntimeStub::GetIterator(JSThread *thread, JSTaggedValue obj)
1421 {
1422     INTERPRETER_TRACE(thread, GetIterator);
1423     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1424     EcmaVM *vm = thread->GetEcmaVM();
1425     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1426     JSHandle<JSTaggedValue> objHandle(thread, obj);
1427     JSHandle<JSTaggedValue> valuesFunc =
1428         JSTaggedValue::GetProperty(thread, objHandle, env->GetIteratorSymbol()).GetValue();
1429     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1430     if (!valuesFunc->IsCallable()) {
1431         return valuesFunc.GetTaggedValue();
1432     }
1433     JSHandle<JSTaggedValue> newTarget(thread, JSTaggedValue::Undefined());
1434     InternalCallParams *params = thread->GetInternalCallParams();
1435     params->MakeEmptyArgv();
1436     JSTaggedValue res = InvokeJsFunction(thread, JSHandle<JSFunction>(valuesFunc), objHandle, newTarget, params);
1437 
1438     return res;
1439 }
1440 
DefineGetterSetterByValue(JSThread * thread,JSTaggedValue obj,JSTaggedValue prop,JSTaggedValue getter,JSTaggedValue setter,bool flag)1441 JSTaggedValue SlowRuntimeStub::DefineGetterSetterByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop,
1442                                                          JSTaggedValue getter, JSTaggedValue setter, bool flag)
1443 {
1444     INTERPRETER_TRACE(thread, DefineGetterSetterByValue);
1445     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1446     JSHandle<JSObject> objHandle(thread, obj);
1447     JSHandle<JSTaggedValue> propHandle(thread, prop);
1448 
1449     JSHandle<JSTaggedValue> getterHandle(thread, getter);
1450     JSHandle<JSTaggedValue> setterHandle(thread, setter);
1451     JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, propHandle);
1452 
1453     auto globalConst = thread->GlobalConstants();
1454     if (objHandle.GetTaggedValue().IsClassConstructor() &&
1455         JSTaggedValue::SameValue(propKey, globalConst->GetHandledPrototypeString())) {
1456         return ThrowTypeError(
1457             thread,
1458             "In a class, computed property names for static getter that are named 'prototype' throw a TypeError");
1459     }
1460 
1461     if (flag) {
1462         if (!getterHandle->IsUndefined()) {
1463             if (propKey->IsNumber()) {
1464                 propKey =
1465                     JSHandle<JSTaggedValue>::Cast(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()));
1466             }
1467             JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(getterHandle), propKey,
1468                                             JSHandle<JSTaggedValue>(thread, globalConst->GetGetString()));
1469         }
1470 
1471         if (!setterHandle->IsUndefined()) {
1472             if (propKey->IsNumber()) {
1473                 propKey =
1474                     JSHandle<JSTaggedValue>::Cast(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()));
1475             }
1476             JSFunctionBase::SetFunctionName(thread, JSHandle<JSFunctionBase>::Cast(setterHandle), propKey,
1477                                             JSHandle<JSTaggedValue>(thread, globalConst->GetSetString()));
1478         }
1479     }
1480 
1481     // set accessor
1482     bool enumerable =
1483         !(objHandle.GetTaggedValue().IsClassPrototype() || objHandle.GetTaggedValue().IsClassConstructor());
1484     PropertyDescriptor desc(thread, true, enumerable, true);
1485     if (!getterHandle->IsUndefined()) {
1486         JSHandle<JSFunction>::Cast(getterHandle)->SetFunctionKind(FunctionKind::GETTER_FUNCTION);
1487         desc.SetGetter(getterHandle);
1488     }
1489     if (!setterHandle->IsUndefined()) {
1490         JSHandle<JSFunction>::Cast(setterHandle)->SetFunctionKind(FunctionKind::SETTER_FUNCTION);
1491         desc.SetSetter(setterHandle);
1492     }
1493     JSObject::DefineOwnProperty(thread, objHandle, propKey, desc);
1494 
1495     return objHandle.GetTaggedValue();
1496 }
1497 
LdObjByIndex(JSThread * thread,JSTaggedValue obj,uint32_t idx,bool callGetter,JSTaggedValue receiver)1498 JSTaggedValue SlowRuntimeStub::LdObjByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, bool callGetter,
1499                                             JSTaggedValue receiver)
1500 {
1501     INTERPRETER_TRACE(thread, LdObjByIndexDyn);
1502     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1503 
1504     JSTaggedValue res;
1505     JSHandle<JSTaggedValue> objHandle(thread, obj);
1506     if (callGetter) {
1507         res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), objHandle);
1508     } else {
1509         res = JSTaggedValue::GetProperty(thread, objHandle, idx).GetValue().GetTaggedValue();
1510     }
1511     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1512     return res;
1513 }
1514 
StObjByIndex(JSThread * thread,JSTaggedValue obj,uint32_t idx,JSTaggedValue value)1515 JSTaggedValue SlowRuntimeStub::StObjByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, JSTaggedValue value)
1516 {
1517     INTERPRETER_TRACE(thread, StObjByIndexDyn);
1518     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1519 
1520     JSTaggedValue::SetProperty(thread, JSHandle<JSTaggedValue>(thread, obj), idx,
1521                                JSHandle<JSTaggedValue>(thread, value), true);
1522     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1523     return JSTaggedValue::True();
1524 }
1525 
LdObjByName(JSThread * thread,JSTaggedValue obj,JSTaggedValue prop,bool callGetter,JSTaggedValue receiver)1526 JSTaggedValue SlowRuntimeStub::LdObjByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, bool callGetter,
1527                                            JSTaggedValue receiver)
1528 {
1529     INTERPRETER_TRACE(thread, LdObjByNameDyn);
1530     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1531 
1532     JSHandle<JSTaggedValue> objHandle(thread, obj);
1533     JSTaggedValue res;
1534     if (callGetter) {
1535         res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), objHandle);
1536     } else {
1537         JSHandle<JSTaggedValue> propHandle(thread, prop);
1538         res = JSTaggedValue::GetProperty(thread, objHandle, propHandle).GetValue().GetTaggedValue();
1539     }
1540     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1541     return res;
1542 }
1543 
StObjByName(JSThread * thread,JSTaggedValue obj,JSTaggedValue prop,JSTaggedValue value)1544 JSTaggedValue SlowRuntimeStub::StObjByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, JSTaggedValue value)
1545 {
1546     INTERPRETER_TRACE(thread, StObjByNameDyn);
1547     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1548 
1549     JSHandle<JSTaggedValue> objHandle(thread, obj);
1550     JSHandle<JSTaggedValue> propHandle(thread, prop);
1551     JSHandle<JSTaggedValue> valueHandle(thread, value);
1552     JSTaggedValue::SetProperty(thread, objHandle, propHandle, valueHandle, true);
1553     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1554     return JSTaggedValue::True();
1555 }
1556 
LdObjByValue(JSThread * thread,JSTaggedValue obj,JSTaggedValue prop,bool callGetter,JSTaggedValue receiver)1557 JSTaggedValue SlowRuntimeStub::LdObjByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, bool callGetter,
1558                                             JSTaggedValue receiver)
1559 {
1560     INTERPRETER_TRACE(thread, LdObjByValueDyn);
1561     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1562 
1563     JSHandle<JSTaggedValue> objHandle(thread, obj);
1564     JSTaggedValue res;
1565     if (callGetter) {
1566         res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), objHandle);
1567     } else {
1568         JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread, JSHandle<JSTaggedValue>(thread, prop));
1569         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1570         res = JSTaggedValue::GetProperty(thread, objHandle, propKey).GetValue().GetTaggedValue();
1571     }
1572     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1573     return res;
1574 }
1575 
StObjByValue(JSThread * thread,JSTaggedValue obj,JSTaggedValue prop,JSTaggedValue value)1576 JSTaggedValue SlowRuntimeStub::StObjByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop,
1577                                             JSTaggedValue value)
1578 {
1579     INTERPRETER_TRACE(thread, StObjByValueDyn);
1580     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1581 
1582     JSHandle<JSTaggedValue> objHandle(thread, obj);
1583     JSHandle<JSTaggedValue> propHandle(thread, prop);
1584     JSHandle<JSTaggedValue> valueHandle(thread, value);
1585     JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, propHandle));
1586 
1587     // strict mode is true
1588     JSTaggedValue::SetProperty(thread, objHandle, propKey, valueHandle, true);
1589     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1590     return JSTaggedValue::True();
1591 }
1592 
TryLdGlobalByName(JSThread * thread,JSTaggedValue global,JSTaggedValue prop)1593 JSTaggedValue SlowRuntimeStub::TryLdGlobalByName(JSThread *thread, JSTaggedValue global, JSTaggedValue prop)
1594 {
1595     INTERPRETER_TRACE(thread, Trygetobjprop);
1596     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1597 
1598     JSHandle<JSTaggedValue> obj(thread, global.GetTaggedObject()->GetClass()->GetPrototype());
1599     JSHandle<JSTaggedValue> propHandle(thread, prop);
1600     OperationResult res = JSTaggedValue::GetProperty(thread, obj, propHandle);
1601     if (!res.GetPropertyMetaData().IsFound()) {
1602         return ThrowReferenceError(thread, prop, " is not defined");
1603     }
1604     return res.GetValue().GetTaggedValue();
1605 }
1606 
TryStGlobalByName(JSThread * thread,JSTaggedValue prop)1607 JSTaggedValue SlowRuntimeStub::TryStGlobalByName(JSThread *thread, JSTaggedValue prop)
1608 {
1609     INTERPRETER_TRACE(thread, TryStGlobalByName);
1610     // If fast path is fail, not need slow path, just throw error.
1611     return ThrowReferenceError(thread, prop, " is not defined");
1612 }
1613 
LdGlobalVar(JSThread * thread,JSTaggedValue global,JSTaggedValue prop)1614 JSTaggedValue SlowRuntimeStub::LdGlobalVar(JSThread *thread, JSTaggedValue global, JSTaggedValue prop)
1615 {
1616     INTERPRETER_TRACE(thread, LdGlobalVar);
1617     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1618 
1619     JSHandle<JSTaggedValue> objHandle(thread, global.GetTaggedObject()->GetClass()->GetPrototype());
1620     JSHandle<JSTaggedValue> propHandle(thread, prop);
1621     OperationResult res = JSTaggedValue::GetProperty(thread, objHandle, propHandle);
1622     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1623     return res.GetValue().GetTaggedValue();
1624 }
1625 
StGlobalVar(JSThread * thread,JSTaggedValue prop,JSTaggedValue value)1626 JSTaggedValue SlowRuntimeStub::StGlobalVar(JSThread *thread, JSTaggedValue prop, JSTaggedValue value)
1627 {
1628     INTERPRETER_TRACE(thread, StGlobalVar);
1629     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1630 
1631     JSHandle<JSTaggedValue> global(thread, thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject());
1632     JSHandle<JSTaggedValue> propHandle(thread, prop);
1633     JSHandle<JSTaggedValue> valueHandle(thread, value);
1634 
1635     JSObject::GlobalSetProperty(thread, propHandle, valueHandle, true);
1636     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1637     return JSTaggedValue::True();
1638 }
1639 
TryUpdateGlobalRecord(JSThread * thread,JSTaggedValue prop,JSTaggedValue value)1640 JSTaggedValue SlowRuntimeStub::TryUpdateGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value)
1641 {
1642     INTERPRETER_TRACE(thread, TryUpdateGlobalRecord);
1643     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1644 
1645     EcmaVM *vm = thread->GetEcmaVM();
1646     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1647     GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
1648     int entry = dict->FindEntry(prop);
1649     ASSERT(entry != -1);
1650 
1651     if (dict->GetAttributes(entry).IsConstProps()) {
1652         return ThrowSyntaxError(thread, "const variable can not be modified");
1653     }
1654 
1655     PropertyBox *box = dict->GetBox(entry);
1656     box->SetValue(thread, value);
1657     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1658     return JSTaggedValue::True();
1659 }
1660 
1661 // return box
LdGlobalRecord(JSThread * thread,JSTaggedValue key)1662 JSTaggedValue SlowRuntimeStub::LdGlobalRecord(JSThread *thread, JSTaggedValue key)
1663 {
1664     INTERPRETER_TRACE(thread, LdGlobalRecord);
1665     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1666 
1667     EcmaVM *vm = thread->GetEcmaVM();
1668     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1669     GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
1670     int entry = dict->FindEntry(key);
1671     if (entry != -1) {
1672         return JSTaggedValue(dict->GetBox(entry));
1673     }
1674     return JSTaggedValue::Undefined();
1675 }
1676 
StGlobalRecord(JSThread * thread,JSTaggedValue prop,JSTaggedValue value,bool isConst)1677 JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value, bool isConst)
1678 {
1679     INTERPRETER_TRACE(thread, StGlobalRecord);
1680     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1681 
1682     EcmaVM *vm = thread->GetEcmaVM();
1683     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1684     GlobalDictionary *dict = GlobalDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject());
1685 
1686     // cross files global record name binding judgment
1687     int entry = dict->FindEntry(prop);
1688     if (entry != -1) {
1689         return ThrowSyntaxError(thread, "Duplicate identifier");
1690     }
1691 
1692     PropertyAttributes attributes;
1693     if (isConst) {
1694         attributes.SetIsConstProps(true);
1695     }
1696     JSHandle<JSTaggedValue> propHandle(thread, prop);
1697     JSHandle<JSTaggedValue> valueHandle(thread, value);
1698     JSHandle<GlobalDictionary> dictHandle(thread, dict);
1699 
1700     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1701     JSHandle<PropertyBox> box = factory->NewPropertyBox(valueHandle);
1702     PropertyBoxType boxType = valueHandle->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
1703     attributes.SetBoxType(boxType);
1704 
1705     dict = *GlobalDictionary::PutIfAbsent(thread, dictHandle, propHandle, JSHandle<JSTaggedValue>(box), attributes);
1706     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1707     env->SetGlobalRecord(thread, JSTaggedValue(dict));
1708     return JSTaggedValue::True();
1709 }
1710 
ThrowReferenceError(JSThread * thread,JSTaggedValue prop,const char * desc)1711 JSTaggedValue SlowRuntimeStub::ThrowReferenceError(JSThread *thread, JSTaggedValue prop, const char *desc)
1712 {
1713     INTERPRETER_TRACE(thread, ThrowReferenceError);
1714     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1715     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1716     JSHandle<EcmaString> propName = JSTaggedValue::ToString(thread, JSHandle<JSTaggedValue>(thread, prop));
1717     ASSERT_NO_ABRUPT_COMPLETION(thread);
1718     JSHandle<EcmaString> info = factory->NewFromString(desc);
1719     JSHandle<EcmaString> msg = factory->ConcatFromString(propName, info);
1720     THROW_NEW_ERROR_AND_RETURN_VALUE(thread,
1721                                      factory->NewJSError(base::ErrorType::REFERENCE_ERROR, msg).GetTaggedValue(),
1722                                      JSTaggedValue::Exception());
1723 }
1724 
ThrowTypeError(JSThread * thread,const char * message)1725 JSTaggedValue SlowRuntimeStub::ThrowTypeError(JSThread *thread, const char *message)
1726 {
1727     INTERPRETER_TRACE(thread, ThrowTypeError);
1728     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1729     ASSERT_NO_ABRUPT_COMPLETION(thread);
1730     THROW_TYPE_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception());
1731 }
1732 
ThrowSyntaxError(JSThread * thread,const char * message)1733 JSTaggedValue SlowRuntimeStub::ThrowSyntaxError(JSThread *thread, const char *message)
1734 {
1735     INTERPRETER_TRACE(thread, ThrowSyntaxError);
1736     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1737     ASSERT_NO_ABRUPT_COMPLETION(thread);
1738     THROW_SYNTAX_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception());
1739 }
1740 
StArraySpread(JSThread * thread,JSTaggedValue dst,JSTaggedValue index,JSTaggedValue src)1741 JSTaggedValue SlowRuntimeStub::StArraySpread(JSThread *thread, JSTaggedValue dst, JSTaggedValue index,
1742                                              JSTaggedValue src)
1743 {
1744     INTERPRETER_TRACE(thread, StArraySpread);
1745     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1746 
1747     JSHandle<JSTaggedValue> dstHandle(thread, dst);
1748     JSHandle<JSTaggedValue> srcHandle(thread, src);
1749     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1750     ASSERT(dstHandle->IsJSArray() && !srcHandle->IsNull() && !srcHandle->IsUndefined());
1751     if (srcHandle->IsString()) {
1752         JSHandle<EcmaString> srcString = JSTaggedValue::ToString(thread, srcHandle);
1753         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1754         uint32_t dstLen = index.GetInt();
1755         uint32_t strLen = srcString->GetLength();
1756         for (uint32_t i = 0; i < strLen; i++) {
1757             uint16_t res = srcString->At<false>(i);
1758             JSHandle<JSTaggedValue> strValue(factory->NewFromUtf16Literal(&res, 1));
1759             JSTaggedValue::SetProperty(thread, dstHandle, dstLen + i, strValue, true);
1760             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1761         }
1762         return JSTaggedValue(dstLen + strLen);
1763     }
1764 
1765     JSHandle<JSTaggedValue> iter;
1766     auto globalConst = thread->GlobalConstants();
1767     if (srcHandle->IsJSArrayIterator() || srcHandle->IsJSMapIterator() || srcHandle->IsJSSetIterator() ||
1768         srcHandle->IsIterator()) {
1769         iter = srcHandle;
1770     } else if (srcHandle->IsJSArray() || srcHandle->IsJSMap() || srcHandle->IsTypedArray() || srcHandle->IsJSSet()) {
1771         JSHandle<JSTaggedValue> valuesStr = globalConst->GetHandledValuesString();
1772         JSHandle<JSTaggedValue> valuesMethod = JSObject::GetMethod(thread, srcHandle, valuesStr);
1773         iter = JSIterator::GetIterator(thread, srcHandle, valuesMethod);
1774         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1775     } else {
1776         iter = JSIterator::GetIterator(thread, srcHandle);
1777         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1778     }
1779 
1780     JSMutableHandle<JSTaggedValue> indexHandle(thread, index);
1781     JSHandle<JSTaggedValue> valueStr = globalConst->GetHandledValueString();
1782     PropertyDescriptor desc(thread);
1783     JSHandle<JSTaggedValue> iterResult;
1784     do {
1785         iterResult = JSIterator::IteratorStep(thread, iter);
1786         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1787         if (iterResult->IsFalse()) {
1788             break;
1789         }
1790         bool success = JSTaggedValue::GetOwnProperty(thread, iterResult, valueStr, desc);
1791         if (success && desc.IsEnumerable()) {
1792             JSTaggedValue::DefineOwnProperty(thread, dstHandle, indexHandle, desc);
1793             int tmp = indexHandle->GetInt();
1794             indexHandle.Update(JSTaggedValue(tmp + 1));
1795         }
1796     } while (true);
1797 
1798     return indexHandle.GetTaggedValue();
1799 }
1800 
DefineGeneratorFunc(JSThread * thread,JSFunction * func)1801 JSTaggedValue SlowRuntimeStub::DefineGeneratorFunc(JSThread *thread, JSFunction *func)
1802 {
1803     INTERPRETER_TRACE(thread, DefineGeneratorFunc);
1804     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1805     auto method = func->GetCallTarget();
1806 
1807     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1808     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1809     JSHandle<JSFunction> jsFunc = factory->NewJSGeneratorFunction(method);
1810     ASSERT_NO_ABRUPT_COMPLETION(thread);
1811 
1812     // 26.3.4.3 prototype
1813     // Whenever a GeneratorFunction instance is created another ordinary object is also created and
1814     // is the initial value of the generator function's "prototype" property.
1815     JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
1816     JSHandle<JSObject> initialGeneratorFuncPrototype =
1817         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
1818     JSObject::SetPrototype(thread, initialGeneratorFuncPrototype, env->GetGeneratorPrototype());
1819     ASSERT_NO_ABRUPT_COMPLETION(thread);
1820     jsFunc->SetProtoOrDynClass(thread, initialGeneratorFuncPrototype);
1821 
1822     return jsFunc.GetTaggedValue();
1823 }
1824 
DefineAsyncFunc(JSThread * thread,JSFunction * func)1825 JSTaggedValue SlowRuntimeStub::DefineAsyncFunc(JSThread *thread, JSFunction *func)
1826 {
1827     INTERPRETER_TRACE(thread, DefineAsyncFunc);
1828     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1829     auto method = func->GetCallTarget();
1830 
1831     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1832     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1833     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetAsyncFunctionClass());
1834     JSHandle<JSFunction> jsFunc = factory->NewJSFunctionByDynClass(method, dynclass, FunctionKind::ASYNC_FUNCTION);
1835     ASSERT_NO_ABRUPT_COMPLETION(thread);
1836     return jsFunc.GetTaggedValue();
1837 }
1838 
DefineNCFuncDyn(JSThread * thread,JSFunction * func)1839 JSTaggedValue SlowRuntimeStub::DefineNCFuncDyn(JSThread *thread, JSFunction *func)
1840 {
1841     INTERPRETER_TRACE(thread, DefineNCFuncDyn);
1842     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1843     auto method = func->GetCallTarget();
1844 
1845     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1846     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1847     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
1848     JSHandle<JSFunction> jsFunc = factory->NewJSFunctionByDynClass(method, dynclass, FunctionKind::ARROW_FUNCTION);
1849     ASSERT_NO_ABRUPT_COMPLETION(thread);
1850     return jsFunc.GetTaggedValue();
1851 }
1852 
DefinefuncDyn(JSThread * thread,JSFunction * func)1853 JSTaggedValue SlowRuntimeStub::DefinefuncDyn(JSThread *thread, JSFunction *func)
1854 {
1855     INTERPRETER_TRACE(thread, DefinefuncDyn);
1856     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1857     auto method = func->GetCallTarget();
1858 
1859     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1860     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1861     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto());
1862     JSHandle<JSFunction> jsFunc = factory->NewJSFunctionByDynClass(method, dynclass, FunctionKind::BASE_CONSTRUCTOR);
1863     ASSERT_NO_ABRUPT_COMPLETION(thread);
1864     return jsFunc.GetTaggedValue();
1865 }
1866 
SuperCall(JSThread * thread,JSTaggedValue func,JSTaggedValue newTarget,uint16_t firstVRegIdx,uint16_t length)1867 JSTaggedValue SlowRuntimeStub::SuperCall(JSThread *thread, JSTaggedValue func, JSTaggedValue newTarget,
1868                                          uint16_t firstVRegIdx, uint16_t length)
1869 {
1870     INTERPRETER_TRACE(thread, SuperCall);
1871     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1872     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1873     InterpretedFrameHandler frameHandler(thread);
1874 
1875     JSHandle<JSTaggedValue> funcHandle(thread, func);
1876     JSHandle<JSTaggedValue> newTargetHandle(thread, newTarget);
1877 
1878     JSHandle<JSTaggedValue> superFunc(thread, JSHandle<JSObject>::Cast(funcHandle)->GetPrototype(thread));
1879     ASSERT(superFunc->IsJSFunction());
1880 
1881     JSHandle<TaggedArray> argv = factory->NewTaggedArray(length);
1882     for (size_t i = 0; i < length; ++i) {
1883         argv->Set(thread, i, frameHandler.GetVRegValue(firstVRegIdx + i));
1884     }
1885     InternalCallParams *arguments = thread->GetInternalCallParams();
1886     arguments->MakeArgList(*argv);
1887     JSTaggedValue result = JSFunction::Construct(thread, superFunc, length, arguments->GetArgv(), newTargetHandle);
1888     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1889 
1890     return result;
1891 }
1892 
SuperCallSpread(JSThread * thread,JSTaggedValue func,JSTaggedValue newTarget,JSTaggedValue array)1893 JSTaggedValue SlowRuntimeStub::SuperCallSpread(JSThread *thread, JSTaggedValue func, JSTaggedValue newTarget,
1894                                                JSTaggedValue array)
1895 {
1896     INTERPRETER_TRACE(thread, SuperCallSpread);
1897     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1898     InterpretedFrameHandler frameHandler(thread);
1899 
1900     JSHandle<JSTaggedValue> funcHandle(thread, func);
1901     JSHandle<JSTaggedValue> newTargetHandle(thread, newTarget);
1902     JSHandle<JSTaggedValue> jsArray(thread, array);
1903 
1904     JSHandle<JSTaggedValue> superFunc(thread, JSHandle<JSObject>::Cast(funcHandle)->GetPrototype(thread));
1905     ASSERT(superFunc->IsJSFunction());
1906 
1907     JSHandle<TaggedArray> argv(thread, GetCallSpreadArgs(thread, jsArray.GetTaggedValue()));
1908     InternalCallParams *arguments = thread->GetInternalCallParams();
1909     arguments->MakeArgList(*argv);
1910     JSTaggedValue result =
1911         JSFunction::Construct(thread, superFunc, argv->GetLength(), arguments->GetArgv(), newTargetHandle);
1912     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1913 
1914     return result;
1915 }
1916 
DefineMethod(JSThread * thread,JSFunction * func,JSTaggedValue homeObject)1917 JSTaggedValue SlowRuntimeStub::DefineMethod(JSThread *thread, JSFunction *func, JSTaggedValue homeObject)
1918 {
1919     INTERPRETER_TRACE(thread, DefineMethod);
1920     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1921     ASSERT(homeObject.IsECMAObject());
1922     JSHandle<JSTaggedValue> homeObjectHandle(thread, homeObject);
1923     auto method = func->GetCallTarget();
1924 
1925     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1926     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1927     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
1928     JSHandle<JSFunction> jsFunc = factory->NewJSFunctionByDynClass(method, dynclass, FunctionKind::NORMAL_FUNCTION);
1929     jsFunc->SetHomeObject(thread, homeObjectHandle);
1930     ASSERT_NO_ABRUPT_COMPLETION(thread);
1931     return jsFunc.GetTaggedValue();
1932 }
1933 
LdSuperByValue(JSThread * thread,JSTaggedValue obj,JSTaggedValue key,JSTaggedValue thisFunc)1934 JSTaggedValue SlowRuntimeStub::LdSuperByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key,
1935                                               JSTaggedValue thisFunc)
1936 {
1937     INTERPRETER_TRACE(thread, LdSuperByValue);
1938     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1939     ASSERT(thisFunc.IsJSFunction());
1940     // get Homeobject form function
1941     JSHandle<JSTaggedValue> homeObject(thread, JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject());
1942 
1943     if (obj.IsUndefined()) {
1944         return ThrowReferenceError(thread, obj, "this is uninitialized.");
1945     }
1946     JSHandle<JSTaggedValue> objHandle(thread, obj);
1947     JSHandle<JSTaggedValue> propHandle(thread, key);
1948 
1949     JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, propHandle));
1950     JSHandle<JSTaggedValue> superBase(thread, JSTaggedValue::GetSuperBase(thread, homeObject));
1951     JSTaggedValue::RequireObjectCoercible(thread, superBase);
1952     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1953 
1954     JSTaggedValue res = JSTaggedValue::GetProperty(thread, superBase, propKey, objHandle).GetValue().GetTaggedValue();
1955     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1956     return res;
1957 }
1958 
StSuperByValue(JSThread * thread,JSTaggedValue obj,JSTaggedValue key,JSTaggedValue value,JSTaggedValue thisFunc)1959 JSTaggedValue SlowRuntimeStub::StSuperByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key,
1960                                               JSTaggedValue value, JSTaggedValue thisFunc)
1961 {
1962     INTERPRETER_TRACE(thread, StSuperByValue);
1963     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1964     ASSERT(thisFunc.IsJSFunction());
1965     // get Homeobject form function
1966     JSHandle<JSTaggedValue> homeObject(thread, JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject());
1967 
1968     if (obj.IsUndefined()) {
1969         return ThrowReferenceError(thread, obj, "this is uninitialized.");
1970     }
1971     JSHandle<JSTaggedValue> objHandle(thread, obj);
1972     JSHandle<JSTaggedValue> propHandle(thread, key);
1973     JSHandle<JSTaggedValue> valueHandle(thread, value);
1974 
1975     JSHandle<JSTaggedValue> propKey(JSTaggedValue::ToPropertyKey(thread, propHandle));
1976     JSHandle<JSTaggedValue> superBase(thread, JSTaggedValue::GetSuperBase(thread, homeObject));
1977     JSTaggedValue::RequireObjectCoercible(thread, superBase);
1978     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1979 
1980     // check may_throw is false?
1981     JSTaggedValue::SetProperty(thread, superBase, propKey, valueHandle, objHandle, true);
1982     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1983     return JSTaggedValue::True();
1984 }
1985 
GetCallSpreadArgs(JSThread * thread,JSTaggedValue array)1986 JSTaggedValue SlowRuntimeStub::GetCallSpreadArgs(JSThread *thread, JSTaggedValue array)
1987 {
1988     INTERPRETER_TRACE(thread, GetCallSpreadArgs);
1989     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1990     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1991 
1992     JSHandle<JSTaggedValue> jsArray(thread, array);
1993     uint32_t argvMayMaxLength = JSHandle<JSArray>::Cast(jsArray)->GetArrayLength();
1994     JSHandle<TaggedArray> argv = factory->NewTaggedArray(argvMayMaxLength);
1995     JSHandle<JSTaggedValue> itor = JSIterator::GetIterator(thread, jsArray);
1996     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1997     JSMutableHandle<JSTaggedValue> next(thread, JSTaggedValue::Undefined());
1998     JSMutableHandle<JSTaggedValue> nextArg(thread, JSTaggedValue::Undefined());
1999     size_t argvIndex = 0;
2000     while (true) {
2001         next.Update(JSIterator::IteratorStep(thread, itor).GetTaggedValue());
2002         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2003         if (JSTaggedValue::SameValue(next.GetTaggedValue(), JSTaggedValue::False())) {
2004             break;
2005         }
2006         nextArg.Update(JSIterator::IteratorValue(thread, next).GetTaggedValue());
2007         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2008         argv->Set(thread, argvIndex++, nextArg);
2009     }
2010 
2011     argv = factory->CopyArray(argv, argvMayMaxLength, argvIndex);
2012     return argv.GetTaggedValue();
2013 }
2014 
ThrowDeleteSuperProperty(JSThread * thread)2015 void SlowRuntimeStub::ThrowDeleteSuperProperty(JSThread *thread)
2016 {
2017     INTERPRETER_TRACE(thread, ThrowDeleteSuperProperty);
2018     [[maybe_unused]] EcmaHandleScope handleScope(thread);
2019 
2020     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2021     JSHandle<EcmaString> info = factory->NewFromCanBeCompressString("Can not delete super property");
2022     JSHandle<JSObject> errorObj = factory->NewJSError(base::ErrorType::REFERENCE_ERROR, info);
2023     THROW_NEW_ERROR_AND_RETURN(thread, errorObj.GetTaggedValue());
2024 }
2025 
NotifyInlineCache(JSThread * thread,JSFunction * func,JSMethod * method)2026 JSTaggedValue SlowRuntimeStub::NotifyInlineCache(JSThread *thread, JSFunction *func, JSMethod *method)
2027 {
2028     INTERPRETER_TRACE(thread, NotifyInlineCache);
2029     uint32_t icSlotSize = method->GetSlotSize();
2030     if (icSlotSize > 0 && icSlotSize < ProfileTypeInfo::INVALID_SLOT_INDEX) {
2031         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2032         [[maybe_unused]] EcmaHandleScope handleScope(thread);
2033 
2034         JSHandle<JSFunction> funcHandle(thread, func);
2035         JSHandle<ProfileTypeInfo> profileTypeInfo = factory->NewProfileTypeInfo(icSlotSize);
2036         funcHandle->SetProfileTypeInfo(thread, profileTypeInfo.GetTaggedValue());
2037         return profileTypeInfo.GetTaggedValue();
2038     }
2039     return JSTaggedValue::Undefined();
2040 }
2041 
ResolveClass(JSThread * thread,JSTaggedValue ctor,TaggedArray * literal,JSTaggedValue base,JSTaggedValue lexenv,ConstantPool * constpool)2042 JSTaggedValue SlowRuntimeStub::ResolveClass(JSThread *thread, JSTaggedValue ctor, TaggedArray *literal,
2043                                             JSTaggedValue base, JSTaggedValue lexenv, ConstantPool *constpool)
2044 {
2045     ASSERT(ctor.IsClassConstructor());
2046     JSHandle<JSFunction> cls(thread, ctor);
2047     JSHandle<TaggedArray> literalBuffer(thread, literal);
2048     JSHandle<JSTaggedValue> lexicalEnv(thread, lexenv);
2049     JSHandle<ConstantPool> constpoolHandle(thread, constpool);
2050 
2051     SetClassInheritanceRelationship(thread, ctor, base);
2052     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2053 
2054     uint32_t literalBufferLength = literalBuffer->GetLength();
2055 
2056     // only traverse the value of key-value pair
2057     for (uint32_t index = 1; index < literalBufferLength - 1; index += 2) {  // 2: key-value pair
2058         JSTaggedValue value = literalBuffer->Get(index);
2059         if (LIKELY(value.IsJSFunction())) {
2060             JSFunction::Cast(value.GetTaggedObject())->SetLexicalEnv(thread, lexicalEnv.GetTaggedValue());
2061             JSFunction::Cast(value.GetTaggedObject())->SetConstantPool(thread, constpoolHandle.GetTaggedValue());
2062         }
2063     }
2064 
2065     cls->SetResolved(true);
2066     return cls.GetTaggedValue();
2067 }
2068 
2069 // clone class may need re-set inheritance relationship due to extends may be a variable.
CloneClassFromTemplate(JSThread * thread,JSTaggedValue ctor,JSTaggedValue base,JSTaggedValue lexenv,ConstantPool * constpool)2070 JSTaggedValue SlowRuntimeStub::CloneClassFromTemplate(JSThread *thread, JSTaggedValue ctor, JSTaggedValue base,
2071                                                       JSTaggedValue lexenv, ConstantPool *constpool)
2072 {
2073     [[maybe_unused]] EcmaHandleScope handleScope(thread);
2074     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2075     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
2076 
2077     ASSERT(ctor.IsClassConstructor());
2078     JSHandle<JSTaggedValue> lexenvHandle(thread, lexenv);
2079     JSHandle<JSTaggedValue> constpoolHandle(thread, JSTaggedValue(constpool));
2080     JSHandle<JSTaggedValue> baseHandle(thread, base);
2081 
2082     JSHandle<JSFunction> cls(thread, ctor);
2083 
2084     JSHandle<JSObject> clsPrototype(thread, cls->GetFunctionPrototype());
2085 
2086     bool canShareHClass = false;
2087 
2088     JSHandle<JSFunction> cloneClass = factory->CloneClassCtor(cls, lexenvHandle, canShareHClass);
2089     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2090     JSHandle<JSObject> cloneClassPrototype = factory->CloneObjectLiteral(JSHandle<JSObject>(clsPrototype), lexenvHandle,
2091                                                                          constpoolHandle, canShareHClass);
2092     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2093 
2094     // After clone both, reset "constructor" and "prototype" properties.
2095     cloneClass->SetFunctionPrototype(thread, cloneClassPrototype.GetTaggedValue());
2096     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2097 
2098     PropertyDescriptor ctorDesc(thread, JSHandle<JSTaggedValue>(cloneClass), true, false, true);
2099     JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(cloneClassPrototype),
2100                                          globalConst->GetHandledConstructorString(), ctorDesc);
2101     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2102 
2103     cloneClass->SetHomeObject(thread, cloneClassPrototype);
2104 
2105     if (!canShareHClass) {
2106         SetClassInheritanceRelationship(thread, cloneClass.GetTaggedValue(), baseHandle.GetTaggedValue());
2107         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2108     }
2109 
2110     return cloneClass.GetTaggedValue();
2111 }
2112 
SetClassInheritanceRelationship(JSThread * thread,JSTaggedValue ctor,JSTaggedValue base)2113 JSTaggedValue SlowRuntimeStub::SetClassInheritanceRelationship(JSThread *thread, JSTaggedValue ctor, JSTaggedValue base)
2114 {
2115     [[maybe_unused]] EcmaHandleScope handleScope(thread);
2116     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
2117     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
2118 
2119     JSHandle<JSTaggedValue> cls(thread, ctor);
2120     ASSERT(cls->IsJSFunction());
2121     JSMutableHandle<JSTaggedValue> parent(thread, base);
2122 
2123     /*
2124      *         class A / class A extends null                             class A extends B
2125      *                                       a                                                 a
2126      *                                       |                                                 |
2127      *                                       |  __proto__                                      |  __proto__
2128      *                                       |                                                 |
2129      *       A            ---->         A.prototype                  A             ---->    A.prototype
2130      *       |                               |                       |                         |
2131      *       |  __proto__                    |  __proto__            |  __proto__              |  __proto__
2132      *       |                               |                       |                         |
2133      *   Function.prototype       Object.prototype / null            B             ---->    B.prototype
2134      */
2135 
2136     JSHandle<JSTaggedValue> parentPrototype;
2137     // hole means parent is not present
2138     if (parent->IsHole()) {
2139         JSHandle<JSFunction>::Cast(cls)->SetFunctionKind(FunctionKind::CLASS_CONSTRUCTOR);
2140         parentPrototype = env->GetObjectFunctionPrototype();
2141         parent.Update(env->GetFunctionPrototype().GetTaggedValue());
2142     } else if (parent->IsNull()) {
2143         JSHandle<JSFunction>::Cast(cls)->SetFunctionKind(FunctionKind::DERIVED_CONSTRUCTOR);
2144         parentPrototype = JSHandle<JSTaggedValue>(thread, JSTaggedValue::Null());
2145         parent.Update(env->GetFunctionPrototype().GetTaggedValue());
2146     } else if (!parent->IsConstructor()) {
2147         return ThrowTypeError(thread, "parent class is not constructor");
2148     } else {
2149         JSHandle<JSFunction>::Cast(cls)->SetFunctionKind(FunctionKind::DERIVED_CONSTRUCTOR);
2150         parentPrototype = JSTaggedValue::GetProperty(thread, parent,
2151             globalConst->GetHandledPrototypeString()).GetValue();
2152         if (!parentPrototype->IsECMAObject() && !parentPrototype->IsNull()) {
2153             return ThrowTypeError(thread, "parent class have no valid prototype");
2154         }
2155     }
2156 
2157     cls->GetTaggedObject()->GetClass()->SetPrototype(thread, parent);
2158 
2159     JSHandle<JSObject> clsPrototype(thread, JSHandle<JSFunction>(cls)->GetFunctionPrototype());
2160     clsPrototype->GetClass()->SetPrototype(thread, parentPrototype);
2161 
2162     return JSTaggedValue::Undefined();
2163 }
2164 
SetClassConstructorLength(JSThread * thread,JSTaggedValue ctor,JSTaggedValue length)2165 JSTaggedValue SlowRuntimeStub::SetClassConstructorLength(JSThread *thread, JSTaggedValue ctor, JSTaggedValue length)
2166 {
2167     ASSERT(ctor.IsClassConstructor());
2168 
2169     JSFunction* cls = JSFunction::Cast(ctor.GetTaggedObject());
2170     if (LIKELY(!cls->GetClass()->IsDictionaryMode())) {
2171         cls->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, length);
2172     } else {
2173         const GlobalEnvConstants *globalConst = thread->GlobalConstants();
2174         cls->UpdatePropertyInDictionary(thread, globalConst->GetLengthString(), length);
2175     }
2176     return JSTaggedValue::Undefined();
2177 }
2178 
LdBigInt(JSThread * thread,JSTaggedValue numberBigInt)2179 JSTaggedValue SlowRuntimeStub::LdBigInt(JSThread *thread, JSTaggedValue numberBigInt)
2180 {
2181     INTERPRETER_TRACE(thread, LdBigInt);
2182     [[maybe_unused]] EcmaHandleScope handleScope(thread);
2183     JSHandle<JSTaggedValue> bigint(thread, numberBigInt);
2184     return JSTaggedValue::ToBigInt(thread, bigint);
2185 }
2186 }  // namespace panda::ecmascript
2187