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