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_INTERPRETER_INTERPRETER_INL_H
17 #define ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H
18
19 #include "ecmascript/debugger/js_debugger_manager.h"
20 #include "ecmascript/ecma_context.h"
21 #include "ecmascript/ecma_string.h"
22 #include "ecmascript/ecma_vm.h"
23 #include "ecmascript/global_env.h"
24 #include "ecmascript/ic/ic_runtime_stub-inl.h"
25 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
26 #include "ecmascript/interpreter/interpreter.h"
27 #include "ecmascript/interpreter/interpreter_assembly.h"
28 #include "ecmascript/interpreter/frame_handler.h"
29 #include "ecmascript/interpreter/slow_runtime_stub.h"
30 #include "ecmascript/jspandafile/literal_data_extractor.h"
31 #include "ecmascript/jspandafile/program_object.h"
32 #include "ecmascript/js_async_generator_object.h"
33 #include "ecmascript/js_generator_object.h"
34 #include "ecmascript/js_tagged_value.h"
35 #include "ecmascript/mem/concurrent_marker.h"
36 #include "ecmascript/module/js_module_manager.h"
37 #include "ecmascript/module/js_module_source_text.h"
38 #include "ecmascript/runtime_call_id.h"
39 #include "ecmascript/stubs/runtime_stubs.h"
40 #include "ecmascript/template_string.h"
41 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
42 #include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
43 #endif
44
45 namespace panda::ecmascript {
46 using CommonStubCSigns = kungfu::CommonStubCSigns;
47 #if defined(__clang__)
48 #pragma clang diagnostic push
49 #pragma clang diagnostic ignored "-Wvoid-ptr-dereference"
50 #pragma clang diagnostic ignored "-Wgnu-label-as-value"
51 #elif defined(__GNUC__)
52 #pragma GCC diagnostic push
53 #pragma GCC diagnostic ignored "-Wpedantic"
54 #endif
55
56 #if ECMASCRIPT_ENABLE_INTERPRETER_LOG
57 #define HANDLE_OPCODE(opcode) \
58 HANDLE_##opcode: \
59 { \
60 RuntimeStubs::DebugPrintInstruction(thread->GetGlueAddr(), pc); \
61 }
62 #else
63 #define HANDLE_OPCODE(opcode) \
64 HANDLE_##opcode:
65 #endif
66
67 #define NOPRINT_HANDLE_OPCODE(opcode) \
68 HANDLE_##opcode:
69
70 #define LOG_INST() false && LOG_INTERPRETER(DEBUG)
71
72 #define DEBUG_HANDLE_OPCODE(opcode) \
73 DEBUG_HANDLE_##opcode:
74
75 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
76 #define ADVANCE_PC(offset) \
77 pc += (offset); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic, cppcoreguidelines-macro-usage)
78
79 #define GOTO_NEXT() // NOLINT(clang-diagnostic-gnu-label-as-value, cppcoreguidelines-macro-usage)
80
81 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
82 #define DISPATCH(curOpcode) \
83 do { \
84 ADVANCE_PC(BytecodeInstruction::Size(EcmaOpcode::curOpcode)) \
85 opcode = READ_INST_OP(); goto *dispatchTable[opcode]; \
86 } while (false)
87
88 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
89 #define DISPATCH_OFFSET(offset) \
90 do { \
91 ADVANCE_PC(offset) \
92 opcode = READ_INST_OP(); goto *dispatchTable[opcode]; \
93 } while (false)
94
95 #define DISPATCH_THROW() \
96 do { \
97 opcode = *(pc + 1); \
98 goto *throwDispatchTable[opcode]; \
99 } while (false)
100
101 #define DISPATCH_WIDE() \
102 do { \
103 opcode = *(pc + 1); \
104 goto *wideDispatchTable[opcode]; \
105 } while (false)
106
107 #define DISPATCH_DEPRECATED() \
108 do { \
109 opcode = *(pc + 1); \
110 goto *deprecatedDispatchTable[opcode]; \
111 } while (false)
112
113 #define DISPATCH_CALLRUNTIME() \
114 do { \
115 opcode = *(pc + 1); \
116 goto *callRuntimeDispatchTable[opcode]; \
117 } while (false)
118
119 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
120 #define GET_FRAME(CurrentSp) \
121 (reinterpret_cast<InterpretedFrame *>(CurrentSp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
122 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
123 #define GET_ENTRY_FRAME(sp) \
124 (reinterpret_cast<InterpretedEntryFrame *>(sp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
125 #define GET_BUILTIN_FRAME(sp) \
126 (reinterpret_cast<InterpretedBuiltinFrame *>(sp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
127 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
128 #define SAVE_PC() (GET_FRAME(sp)->pc = pc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
129 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
130 #define SAVE_ACC() (GET_FRAME(sp)->acc = acc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
131 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
132 #define RESTORE_ACC() (acc = GET_FRAME(sp)->acc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
133 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
134 #define GET_VREG(idx) (sp[idx]) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
135 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
136 #define GET_VREG_VALUE(idx) (JSTaggedValue(sp[idx])) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
137 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
138 #define SET_VREG(idx, val) (sp[idx] = (val)); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
139 #define GET_ACC() (acc) // NOLINT(cppcoreguidelines-macro-usage)
140 #define SET_ACC(val) (acc = val) // NOLINT(cppcoreguidelines-macro-usage)
141
142 #define GET_METHOD_FROM_CACHE(index) \
143 ConstantPool::GetMethodFromCache(thread, constpool, index)
144
145 #define GET_STR_FROM_CACHE(index) \
146 ConstantPool::GetStringFromCache(thread, constpool, index)
147
148 #define GET_LITERA_FROM_CACHE(index, type, module) \
149 ConstantPool::GetLiteralFromCache<type>(thread, constpool, index, module)
150
151 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
152 #define INTERPRETER_GOTO_EXCEPTION_HANDLER() \
153 do { \
154 SAVE_PC(); \
155 goto *dispatchTable[EXCEPTION_OPCODE]; \
156 } while (false)
157
158 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
159 #define INTERPRETER_HANDLE_RETURN() \
160 do { \
161 size_t jumpSize = GetJumpSizeAfterCall(pc); \
162 DISPATCH_OFFSET(jumpSize); \
163 } while (false)
164
165 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
166 #define CHECK_SWITCH_TO_DEBUGGER_TABLE() \
167 if (ecmaVm->GetJsDebuggerManager()->IsDebugMode()) { \
168 dispatchTable = debugDispatchTable.data(); \
169 }
170
171 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
172 #define REAL_GOTO_DISPATCH_OPCODE(opcode) \
173 do { \
174 ASSERT(static_cast<uint16_t>(opcode) <= 0xff); \
175 goto *instDispatchTable[static_cast<uint8_t>(opcode)]; \
176 } while (false)
177
178 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
179 #define REAL_GOTO_EXCEPTION_HANDLER() \
180 do { \
181 SAVE_PC(); \
182 goto *instDispatchTable[EXCEPTION_OPCODE]; \
183 } while (false)
184
185 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
186 #define INTERPRETER_RETURN_IF_ABRUPT(result) \
187 do { \
188 if (result.IsException()) { \
189 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
190 } \
191 } while (false)
192
193 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
194 #define HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(_thread) \
195 do { \
196 if (UNLIKELY((_thread)->HasPendingException())) { \
197 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
198 } \
199 } while (false)
200
201 #define RESET_AND_JUMP_IF_DROPFRAME() \
202 do { \
203 if (thread->GetFrameDroppedBit()) { \
204 thread->ResetFrameDroppedBit(); \
205 sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame()); \
206 InterpretedFrame *state = GET_FRAME(sp); \
207 pc = state->pc; \
208 RESTORE_ACC(); \
209 DISPATCH_OFFSET(0); \
210 } \
211 } while (false)
212
213 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
214 #define NOTIFY_DEBUGGER_EVENT() \
215 do { \
216 SAVE_ACC(); \
217 SAVE_PC(); \
218 NotifyBytecodePcChanged(thread); \
219 RESET_AND_JUMP_IF_DROPFRAME(); \
220 RESTORE_ACC(); \
221 } while (false)
222
223 /*
224 * reasons of set acc with hole:
225 * 1. acc will become illegal when new error
226 * 2. debugger logic will save acc, so illegal acc will set to frame
227 * 3. when debugger trigger gc, will mark an invalid acc and crash
228 * 4. acc will set to exception later, so it can set to hole template
229 */
230 #define NOTIFY_DEBUGGER_EXCEPTION_EVENT() \
231 do { \
232 SET_ACC(JSTaggedValue::Hole()); \
233 NOTIFY_DEBUGGER_EVENT(); \
234 } while (false)
235
236 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
237 #define DEPRECATED_CALL_INITIALIZE() \
238 do { \
239 SAVE_PC(); \
240 thread->CheckSafepoint(); \
241 funcTagged = sp[startReg]; \
242 JSTaggedValue funcValue(funcTagged); \
243 if (!funcValue.IsCallable()) { \
244 { \
245 [[maybe_unused]] EcmaHandleScope handleScope(thread); \
246 JSHandle<JSObject> error = factory->GetJSError( \
247 ErrorType::TYPE_ERROR, "is not callable"); \
248 thread->SetException(error.GetTaggedValue()); \
249 } \
250 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
251 } \
252 funcObject = ECMAObject::Cast(funcValue.GetTaggedObject()); \
253 methodHandle.Update(JSTaggedValue(funcObject->GetCallTarget())); \
254 newSp = sp - InterpretedFrame::NumOfMembers(); \
255 } while (false)
256
257 #define CALL_INITIALIZE() \
258 do { \
259 SAVE_PC(); \
260 SAVE_ACC(); \
261 thread->CheckSafepoint(); \
262 RESTORE_ACC(); \
263 funcTagged = acc.GetRawData(); \
264 JSTaggedValue funcValue = acc; \
265 if (!funcValue.IsCallable()) { \
266 { \
267 [[maybe_unused]] EcmaHandleScope handleScope(thread); \
268 JSHandle<JSObject> error = factory->GetJSError( \
269 ErrorType::TYPE_ERROR, "is not callable"); \
270 thread->SetException(error.GetTaggedValue()); \
271 } \
272 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
273 } \
274 funcObject = ECMAObject::Cast(funcValue.GetTaggedObject()); \
275 methodHandle.Update(JSTaggedValue(funcObject->GetCallTarget())); \
276 newSp = sp - InterpretedFrame::NumOfMembers(); \
277 } while (false)
278
279 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
280 #define CALL_PUSH_UNDEFINED(n) \
281 do { \
282 for (int i = 0; i < (n); i++) { \
283 *(--newSp) = JSTaggedValue::VALUE_UNDEFINED; \
284 } \
285 } while (false)
286
287 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
288 #define CALL_PUSH_ARGS_0() \
289 do { \
290 /* do nothing when 0 arg */ \
291 } while (false)
292
293 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
294 #define DEPRECATED_CALL_PUSH_ARGS_0() CALL_PUSH_ARGS_0()
295
296 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
297 #define CALL_PUSH_ARGS_1() \
298 do { \
299 *(--newSp) = sp[a0]; \
300 } while (false)
301
302 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
303 #define DEPRECATED_CALL_PUSH_ARGS_1() CALL_PUSH_ARGS_1()
304
305 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
306 #define CALL_PUSH_ARGS_2() \
307 do { \
308 *(--newSp) = sp[a1]; \
309 CALL_PUSH_ARGS_1(); \
310 } while (false)
311
312 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
313 #define DEPRECATED_CALL_PUSH_ARGS_2() CALL_PUSH_ARGS_2()
314
315 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
316 #define CALL_PUSH_ARGS_3() \
317 do { \
318 *(--newSp) = sp[a2]; \
319 CALL_PUSH_ARGS_2(); \
320 } while (false)
321
322 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
323 #define DEPRECATED_CALL_PUSH_ARGS_3() CALL_PUSH_ARGS_3()
324
325 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
326 #define CALL_PUSH_ARGS_RANGE() \
327 do { \
328 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - actualNumArgs))) { \
329 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
330 } \
331 for (int i = actualNumArgs - 1; i >= 0; i--) { \
332 *(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
333 } \
334 } while (false)
335
336 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
337 #define DEPRECATED_CALL_PUSH_ARGS_RANGE() \
338 do { \
339 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - actualNumArgs))) { \
340 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
341 } \
342 for (int i = actualNumArgs; i > 0; i--) { \
343 *(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
344 } \
345 } while (false)
346
347 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
348 #define CALL_PUSH_ARGS_THISRANGE() \
349 do { \
350 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - actualNumArgs))) { \
351 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
352 } \
353 /* 1: skip this */ \
354 for (int i = actualNumArgs; i > 0; i--) { \
355 *(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
356 } \
357 } while (false)
358
359 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
360 #define DEPRECATED_CALL_PUSH_ARGS_THISRANGE() \
361 do { \
362 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - actualNumArgs))) { \
363 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
364 } \
365 /* 1: skip this */ \
366 for (int i = actualNumArgs + 1; i > 1; i--) { \
367 *(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
368 } \
369 } while (false)
370
371 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
372 #define CALL_PUSH_ARGS_0_NO_EXTRA() \
373 do { \
374 /* do nothing when 0 arg */ \
375 } while (false)
376
377 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
378 #define DEPRECATED_CALL_PUSH_ARGS_0_NO_EXTRA() CALL_PUSH_ARGS_0_NO_EXTRA()
379
380 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
381 #define CALL_PUSH_ARGS_1_NO_EXTRA() \
382 do { \
383 if (declaredNumArgs >= ActualNumArgsOfCall::CALLARG1) { \
384 *(--newSp) = sp[a0]; \
385 } \
386 } while (false)
387
388 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
389 #define DEPRECATED_CALL_PUSH_ARGS_1_NO_EXTRA() CALL_PUSH_ARGS_1_NO_EXTRA()
390
391 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
392 #define CALL_PUSH_ARGS_2_NO_EXTRA() \
393 do { \
394 if (declaredNumArgs >= ActualNumArgsOfCall::CALLARGS2) { \
395 *(--newSp) = sp[a1]; \
396 } \
397 DEPRECATED_CALL_PUSH_ARGS_1_NO_EXTRA(); \
398 } while (false)
399
400 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
401 #define DEPRECATED_CALL_PUSH_ARGS_2_NO_EXTRA() CALL_PUSH_ARGS_2_NO_EXTRA()
402
403 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
404 #define CALL_PUSH_ARGS_3_NO_EXTRA() \
405 do { \
406 if (declaredNumArgs >= ActualNumArgsOfCall::CALLARGS3) { \
407 *(--newSp) = sp[a2]; \
408 } \
409 DEPRECATED_CALL_PUSH_ARGS_2_NO_EXTRA(); \
410 } while (false)
411
412 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
413 #define DEPRECATED_CALL_PUSH_ARGS_3_NO_EXTRA() CALL_PUSH_ARGS_3_NO_EXTRA()
414
415 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
416 #define CALL_PUSH_ARGS_RANGE_NO_EXTRA() \
417 do { \
418 int num = std::min(actualNumArgs, declaredNumArgs); \
419 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - num))) { \
420 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
421 } \
422 for (int i = num - 1; i >= 0; i--) { \
423 *(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
424 } \
425 } while (false)
426
427 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
428 #define DEPRECATED_CALL_PUSH_ARGS_RANGE_NO_EXTRA() \
429 do { \
430 int num = std::min(actualNumArgs, declaredNumArgs); \
431 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - num))) { \
432 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
433 } \
434 for (int i = num; i > 0; i--) { \
435 *(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
436 } \
437 } while (false)
438
439 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
440 #define CALL_PUSH_ARGS_THISRANGE_NO_EXTRA() \
441 do { \
442 int num = std::min(actualNumArgs, declaredNumArgs); \
443 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - num))) { \
444 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
445 } \
446 /* 1: skip this */ \
447 for (int i = num; i > 0; i--) { \
448 *(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
449 } \
450 } while (false)
451
452 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
453 #define DEPRECATED_CALL_PUSH_ARGS_THISRANGE_NO_EXTRA() \
454 do { \
455 int num = std::min(actualNumArgs, declaredNumArgs); \
456 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - num))) { \
457 INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
458 } \
459 /* 1: skip this */ \
460 for (int i = num + 1; i > 1; i--) { \
461 *(--newSp) = sp[startReg + static_cast<uint32_t>(i)]; \
462 } \
463 } while (false)
464
465 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
466 #define CALL_PUSH_ARGS(ARG_TYPE) \
467 do { \
468 if (methodHandle->IsNativeWithCallField()) { \
469 /* native, just push all args directly */ \
470 CALL_PUSH_ARGS_##ARG_TYPE(); \
471 goto setVregsAndFrameNative; \
472 } \
473 int32_t declaredNumArgs = \
474 static_cast<int32_t>(methodHandle->GetNumArgsWithCallField()); \
475 if (actualNumArgs == declaredNumArgs) { \
476 /* fast path, just push all args directly */ \
477 CALL_PUSH_ARGS_##ARG_TYPE(); \
478 goto setVregsAndFrameNotNative; \
479 } \
480 /* slow path */ \
481 if (!methodHandle->HaveExtraWithCallField()) { \
482 /* push length = declaredNumArgs, may push undefined */ \
483 CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs); \
484 CALL_PUSH_ARGS_##ARG_TYPE##_NO_EXTRA(); \
485 } else { \
486 /* push actualNumArgs in the end, then all args, may push undefined */ \
487 *(--newSp) = JSTaggedValue(actualNumArgs).GetRawData(); \
488 CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs); \
489 CALL_PUSH_ARGS_##ARG_TYPE(); \
490 } \
491 goto setVregsAndFrameNotNative; \
492 } while (false)
493
494 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
495 #define DEPRECATED_CALL_PUSH_ARGS(ARG_TYPE) \
496 do { \
497 if (methodHandle->IsNativeWithCallField()) { \
498 /* native, just push all args directly */ \
499 DEPRECATED_CALL_PUSH_ARGS_##ARG_TYPE(); \
500 goto deprecatedSetVregsAndFrameNative; \
501 } \
502 int32_t declaredNumArgs = \
503 static_cast<int32_t>(methodHandle->GetNumArgsWithCallField()); \
504 if (actualNumArgs == declaredNumArgs) { \
505 /* fast path, just push all args directly */ \
506 DEPRECATED_CALL_PUSH_ARGS_##ARG_TYPE(); \
507 goto deprecatedSetVregsAndFrameNotNative; \
508 } \
509 /* slow path */ \
510 if (!methodHandle->HaveExtraWithCallField()) { \
511 /* push length = declaredNumArgs, may push undefined */ \
512 CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs); \
513 DEPRECATED_CALL_PUSH_ARGS_##ARG_TYPE##_NO_EXTRA(); \
514 } else { \
515 /* push actualNumArgs in the end, then all args, may push undefined */ \
516 *(--newSp) = JSTaggedValue(actualNumArgs).GetRawData(); \
517 CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs); \
518 DEPRECATED_CALL_PUSH_ARGS_##ARG_TYPE(); \
519 } \
520 goto deprecatedSetVregsAndFrameNotNative; \
521 } while (false)
522
523 #if ECMASCRIPT_ENABLE_IC
524 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
525 #define UPDATE_HOTNESS_COUNTER_NON_ACC(offset) (UpdateHotnessCounter(thread, sp, acc, offset))
526
527 #define UPDATE_HOTNESS_COUNTER(offset) \
528 do { \
529 if (UpdateHotnessCounter(thread, sp, acc, offset)) { \
530 RESTORE_ACC(); \
531 } \
532 } while (false)
533 #else
534 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
535 #define UPDATE_HOTNESS_COUNTER(offset) static_cast<void>(0)
536 #define UPDATE_HOTNESS_COUNTER_NON_ACC(offset) static_cast<void>(0)
537 #endif
538
539 #define READ_INST_OP() READ_INST_8(0) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
540 #define READ_INST_4_0() (READ_INST_8(1) & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
541 #define READ_INST_4_1() (READ_INST_8(1) >> 4 & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
542 #define READ_INST_4_2() (READ_INST_8(2) & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
543 #define READ_INST_4_3() (READ_INST_8(2) >> 4 & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
544 #define READ_INST_8_0() READ_INST_8(1) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
545 #define READ_INST_8_1() READ_INST_8(2) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
546 #define READ_INST_8_2() READ_INST_8(3) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
547 #define READ_INST_8_3() READ_INST_8(4) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
548 #define READ_INST_8_4() READ_INST_8(5) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
549 #define READ_INST_8_5() READ_INST_8(6) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
550 #define READ_INST_8_6() READ_INST_8(7) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
551 #define READ_INST_8_7() READ_INST_8(8) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
552 #define READ_INST_8_8() READ_INST_8(9) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
553 #define READ_INST_8(offset) (*(pc + (offset)))
554 #define MOVE_AND_READ_INST_8(currentInst, offset) \
555 currentInst <<= 8; \
556 currentInst += READ_INST_8(offset); \
557
558 #define READ_INST_16_0() READ_INST_16(2)
559 #define READ_INST_16_1() READ_INST_16(3)
560 #define READ_INST_16_2() READ_INST_16(4)
561 #define READ_INST_16_3() READ_INST_16(5)
562 #define READ_INST_16_4() READ_INST_16(6)
563 #define READ_INST_16_5() READ_INST_16(7)
564 #define READ_INST_16_6() READ_INST_16(8)
565 #define READ_INST_16(offset) \
566 ({ \
567 uint16_t currentInst = READ_INST_8(offset); \
568 MOVE_AND_READ_INST_8(currentInst, offset - 1) \
569 })
570
571 #define READ_INST_32_0() READ_INST_32(4)
572 #define READ_INST_32_1() READ_INST_32(5)
573 #define READ_INST_32_2() READ_INST_32(6)
574 #define READ_INST_32(offset) \
575 ({ \
576 uint32_t currentInst = READ_INST_8(offset); \
577 MOVE_AND_READ_INST_8(currentInst, offset - 1) \
578 MOVE_AND_READ_INST_8(currentInst, offset - 2) \
579 MOVE_AND_READ_INST_8(currentInst, offset - 3) \
580 })
581
582 #define READ_INST_64_0() \
583 ({ \
584 uint64_t currentInst = READ_INST_8(8); \
585 MOVE_AND_READ_INST_8(currentInst, 7) \
586 MOVE_AND_READ_INST_8(currentInst, 6) \
587 MOVE_AND_READ_INST_8(currentInst, 5) \
588 MOVE_AND_READ_INST_8(currentInst, 4) \
589 MOVE_AND_READ_INST_8(currentInst, 3) \
590 MOVE_AND_READ_INST_8(currentInst, 2) \
591 MOVE_AND_READ_INST_8(currentInst, 1) \
592 })
593
594 #ifndef EXCLUDE_C_INTERPRETER
ExecuteNative(EcmaRuntimeCallInfo * info)595 JSTaggedValue EcmaInterpreter::ExecuteNative(EcmaRuntimeCallInfo *info)
596 {
597 JSThread *thread = info->GetThread();
598 INTERPRETER_TRACE(thread, ExecuteNative);
599
600 // current is entry frame.
601 JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
602 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
603 JSTaggedType *newSp = sp - InterpretedEntryFrame::NumOfMembers();
604
605 InterpretedFrame *state = GET_FRAME(newSp);
606 state->base.prev = sp;
607 state->base.type = FrameType::INTERPRETER_FRAME;
608 state->pc = nullptr;
609 state->function = info->GetFunctionValue();
610 state->thisObj = info->GetThisValue();
611 thread->SetCurrentSPFrame(newSp);
612 thread->CheckSafepoint();
613 ECMAObject *callTarget = reinterpret_cast<ECMAObject*>(info->GetFunctionValue().GetTaggedObject());
614 Method *method = callTarget->GetCallTarget();
615 LOG_INST() << "Entry: Runtime Call.";
616 JSTaggedValue tagged =
617 reinterpret_cast<EcmaEntrypoint>(const_cast<void *>(method->GetNativePointer()))(info);
618 LOG_INST() << "Exit: Runtime Call.";
619
620 InterpretedEntryFrame *entryState = GET_ENTRY_FRAME(sp);
621 JSTaggedType *prevSp = entryState->base.prev;
622 thread->SetCurrentSPFrame(prevSp);
623 return tagged;
624 }
625 #endif
626
Execute(EcmaRuntimeCallInfo * info)627 JSTaggedValue EcmaInterpreter::Execute(EcmaRuntimeCallInfo *info)
628 {
629 if (info == nullptr) {
630 return JSTaggedValue::Exception();
631 }
632
633 JSThread *thread = info->GetThread();
634 INTERPRETER_TRACE(thread, Execute);
635 if (thread->IsAsmInterpreter()) {
636 return InterpreterAssembly::Execute(info);
637 }
638 #ifndef EXCLUDE_C_INTERPRETER
639 JSHandle<JSTaggedValue> func = info->GetFunction();
640 ECMAObject *callTarget = reinterpret_cast<ECMAObject*>(func.GetTaggedValue().GetTaggedObject());
641 ASSERT(callTarget != nullptr);
642 Method *method = callTarget->GetCallTarget();
643 if (method->IsNativeWithCallField()) {
644 return EcmaInterpreter::ExecuteNative(info);
645 }
646
647 // current is entry frame.
648 JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
649 int32_t actualNumArgs = static_cast<int32_t>(info->GetArgsNumber());
650 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
651 JSTaggedType *newSp = sp - InterpretedEntryFrame::NumOfMembers();
652 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - actualNumArgs - NUM_MANDATORY_JSFUNC_ARGS))) {
653 return JSTaggedValue::Undefined();
654 }
655
656 int32_t declaredNumArgs = static_cast<int32_t>(method->GetNumArgsWithCallField());
657 // push args
658 if (actualNumArgs == declaredNumArgs) {
659 // fast path, just push all args directly
660 for (int i = actualNumArgs - 1; i >= 0; i--) {
661 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
662 *(--newSp) = info->GetCallArgValue(i).GetRawData();
663 }
664 } else {
665 // slow path
666 if (!method->HaveExtraWithCallField()) {
667 // push length = declaredNumArgs, may push undefined
668 if (declaredNumArgs > actualNumArgs) {
669 CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs);
670 }
671 for (int32_t i = std::min(actualNumArgs, declaredNumArgs) - 1; i >= 0; i--) {
672 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
673 *(--newSp) = info->GetCallArgValue(i).GetRawData();
674 }
675 } else {
676 // push actualNumArgs in the end, then all args, may push undefined
677 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
678 *(--newSp) = JSTaggedValue(actualNumArgs).GetRawData();
679 if (declaredNumArgs > actualNumArgs) {
680 CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs);
681 }
682 for (int32_t i = actualNumArgs - 1; i >= 0; i--) {
683 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
684 *(--newSp) = info->GetCallArgValue(i).GetRawData();
685 }
686 }
687 }
688 uint64_t callField = method->GetCallField();
689 if ((callField & CALL_TYPE_MASK) != 0) {
690 // not normal call type, setting func/newTarget/this cannot be skipped
691 if (method->HaveThisWithCallField()) {
692 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
693 *(--newSp) = info->GetThisValue().GetRawData(); // push this
694 }
695 if (method->HaveNewTargetWithCallField()) {
696 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
697 *(--newSp) = info->GetNewTargetValue().GetRawData(); // push new target
698 }
699 if (method->HaveFuncWithCallField()) {
700 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
701 *(--newSp) = info->GetFunctionValue().GetRawData(); // push func
702 }
703 }
704 int32_t numVregs = static_cast<int32_t>(method->GetNumVregsWithCallField());
705 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - numVregs))) {
706 return JSTaggedValue::Undefined();
707 }
708 // push vregs
709 CALL_PUSH_UNDEFINED(numVregs);
710
711 const uint8_t *pc = method->GetBytecodeArray();
712 InterpretedFrame *state = GET_FRAME(newSp);
713 state->pc = pc;
714 state->function = info->GetFunctionValue();
715 state->thisObj = info->GetThisValue();
716 state->acc = JSTaggedValue::Hole();
717
718 state->constpool = method->GetConstantPool();
719 JSHandle<JSFunction> thisFunc = JSHandle<JSFunction>::Cast(func);
720 state->profileTypeInfo = method->GetProfileTypeInfo();
721 state->base.prev = sp;
722 state->base.type = FrameType::INTERPRETER_FRAME;
723 state->env = thisFunc->GetLexicalEnv();
724 thread->SetCurrentSPFrame(newSp);
725 thread->CheckSafepoint();
726 LOG_INST() << "Entry: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(newSp) << " "
727 << std::hex << reinterpret_cast<uintptr_t>(pc);
728
729 EcmaInterpreter::RunInternal(thread, pc, newSp);
730
731 // NOLINTNEXTLINE(readability-identifier-naming)
732 const JSTaggedValue resAcc = state->acc;
733 // pop frame
734 InterpretedEntryFrame *entryState = GET_ENTRY_FRAME(sp);
735 JSTaggedType *prevSp = entryState->base.prev;
736 thread->SetCurrentSPFrame(prevSp);
737 return resAcc;
738 #else
739 return JSTaggedValue::Exception();
740 #endif
741 }
742
GeneratorReEnterInterpreter(JSThread * thread,JSHandle<GeneratorContext> context)743 JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSHandle<GeneratorContext> context)
744 {
745 [[maybe_unused]] EcmaHandleScope handleScope(thread);
746 JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(JSHandle<JSTaggedValue>(thread, context->GetMethod()));
747 if (func->GetClass()->IsOptimized()) {
748 return GeneratorReEnterAot(thread, context);
749 }
750
751 if (thread->IsAsmInterpreter()) {
752 return InterpreterAssembly::GeneratorReEnterInterpreter(thread, context);
753 }
754 #ifndef EXCLUDE_C_INTERPRETER
755 JSTaggedType *currentSp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
756
757 // push break frame
758 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
759 JSTaggedType *breakSp = currentSp - InterpretedFrame::NumOfMembers();
760 if (UNLIKELY(thread->DoStackOverflowCheck(breakSp))) {
761 return JSTaggedValue::Exception();
762 }
763
764 InterpretedFrame *breakState = GET_FRAME(breakSp);
765 breakState->pc = nullptr;
766 breakState->function = JSTaggedValue::Hole();
767 breakState->thisObj = JSTaggedValue::Hole();
768 breakState->base.prev = currentSp;
769 breakState->base.type = FrameType::INTERPRETER_FRAME;
770
771 // create new frame and resume sp and pc
772 uint32_t nregs = context->GetNRegs();
773 size_t newFrameSize = InterpretedFrame::NumOfMembers() + nregs;
774 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic
775 JSTaggedType *newSp = breakSp - newFrameSize;
776 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
777 return JSTaggedValue::Exception();
778 }
779 JSHandle<TaggedArray> regsArray(thread, context->GetRegsArray());
780 for (size_t i = 0; i < nregs; i++) {
781 newSp[i] = regsArray->Get(i).GetRawData(); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
782 }
783 uint32_t pcOffset = context->GetBCOffset();
784 Method *method = func->GetCallTarget();
785 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
786 const uint8_t *resumePc = method->GetBytecodeArray() + pcOffset;
787
788 InterpretedFrame *state = GET_FRAME(newSp);
789 state->pc = resumePc;
790 state->function = func.GetTaggedValue();
791 state->thisObj = context->GetThis();
792 state->constpool = method->GetConstantPool();
793 state->profileTypeInfo = method->GetProfileTypeInfo();
794 state->acc = context->GetAcc();
795 state->base.prev = breakSp;
796 state->base.type = FrameType::INTERPRETER_FRAME;
797 JSTaggedValue env = context->GetLexicalEnv();
798 state->env = env;
799 // execute interpreter
800 thread->SetCurrentSPFrame(newSp);
801
802 EcmaInterpreter::RunInternal(thread, resumePc, newSp);
803
804 JSTaggedValue res = state->acc;
805 // pop frame
806 thread->SetCurrentSPFrame(currentSp);
807 return res;
808 #else
809 return JSTaggedValue::Exception();
810 #endif
811 }
812
GeneratorReEnterAot(JSThread * thread,JSHandle<GeneratorContext> context)813 JSTaggedValue EcmaInterpreter::GeneratorReEnterAot(JSThread *thread, JSHandle<GeneratorContext> context)
814 {
815 JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(JSHandle<JSTaggedValue>(thread, context->GetMethod()));
816 if (func->IsClassConstructor()) {
817 {
818 EcmaVM *ecmaVm = thread->GetEcmaVM();
819 ObjectFactory *factory = ecmaVm->GetFactory();
820 JSHandle<JSObject> error =
821 factory->GetJSError(ErrorType::TYPE_ERROR, "class constructor cannot called without 'new'");
822 thread->SetException(error.GetTaggedValue());
823 }
824 return thread->GetException();
825 }
826 Method *method = func->GetCallTarget();
827 JSTaggedValue genObject = context->GetGeneratorObject();
828 std::vector<JSTaggedType> args(method->GetNumArgs() + NUM_MANDATORY_JSFUNC_ARGS,
829 JSTaggedValue::Undefined().GetRawData());
830 args[0] = func.GetTaggedValue().GetRawData();
831 args[1] = genObject.GetRawData();
832 args[2] = context->GetThis().GetRawData(); // 2: this
833 const JSTaggedType *prevFp = thread->GetLastLeaveFrame();
834 #if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
835 RuntimeStubs::StartCallTimer(thread->GetGlueAddr(), func.GetTaggedType(), true);
836 #endif
837 auto res = thread->GetCurrentEcmaContext()->ExecuteAot(method->GetNumArgs(), args.data(), prevFp, false);
838 #if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
839 RuntimeStubs::EndCallTimer(thread->GetGlueAddr(), func.GetTaggedType());
840 #endif
841 return res;
842 }
843
NotifyBytecodePcChanged(JSThread * thread)844 void EcmaInterpreter::NotifyBytecodePcChanged(JSThread *thread)
845 {
846 FrameHandler frameHandler(thread);
847 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
848 if (frameHandler.IsEntryFrame()) {
849 continue;
850 }
851 Method *method = frameHandler.GetMethod();
852 // Skip builtins method
853 if (method->IsNativeWithCallField()) {
854 continue;
855 }
856 auto bcOffset = frameHandler.GetBytecodeOffset();
857 auto *debuggerMgr = thread->GetEcmaVM()->GetJsDebuggerManager();
858 debuggerMgr->GetNotificationManager()->BytecodePcChangedEvent(thread, method, bcOffset);
859 return;
860 }
861 }
862
NotifyDebuggerStmt(JSThread * thread)863 void EcmaInterpreter::NotifyDebuggerStmt(JSThread *thread)
864 {
865 FrameHandler frameHandler(thread);
866 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
867 if (frameHandler.IsEntryFrame()) {
868 continue;
869 }
870 Method *method = frameHandler.GetMethod();
871 if (method->IsNativeWithCallField()) {
872 continue;
873 }
874 auto bcOffset = frameHandler.GetBytecodeOffset();
875 auto *debuggerMgr = thread->GetEcmaVM()->GetJsDebuggerManager();
876 debuggerMgr->GetNotificationManager()->DebuggerStmtEvent(thread, method, bcOffset);
877 return;
878 }
879 }
880
MethodEntry(JSThread * thread)881 void EcmaInterpreter::MethodEntry(JSThread *thread)
882 {
883 FrameHandler frameHandler(thread);
884 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
885 if (frameHandler.IsEntryFrame()) {
886 continue;
887 }
888 Method *method = frameHandler.GetMethod();
889 if (method->IsNativeWithCallField()) {
890 continue;
891 }
892 auto *debuggerMgr = thread->GetEcmaVM()->GetJsDebuggerManager();
893 debuggerMgr->GetNotificationManager()->MethodEntryEvent(thread, method);
894 return;
895 }
896 }
897
MethodExit(JSThread * thread)898 void EcmaInterpreter::MethodExit(JSThread *thread)
899 {
900 FrameHandler frameHandler(thread);
901 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
902 if (frameHandler.IsEntryFrame()) {
903 continue;
904 }
905 Method *method = frameHandler.GetMethod();
906 if (method->IsNativeWithCallField()) {
907 continue;
908 }
909 auto *debuggerMgr = thread->GetEcmaVM()->GetJsDebuggerManager();
910 debuggerMgr->GetNotificationManager()->MethodExitEvent(thread, method);
911 return;
912 }
913 }
914
GetNativeCallPandafile(JSThread * thread)915 const JSPandaFile *EcmaInterpreter::GetNativeCallPandafile(JSThread *thread)
916 {
917 FrameHandler frameHandler(thread);
918 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
919 if (frameHandler.IsEntryFrame()) {
920 continue;
921 }
922 Method *method = frameHandler.GetMethod();
923 // Skip builtins method
924 if (method->IsNativeWithCallField()) {
925 continue;
926 }
927 const JSPandaFile *jsPandaFile = method->GetJSPandaFile();
928 return jsPandaFile;
929 }
930 LOG_ECMA(FATAL) << "this branch is unreachable";
931 UNREACHABLE();
932 }
933
GetCurrentEntryPoint(JSThread * thread)934 JSTaggedValue EcmaInterpreter::GetCurrentEntryPoint(JSThread *thread)
935 {
936 FrameHandler frameHandler(thread);
937 JSMutableHandle<JSTaggedValue> recordName(thread, thread->GlobalConstants()->GetUndefined());
938
939 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
940 if (frameHandler.IsEntryFrame()) {
941 continue;
942 }
943 Method *method = frameHandler.GetMethod();
944 // Skip builtins method
945 if (method->IsNativeWithCallField()) {
946 continue;
947 }
948 JSTaggedValue func = frameHandler.GetFunction();
949 JSHandle<JSTaggedValue> module(thread, JSFunction::Cast(func.GetTaggedObject())->GetModule());
950
951 if (module->IsSourceTextModule()) {
952 recordName.Update(SourceTextModule::Cast(module->GetTaggedObject())->GetEcmaModuleRecordName());
953 } else if (module->IsString()) {
954 recordName.Update(module);
955 } else {
956 continue;
957 }
958 return recordName.GetTaggedValue();
959 }
960 UNREACHABLE();
961 }
962
963 #ifndef EXCLUDE_C_INTERPRETER
964 // NOLINTNEXTLINE(readability-function-size)
RunInternal(JSThread * thread,const uint8_t * pc,JSTaggedType * sp)965 NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t *pc, JSTaggedType *sp)
966 {
967 INTERPRETER_TRACE(thread, RunInternal);
968 uint8_t opcode = READ_INST_OP();
969 JSTaggedValue acc = JSTaggedValue::Hole();
970 EcmaVM *ecmaVm = thread->GetEcmaVM();
971 JSHandle<GlobalEnv> globalEnv = ecmaVm->GetGlobalEnv();
972 JSTaggedValue globalObj = globalEnv->GetGlobalObject();
973 ObjectFactory *factory = ecmaVm->GetFactory();
974 JSMutableHandle<Method> methodHandle(thread, JSTaggedValue::Undefined());
975
976 constexpr size_t numOps = 0x100;
977 constexpr size_t numThrowOps = 10;
978 constexpr size_t numWideOps = 20;
979 constexpr size_t numCallRuntimeOps = 1;
980 constexpr size_t numDeprecatedOps = 47;
981
982 static std::array<const void *, numOps> instDispatchTable {
983 #include "templates/instruction_dispatch.inl"
984 };
985
986 static std::array<const void *, numThrowOps> throwDispatchTable {
987 #include "templates/throw_instruction_dispatch.inl"
988 };
989
990 static std::array<const void *, numWideOps> wideDispatchTable {
991 #include "templates/wide_instruction_dispatch.inl"
992 };
993
994 static std::array<const void *, numCallRuntimeOps> callRuntimeDispatchTable {
995 #include "templates/call_runtime_instruction_dispatch.inl"
996 };
997
998 static std::array<const void *, numDeprecatedOps> deprecatedDispatchTable {
999 #include "templates/deprecated_instruction_dispatch.inl"
1000 };
1001
1002 static std::array<const void *, numOps> debugDispatchTable {
1003 #include "templates/debugger_instruction_dispatch.inl"
1004 };
1005
1006 auto *dispatchTable = instDispatchTable.data();
1007 CHECK_SWITCH_TO_DEBUGGER_TABLE();
1008 goto *dispatchTable[opcode];
1009
1010 HANDLE_OPCODE(MOV_V4_V4) {
1011 uint16_t vdst = READ_INST_4_0();
1012 uint16_t vsrc = READ_INST_4_1();
1013 LOG_INST() << "mov v" << vdst << ", v" << vsrc;
1014 uint64_t value = GET_VREG(vsrc);
1015 SET_VREG(vdst, value)
1016 DISPATCH(MOV_V4_V4);
1017 }
1018 HANDLE_OPCODE(MOV_V8_V8) {
1019 uint16_t vdst = READ_INST_8_0();
1020 uint16_t vsrc = READ_INST_8_1();
1021 LOG_INST() << "mov v" << vdst << ", v" << vsrc;
1022 uint64_t value = GET_VREG(vsrc);
1023 SET_VREG(vdst, value)
1024 DISPATCH(MOV_V8_V8);
1025 }
1026 HANDLE_OPCODE(MOV_V16_V16) {
1027 uint16_t vdst = READ_INST_16_0();
1028 uint16_t vsrc = READ_INST_16_2();
1029 LOG_INST() << "mov v" << vdst << ", v" << vsrc;
1030 uint64_t value = GET_VREG(vsrc);
1031 SET_VREG(vdst, value)
1032 DISPATCH(MOV_V16_V16);
1033 }
1034 HANDLE_OPCODE(LDA_STR_ID16) {
1035 uint16_t stringId = READ_INST_16_0();
1036 LOG_INST() << "lda.str " << std::hex << stringId;
1037 auto constpool = GetConstantPool(sp);
1038 SET_ACC(GET_STR_FROM_CACHE(stringId));
1039 DISPATCH(LDA_STR_ID16);
1040 }
1041 HANDLE_OPCODE(JMP_IMM8) {
1042 int8_t offset = READ_INST_8_0();
1043 UPDATE_HOTNESS_COUNTER(offset);
1044 LOG_INST() << "jmp " << std::hex << static_cast<int32_t>(offset);
1045 DISPATCH_OFFSET(offset);
1046 }
1047 HANDLE_OPCODE(JMP_IMM16) {
1048 int16_t offset = READ_INST_16_0();
1049 UPDATE_HOTNESS_COUNTER(offset);
1050 LOG_INST() << "jmp " << std::hex << static_cast<int32_t>(offset);
1051 DISPATCH_OFFSET(offset);
1052 }
1053 HANDLE_OPCODE(JMP_IMM32) {
1054 int32_t offset = READ_INST_32_0();
1055 UPDATE_HOTNESS_COUNTER(offset);
1056 LOG_INST() << "jmp " << std::hex << offset;
1057 DISPATCH_OFFSET(offset);
1058 }
1059 HANDLE_OPCODE(JEQZ_IMM8) {
1060 int8_t offset = READ_INST_8_0();
1061 LOG_INST() << "jeqz ->\t"
1062 << "cond jmpz " << std::hex << static_cast<int32_t>(offset);
1063 if (GET_ACC().IsFalse() || (GET_ACC().IsInt() && GET_ACC().GetInt() == 0) ||
1064 (GET_ACC().IsDouble() && GET_ACC().GetDouble() == 0)) {
1065 UPDATE_HOTNESS_COUNTER(offset);
1066 DISPATCH_OFFSET(offset);
1067 } else {
1068 DISPATCH(JEQZ_IMM8);
1069 }
1070 }
1071 HANDLE_OPCODE(JEQZ_IMM16) {
1072 int16_t offset = READ_INST_16_0();
1073 LOG_INST() << "jeqz ->\t"
1074 << "cond jmpz " << std::hex << static_cast<int32_t>(offset);
1075 if (GET_ACC().IsFalse() || (GET_ACC().IsInt() && GET_ACC().GetInt() == 0) ||
1076 (GET_ACC().IsDouble() && GET_ACC().GetDouble() == 0)) {
1077 UPDATE_HOTNESS_COUNTER(offset);
1078 DISPATCH_OFFSET(offset);
1079 } else {
1080 DISPATCH(JEQZ_IMM16);
1081 }
1082 }
1083 HANDLE_OPCODE(JEQZ_IMM32) {
1084 int32_t offset = READ_INST_32_0();
1085 LOG_INST() << "jeqz ->\t"
1086 << "cond jmpz " << std::hex << static_cast<int32_t>(offset);
1087 if (GET_ACC().IsFalse() || (GET_ACC().IsInt() && GET_ACC().GetInt() == 0) ||
1088 (GET_ACC().IsDouble() && GET_ACC().GetDouble() == 0)) {
1089 UPDATE_HOTNESS_COUNTER(offset);
1090 DISPATCH_OFFSET(offset);
1091 } else {
1092 DISPATCH(JEQZ_IMM32);
1093 }
1094 }
1095 HANDLE_OPCODE(JNEZ_IMM8) {
1096 int8_t offset = READ_INST_8_0();
1097 LOG_INST() << "jnez ->\t"
1098 << "cond jmpz " << std::hex << static_cast<int32_t>(offset);
1099 if (GET_ACC().IsTrue() || (GET_ACC().IsInt() && GET_ACC().GetInt() != 0) ||
1100 (GET_ACC().IsDouble() && GET_ACC().GetDouble() != 0)) {
1101 UPDATE_HOTNESS_COUNTER(offset);
1102 DISPATCH_OFFSET(offset);
1103 } else {
1104 DISPATCH(JNEZ_IMM8);
1105 }
1106 }
1107 HANDLE_OPCODE(JNEZ_IMM16) {
1108 int16_t offset = READ_INST_16_0();
1109 LOG_INST() << "jnez ->\t"
1110 << "cond jmpz " << std::hex << static_cast<int32_t>(offset);
1111 if (GET_ACC().IsTrue() || (GET_ACC().IsInt() && GET_ACC().GetInt() != 0) ||
1112 (GET_ACC().IsDouble() && GET_ACC().GetDouble() != 0)) {
1113 UPDATE_HOTNESS_COUNTER(offset);
1114 DISPATCH_OFFSET(offset);
1115 } else {
1116 DISPATCH(JNEZ_IMM16);
1117 }
1118 }
1119 HANDLE_OPCODE(JNEZ_IMM32) {
1120 int32_t offset = READ_INST_32_0();
1121 LOG_INST() << "jnez ->\t"
1122 << "cond jmpz " << std::hex << static_cast<int32_t>(offset);
1123 if (GET_ACC().IsTrue() || (GET_ACC().IsInt() && GET_ACC().GetInt() != 0) ||
1124 (GET_ACC().IsDouble() && GET_ACC().GetDouble() != 0)) {
1125 UPDATE_HOTNESS_COUNTER(offset);
1126 DISPATCH_OFFSET(offset);
1127 } else {
1128 DISPATCH(JNEZ_IMM32);
1129 }
1130 }
1131 HANDLE_OPCODE(LDA_V8) {
1132 uint16_t vsrc = READ_INST_8_0();
1133 LOG_INST() << "lda v" << vsrc;
1134 uint64_t value = GET_VREG(vsrc);
1135 SET_ACC(JSTaggedValue(value));
1136 DISPATCH(LDA_V8);
1137 }
1138 HANDLE_OPCODE(STA_V8) {
1139 uint16_t vdst = READ_INST_8_0();
1140 LOG_INST() << "sta v" << vdst;
1141 SET_VREG(vdst, GET_ACC().GetRawData())
1142 DISPATCH(STA_V8);
1143 }
1144 HANDLE_OPCODE(LDAI_IMM32) {
1145 int32_t imm = READ_INST_32_0();
1146 LOG_INST() << "ldai " << std::hex << imm;
1147 SET_ACC(JSTaggedValue(imm));
1148 DISPATCH(LDAI_IMM32);
1149 }
1150
1151 HANDLE_OPCODE(FLDAI_IMM64) {
1152 auto imm = base::bit_cast<double>(READ_INST_64_0());
1153 LOG_INST() << "fldai " << imm;
1154 SET_ACC(JSTaggedValue(imm));
1155 DISPATCH(FLDAI_IMM64);
1156 }
1157 {
1158 int32_t actualNumArgs;
1159 int32_t startReg;
1160 JSTaggedType funcTagged;
1161 ECMAObject *funcObject;
1162 JSTaggedType *newSp;
1163 bool callThis;
1164
1165 HANDLE_OPCODE(CALLARG0_IMM8) {
1166 actualNumArgs = ActualNumArgsOfCall::CALLARG0;
1167 LOG_INST() << "callarg0";
1168 CALL_INITIALIZE();
1169 callThis = false;
1170 CALL_PUSH_ARGS(0);
1171 }
1172 HANDLE_OPCODE(DEPRECATED_CALLARG0_PREF_V8) {
1173 actualNumArgs = ActualNumArgsOfCall::CALLARG0;
1174 startReg = READ_INST_8_1();
1175 LOG_INST() << "callarg0 "
1176 << "v" << startReg;
1177 DEPRECATED_CALL_INITIALIZE();
1178 callThis = false;
1179 DEPRECATED_CALL_PUSH_ARGS(0);
1180 }
1181 HANDLE_OPCODE(CALLARG1_IMM8_V8) {
1182 actualNumArgs = ActualNumArgsOfCall::CALLARG1;
1183 uint32_t a0 = READ_INST_8_1();
1184 LOG_INST() << "callarg1 "
1185 << "v" << a0;
1186 CALL_INITIALIZE();
1187 callThis = false;
1188 CALL_PUSH_ARGS(1);
1189 }
1190 HANDLE_OPCODE(DEPRECATED_CALLARG1_PREF_V8_V8) {
1191 actualNumArgs = ActualNumArgsOfCall::CALLARG1;
1192 startReg = READ_INST_8_1();
1193 uint32_t a0 = READ_INST_8_2();
1194 LOG_INST() << "callarg1 "
1195 << "v" << startReg << ", v" << a0;
1196 DEPRECATED_CALL_INITIALIZE();
1197 callThis = false;
1198 DEPRECATED_CALL_PUSH_ARGS(1);
1199 }
1200 HANDLE_OPCODE(CALLARGS2_IMM8_V8_V8) {
1201 actualNumArgs = ActualNumArgsOfCall::CALLARGS2;
1202 uint32_t a0 = READ_INST_8_1();
1203 uint32_t a1 = READ_INST_8_2();
1204 LOG_INST() << "callargs2 "
1205 << "v" << a0 << ", v" << a1;
1206 CALL_INITIALIZE();
1207 callThis = false;
1208 CALL_PUSH_ARGS(2);
1209 }
1210 HANDLE_OPCODE(DEPRECATED_CALLARGS2_PREF_V8_V8_V8) {
1211 actualNumArgs = ActualNumArgsOfCall::CALLARGS2;
1212 startReg = READ_INST_8_1();
1213 uint32_t a0 = READ_INST_8_2();
1214 uint32_t a1 = READ_INST_8_3();
1215 LOG_INST() << "callargs2 "
1216 << "v" << startReg << ", v" << a0 << ", v" << a1;
1217 DEPRECATED_CALL_INITIALIZE();
1218 callThis = false;
1219 DEPRECATED_CALL_PUSH_ARGS(2);
1220 }
1221 HANDLE_OPCODE(CALLARGS3_IMM8_V8_V8_V8) {
1222 actualNumArgs = ActualNumArgsOfCall::CALLARGS3;
1223 uint32_t a0 = READ_INST_8_1();
1224 uint32_t a1 = READ_INST_8_2();
1225 uint32_t a2 = READ_INST_8_3();
1226 LOG_INST() << "callargs3 "
1227 << "v" << a0 << ", v" << a1 << ", v" << a2;
1228 CALL_INITIALIZE();
1229 callThis = false;
1230 CALL_PUSH_ARGS(3);
1231 }
1232 HANDLE_OPCODE(DEPRECATED_CALLARGS3_PREF_V8_V8_V8_V8) {
1233 actualNumArgs = ActualNumArgsOfCall::CALLARGS3;
1234 startReg = READ_INST_8_1();
1235 uint32_t a0 = READ_INST_8_2();
1236 uint32_t a1 = READ_INST_8_3();
1237 uint32_t a2 = READ_INST_8_4();
1238 LOG_INST() << "callargs3 "
1239 << "v" << startReg << ", v" << a0 << ", v" << a1 << ", v" << a2;
1240 DEPRECATED_CALL_INITIALIZE();
1241 callThis = false;
1242 DEPRECATED_CALL_PUSH_ARGS(3);
1243 }
1244 HANDLE_OPCODE(CALLTHIS0_IMM8_V8) {
1245 actualNumArgs = ActualNumArgsOfCall::CALLARG0;
1246 startReg = READ_INST_8_1();
1247 LOG_INST() << "call.this0, v" << startReg;
1248 CALL_INITIALIZE();
1249 callThis = true;
1250 CALL_PUSH_ARGS(0);
1251 }
1252 HANDLE_OPCODE(CALLTHIS1_IMM8_V8_V8) {
1253 actualNumArgs = ActualNumArgsOfCall::CALLARG1;
1254 startReg = READ_INST_8_1();
1255 uint32_t a0 = READ_INST_8_2();
1256 LOG_INST() << "call.this1, v" << startReg << " v" << a0;
1257 CALL_INITIALIZE();
1258 callThis = true;
1259 CALL_PUSH_ARGS(1);
1260 }
1261 HANDLE_OPCODE(CALLTHIS2_IMM8_V8_V8_V8) {
1262 actualNumArgs = ActualNumArgsOfCall::CALLARGS2;
1263 startReg = READ_INST_8_1();
1264 uint32_t a0 = READ_INST_8_2();
1265 uint32_t a1 = READ_INST_8_3();
1266 LOG_INST() << "call.this2, v" << startReg << " v" << a0 << " v" << a1;
1267 CALL_INITIALIZE();
1268 callThis = true;
1269 CALL_PUSH_ARGS(2);
1270 }
1271 HANDLE_OPCODE(CALLTHIS3_IMM8_V8_V8_V8_V8) {
1272 actualNumArgs = ActualNumArgsOfCall::CALLARGS3;
1273 startReg = READ_INST_8_1();
1274 uint32_t a0 = READ_INST_8_2();
1275 uint32_t a1 = READ_INST_8_3();
1276 uint32_t a2 = READ_INST_8_4();
1277 LOG_INST() << "call.this3, v" << startReg << " v" << a0 << " v" << a1 << " v" << a2;
1278 CALL_INITIALIZE();
1279 callThis = true;
1280 CALL_PUSH_ARGS(3);
1281 }
1282 HANDLE_OPCODE(CALLTHISRANGE_IMM8_IMM8_V8) {
1283 actualNumArgs = READ_INST_8_1();
1284 startReg = READ_INST_8_2();
1285 LOG_INST() << "call.this.range " << actualNumArgs << ", v" << startReg;
1286 CALL_INITIALIZE();
1287 callThis = true;
1288 CALL_PUSH_ARGS(THISRANGE);
1289 }
1290 HANDLE_OPCODE(WIDE_CALLTHISRANGE_PREF_IMM16_V8) {
1291 actualNumArgs = READ_INST_16_1();
1292 startReg = READ_INST_8_3();
1293 LOG_INST() << "call.this.range " << actualNumArgs << ", v" << startReg;
1294 CALL_INITIALIZE();
1295 callThis = true;
1296 CALL_PUSH_ARGS(THISRANGE);
1297 }
1298 HANDLE_OPCODE(DEPRECATED_CALLTHISRANGE_PREF_IMM16_V8) {
1299 actualNumArgs = static_cast<int32_t>(READ_INST_16_1() - 1); // 1: exclude this
1300 startReg = READ_INST_8_3();
1301 LOG_INST() << "call.this.range " << actualNumArgs << ", v" << startReg;
1302 DEPRECATED_CALL_INITIALIZE();
1303 callThis = true;
1304 DEPRECATED_CALL_PUSH_ARGS(THISRANGE);
1305 }
1306 HANDLE_OPCODE(CALLRANGE_IMM8_IMM8_V8) {
1307 actualNumArgs = READ_INST_8_1();
1308 startReg = READ_INST_8_2();
1309 LOG_INST() << "calli.range " << actualNumArgs << ", v" << startReg;
1310 CALL_INITIALIZE();
1311 callThis = false;
1312 CALL_PUSH_ARGS(RANGE);
1313 }
1314 HANDLE_OPCODE(WIDE_CALLRANGE_PREF_IMM16_V8) {
1315 actualNumArgs = READ_INST_16_1();
1316 startReg = READ_INST_8_3();
1317 LOG_INST() << "calli.range " << actualNumArgs << ", v" << startReg;
1318 CALL_INITIALIZE();
1319 callThis = false;
1320 CALL_PUSH_ARGS(RANGE);
1321 }
1322 HANDLE_OPCODE(DEPRECATED_CALLRANGE_PREF_IMM16_V8) {
1323 actualNumArgs = READ_INST_16_1();
1324 startReg = READ_INST_8_3();
1325 LOG_INST() << "calli.range " << actualNumArgs << ", v" << startReg;
1326 DEPRECATED_CALL_INITIALIZE();
1327 callThis = false;
1328 DEPRECATED_CALL_PUSH_ARGS(RANGE);
1329 }
1330 setVregsAndFrameNative:
1331 startReg--;
1332 deprecatedSetVregsAndFrameNative: {
1333 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1334 *(--newSp) = (callThis ? sp[startReg + 1] : JSTaggedValue::VALUE_UNDEFINED); // push this
1335 *(--newSp) = JSTaggedValue::VALUE_UNDEFINED; // push new target
1336 *(--newSp) = ToUintPtr(funcObject); // push func
1337 ASSERT(methodHandle->GetNumVregsWithCallField() == 0); // no need to push vregs
1338 *(--newSp) = actualNumArgs + NUM_MANDATORY_JSFUNC_ARGS;
1339 *(--newSp) = ToUintPtr(thread);
1340 EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo *>(newSp);
1341
1342 InterpretedBuiltinFrame *state = GET_BUILTIN_FRAME(newSp);
1343 state->base.prev = sp;
1344 state->base.type = FrameType::INTERPRETER_BUILTIN_FRAME;
1345 state->pc = nullptr;
1346 state->function = JSTaggedValue(funcTagged);
1347 thread->SetCurrentSPFrame(newSp);
1348 LOG_INST() << "Entry: Runtime Call.";
1349 SAVE_PC();
1350 JSTaggedValue retValue = reinterpret_cast<EcmaEntrypoint>(
1351 const_cast<void *>(methodHandle->GetNativePointer()))(ecmaRuntimeCallInfo);
1352 thread->SetCurrentSPFrame(sp);
1353 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1354 LOG_INST() << "Exit: Runtime Call.";
1355 SET_ACC(retValue);
1356 INTERPRETER_HANDLE_RETURN();
1357 }
1358 setVregsAndFrameNotNative:
1359 startReg--;
1360 deprecatedSetVregsAndFrameNotNative: {
1361 if (JSFunction::Cast(funcObject)->IsClassConstructor()) {
1362 {
1363 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1364 JSHandle<JSObject> error =
1365 factory->GetJSError(ErrorType::TYPE_ERROR, "class constructor cannot called without 'new'");
1366 thread->SetException(error.GetTaggedValue());
1367 }
1368 INTERPRETER_GOTO_EXCEPTION_HANDLER();
1369 }
1370 JSTaggedType thisObj = JSTaggedValue::VALUE_UNDEFINED;
1371 uint64_t callField = methodHandle->GetCallField();
1372 if ((callField & CALL_TYPE_MASK) != 0) {
1373 // not normal call type, setting func/newTarget/this cannot be skipped
1374 if (methodHandle->HaveThisWithCallField()) {
1375 if (callThis) {
1376 thisObj = sp[startReg + 1];
1377 }
1378 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1379 *(--newSp) = thisObj; // push this
1380 }
1381 if (methodHandle->HaveNewTargetWithCallField()) {
1382 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1383 *(--newSp) = JSTaggedValue::VALUE_UNDEFINED; // push new target
1384 }
1385 if (methodHandle->HaveFuncWithCallField()) {
1386 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1387 *(--newSp) = ToUintPtr(funcObject); // push func
1388 }
1389 }
1390 int32_t numVregs = static_cast<int32_t>(methodHandle->GetNumVregsWithCallField());
1391 if (UNLIKELY(thread->DoStackOverflowCheck(newSp - numVregs))) {
1392 INTERPRETER_GOTO_EXCEPTION_HANDLER();
1393 }
1394 // push vregs
1395 CALL_PUSH_UNDEFINED(numVregs);
1396 SAVE_PC();
1397
1398 InterpretedFrame *state = GET_FRAME(newSp);
1399 state->base.prev = sp;
1400 state->base.type = FrameType::INTERPRETER_FRAME;
1401 state->pc = pc = methodHandle->GetBytecodeArray();
1402 sp = newSp;
1403 state->function = JSTaggedValue(funcTagged);
1404 state->thisObj = JSTaggedValue(thisObj);
1405 state->acc = JSTaggedValue::Hole();
1406 state->constpool = methodHandle->GetConstantPool();
1407 state->profileTypeInfo = methodHandle->GetProfileTypeInfo();
1408 JSTaggedValue env = JSFunction::Cast(funcObject)->GetLexicalEnv();
1409 state->env = env;
1410 thread->SetCurrentSPFrame(newSp);
1411 LOG_INST() << "Entry: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
1412 << std::hex << reinterpret_cast<uintptr_t>(pc);
1413 MethodEntry(thread);
1414 DISPATCH_OFFSET(0);
1415 }
1416 }
1417 HANDLE_OPCODE(APPLY_IMM8_V8_V8) {
1418 uint16_t v0 = READ_INST_8_1();
1419 uint16_t v1 = READ_INST_8_2();
1420 LOG_INST() << "intrinsics::callspread"
1421 << " v" << v0 << " v" << v1;
1422 JSTaggedValue func = GET_ACC();
1423 JSTaggedValue obj = GET_VREG_VALUE(v0);
1424 JSTaggedValue array = GET_VREG_VALUE(v1);
1425
1426 SAVE_PC();
1427 JSTaggedValue res = SlowRuntimeStub::CallSpread(thread, func, obj, array);
1428 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1429 SET_ACC(res);
1430
1431 DISPATCH(APPLY_IMM8_V8_V8);
1432 }
1433 HANDLE_OPCODE(DEPRECATED_CALLSPREAD_PREF_V8_V8_V8) {
1434 uint16_t v0 = READ_INST_8_1();
1435 uint16_t v1 = READ_INST_8_2();
1436 uint16_t v2 = READ_INST_8_3();
1437 LOG_INST() << "intrinsics::callspread"
1438 << " v" << v0 << " v" << v1 << " v" << v2;
1439 JSTaggedValue func = GET_VREG_VALUE(v0);
1440 JSTaggedValue obj = GET_VREG_VALUE(v1);
1441 JSTaggedValue array = GET_VREG_VALUE(v2);
1442
1443 SAVE_PC();
1444 JSTaggedValue res = SlowRuntimeStub::CallSpread(thread, func, obj, array);
1445 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1446 SET_ACC(res);
1447
1448 DISPATCH(DEPRECATED_CALLSPREAD_PREF_V8_V8_V8);
1449 }
1450 HANDLE_OPCODE(RETURN) {
1451 MethodExit(thread);
1452 LOG_INST() << "return";
1453 InterpretedFrame *state = GET_FRAME(sp);
1454 LOG_INST() << "Exit: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
1455 << std::hex << reinterpret_cast<uintptr_t>(state->pc);
1456 methodHandle.Update(JSFunction::Cast(state->function.GetTaggedObject())->GetMethod());
1457 [[maybe_unused]] auto fistPC = methodHandle->GetBytecodeArray();
1458 UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
1459
1460 JSTaggedType *currentSp = sp;
1461 sp = state->base.prev;
1462 ASSERT(sp != nullptr);
1463 InterpretedFrame *prevState = GET_FRAME(sp);
1464 pc = prevState->pc;
1465 // entry frame
1466 if (FrameHandler::IsEntryFrame(pc)) {
1467 state->acc = acc;
1468 return;
1469 }
1470 thread->SetCurrentSPFrame(sp);
1471 if (IsFastNewFrameExit(currentSp)) {
1472 JSFunction *func = JSFunction::Cast(GetFunction(currentSp).GetTaggedObject());
1473 if (acc.IsECMAObject()) {
1474 INTERPRETER_HANDLE_RETURN();
1475 }
1476
1477 if (func->IsBase()) {
1478 JSTaggedValue thisObject = GetThis(currentSp);
1479 SET_ACC(thisObject);
1480 INTERPRETER_HANDLE_RETURN();
1481 }
1482
1483 if (!acc.IsUndefined()) {
1484 {
1485 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1486 JSHandle<JSObject> error = factory->GetJSError(ErrorType::TYPE_ERROR,
1487 "Derived constructor must return object or undefined");
1488 thread->SetException(error.GetTaggedValue());
1489 }
1490 INTERPRETER_GOTO_EXCEPTION_HANDLER();
1491 }
1492
1493 JSTaggedValue thisObject = GetThis(currentSp);
1494 SET_ACC(thisObject);
1495 INTERPRETER_HANDLE_RETURN();
1496 }
1497 INTERPRETER_HANDLE_RETURN();
1498 }
1499 HANDLE_OPCODE(RETURNUNDEFINED) {
1500 MethodExit(thread);
1501 LOG_INST() << "return.undefined";
1502 InterpretedFrame *state = GET_FRAME(sp);
1503 LOG_INST() << "Exit: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
1504 << std::hex << reinterpret_cast<uintptr_t>(state->pc);
1505 methodHandle.Update(JSFunction::Cast(state->function.GetTaggedObject())->GetMethod());
1506 [[maybe_unused]] auto fistPC = methodHandle->GetBytecodeArray();
1507 UPDATE_HOTNESS_COUNTER_NON_ACC(-(pc - fistPC));
1508
1509 JSTaggedType *currentSp = sp;
1510 sp = state->base.prev;
1511 ASSERT(sp != nullptr);
1512 InterpretedFrame *prevState = GET_FRAME(sp);
1513 pc = prevState->pc;
1514 // entry frame
1515 if (FrameHandler::IsEntryFrame(pc)) {
1516 state->acc = JSTaggedValue::Undefined();
1517 return;
1518 }
1519 thread->SetCurrentSPFrame(sp);
1520 if (IsFastNewFrameExit(currentSp)) {
1521 JSFunction *func = JSFunction::Cast(GetFunction(currentSp).GetTaggedObject());
1522 if (func->IsBase()) {
1523 JSTaggedValue thisObject = GetThis(currentSp);
1524 SET_ACC(thisObject);
1525 INTERPRETER_HANDLE_RETURN();
1526 }
1527
1528 if (!acc.IsUndefined()) {
1529 {
1530 [[maybe_unused]] EcmaHandleScope handleScope(thread);
1531 JSHandle<JSObject> error = factory->GetJSError(ErrorType::TYPE_ERROR,
1532 "Derived constructor must return object or undefined");
1533 thread->SetException(error.GetTaggedValue());
1534 }
1535 INTERPRETER_GOTO_EXCEPTION_HANDLER();
1536 }
1537
1538 JSTaggedValue thisObject = GetThis(currentSp);
1539 SET_ACC(thisObject);
1540 INTERPRETER_HANDLE_RETURN();
1541 } else {
1542 SET_ACC(JSTaggedValue::Undefined());
1543 }
1544 INTERPRETER_HANDLE_RETURN();
1545 }
1546 HANDLE_OPCODE(LDNAN) {
1547 LOG_INST() << "intrinsics::ldnan";
1548 SET_ACC(JSTaggedValue(base::NAN_VALUE));
1549 DISPATCH(LDNAN);
1550 }
1551 HANDLE_OPCODE(LDINFINITY) {
1552 LOG_INST() << "intrinsics::ldinfinity";
1553 SET_ACC(JSTaggedValue(base::POSITIVE_INFINITY));
1554 DISPATCH(LDINFINITY);
1555 }
1556 HANDLE_OPCODE(LDUNDEFINED) {
1557 LOG_INST() << "intrinsics::ldundefined";
1558 SET_ACC(JSTaggedValue::Undefined());
1559 DISPATCH(LDUNDEFINED);
1560 }
1561 HANDLE_OPCODE(LDNULL) {
1562 LOG_INST() << "intrinsics::ldnull";
1563 SET_ACC(JSTaggedValue::Null());
1564 DISPATCH(LDNULL);
1565 }
1566 HANDLE_OPCODE(LDSYMBOL) {
1567 LOG_INST() << "intrinsics::ldsymbol";
1568 SET_ACC(globalEnv->GetSymbolFunction().GetTaggedValue());
1569 DISPATCH(LDSYMBOL);
1570 }
1571 HANDLE_OPCODE(LDGLOBAL) {
1572 LOG_INST() << "intrinsics::ldglobal";
1573 SET_ACC(globalObj);
1574 DISPATCH(LDGLOBAL);
1575 }
1576 HANDLE_OPCODE(LDTRUE) {
1577 LOG_INST() << "intrinsics::ldtrue";
1578 SET_ACC(JSTaggedValue::True());
1579 DISPATCH(LDTRUE);
1580 }
1581 HANDLE_OPCODE(LDFALSE) {
1582 LOG_INST() << "intrinsics::ldfalse";
1583 SET_ACC(JSTaggedValue::False());
1584 DISPATCH(LDFALSE);
1585 }
1586 HANDLE_OPCODE(GETUNMAPPEDARGS) {
1587 LOG_INST() << "intrinsics::getunmappedargs";
1588
1589 uint32_t startIdx = 0;
1590 uint32_t actualNumArgs = GetNumArgs(sp, 0, startIdx);
1591
1592 SAVE_PC();
1593 JSTaggedValue res = SlowRuntimeStub::GetUnmapedArgs(thread, sp, actualNumArgs, startIdx);
1594 INTERPRETER_RETURN_IF_ABRUPT(res);
1595 SET_ACC(res);
1596 DISPATCH(GETUNMAPPEDARGS);
1597 }
1598 HANDLE_OPCODE(ASYNCFUNCTIONENTER) {
1599 LOG_INST() << "intrinsics::asyncfunctionenter";
1600 SAVE_PC();
1601 JSTaggedValue res = SlowRuntimeStub::AsyncFunctionEnter(thread);
1602 INTERPRETER_RETURN_IF_ABRUPT(res);
1603 SET_ACC(res);
1604 DISPATCH(ASYNCFUNCTIONENTER);
1605 }
1606 HANDLE_OPCODE(TYPEOF_IMM8) {
1607 LOG_INST() << "intrinsics::typeof";
1608 JSTaggedValue res = FastRuntimeStub::FastTypeOf(thread, GET_ACC());
1609 SET_ACC(res);
1610 DISPATCH(TYPEOF_IMM8);
1611 }
1612 HANDLE_OPCODE(TYPEOF_IMM16) {
1613 LOG_INST() << "intrinsics::typeof";
1614 JSTaggedValue res = FastRuntimeStub::FastTypeOf(thread, GET_ACC());
1615 SET_ACC(res);
1616 DISPATCH(TYPEOF_IMM16);
1617 }
1618 HANDLE_OPCODE(GETPROPITERATOR) {
1619 LOG_INST() << "intrinsics::getpropiterator";
1620 SAVE_PC();
1621 JSTaggedValue res = SlowRuntimeStub::GetPropIterator(thread, GET_ACC());
1622 INTERPRETER_RETURN_IF_ABRUPT(res);
1623 SET_ACC(res);
1624 DISPATCH(GETPROPITERATOR);
1625 }
1626 HANDLE_OPCODE(CLOSEITERATOR_IMM8_V8) {
1627 uint16_t v0 = READ_INST_8_1();
1628 LOG_INST() << "intrinsics::closeiterator"
1629 << " v" << v0;
1630 SAVE_PC();
1631 JSTaggedValue iter = GET_VREG_VALUE(v0);
1632 JSTaggedValue res = SlowRuntimeStub::CloseIterator(thread, iter);
1633 INTERPRETER_RETURN_IF_ABRUPT(res);
1634 SET_ACC(res);
1635 DISPATCH(CLOSEITERATOR_IMM8_V8);
1636 }
1637 HANDLE_OPCODE(ADD2_IMM8_V8) {
1638 uint16_t v0 = READ_INST_8_1();
1639 LOG_INST() << "intrinsics::add2"
1640 << " v" << v0;
1641 int32_t a0;
1642 int32_t a1;
1643 JSTaggedValue left = GET_VREG_VALUE(v0);
1644 JSTaggedValue right = GET_ACC();
1645 // number, fast path
1646 if (left.IsInt() && right.IsInt()) {
1647 a0 = left.GetInt();
1648 a1 = right.GetInt();
1649 if ((a0 > 0 && a1 > INT32_MAX - a0) || (a0 < 0 && a1 < INT32_MIN - a0)) {
1650 auto ret = static_cast<double>(a0) + static_cast<double>(a1);
1651 SET_ACC(JSTaggedValue(ret));
1652 } else {
1653 SET_ACC(JSTaggedValue(a0 + a1));
1654 }
1655 } else if (left.IsNumber() && right.IsNumber()) {
1656 double a0Double = left.IsInt() ? left.GetInt() : left.GetDouble();
1657 double a1Double = right.IsInt() ? right.GetInt() : right.GetDouble();
1658 double ret = a0Double + a1Double;
1659 SET_ACC(JSTaggedValue(ret));
1660 } else {
1661 // one or both are not number, slow path
1662 SAVE_PC();
1663 JSTaggedValue res = SlowRuntimeStub::Add2(thread, left, right);
1664 INTERPRETER_RETURN_IF_ABRUPT(res);
1665 SET_ACC(res);
1666 }
1667 DISPATCH(ADD2_IMM8_V8);
1668 }
1669 HANDLE_OPCODE(SUB2_IMM8_V8) {
1670 uint16_t v0 = READ_INST_8_1();
1671 LOG_INST() << "intrinsics::sub2"
1672 << " v" << v0;
1673 int32_t a0;
1674 int32_t a1;
1675 JSTaggedValue left = GET_VREG_VALUE(v0);
1676 JSTaggedValue right = GET_ACC();
1677 if (left.IsInt() && right.IsInt()) {
1678 a0 = left.GetInt();
1679 a1 = -right.GetInt();
1680 if ((a0 > 0 && a1 > INT32_MAX - a0) || (a0 < 0 && a1 < INT32_MIN - a0)) {
1681 auto ret = static_cast<double>(a0) + static_cast<double>(a1);
1682 SET_ACC(JSTaggedValue(ret));
1683 } else {
1684 SET_ACC(JSTaggedValue(a0 + a1));
1685 }
1686 } else if (left.IsNumber() && right.IsNumber()) {
1687 double a0Double = left.IsInt() ? left.GetInt() : left.GetDouble();
1688 double a1Double = right.IsInt() ? right.GetInt() : right.GetDouble();
1689 double ret = a0Double - a1Double;
1690 SET_ACC(JSTaggedValue(ret));
1691 } else {
1692 // one or both are not number, slow path
1693 SAVE_PC();
1694 JSTaggedValue res = SlowRuntimeStub::Sub2(thread, left, right);
1695 INTERPRETER_RETURN_IF_ABRUPT(res);
1696 SET_ACC(res);
1697 }
1698 DISPATCH(SUB2_IMM8_V8);
1699 }
1700 HANDLE_OPCODE(MUL2_IMM8_V8) {
1701 uint16_t v0 = READ_INST_8_1();
1702 LOG_INST() << "intrinsics::mul2"
1703 << " v" << v0;
1704 JSTaggedValue left = GET_VREG_VALUE(v0);
1705 JSTaggedValue right = acc;
1706 JSTaggedValue value = FastRuntimeStub::FastMul(left, right);
1707 if (!value.IsHole()) {
1708 SET_ACC(value);
1709 } else {
1710 // slow path
1711 SAVE_PC();
1712 JSTaggedValue res = SlowRuntimeStub::Mul2(thread, left, right);
1713 INTERPRETER_RETURN_IF_ABRUPT(res);
1714 SET_ACC(res);
1715 }
1716 DISPATCH(MUL2_IMM8_V8);
1717 }
1718 HANDLE_OPCODE(DIV2_IMM8_V8) {
1719 uint16_t v0 = READ_INST_8_1();
1720 LOG_INST() << "intrinsics::div2"
1721 << " v" << v0;
1722 JSTaggedValue left = GET_VREG_VALUE(v0);
1723 JSTaggedValue right = acc;
1724 // fast path
1725 JSTaggedValue res = FastRuntimeStub::FastDiv(left, right);
1726 if (!res.IsHole()) {
1727 SET_ACC(res);
1728 } else {
1729 // slow path
1730 SAVE_PC();
1731 JSTaggedValue slowRes = SlowRuntimeStub::Div2(thread, left, right);
1732 INTERPRETER_RETURN_IF_ABRUPT(slowRes);
1733 SET_ACC(slowRes);
1734 }
1735 DISPATCH(DIV2_IMM8_V8);
1736 }
1737 HANDLE_OPCODE(MOD2_IMM8_V8) {
1738 uint16_t vs = READ_INST_8_1();
1739 LOG_INST() << "intrinsics::mod2"
1740 << " v" << vs;
1741 JSTaggedValue left = GET_VREG_VALUE(vs);
1742 JSTaggedValue right = GET_ACC();
1743 JSTaggedValue res = FastRuntimeStub::FastMod(left, right);
1744 if (!res.IsHole()) {
1745 SET_ACC(res);
1746 } else {
1747 // slow path
1748 SAVE_PC();
1749 JSTaggedValue slowRes = SlowRuntimeStub::Mod2(thread, left, right);
1750 INTERPRETER_RETURN_IF_ABRUPT(slowRes);
1751 SET_ACC(slowRes);
1752 }
1753 DISPATCH(MOD2_IMM8_V8);
1754 }
1755 HANDLE_OPCODE(EQ_IMM8_V8) {
1756 uint16_t v0 = READ_INST_8_1();
1757
1758 LOG_INST() << "intrinsics::eq"
1759 << " v" << v0;
1760 JSTaggedValue left = GET_VREG_VALUE(v0);
1761 JSTaggedValue right = acc;
1762 JSTaggedValue res = FastRuntimeStub::FastEqual(left, right);
1763 if (!res.IsHole()) {
1764 SET_ACC(res);
1765 } else {
1766 // slow path
1767 SAVE_PC();
1768 res = SlowRuntimeStub::Eq(thread, left, right);
1769 INTERPRETER_RETURN_IF_ABRUPT(res);
1770 SET_ACC(res);
1771 }
1772
1773 DISPATCH(EQ_IMM8_V8);
1774 }
1775 HANDLE_OPCODE(NOTEQ_IMM8_V8) {
1776 uint16_t v0 = READ_INST_8_1();
1777
1778 LOG_INST() << "intrinsics::noteq"
1779 << " v" << v0;
1780 JSTaggedValue left = GET_VREG_VALUE(v0);
1781 JSTaggedValue right = acc;
1782
1783 JSTaggedValue res = FastRuntimeStub::FastEqual(left, right);
1784 if (!res.IsHole()) {
1785 res = res.IsTrue() ? JSTaggedValue::False() : JSTaggedValue::True();
1786 SET_ACC(res);
1787 } else {
1788 // slow path
1789 SAVE_PC();
1790 res = SlowRuntimeStub::NotEq(thread, left, right);
1791 INTERPRETER_RETURN_IF_ABRUPT(res);
1792 SET_ACC(res);
1793 }
1794 DISPATCH(NOTEQ_IMM8_V8);
1795 }
1796 HANDLE_OPCODE(LESS_IMM8_V8) {
1797 uint16_t v0 = READ_INST_8_1();
1798
1799 LOG_INST() << "intrinsics::less"
1800 << " v" << v0;
1801 JSTaggedValue left = GET_VREG_VALUE(v0);
1802 JSTaggedValue right = GET_ACC();
1803 if (left.IsNumber() && right.IsNumber()) {
1804 // fast path
1805 double valueA = left.IsInt() ? static_cast<double>(left.GetInt()) : left.GetDouble();
1806 double valueB = right.IsInt() ? static_cast<double>(right.GetInt()) : right.GetDouble();
1807 bool ret = JSTaggedValue::StrictNumberCompare(valueA, valueB) == ComparisonResult::LESS;
1808 SET_ACC(ret ? JSTaggedValue::True() : JSTaggedValue::False());
1809 } else if (left.IsBigInt() && right.IsBigInt()) {
1810 bool result = BigInt::LessThan(left, right);
1811 SET_ACC(JSTaggedValue(result));
1812 } else {
1813 // slow path
1814 SAVE_PC();
1815 JSTaggedValue res = SlowRuntimeStub::Less(thread, left, right);
1816 INTERPRETER_RETURN_IF_ABRUPT(res);
1817 SET_ACC(res);
1818 }
1819 DISPATCH(LESS_IMM8_V8);
1820 }
1821 HANDLE_OPCODE(LESSEQ_IMM8_V8) {
1822 uint16_t vs = READ_INST_8_1();
1823 LOG_INST() << "intrinsics::lesseq "
1824 << " v" << vs;
1825 JSTaggedValue left = GET_VREG_VALUE(vs);
1826 JSTaggedValue right = GET_ACC();
1827 if (left.IsNumber() && right.IsNumber()) {
1828 // fast path
1829 double valueA = left.IsInt() ? static_cast<double>(left.GetInt()) : left.GetDouble();
1830 double valueB = right.IsInt() ? static_cast<double>(right.GetInt()) : right.GetDouble();
1831 bool ret = JSTaggedValue::StrictNumberCompare(valueA, valueB) <= ComparisonResult::EQUAL;
1832 SET_ACC(ret ? JSTaggedValue::True() : JSTaggedValue::False());
1833 } else if (left.IsBigInt() && right.IsBigInt()) {
1834 bool result = BigInt::LessThan(left, right) || BigInt::Equal(left, right);
1835 SET_ACC(JSTaggedValue(result));
1836 } else {
1837 // slow path
1838 SAVE_PC();
1839 JSTaggedValue res = SlowRuntimeStub::LessEq(thread, left, right);
1840 INTERPRETER_RETURN_IF_ABRUPT(res);
1841 SET_ACC(res);
1842 }
1843 DISPATCH(LESSEQ_IMM8_V8);
1844 }
1845 HANDLE_OPCODE(GREATER_IMM8_V8) {
1846 uint16_t v0 = READ_INST_8_1();
1847
1848 LOG_INST() << "intrinsics::greater"
1849 << " v" << v0;
1850 JSTaggedValue left = GET_VREG_VALUE(v0);
1851 JSTaggedValue right = acc;
1852 if (left.IsNumber() && right.IsNumber()) {
1853 // fast path
1854 double valueA = left.IsInt() ? static_cast<double>(left.GetInt()) : left.GetDouble();
1855 double valueB = right.IsInt() ? static_cast<double>(right.GetInt()) : right.GetDouble();
1856 bool ret = JSTaggedValue::StrictNumberCompare(valueA, valueB) == ComparisonResult::GREAT;
1857 SET_ACC(ret ? JSTaggedValue::True() : JSTaggedValue::False());
1858 } else if (left.IsBigInt() && right.IsBigInt()) {
1859 bool result = BigInt::LessThan(right, left);
1860 SET_ACC(JSTaggedValue(result));
1861 } else {
1862 // slow path
1863 SAVE_PC();
1864 JSTaggedValue res = SlowRuntimeStub::Greater(thread, left, right);
1865 INTERPRETER_RETURN_IF_ABRUPT(res);
1866 SET_ACC(res);
1867 }
1868 DISPATCH(GREATER_IMM8_V8);
1869 }
1870 HANDLE_OPCODE(GREATEREQ_IMM8_V8) {
1871 uint16_t vs = READ_INST_8_1();
1872 LOG_INST() << "intrinsics::greateq "
1873 << " v" << vs;
1874 JSTaggedValue left = GET_VREG_VALUE(vs);
1875 JSTaggedValue right = GET_ACC();
1876 if (left.IsNumber() && right.IsNumber()) {
1877 // fast path
1878 double valueA = left.IsInt() ? static_cast<double>(left.GetInt()) : left.GetDouble();
1879 double valueB = right.IsInt() ? static_cast<double>(right.GetInt()) : right.GetDouble();
1880 ComparisonResult comparison = JSTaggedValue::StrictNumberCompare(valueA, valueB);
1881 bool ret = (comparison == ComparisonResult::GREAT) || (comparison == ComparisonResult::EQUAL);
1882 SET_ACC(ret ? JSTaggedValue::True() : JSTaggedValue::False());
1883 } else if (left.IsBigInt() && right.IsBigInt()) {
1884 bool result = BigInt::LessThan(right, left) || BigInt::Equal(right, left);
1885 SET_ACC(JSTaggedValue(result));
1886 } else {
1887 // slow path
1888 SAVE_PC();
1889 JSTaggedValue res = SlowRuntimeStub::GreaterEq(thread, left, right);
1890 INTERPRETER_RETURN_IF_ABRUPT(res);
1891 SET_ACC(res);
1892 }
1893 DISPATCH(GREATEREQ_IMM8_V8);
1894 }
1895 HANDLE_OPCODE(SHL2_IMM8_V8) {
1896 uint16_t v0 = READ_INST_8_1();
1897
1898 LOG_INST() << "intrinsics::shl2"
1899 << " v" << v0;
1900 JSTaggedValue left = GET_VREG_VALUE(v0);
1901 JSTaggedValue right = GET_ACC();
1902 // both number, fast path
1903 if (left.IsInt() && right.IsInt()) {
1904 int32_t opNumber0 = left.GetInt();
1905 int32_t opNumber1 = right.GetInt();
1906 uint32_t shift =
1907 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1908 using unsigned_type = std::make_unsigned_t<int32_t>;
1909 auto ret =
1910 static_cast<int32_t>(static_cast<unsigned_type>(opNumber0) << shift); // NOLINT(hicpp-signed-bitwise)
1911 SET_ACC(JSTaggedValue(ret));
1912 } else if (left.IsNumber() && right.IsNumber()) {
1913 int32_t opNumber0 =
1914 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
1915 int32_t opNumber1 =
1916 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
1917 uint32_t shift =
1918 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1919 using unsigned_type = std::make_unsigned_t<int32_t>;
1920 auto ret =
1921 static_cast<int32_t>(static_cast<unsigned_type>(opNumber0) << shift); // NOLINT(hicpp-signed-bitwise)
1922 SET_ACC(JSTaggedValue(ret));
1923 } else {
1924 // slow path
1925 SAVE_PC();
1926 JSTaggedValue res = SlowRuntimeStub::Shl2(thread, left, right);
1927 INTERPRETER_RETURN_IF_ABRUPT(res);
1928 SET_ACC(res);
1929 }
1930 DISPATCH(SHL2_IMM8_V8);
1931 }
1932 HANDLE_OPCODE(SHR2_IMM8_V8) {
1933 uint16_t v0 = READ_INST_8_1();
1934
1935 LOG_INST() << "intrinsics::shr2"
1936 << " v" << v0;
1937 JSTaggedValue left = GET_VREG_VALUE(v0);
1938 JSTaggedValue right = GET_ACC();
1939 // both number, fast path
1940 if (left.IsInt() && right.IsInt()) {
1941 int32_t opNumber0 = left.GetInt();
1942 int32_t opNumber1 = right.GetInt();
1943 uint32_t shift =
1944 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1945 using unsigned_type = std::make_unsigned_t<uint32_t>;
1946 auto ret =
1947 static_cast<uint32_t>(static_cast<unsigned_type>(opNumber0) >> shift); // NOLINT(hicpp-signed-bitwise)
1948 SET_ACC(JSTaggedValue(ret));
1949 } else if (left.IsNumber() && right.IsNumber()) {
1950 int32_t opNumber0 =
1951 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
1952 int32_t opNumber1 =
1953 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
1954 uint32_t shift =
1955 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1956 using unsigned_type = std::make_unsigned_t<uint32_t>;
1957 auto ret =
1958 static_cast<uint32_t>(static_cast<unsigned_type>(opNumber0) >> shift); // NOLINT(hicpp-signed-bitwise)
1959 SET_ACC(JSTaggedValue(ret));
1960 } else {
1961 // slow path
1962 SAVE_PC();
1963 JSTaggedValue res = SlowRuntimeStub::Shr2(thread, left, right);
1964 INTERPRETER_RETURN_IF_ABRUPT(res);
1965 SET_ACC(res);
1966 }
1967 DISPATCH(SHR2_IMM8_V8);
1968 }
1969 HANDLE_OPCODE(ASHR2_IMM8_V8) {
1970 uint16_t v0 = READ_INST_8_1();
1971
1972 LOG_INST() << "intrinsics::ashr2"
1973 << " v" << v0;
1974 JSTaggedValue left = GET_VREG_VALUE(v0);
1975 JSTaggedValue right = GET_ACC();
1976 // both number, fast path
1977 if (left.IsInt() && right.IsInt()) {
1978 int32_t opNumber0 = left.GetInt();
1979 int32_t opNumber1 = right.GetInt();
1980 uint32_t shift =
1981 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1982 auto ret = static_cast<int32_t>(opNumber0 >> shift); // NOLINT(hicpp-signed-bitwise)
1983 SET_ACC(JSTaggedValue(ret));
1984 } else if (left.IsNumber() && right.IsNumber()) {
1985 int32_t opNumber0 =
1986 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
1987 int32_t opNumber1 =
1988 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
1989 uint32_t shift =
1990 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1991 auto ret = static_cast<int32_t>(opNumber0 >> shift); // NOLINT(hicpp-signed-bitwise)
1992 SET_ACC(JSTaggedValue(ret));
1993 } else {
1994 // slow path
1995 SAVE_PC();
1996 JSTaggedValue res = SlowRuntimeStub::Ashr2(thread, left, right);
1997 INTERPRETER_RETURN_IF_ABRUPT(res);
1998 SET_ACC(res);
1999 }
2000 DISPATCH(ASHR2_IMM8_V8);
2001 }
2002 HANDLE_OPCODE(AND2_IMM8_V8) {
2003 uint16_t v0 = READ_INST_8_1();
2004
2005 LOG_INST() << "intrinsics::and2"
2006 << " v" << v0;
2007 JSTaggedValue left = GET_VREG_VALUE(v0);
2008 JSTaggedValue right = GET_ACC();
2009 // both number, fast path
2010 if (left.IsInt() && right.IsInt()) {
2011 int32_t opNumber0 = left.GetInt();
2012 int32_t opNumber1 = right.GetInt();
2013 // NOLINT(hicpp-signed-bitwise)
2014 auto ret = static_cast<uint32_t>(opNumber0) & static_cast<uint32_t>(opNumber1);
2015 SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)));
2016 } else if (left.IsNumber() && right.IsNumber()) {
2017 int32_t opNumber0 =
2018 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
2019 int32_t opNumber1 =
2020 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
2021 // NOLINT(hicpp-signed-bitwise)
2022 auto ret = static_cast<uint32_t>(opNumber0) & static_cast<uint32_t>(opNumber1);
2023 SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)));
2024 } else {
2025 // slow path
2026 SAVE_PC();
2027 JSTaggedValue res = SlowRuntimeStub::And2(thread, left, right);
2028 INTERPRETER_RETURN_IF_ABRUPT(res);
2029 SET_ACC(res);
2030 }
2031 DISPATCH(AND2_IMM8_V8);
2032 }
2033 HANDLE_OPCODE(OR2_IMM8_V8) {
2034 uint16_t v0 = READ_INST_8_1();
2035
2036 LOG_INST() << "intrinsics::or2"
2037 << " v" << v0;
2038 JSTaggedValue left = GET_VREG_VALUE(v0);
2039 JSTaggedValue right = GET_ACC();
2040 // both number, fast path
2041 if (left.IsInt() && right.IsInt()) {
2042 int32_t opNumber0 = left.GetInt();
2043 int32_t opNumber1 = right.GetInt();
2044 // NOLINT(hicpp-signed-bitwise)
2045 auto ret = static_cast<uint32_t>(opNumber0) | static_cast<uint32_t>(opNumber1);
2046 SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)));
2047 } else if (left.IsNumber() && right.IsNumber()) {
2048 int32_t opNumber0 =
2049 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
2050 int32_t opNumber1 =
2051 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
2052 // NOLINT(hicpp-signed-bitwise)
2053 auto ret = static_cast<uint32_t>(opNumber0) | static_cast<uint32_t>(opNumber1);
2054 SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)));
2055 } else {
2056 // slow path
2057 SAVE_PC();
2058 JSTaggedValue res = SlowRuntimeStub::Or2(thread, left, right);
2059 INTERPRETER_RETURN_IF_ABRUPT(res);
2060 SET_ACC(res);
2061 }
2062 DISPATCH(OR2_IMM8_V8);
2063 }
2064 HANDLE_OPCODE(XOR2_IMM8_V8) {
2065 uint16_t v0 = READ_INST_8_1();
2066
2067 LOG_INST() << "intrinsics::xor2"
2068 << " v" << v0;
2069 JSTaggedValue left = GET_VREG_VALUE(v0);
2070 JSTaggedValue right = GET_ACC();
2071 // both number, fast path
2072 if (left.IsInt() && right.IsInt()) {
2073 int32_t opNumber0 = left.GetInt();
2074 int32_t opNumber1 = right.GetInt();
2075 // NOLINT(hicpp-signed-bitwise)
2076 auto ret = static_cast<uint32_t>(opNumber0) ^ static_cast<uint32_t>(opNumber1);
2077 SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)));
2078 } else if (left.IsNumber() && right.IsNumber()) {
2079 int32_t opNumber0 =
2080 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
2081 int32_t opNumber1 =
2082 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
2083 // NOLINT(hicpp-signed-bitwise)
2084 auto ret = static_cast<uint32_t>(opNumber0) ^ static_cast<uint32_t>(opNumber1);
2085 SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)));
2086 } else {
2087 // slow path
2088 SAVE_PC();
2089 JSTaggedValue res = SlowRuntimeStub::Xor2(thread, left, right);
2090 INTERPRETER_RETURN_IF_ABRUPT(res);
2091 SET_ACC(res);
2092 }
2093 DISPATCH(XOR2_IMM8_V8);
2094 }
2095 HANDLE_OPCODE(EXP_IMM8_V8) {
2096 uint16_t v0 = READ_INST_8_1();
2097 LOG_INST() << "intrinsics::exp"
2098 << " v" << v0;
2099 JSTaggedValue base = GET_VREG_VALUE(v0);
2100 JSTaggedValue exponent = GET_ACC();
2101 if (base.IsNumber() && exponent.IsNumber()) {
2102 // fast path
2103 double doubleBase = base.IsInt() ? base.GetInt() : base.GetDouble();
2104 double doubleExponent = exponent.IsInt() ? exponent.GetInt() : exponent.GetDouble();
2105 if (std::abs(doubleBase) == 1 && std::isinf(doubleExponent)) {
2106 SET_ACC(JSTaggedValue(base::NAN_VALUE));
2107 }
2108 bool baseZero = doubleBase == 0 &&
2109 (base::bit_cast<uint64_t>(doubleBase) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK;
2110 bool isFinite = std::isfinite(doubleExponent);
2111 bool truncEqual = base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent;
2112 bool halfTruncEqual = (base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF) ==
2113 (doubleExponent / 2);
2114 if (baseZero && isFinite && truncEqual && halfTruncEqual) {
2115 if (doubleExponent > 0) {
2116 SET_ACC(JSTaggedValue(-0.0));
2117 }
2118 if (doubleExponent < 0) {
2119 SET_ACC(JSTaggedValue(-base::POSITIVE_INFINITY));
2120 }
2121 }
2122 SET_ACC(JSTaggedValue(std::pow(doubleBase, doubleExponent)));
2123 } else {
2124 // slow path
2125 SAVE_PC();
2126 JSTaggedValue res = SlowRuntimeStub::Exp(thread, base, exponent);
2127 INTERPRETER_RETURN_IF_ABRUPT(res);
2128 SET_ACC(res);
2129 }
2130 DISPATCH(EXP_IMM8_V8);
2131 }
2132 HANDLE_OPCODE(ISIN_IMM8_V8) {
2133 uint16_t v0 = READ_INST_8_1();
2134 LOG_INST() << "intrinsics::isin"
2135 << " v" << v0;
2136 JSTaggedValue prop = GET_VREG_VALUE(v0);
2137 JSTaggedValue obj = GET_ACC();
2138 SAVE_PC();
2139 JSTaggedValue res = SlowRuntimeStub::IsIn(thread, prop, obj);
2140 INTERPRETER_RETURN_IF_ABRUPT(res);
2141 SET_ACC(res);
2142 DISPATCH(ISIN_IMM8_V8);
2143 }
2144 HANDLE_OPCODE(INSTANCEOF_IMM8_V8) {
2145 uint16_t v0 = READ_INST_8_1();
2146 LOG_INST() << "intrinsics::instanceof"
2147 << " v" << v0;
2148 JSTaggedValue object = GET_VREG_VALUE(v0);
2149 JSTaggedValue target = GET_ACC();
2150
2151 #if ECMASCRIPT_ENABLE_IC
2152 // 1. If Type(target) is not Object, throw a TypeError exception.
2153 if (target.IsECMAObject()) {
2154 // 2. Let instOfHandler be GetMethod(target, @@hasInstance).
2155 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2156 if (!profileTypeInfo.IsUndefined()) {
2157 uint16_t slotId = READ_INST_8_0();
2158 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
2159 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
2160 JSTaggedValue instOfHandler = JSTaggedValue::Hole();
2161 JSTaggedValue res = JSTaggedValue::Hole();
2162 if (LIKELY(firstValue.IsHeapObject())) {
2163 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
2164 instOfHandler = ICRuntimeStub::TryLoadICByName(thread, target, firstValue, secondValue);
2165 }
2166 if (LIKELY(!instOfHandler.IsHole())) {
2167 res = SlowRuntimeStub::InstanceofByHandler(thread, target, object, instOfHandler);
2168 } else if (!firstValue.IsHole()) {
2169 // IC Miss
2170 SAVE_ACC();
2171 profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2172 profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
2173 EcmaVM *vm = thread->GetEcmaVM();
2174 JSTaggedValue key = vm->GetGlobalEnv()->GetHasInstanceSymbol().GetTaggedValue();
2175 instOfHandler = ICRuntimeStub::LoadICByName(thread, profileTypeArray, target, key, slotId);
2176 RESTORE_ACC();
2177 target = GET_ACC();
2178 object = GET_VREG_VALUE(v0);
2179 res = SlowRuntimeStub::InstanceofByHandler(thread, target, object, instOfHandler);
2180 }
2181 if (LIKELY(!res.IsHole())) {
2182 INTERPRETER_RETURN_IF_ABRUPT(res);
2183 SET_ACC(res);
2184 DISPATCH(INSTANCEOF_IMM8_V8);
2185 }
2186 }
2187 }
2188 #endif
2189 SAVE_PC();
2190 JSTaggedValue res = SlowRuntimeStub::Instanceof(thread, object, target);
2191 INTERPRETER_RETURN_IF_ABRUPT(res);
2192 SET_ACC(res);
2193 DISPATCH(INSTANCEOF_IMM8_V8);
2194 }
2195 HANDLE_OPCODE(STRICTNOTEQ_IMM8_V8) {
2196 uint16_t v0 = READ_INST_8_1();
2197 LOG_INST() << "intrinsics::strictnoteq"
2198 << " v" << v0;
2199 JSTaggedValue left = GET_VREG_VALUE(v0);
2200 JSTaggedValue right = GET_ACC();
2201 JSTaggedValue res = FastRuntimeStub::FastStrictEqual(left, right);
2202 if (!res.IsHole()) {
2203 res = res.IsTrue() ? JSTaggedValue::False() : JSTaggedValue::True();
2204 SET_ACC(res);
2205 } else {
2206 // slow path
2207 SAVE_PC();
2208 res = SlowRuntimeStub::NotEq(thread, left, right);
2209 INTERPRETER_RETURN_IF_ABRUPT(res);
2210 SET_ACC(res);
2211 }
2212 DISPATCH(STRICTNOTEQ_IMM8_V8);
2213 }
2214 HANDLE_OPCODE(STRICTEQ_IMM8_V8) {
2215 uint16_t v0 = READ_INST_8_1();
2216 LOG_INST() << "intrinsics::stricteq"
2217 << " v" << v0;
2218 JSTaggedValue left = GET_VREG_VALUE(v0);
2219 JSTaggedValue right = GET_ACC();
2220 JSTaggedValue res = FastRuntimeStub::FastStrictEqual(left, right);
2221 if (!res.IsHole()) {
2222 SET_ACC(res);
2223 } else {
2224 // slow path
2225 SAVE_PC();
2226 res = SlowRuntimeStub::Eq(thread, left, right);
2227 INTERPRETER_RETURN_IF_ABRUPT(res);
2228 SET_ACC(res);
2229 }
2230 DISPATCH(STRICTEQ_IMM8_V8);
2231 }
2232 HANDLE_OPCODE(CREATEITERRESULTOBJ_V8_V8) {
2233 uint16_t v0 = READ_INST_8_0();
2234 uint16_t v1 = READ_INST_8_1();
2235 LOG_INST() << "intrinsics::createiterresultobj"
2236 << " v" << v0 << " v" << v1;
2237 JSTaggedValue value = GET_VREG_VALUE(v0);
2238 JSTaggedValue flag = GET_VREG_VALUE(v1);
2239 SAVE_PC();
2240 JSTaggedValue res = SlowRuntimeStub::CreateIterResultObj(thread, value, flag);
2241 INTERPRETER_RETURN_IF_ABRUPT(res);
2242 SET_ACC(res);
2243 DISPATCH(CREATEITERRESULTOBJ_V8_V8);
2244 }
2245 HANDLE_OPCODE(NEWOBJAPPLY_IMM8_V8) {
2246 uint16_t v0 = READ_INST_8_1();
2247 LOG_INST() << "intrinsic::newobjapply"
2248 << " v" << v0;
2249 JSTaggedValue func = GET_VREG_VALUE(v0);
2250 JSTaggedValue array = GET_ACC();
2251 SAVE_PC();
2252 JSTaggedValue res = SlowRuntimeStub::NewObjApply(thread, func, array);
2253 INTERPRETER_RETURN_IF_ABRUPT(res);
2254 SET_ACC(res);
2255 DISPATCH(NEWOBJAPPLY_IMM8_V8);
2256 }
2257 HANDLE_OPCODE(NEWOBJAPPLY_IMM16_V8) {
2258 uint16_t v0 = READ_INST_8_2();
2259 LOG_INST() << "intrinsic::newobjapply"
2260 << " v" << v0;
2261 JSTaggedValue func = GET_VREG_VALUE(v0);
2262 JSTaggedValue array = GET_ACC();
2263 SAVE_PC();
2264 JSTaggedValue res = SlowRuntimeStub::NewObjApply(thread, func, array);
2265 INTERPRETER_RETURN_IF_ABRUPT(res);
2266 SET_ACC(res);
2267 DISPATCH(NEWOBJAPPLY_IMM16_V8);
2268 }
2269 HANDLE_OPCODE(STOWNBYNAME_IMM8_ID16_V8) {
2270 uint16_t stringId = READ_INST_16_1();
2271 uint32_t v0 = READ_INST_8_3();
2272 LOG_INST() << "intrinsics::stownbyname "
2273 << "v" << v0 << " stringId:" << stringId;
2274
2275 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2276 if (receiver.IsJSObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
2277 SAVE_ACC();
2278 auto constpool = GetConstantPool(sp);
2279 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
2280 RESTORE_ACC();
2281 JSTaggedValue value = GET_ACC();
2282 // fast path
2283 SAVE_ACC();
2284 receiver = GET_VREG_VALUE(v0);
2285 JSTaggedValue res = FastRuntimeStub::SetPropertyByName<true>(thread, receiver, propKey, value);
2286 if (!res.IsHole()) {
2287 INTERPRETER_RETURN_IF_ABRUPT(res);
2288 RESTORE_ACC();
2289 DISPATCH(STOWNBYNAME_IMM8_ID16_V8);
2290 }
2291 RESTORE_ACC();
2292 }
2293
2294 SAVE_ACC();
2295 auto constpool = GetConstantPool(sp);
2296 auto propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
2297 RESTORE_ACC();
2298 auto value = GET_ACC(); // Maybe moved by GC
2299 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
2300 JSTaggedValue res = SlowRuntimeStub::StOwnByName(thread, receiver, propKey, value);
2301 RESTORE_ACC();
2302 INTERPRETER_RETURN_IF_ABRUPT(res);
2303 DISPATCH(STOWNBYNAME_IMM8_ID16_V8);
2304 }
2305 HANDLE_OPCODE(STOWNBYNAME_IMM16_ID16_V8) {
2306 uint16_t stringId = READ_INST_16_2();
2307 uint32_t v0 = READ_INST_8_4();
2308 LOG_INST() << "intrinsics::stownbyname "
2309 << "v" << v0 << " stringId:" << stringId;
2310
2311 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2312 if (receiver.IsJSObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
2313 SAVE_ACC();
2314 auto constpool = GetConstantPool(sp);
2315 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
2316 RESTORE_ACC();
2317 JSTaggedValue value = GET_ACC();
2318 // fast path
2319 SAVE_ACC();
2320 receiver = GET_VREG_VALUE(v0);
2321 JSTaggedValue res = FastRuntimeStub::SetPropertyByName<true>(thread, receiver, propKey, value);
2322 if (!res.IsHole()) {
2323 INTERPRETER_RETURN_IF_ABRUPT(res);
2324 RESTORE_ACC();
2325 DISPATCH(STOWNBYNAME_IMM16_ID16_V8);
2326 }
2327 RESTORE_ACC();
2328 }
2329
2330 SAVE_ACC();
2331 auto constpool = GetConstantPool(sp);
2332 auto propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
2333 RESTORE_ACC();
2334 auto value = GET_ACC(); // Maybe moved by GC
2335 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
2336 JSTaggedValue res = SlowRuntimeStub::StOwnByName(thread, receiver, propKey, value);
2337 RESTORE_ACC();
2338 INTERPRETER_RETURN_IF_ABRUPT(res);
2339 DISPATCH(STOWNBYNAME_IMM16_ID16_V8);
2340 }
2341 HANDLE_OPCODE(CREATEEMPTYARRAY_IMM8) {
2342 LOG_INST() << "intrinsics::createemptyarray";
2343 SAVE_PC();
2344 JSTaggedValue res = SlowRuntimeStub::CreateEmptyArray(thread, factory, globalEnv);
2345 SET_ACC(res);
2346 DISPATCH(CREATEEMPTYARRAY_IMM8);
2347 }
2348 HANDLE_OPCODE(CREATEEMPTYARRAY_IMM16) {
2349 LOG_INST() << "intrinsics::createemptyarray";
2350 SAVE_PC();
2351 JSTaggedValue res = SlowRuntimeStub::CreateEmptyArray(thread, factory, globalEnv);
2352 SET_ACC(res);
2353 DISPATCH(CREATEEMPTYARRAY_IMM16);
2354 }
2355 HANDLE_OPCODE(CREATEEMPTYOBJECT) {
2356 LOG_INST() << "intrinsics::createemptyobject";
2357 SAVE_PC();
2358 JSTaggedValue res = SlowRuntimeStub::CreateEmptyObject(thread, factory, globalEnv);
2359 SET_ACC(res);
2360 DISPATCH(CREATEEMPTYOBJECT);
2361 }
2362 HANDLE_OPCODE(CREATEREGEXPWITHLITERAL_IMM8_ID16_IMM8) {
2363 uint16_t stringId = READ_INST_16_1();
2364 SAVE_ACC();
2365 auto constpool = GetConstantPool(sp);
2366 JSTaggedValue pattern = GET_STR_FROM_CACHE(stringId);
2367 uint8_t flags = READ_INST_8_3();
2368 LOG_INST() << "intrinsics::createregexpwithliteral "
2369 << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(pattern.GetTaggedObject()))
2370 << ", flags:" << flags;
2371 JSTaggedValue res = SlowRuntimeStub::CreateRegExpWithLiteral(thread, pattern, flags);
2372 INTERPRETER_RETURN_IF_ABRUPT(res);
2373 SET_ACC(res);
2374 DISPATCH(CREATEREGEXPWITHLITERAL_IMM8_ID16_IMM8);
2375 }
2376 HANDLE_OPCODE(CREATEREGEXPWITHLITERAL_IMM16_ID16_IMM8) {
2377 uint16_t stringId = READ_INST_16_2();
2378 SAVE_ACC();
2379 auto constpool = GetConstantPool(sp);
2380 JSTaggedValue pattern = GET_STR_FROM_CACHE(stringId);
2381 uint8_t flags = READ_INST_8_4();
2382 LOG_INST() << "intrinsics::createregexpwithliteral "
2383 << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(pattern.GetTaggedObject()))
2384 << ", flags:" << flags;
2385 JSTaggedValue res = SlowRuntimeStub::CreateRegExpWithLiteral(thread, pattern, flags);
2386 INTERPRETER_RETURN_IF_ABRUPT(res);
2387 SET_ACC(res);
2388 DISPATCH(CREATEREGEXPWITHLITERAL_IMM16_ID16_IMM8);
2389 }
2390 HANDLE_OPCODE(GETNEXTPROPNAME_V8) {
2391 uint16_t v0 = READ_INST_8_0();
2392 LOG_INST() << "intrinsic::getnextpropname"
2393 << " v" << v0;
2394 JSTaggedValue iter = GET_VREG_VALUE(v0);
2395 SAVE_PC();
2396 JSTaggedValue res = SlowRuntimeStub::GetNextPropName(thread, iter);
2397 INTERPRETER_RETURN_IF_ABRUPT(res);
2398 SET_ACC(res);
2399 DISPATCH(GETNEXTPROPNAME_V8);
2400 }
2401 HANDLE_OPCODE(STOWNBYVALUE_IMM8_V8_V8) {
2402 uint32_t v0 = READ_INST_8_1();
2403 uint32_t v1 = READ_INST_8_2();
2404 LOG_INST() << "intrinsics::stownbyvalue"
2405 << " v" << v0 << " v" << v1;
2406
2407 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2408 if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
2409 SAVE_ACC();
2410 JSTaggedValue propKey = GET_VREG_VALUE(v1);
2411 JSTaggedValue value = GET_ACC();
2412 // fast path
2413 JSTaggedValue res = FastRuntimeStub::SetPropertyByValue<true>(thread, receiver, propKey, value);
2414
2415 // SetPropertyByValue maybe gc need update the value
2416 RESTORE_ACC();
2417 propKey = GET_VREG_VALUE(v1);
2418 value = GET_ACC();
2419 if (!res.IsHole()) {
2420 INTERPRETER_RETURN_IF_ABRUPT(res);
2421 RESTORE_ACC();
2422 DISPATCH(STOWNBYVALUE_IMM8_V8_V8);
2423 }
2424 }
2425
2426 // slow path
2427 SAVE_ACC();
2428 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
2429 auto propKey = GET_VREG_VALUE(v1); // Maybe moved by GC
2430 auto value = GET_ACC(); // Maybe moved by GC
2431 SAVE_PC();
2432 JSTaggedValue res = SlowRuntimeStub::StOwnByValue(thread, receiver, propKey, value);
2433 RESTORE_ACC();
2434 INTERPRETER_RETURN_IF_ABRUPT(res);
2435 DISPATCH(STOWNBYVALUE_IMM8_V8_V8);
2436 }
2437 HANDLE_OPCODE(LDHOLE) {
2438 LOG_INST() << "intrinsic::ldhole";
2439 SET_ACC(JSTaggedValue::Hole());
2440 DISPATCH(LDHOLE);
2441 }
2442 HANDLE_OPCODE(DEFINEGETTERSETTERBYVALUE_V8_V8_V8_V8) {
2443 uint16_t v0 = READ_INST_8_0();
2444 uint16_t v1 = READ_INST_8_1();
2445 uint16_t v2 = READ_INST_8_2();
2446 uint16_t v3 = READ_INST_8_3();
2447 LOG_INST() << "intrinsics::definegettersetterbyvalue"
2448 << " v" << v0 << " v" << v1 << " v" << v2 << " v" << v3;
2449
2450 JSTaggedValue obj = GET_VREG_VALUE(v0);
2451 JSTaggedValue prop = GET_VREG_VALUE(v1);
2452 JSTaggedValue getter = GET_VREG_VALUE(v2);
2453 JSTaggedValue setter = GET_VREG_VALUE(v3);
2454 JSTaggedValue flag = GET_ACC();
2455 SAVE_PC();
2456 JSTaggedValue res =
2457 SlowRuntimeStub::DefineGetterSetterByValue(thread, obj, prop, getter, setter, flag.ToBoolean());
2458 INTERPRETER_RETURN_IF_ABRUPT(res);
2459 SET_ACC(res);
2460 DISPATCH(DEFINEGETTERSETTERBYVALUE_V8_V8_V8_V8);
2461 }
2462 HANDLE_OPCODE(STOBJBYVALUE_IMM8_V8_V8) {
2463 uint32_t v0 = READ_INST_8_1();
2464 uint32_t v1 = READ_INST_8_2();
2465
2466 LOG_INST() << "intrinsics::stobjbyvalue"
2467 << " v" << v0 << " v" << v1;
2468
2469 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2470 #if ECMASCRIPT_ENABLE_IC
2471 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2472 if (!profileTypeInfo.IsUndefined()) {
2473 uint16_t slotId = READ_INST_8_0();
2474 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
2475 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
2476 JSTaggedValue propKey = GET_VREG_VALUE(v1);
2477 JSTaggedValue value = GET_ACC();
2478 JSTaggedValue res = JSTaggedValue::Hole();
2479 SAVE_ACC();
2480
2481 if (LIKELY(firstValue.IsHeapObject())) {
2482 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
2483 res = ICRuntimeStub::TryStoreICByValue(thread, receiver, propKey, firstValue, secondValue, value);
2484 }
2485 // IC miss and not enter the megamorphic state, store as polymorphic
2486 if (res.IsHole() && !firstValue.IsHole()) {
2487 res = ICRuntimeStub::StoreICByValue(thread,
2488 profileTypeArray,
2489 receiver, propKey, value, slotId);
2490 }
2491
2492 if (LIKELY(!res.IsHole())) {
2493 INTERPRETER_RETURN_IF_ABRUPT(res);
2494 RESTORE_ACC();
2495 DISPATCH(STOBJBYVALUE_IMM8_V8_V8);
2496 }
2497 }
2498 #endif
2499 if (receiver.IsHeapObject()) {
2500 SAVE_ACC();
2501 JSTaggedValue propKey = GET_VREG_VALUE(v1);
2502 JSTaggedValue value = GET_ACC();
2503 // fast path
2504 JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, propKey, value);
2505 if (!res.IsHole()) {
2506 INTERPRETER_RETURN_IF_ABRUPT(res);
2507 RESTORE_ACC();
2508 DISPATCH(STOBJBYVALUE_IMM8_V8_V8);
2509 }
2510 RESTORE_ACC();
2511 }
2512 {
2513 // slow path
2514 SAVE_ACC();
2515 SAVE_PC();
2516 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
2517 JSTaggedValue propKey = GET_VREG_VALUE(v1); // Maybe moved by GC
2518 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
2519 JSTaggedValue res = SlowRuntimeStub::StObjByValue(thread, receiver, propKey, value);
2520 INTERPRETER_RETURN_IF_ABRUPT(res);
2521 RESTORE_ACC();
2522 }
2523 DISPATCH(STOBJBYVALUE_IMM8_V8_V8);
2524 }
2525 HANDLE_OPCODE(STOBJBYVALUE_IMM16_V8_V8) {
2526 uint32_t v0 = READ_INST_8_2();
2527 uint32_t v1 = READ_INST_8_3();
2528
2529 LOG_INST() << "intrinsics::stobjbyvalue"
2530 << " v" << v0 << " v" << v1;
2531
2532 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2533 #if ECMASCRIPT_ENABLE_IC
2534 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2535 if (!profileTypeInfo.IsUndefined()) {
2536 uint16_t slotId = READ_INST_16_0();
2537 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
2538 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
2539 JSTaggedValue propKey = GET_VREG_VALUE(v1);
2540 JSTaggedValue value = GET_ACC();
2541 JSTaggedValue res = JSTaggedValue::Hole();
2542 SAVE_ACC();
2543
2544 if (LIKELY(firstValue.IsHeapObject())) {
2545 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
2546 res = ICRuntimeStub::TryStoreICByValue(thread, receiver, propKey, firstValue, secondValue, value);
2547 }
2548 // IC miss and not enter the megamorphic state, store as polymorphic
2549 if (res.IsHole() && !firstValue.IsHole()) {
2550 res = ICRuntimeStub::StoreICByValue(thread,
2551 profileTypeArray,
2552 receiver, propKey, value, slotId);
2553 }
2554
2555 if (LIKELY(!res.IsHole())) {
2556 INTERPRETER_RETURN_IF_ABRUPT(res);
2557 RESTORE_ACC();
2558 DISPATCH(STOBJBYVALUE_IMM16_V8_V8);
2559 }
2560 }
2561 #endif
2562 if (receiver.IsHeapObject()) {
2563 SAVE_ACC();
2564 JSTaggedValue propKey = GET_VREG_VALUE(v1);
2565 JSTaggedValue value = GET_ACC();
2566 // fast path
2567 JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, propKey, value);
2568 if (!res.IsHole()) {
2569 INTERPRETER_RETURN_IF_ABRUPT(res);
2570 RESTORE_ACC();
2571 DISPATCH(STOBJBYVALUE_IMM16_V8_V8);
2572 }
2573 RESTORE_ACC();
2574 }
2575 {
2576 // slow path
2577 SAVE_ACC();
2578 SAVE_PC();
2579 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
2580 JSTaggedValue propKey = GET_VREG_VALUE(v1); // Maybe moved by GC
2581 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
2582 JSTaggedValue res = SlowRuntimeStub::StObjByValue(thread, receiver, propKey, value);
2583 INTERPRETER_RETURN_IF_ABRUPT(res);
2584 RESTORE_ACC();
2585 }
2586 DISPATCH(STOBJBYVALUE_IMM16_V8_V8);
2587 }
2588 HANDLE_OPCODE(STSUPERBYVALUE_IMM8_V8_V8) {
2589 uint32_t v0 = READ_INST_8_1();
2590 uint32_t v1 = READ_INST_8_2();
2591
2592 LOG_INST() << "intrinsics::stsuperbyvalue"
2593 << " v" << v0 << " v" << v1;
2594 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2595 JSTaggedValue propKey = GET_VREG_VALUE(v1);
2596 JSTaggedValue value = GET_ACC();
2597
2598 // slow path
2599 SAVE_ACC();
2600 SAVE_PC();
2601 JSTaggedValue thisFunc = GetFunction(sp);
2602 JSTaggedValue res = SlowRuntimeStub::StSuperByValue(thread, receiver, propKey, value, thisFunc);
2603 INTERPRETER_RETURN_IF_ABRUPT(res);
2604 RESTORE_ACC();
2605 DISPATCH(STSUPERBYVALUE_IMM8_V8_V8);
2606 }
2607 HANDLE_OPCODE(TRYLDGLOBALBYNAME_IMM8_ID16) {
2608 uint16_t stringId = READ_INST_16_1();
2609 auto constpool = GetConstantPool(sp);
2610 auto prop = GET_STR_FROM_CACHE(stringId);
2611
2612 LOG_INST() << "intrinsics::tryldglobalbyname "
2613 << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(prop.GetTaggedObject()));
2614
2615 #if ECMASCRIPT_ENABLE_IC
2616 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2617 if (!profileTypeInfo.IsUndefined()) {
2618 uint16_t slotId = READ_INST_8_0();
2619 JSTaggedValue res = ICRuntimeStub::LoadGlobalICByName(thread,
2620 ProfileTypeInfo::Cast(
2621 profileTypeInfo.GetTaggedObject()),
2622 globalObj, prop, slotId, true);
2623 INTERPRETER_RETURN_IF_ABRUPT(res);
2624 SET_ACC(res);
2625 DISPATCH(TRYLDGLOBALBYNAME_IMM8_ID16);
2626 }
2627 #endif
2628
2629 // order: 1. global record 2. global object
2630 JSTaggedValue result = SlowRuntimeStub::LdGlobalRecord(thread, prop);
2631 if (!result.IsUndefined()) {
2632 SET_ACC(PropertyBox::Cast(result.GetTaggedObject())->GetValue());
2633 } else {
2634 JSTaggedValue globalResult = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, prop);
2635 if (!globalResult.IsHole()) {
2636 SET_ACC(globalResult);
2637 } else {
2638 // slow path
2639 SAVE_PC();
2640 JSTaggedValue res = SlowRuntimeStub::TryLdGlobalByNameFromGlobalProto(thread, globalObj, prop);
2641 INTERPRETER_RETURN_IF_ABRUPT(res);
2642 SET_ACC(res);
2643 }
2644 }
2645
2646 DISPATCH(TRYLDGLOBALBYNAME_IMM8_ID16);
2647 }
2648 HANDLE_OPCODE(TRYLDGLOBALBYNAME_IMM16_ID16) {
2649 uint16_t stringId = READ_INST_16_2();
2650 auto constpool = GetConstantPool(sp);
2651 auto prop = GET_STR_FROM_CACHE(stringId);
2652
2653 LOG_INST() << "intrinsics::tryldglobalbyname "
2654 << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(prop.GetTaggedObject()));
2655
2656 #if ECMASCRIPT_ENABLE_IC
2657 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2658 if (!profileTypeInfo.IsUndefined()) {
2659 uint16_t slotId = READ_INST_16_0();
2660 JSTaggedValue res = ICRuntimeStub::LoadGlobalICByName(thread,
2661 ProfileTypeInfo::Cast(
2662 profileTypeInfo.GetTaggedObject()),
2663 globalObj, prop, slotId, true);
2664 INTERPRETER_RETURN_IF_ABRUPT(res);
2665 SET_ACC(res);
2666 DISPATCH(TRYLDGLOBALBYNAME_IMM16_ID16);
2667 }
2668 #endif
2669
2670 // order: 1. global record 2. global object
2671 JSTaggedValue result = SlowRuntimeStub::LdGlobalRecord(thread, prop);
2672 if (!result.IsUndefined()) {
2673 SET_ACC(PropertyBox::Cast(result.GetTaggedObject())->GetValue());
2674 } else {
2675 JSTaggedValue globalResult = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, prop);
2676 if (!globalResult.IsHole()) {
2677 SET_ACC(globalResult);
2678 } else {
2679 // slow path
2680 SAVE_PC();
2681 JSTaggedValue res = SlowRuntimeStub::TryLdGlobalByNameFromGlobalProto(thread, globalObj, prop);
2682 INTERPRETER_RETURN_IF_ABRUPT(res);
2683 SET_ACC(res);
2684 }
2685 }
2686
2687 DISPATCH(TRYLDGLOBALBYNAME_IMM16_ID16);
2688 }
2689 HANDLE_OPCODE(TRYSTGLOBALBYNAME_IMM8_ID16) {
2690 uint16_t stringId = READ_INST_16_1();
2691 SAVE_ACC();
2692 auto constpool = GetConstantPool(sp);
2693 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
2694 RESTORE_ACC();
2695 LOG_INST() << "intrinsics::trystglobalbyname"
2696 << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
2697
2698 #if ECMASCRIPT_ENABLE_IC
2699 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2700 if (!profileTypeInfo.IsUndefined()) {
2701 uint16_t slotId = READ_INST_8_0();
2702 JSTaggedValue value = GET_ACC();
2703 SAVE_ACC();
2704 JSTaggedValue res = ICRuntimeStub::StoreGlobalICByName(thread,
2705 ProfileTypeInfo::Cast(
2706 profileTypeInfo.GetTaggedObject()),
2707 globalObj, propKey, value, slotId, true);
2708 INTERPRETER_RETURN_IF_ABRUPT(res);
2709 RESTORE_ACC();
2710 DISPATCH(TRYSTGLOBALBYNAME_IMM8_ID16);
2711 }
2712 #endif
2713
2714 auto recordResult = SlowRuntimeStub::LdGlobalRecord(thread, propKey);
2715 SAVE_PC();
2716 // 1. find from global record
2717 if (!recordResult.IsUndefined()) {
2718 JSTaggedValue value = GET_ACC();
2719 SAVE_ACC();
2720 JSTaggedValue res = SlowRuntimeStub::TryUpdateGlobalRecord(thread, propKey, value);
2721 INTERPRETER_RETURN_IF_ABRUPT(res);
2722 RESTORE_ACC();
2723 } else {
2724 // 2. find from global object
2725 SAVE_ACC();
2726 auto globalResult = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, propKey);
2727 if (globalResult.IsHole()) {
2728 auto result = SlowRuntimeStub::ThrowReferenceError(thread, propKey, " is not defined");
2729 INTERPRETER_RETURN_IF_ABRUPT(result);
2730 }
2731 constpool = GetConstantPool(sp); // Maybe moved by GC
2732 propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
2733 RESTORE_ACC();
2734 JSTaggedValue value = GET_ACC();
2735 JSTaggedValue res = SlowRuntimeStub::StGlobalVar(thread, propKey, value);
2736 INTERPRETER_RETURN_IF_ABRUPT(res);
2737 RESTORE_ACC();
2738 }
2739 DISPATCH(TRYSTGLOBALBYNAME_IMM8_ID16);
2740 }
2741 HANDLE_OPCODE(STOWNBYVALUEWITHNAMESET_IMM8_V8_V8) {
2742 uint32_t v0 = READ_INST_8_1();
2743 uint32_t v1 = READ_INST_8_2();
2744 LOG_INST() << "intrinsics::stownbyvaluewithnameset"
2745 << " v" << v0 << " v" << v1;
2746 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2747 if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
2748 SAVE_ACC();
2749 JSTaggedValue propKey = GET_VREG_VALUE(v1);
2750 JSTaggedValue value = GET_ACC();
2751 // fast path
2752 JSTaggedValue res = FastRuntimeStub::SetPropertyByValue<true>(thread, receiver, propKey, value);
2753
2754 // SetPropertyByValue maybe gc need update the value
2755 RESTORE_ACC();
2756 propKey = GET_VREG_VALUE(v1);
2757 value = GET_ACC();
2758 if (!res.IsHole()) {
2759 INTERPRETER_RETURN_IF_ABRUPT(res);
2760 JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey);
2761 RESTORE_ACC();
2762 DISPATCH(STOWNBYVALUEWITHNAMESET_IMM8_V8_V8);
2763 }
2764 }
2765
2766 // slow path
2767 SAVE_ACC();
2768 SAVE_PC();
2769 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
2770 auto propKey = GET_VREG_VALUE(v1); // Maybe moved by GC
2771 auto value = GET_ACC(); // Maybe moved by GC
2772 JSTaggedValue res = SlowRuntimeStub::StOwnByValueWithNameSet(thread, receiver, propKey, value);
2773 RESTORE_ACC();
2774 INTERPRETER_RETURN_IF_ABRUPT(res);
2775 DISPATCH(STOWNBYVALUEWITHNAMESET_IMM8_V8_V8);
2776 }
2777 HANDLE_OPCODE(STOWNBYNAMEWITHNAMESET_IMM8_ID16_V8) {
2778 uint16_t stringId = READ_INST_16_1();
2779 uint32_t v0 = READ_INST_8_3();
2780 LOG_INST() << "intrinsics::stownbynamewithnameset "
2781 << "v" << v0 << " stringId:" << stringId;
2782
2783 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2784 if (receiver.IsJSObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
2785 SAVE_ACC();
2786 auto constpool = GetConstantPool(sp);
2787 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
2788 RESTORE_ACC();
2789 JSTaggedValue value = GET_ACC();
2790 // fast path
2791 SAVE_ACC();
2792 JSTaggedValue res = FastRuntimeStub::SetPropertyByName<true>(thread, receiver, propKey, value);
2793 if (!res.IsHole()) {
2794 INTERPRETER_RETURN_IF_ABRUPT(res);
2795 JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey);
2796 RESTORE_ACC();
2797 DISPATCH(STOWNBYNAMEWITHNAMESET_IMM8_ID16_V8);
2798 }
2799 RESTORE_ACC();
2800 }
2801
2802 SAVE_ACC();
2803 SAVE_PC();
2804 auto constpool = GetConstantPool(sp);
2805 auto propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
2806 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
2807 RESTORE_ACC();
2808 auto value = GET_ACC(); // Maybe moved by GC
2809 JSTaggedValue res = SlowRuntimeStub::StOwnByNameWithNameSet(thread, receiver, propKey, value);
2810 RESTORE_ACC();
2811 INTERPRETER_RETURN_IF_ABRUPT(res);
2812 DISPATCH(STOWNBYNAMEWITHNAMESET_IMM8_ID16_V8);
2813 }
2814 HANDLE_OPCODE(LDGLOBALVAR_IMM16_ID16) {
2815 uint16_t stringId = READ_INST_16_2();
2816 LOG_INST() << "intrinsics::ldglobalvar stringId:" << stringId;
2817 SAVE_ACC();
2818 auto constpool = GetConstantPool(sp);
2819 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
2820
2821 #if ECMASCRIPT_ENABLE_IC
2822 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2823 if (!profileTypeInfo.IsUndefined()) {
2824 uint16_t slotId = READ_INST_16_0();
2825 JSTaggedValue res = ICRuntimeStub::LoadGlobalICByName(thread,
2826 ProfileTypeInfo::Cast(
2827 profileTypeInfo.GetTaggedObject()),
2828 globalObj, propKey, slotId, false);
2829 INTERPRETER_RETURN_IF_ABRUPT(res);
2830 SET_ACC(res);
2831 DISPATCH(LDGLOBALVAR_IMM16_ID16);
2832 }
2833 #endif
2834
2835 JSTaggedValue result = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, propKey);
2836 if (!result.IsHole()) {
2837 SET_ACC(result);
2838 } else {
2839 // slow path
2840 SAVE_PC();
2841 JSTaggedValue res = SlowRuntimeStub::LdGlobalVarFromGlobalProto(thread, globalObj, propKey);
2842 INTERPRETER_RETURN_IF_ABRUPT(res);
2843 SET_ACC(res);
2844 }
2845 DISPATCH(LDGLOBALVAR_IMM16_ID16);
2846 }
2847 HANDLE_OPCODE(STOBJBYNAME_IMM8_ID16_V8) {
2848 uint32_t v0 = READ_INST_8_3();
2849 #if ECMASCRIPT_ENABLE_IC
2850 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2851 if (!profileTypeInfo.IsUndefined()) {
2852 uint16_t slotId = READ_INST_8_0();
2853 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
2854 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
2855 JSTaggedValue res = JSTaggedValue::Hole();
2856 SAVE_ACC();
2857
2858 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2859 JSTaggedValue value = GET_ACC();
2860 if (LIKELY(firstValue.IsHeapObject())) {
2861 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
2862 res = ICRuntimeStub::TryStoreICByName(thread, receiver, firstValue, secondValue, value);
2863 }
2864 if (LIKELY(!res.IsHole())) {
2865 INTERPRETER_RETURN_IF_ABRUPT(res);
2866 RESTORE_ACC();
2867 DISPATCH(STOBJBYNAME_IMM8_ID16_V8);
2868 } else if (!firstValue.IsHole()) { // IC miss and not enter the megamorphic state, store as polymorphic
2869 uint16_t stringId = READ_INST_16_1();
2870 SAVE_ACC();
2871 auto constpool = GetConstantPool(sp);
2872 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
2873 RESTORE_ACC();
2874 value = GET_ACC();
2875 receiver = GET_VREG_VALUE(v0);
2876 profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2877 profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
2878 res = ICRuntimeStub::StoreICByName(thread,
2879 profileTypeArray,
2880 receiver, propKey, value, slotId);
2881 INTERPRETER_RETURN_IF_ABRUPT(res);
2882 RESTORE_ACC();
2883 DISPATCH(STOBJBYNAME_IMM8_ID16_V8);
2884 }
2885 }
2886 #endif
2887 uint16_t stringId = READ_INST_16_1();
2888 LOG_INST() << "intrinsics::stobjbyname "
2889 << "v" << v0 << " stringId:" << stringId;
2890 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2891 if (receiver.IsHeapObject()) {
2892 SAVE_ACC();
2893 auto constpool = GetConstantPool(sp);
2894 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
2895 RESTORE_ACC();
2896 JSTaggedValue value = GET_ACC();
2897 receiver = GET_VREG_VALUE(v0);
2898 // fast path
2899 JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value);
2900 if (!res.IsHole()) {
2901 INTERPRETER_RETURN_IF_ABRUPT(res);
2902 RESTORE_ACC();
2903 DISPATCH(STOBJBYNAME_IMM8_ID16_V8);
2904 }
2905 RESTORE_ACC();
2906 }
2907 // slow path
2908 SAVE_ACC();
2909 SAVE_PC();
2910 auto constpool = GetConstantPool(sp); // Maybe moved by GC
2911 auto propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
2912 RESTORE_ACC();
2913 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
2914 receiver = GET_VREG_VALUE(v0);
2915 JSTaggedValue res = SlowRuntimeStub::StObjByName(thread, receiver, propKey, value);
2916 INTERPRETER_RETURN_IF_ABRUPT(res);
2917 RESTORE_ACC();
2918 DISPATCH(STOBJBYNAME_IMM8_ID16_V8);
2919 }
2920 HANDLE_OPCODE(STOBJBYNAME_IMM16_ID16_V8) {
2921 uint16_t stringId = READ_INST_16_2();
2922 uint32_t v0 = READ_INST_8_4();
2923 #if ECMASCRIPT_ENABLE_IC
2924 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2925 if (!profileTypeInfo.IsUndefined()) {
2926 uint16_t slotId = READ_INST_16_0();
2927 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
2928 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
2929 JSTaggedValue res = JSTaggedValue::Hole();
2930 SAVE_ACC();
2931
2932 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2933 JSTaggedValue value = GET_ACC();
2934 if (LIKELY(firstValue.IsHeapObject())) {
2935 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
2936 res = ICRuntimeStub::TryStoreICByName(thread, receiver, firstValue, secondValue, value);
2937 }
2938 if (LIKELY(!res.IsHole())) {
2939 INTERPRETER_RETURN_IF_ABRUPT(res);
2940 RESTORE_ACC();
2941 DISPATCH(STOBJBYNAME_IMM16_ID16_V8);
2942 } else if (!firstValue.IsHole()) { // IC miss and not enter the megamorphic state, store as polymorphic
2943 SAVE_ACC();
2944 auto constpool = GetConstantPool(sp);
2945 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
2946 RESTORE_ACC();
2947 value = GET_ACC();
2948 receiver = GET_VREG_VALUE(v0);
2949 profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2950 profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
2951 res = ICRuntimeStub::StoreICByName(thread,
2952 profileTypeArray,
2953 receiver, propKey, value, slotId);
2954 INTERPRETER_RETURN_IF_ABRUPT(res);
2955 RESTORE_ACC();
2956 DISPATCH(STOBJBYNAME_IMM16_ID16_V8);
2957 }
2958 }
2959 #endif
2960 LOG_INST() << "intrinsics::stobjbyname "
2961 << "v" << v0 << " stringId:" << stringId;
2962 JSTaggedValue receiver = GET_VREG_VALUE(v0);
2963 if (receiver.IsHeapObject()) {
2964 SAVE_ACC();
2965 auto constpool = GetConstantPool(sp);
2966 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
2967 RESTORE_ACC();
2968 JSTaggedValue value = GET_ACC();
2969 receiver = GET_VREG_VALUE(v0);
2970 // fast path
2971 JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value);
2972 if (!res.IsHole()) {
2973 INTERPRETER_RETURN_IF_ABRUPT(res);
2974 RESTORE_ACC();
2975 DISPATCH(STOBJBYNAME_IMM16_ID16_V8);
2976 }
2977 RESTORE_ACC();
2978 }
2979 // slow path
2980 SAVE_ACC();
2981 SAVE_PC();
2982 auto constpool = GetConstantPool(sp); // Maybe moved by GC
2983 auto propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
2984 RESTORE_ACC();
2985 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
2986 receiver = GET_VREG_VALUE(v0);
2987 JSTaggedValue res = SlowRuntimeStub::StObjByName(thread, receiver, propKey, value);
2988 INTERPRETER_RETURN_IF_ABRUPT(res);
2989 RESTORE_ACC();
2990 DISPATCH(STOBJBYNAME_IMM16_ID16_V8);
2991 }
2992 HANDLE_OPCODE(STSUPERBYNAME_IMM8_ID16_V8) {
2993 uint16_t stringId = READ_INST_16_1();
2994 uint32_t v0 = READ_INST_8_3();
2995
2996 SAVE_ACC();
2997 auto constpool = GetConstantPool(sp);
2998 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
2999 JSTaggedValue obj = GET_VREG_VALUE(v0);
3000 RESTORE_ACC();
3001 JSTaggedValue value = GET_ACC();
3002
3003 LOG_INST() << "intrinsics::stsuperbyname"
3004 << "v" << v0 << " stringId:" << stringId << ", "
3005 << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << obj.GetRawData()
3006 << ", value:" << value.GetRawData();
3007
3008 // slow path
3009 SAVE_ACC();
3010 SAVE_PC();
3011 JSTaggedValue thisFunc = GetFunction(sp);
3012 JSTaggedValue res = SlowRuntimeStub::StSuperByValue(thread, obj, propKey, value, thisFunc);
3013 INTERPRETER_RETURN_IF_ABRUPT(res);
3014 RESTORE_ACC();
3015 DISPATCH(STSUPERBYNAME_IMM8_ID16_V8);
3016 }
3017 HANDLE_OPCODE(STGLOBALVAR_IMM16_ID16) {
3018 uint16_t stringId = READ_INST_16_2();
3019 SAVE_ACC();
3020 auto constpool = GetConstantPool(sp);
3021 JSTaggedValue prop = GET_STR_FROM_CACHE(stringId);
3022 RESTORE_ACC();
3023 JSTaggedValue value = GET_ACC();
3024
3025 LOG_INST() << "intrinsics::stglobalvar "
3026 << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(prop.GetTaggedObject()))
3027 << ", value:" << value.GetRawData();
3028 #if ECMASCRIPT_ENABLE_IC
3029 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
3030 if (!profileTypeInfo.IsUndefined()) {
3031 uint16_t slotId = READ_INST_16_0();
3032 SAVE_ACC();
3033 JSTaggedValue res = ICRuntimeStub::StoreGlobalICByName(thread,
3034 ProfileTypeInfo::Cast(
3035 profileTypeInfo.GetTaggedObject()),
3036 globalObj, prop, value, slotId, false);
3037 INTERPRETER_RETURN_IF_ABRUPT(res);
3038 RESTORE_ACC();
3039 DISPATCH(STGLOBALVAR_IMM16_ID16);
3040 }
3041 #endif
3042 SAVE_ACC();
3043 SAVE_PC();
3044 JSTaggedValue res = SlowRuntimeStub::StGlobalVar(thread, prop, value);
3045 INTERPRETER_RETURN_IF_ABRUPT(res);
3046 RESTORE_ACC();
3047 DISPATCH(STGLOBALVAR_IMM16_ID16);
3048 }
3049 HANDLE_OPCODE(CREATEGENERATOROBJ_V8) {
3050 uint16_t v0 = READ_INST_8_0();
3051 LOG_INST() << "intrinsics::creategeneratorobj"
3052 << " v" << v0;
3053 SAVE_PC();
3054 JSTaggedValue genFunc = GET_VREG_VALUE(v0);
3055 JSTaggedValue res = SlowRuntimeStub::CreateGeneratorObj(thread, genFunc);
3056 INTERPRETER_RETURN_IF_ABRUPT(res);
3057 SET_ACC(res);
3058 DISPATCH(CREATEGENERATOROBJ_V8);
3059 }
3060 HANDLE_OPCODE(STARRAYSPREAD_V8_V8) {
3061 uint16_t v0 = READ_INST_8_0();
3062 uint16_t v1 = READ_INST_8_1();
3063 LOG_INST() << "ecmascript::intrinsics::starrayspread"
3064 << " v" << v0 << " v" << v1 << "acc";
3065 JSTaggedValue dst = GET_VREG_VALUE(v0);
3066 JSTaggedValue index = GET_VREG_VALUE(v1);
3067 JSTaggedValue src = GET_ACC();
3068 SAVE_PC();
3069 JSTaggedValue res = SlowRuntimeStub::StArraySpread(thread, dst, index, src);
3070 INTERPRETER_RETURN_IF_ABRUPT(res);
3071 SET_ACC(res);
3072 DISPATCH(STARRAYSPREAD_V8_V8);
3073 }
3074 HANDLE_OPCODE(LDFUNCTION) {
3075 LOG_INST() << "intrinsic::ldfunction";
3076 SET_ACC(GetFunction(sp));
3077 DISPATCH(LDFUNCTION);
3078 }
3079 HANDLE_OPCODE(LDBIGINT_ID16) {
3080 uint16_t stringId = READ_INST_16_0();
3081 LOG_INST() << "intrinsic::ldbigint";
3082 SAVE_ACC();
3083 auto constpool = GetConstantPool(sp);
3084 JSTaggedValue numberBigInt = GET_STR_FROM_CACHE(stringId);
3085 SAVE_PC();
3086 JSTaggedValue res = SlowRuntimeStub::LdBigInt(thread, numberBigInt);
3087 INTERPRETER_RETURN_IF_ABRUPT(res);
3088 SET_ACC(res);
3089 DISPATCH(LDBIGINT_ID16);
3090 }
3091 HANDLE_OPCODE(CREATEASYNCGENERATOROBJ_V8) {
3092 uint16_t v0 = READ_INST_8_0();
3093 LOG_INST() << "intrinsics::createasyncgeneratorobj"
3094 << " v" << v0;
3095 SAVE_PC();
3096 JSTaggedValue genFunc = GET_VREG_VALUE(v0);
3097 JSTaggedValue res = SlowRuntimeStub::CreateAsyncGeneratorObj(thread, genFunc);
3098 INTERPRETER_RETURN_IF_ABRUPT(res);
3099 SET_ACC(res);
3100 DISPATCH(CREATEASYNCGENERATOROBJ_V8);
3101 }
3102 HANDLE_OPCODE(ASYNCGENERATORRESOLVE_V8_V8_V8) {
3103 uint16_t v0 = READ_INST_8_0();
3104 uint16_t v1 = READ_INST_8_1();
3105 uint16_t v2 = READ_INST_8_2();
3106 LOG_INST() << "intrinsics::asyncgeneratorresolve"
3107 << " v" << v0 << " v" << v1 << " v" << v2;
3108 JSTaggedValue asyncGenerator = GET_VREG_VALUE(v0);
3109 JSTaggedValue value = GET_VREG_VALUE(v1);
3110 JSTaggedValue flag = GET_VREG_VALUE(v2);
3111 SAVE_PC();
3112 JSTaggedValue res = SlowRuntimeStub::AsyncGeneratorResolve(thread, asyncGenerator, value, flag);
3113 INTERPRETER_RETURN_IF_ABRUPT(res);
3114 SET_ACC(res);
3115
3116 InterpretedFrame *state = GET_FRAME(sp);
3117 Method *method = JSFunction::Cast(state->function.GetTaggedObject())->GetCallTarget();
3118 [[maybe_unused]] auto fistPC = method->GetBytecodeArray();
3119 UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
3120 LOG_INST() << "Exit: AsyncGeneratorResolve " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
3121 << std::hex << reinterpret_cast<uintptr_t>(state->pc);
3122 sp = state->base.prev;
3123 ASSERT(sp != nullptr);
3124 InterpretedFrame *prevState = GET_FRAME(sp);
3125 pc = prevState->pc;
3126 // entry frame
3127 if (FrameHandler::IsEntryFrame(pc)) {
3128 state->acc = acc;
3129 return;
3130 }
3131 thread->SetCurrentSPFrame(sp);
3132 INTERPRETER_HANDLE_RETURN();
3133 }
3134 HANDLE_OPCODE(ASYNCGENERATORREJECT_V8) {
3135 uint16_t v0 = READ_INST_8_0();
3136 LOG_INST() << "intrinsics::asyncgeneratorreject"
3137 << " v" << v0;
3138
3139 JSTaggedValue asyncGenerator = GET_VREG_VALUE(v0);
3140 JSTaggedValue value = GET_ACC();
3141
3142 SAVE_PC();
3143 JSTaggedValue res = SlowRuntimeStub::AsyncGeneratorReject(thread, asyncGenerator, value);
3144 INTERPRETER_RETURN_IF_ABRUPT(res);
3145 SET_ACC(res);
3146 DISPATCH(ASYNCGENERATORREJECT_V8);
3147 }
3148 HANDLE_OPCODE(DEPRECATED_ASYNCGENERATORREJECT_PREF_V8_V8) {
3149 uint16_t v0 = READ_INST_8_1();
3150 uint16_t v1 = READ_INST_8_2();
3151 LOG_INST() << "intrinsics::asyncgeneratorreject"
3152 << " v" << v0 << " v" << v1;
3153
3154 JSTaggedValue asyncGenerator = GET_VREG_VALUE(v0);
3155 JSTaggedValue value = GET_VREG_VALUE(v1);
3156
3157 SAVE_PC();
3158 JSTaggedValue res = SlowRuntimeStub::AsyncGeneratorReject(thread, asyncGenerator, value);
3159 INTERPRETER_RETURN_IF_ABRUPT(res);
3160 SET_ACC(res);
3161 DISPATCH(DEPRECATED_ASYNCGENERATORREJECT_PREF_V8_V8);
3162 }
3163 HANDLE_OPCODE(SUPERCALLTHISRANGE_IMM8_IMM8_V8) {
3164 uint16_t range = READ_INST_8_1();
3165 uint16_t v0 = READ_INST_8_2();
3166 LOG_INST() << "intrinsics::supercall"
3167 << " range: " << range << " v" << v0;
3168
3169 JSTaggedValue thisFunc = GetFunction(sp);
3170 JSTaggedValue newTarget = GetNewTarget(sp);
3171
3172 SAVE_PC();
3173 JSTaggedValue superCtor = SlowRuntimeStub::GetSuperConstructor(thread, thisFunc);
3174 INTERPRETER_RETURN_IF_ABRUPT(superCtor);
3175
3176 if (superCtor.IsJSFunction() && superCtor.IsConstructor() && !newTarget.IsUndefined()) {
3177 JSFunction *superCtorFunc = JSFunction::Cast(superCtor.GetTaggedObject());
3178 methodHandle.Update(superCtorFunc->GetMethod());
3179 if (superCtorFunc->IsBuiltinConstructor()) {
3180 ASSERT(methodHandle->GetNumVregsWithCallField() == 0);
3181 size_t frameSize =
3182 InterpretedFrame::NumOfMembers() + range + NUM_MANDATORY_JSFUNC_ARGS + 2; // 2:thread & numArgs
3183 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3184 JSTaggedType *newSp = sp - frameSize;
3185 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
3186 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3187 }
3188 // copy args
3189 uint32_t index = 0;
3190 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3191 EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo *>(newSp);
3192 newSp[index++] = ToUintPtr(thread);
3193 newSp[index++] = range + NUM_MANDATORY_JSFUNC_ARGS;
3194 // func
3195 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3196 newSp[index++] = superCtor.GetRawData();
3197 // newTarget
3198 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3199 newSp[index++] = newTarget.GetRawData();
3200 // this
3201 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3202 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3203 for (size_t i = 0; i < range; ++i) {
3204 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3205 newSp[index++] = GET_VREG(v0 + i);
3206 }
3207
3208 InterpretedBuiltinFrame *state = GET_BUILTIN_FRAME(newSp);
3209 state->base.prev = sp;
3210 state->base.type = FrameType::INTERPRETER_BUILTIN_FRAME;
3211 state->pc = nullptr;
3212 state->function = superCtor;
3213 thread->SetCurrentSPFrame(newSp);
3214 LOG_INST() << "Entry: Runtime SuperCall ";
3215 JSTaggedValue retValue = reinterpret_cast<EcmaEntrypoint>(
3216 const_cast<void *>(methodHandle->GetNativePointer()))(ecmaRuntimeCallInfo);
3217 thread->SetCurrentSPFrame(sp);
3218
3219 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3220 LOG_INST() << "Exit: Runtime SuperCall ";
3221 SET_ACC(retValue);
3222 DISPATCH(SUPERCALLTHISRANGE_IMM8_IMM8_V8);
3223 }
3224
3225 if (IsFastNewFrameEnter(superCtorFunc, methodHandle)) {
3226 SAVE_PC();
3227 uint32_t numVregs = methodHandle->GetNumVregsWithCallField();
3228 uint32_t numDeclaredArgs = superCtorFunc->IsBase() ?
3229 methodHandle->GetNumArgsWithCallField() + 1 : // +1 for this
3230 methodHandle->GetNumArgsWithCallField() + 2; // +2 for newTarget and this
3231 size_t frameSize = InterpretedFrame::NumOfMembers() + numVregs + numDeclaredArgs;
3232 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3233 JSTaggedType *newSp = sp - frameSize;
3234 InterpretedFrame *state = GET_FRAME(newSp);
3235
3236 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
3237 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3238 }
3239
3240 uint32_t index = 0;
3241 // initialize vregs value
3242 for (size_t i = 0; i < numVregs; ++i) {
3243 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3244 }
3245
3246 // this
3247 JSTaggedValue thisObj;
3248 if (superCtorFunc->IsBase()) {
3249 thisObj = FastRuntimeStub::NewThisObject(thread, superCtor, newTarget, state);
3250 INTERPRETER_RETURN_IF_ABRUPT(thisObj);
3251 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3252 newSp[index++] = thisObj.GetRawData();
3253 } else {
3254 ASSERT(superCtorFunc->IsDerivedConstructor());
3255 newSp[index++] = newTarget.GetRawData();
3256 thisObj = JSTaggedValue::Undefined();
3257 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3258 newSp[index++] = thisObj.GetRawData();
3259
3260 state->function = superCtor;
3261 state->constpool = methodHandle->GetConstantPool();
3262 state->profileTypeInfo = methodHandle->GetProfileTypeInfo();
3263 state->env = superCtorFunc->GetLexicalEnv();
3264 }
3265
3266 // the second condition ensure not push extra args
3267 for (size_t i = 0; i < range && index < numVregs + numDeclaredArgs; ++i) {
3268 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3269 newSp[index++] = GET_VREG(v0 + i);
3270 }
3271
3272 // set undefined to the extra prats of declare
3273 for (size_t i = index; i < numVregs + numDeclaredArgs; ++i) {
3274 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3275 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3276 }
3277
3278 state->base.prev = sp;
3279 state->base.type = FrameType::INTERPRETER_FAST_NEW_FRAME;
3280 state->thisObj = thisObj;
3281 state->pc = pc = methodHandle->GetBytecodeArray();
3282 sp = newSp;
3283 state->acc = JSTaggedValue::Hole();
3284
3285 thread->SetCurrentSPFrame(newSp);
3286 LOG_INST() << "Entry: Runtime SuperCall " << std::hex << reinterpret_cast<uintptr_t>(sp)
3287 << " " << std::hex << reinterpret_cast<uintptr_t>(pc);
3288 DISPATCH_OFFSET(0);
3289 }
3290 }
3291
3292 SAVE_PC();
3293 JSTaggedValue res = SlowRuntimeStub::SuperCall(thread, thisFunc, newTarget, v0, range);
3294 INTERPRETER_RETURN_IF_ABRUPT(res);
3295 SET_ACC(res);
3296 DISPATCH(SUPERCALLTHISRANGE_IMM8_IMM8_V8);
3297 }
3298 HANDLE_OPCODE(WIDE_SUPERCALLTHISRANGE_PREF_IMM16_V8) {
3299 uint16_t range = READ_INST_16_1();
3300 uint16_t v0 = READ_INST_8_3();
3301 LOG_INST() << "intrinsics::supercall"
3302 << " range: " << range << " v" << v0;
3303
3304 JSTaggedValue thisFunc = GetFunction(sp);
3305 JSTaggedValue newTarget = GetNewTarget(sp);
3306
3307 SAVE_PC();
3308 JSTaggedValue superCtor = SlowRuntimeStub::GetSuperConstructor(thread, thisFunc);
3309 INTERPRETER_RETURN_IF_ABRUPT(superCtor);
3310
3311 if (superCtor.IsJSFunction() && superCtor.IsConstructor() && !newTarget.IsUndefined()) {
3312 JSFunction *superCtorFunc = JSFunction::Cast(superCtor.GetTaggedObject());
3313 methodHandle.Update(superCtorFunc->GetMethod());
3314 if (superCtorFunc->IsBuiltinConstructor()) {
3315 ASSERT(methodHandle->GetNumVregsWithCallField() == 0);
3316 size_t frameSize =
3317 InterpretedFrame::NumOfMembers() + range + NUM_MANDATORY_JSFUNC_ARGS + 2; // 2:thread & numArgs
3318 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3319 JSTaggedType *newSp = sp - frameSize;
3320 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
3321 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3322 }
3323 // copy args
3324 uint32_t index = 0;
3325 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3326 EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo *>(newSp);
3327 newSp[index++] = ToUintPtr(thread);
3328 newSp[index++] = range + NUM_MANDATORY_JSFUNC_ARGS;
3329 // func
3330 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3331 newSp[index++] = superCtor.GetRawData();
3332 // newTarget
3333 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3334 newSp[index++] = newTarget.GetRawData();
3335 // this
3336 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3337 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3338 for (size_t i = 0; i < range; ++i) {
3339 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3340 newSp[index++] = GET_VREG(v0 + i);
3341 }
3342
3343 InterpretedBuiltinFrame *state = GET_BUILTIN_FRAME(newSp);
3344 state->base.prev = sp;
3345 state->base.type = FrameType::INTERPRETER_BUILTIN_FRAME;
3346 state->pc = nullptr;
3347 state->function = superCtor;
3348 thread->SetCurrentSPFrame(newSp);
3349 LOG_INST() << "Entry: Runtime SuperCall ";
3350 JSTaggedValue retValue = reinterpret_cast<EcmaEntrypoint>(
3351 const_cast<void *>(methodHandle->GetNativePointer()))(ecmaRuntimeCallInfo);
3352 thread->SetCurrentSPFrame(sp);
3353
3354 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3355 LOG_INST() << "Exit: Runtime SuperCall ";
3356 SET_ACC(retValue);
3357 DISPATCH(WIDE_SUPERCALLTHISRANGE_PREF_IMM16_V8);
3358 }
3359
3360 if (IsFastNewFrameEnter(superCtorFunc, methodHandle)) {
3361 SAVE_PC();
3362 uint32_t numVregs = methodHandle->GetNumVregsWithCallField();
3363 uint32_t numDeclaredArgs = superCtorFunc->IsBase() ?
3364 methodHandle->GetNumArgsWithCallField() + 1 : // +1 for this
3365 methodHandle->GetNumArgsWithCallField() + 2; // +2 for newTarget and this
3366 size_t frameSize = InterpretedFrame::NumOfMembers() + numVregs + numDeclaredArgs;
3367 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3368 JSTaggedType *newSp = sp - frameSize;
3369 InterpretedFrame *state = GET_FRAME(newSp);
3370
3371 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
3372 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3373 }
3374
3375 uint32_t index = 0;
3376 // initialize vregs value
3377 for (size_t i = 0; i < numVregs; ++i) {
3378 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3379 }
3380
3381 // this
3382 JSTaggedValue thisObj;
3383 if (superCtorFunc->IsBase()) {
3384 thisObj = FastRuntimeStub::NewThisObject(thread, superCtor, newTarget, state);
3385 INTERPRETER_RETURN_IF_ABRUPT(thisObj);
3386 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3387 newSp[index++] = thisObj.GetRawData();
3388 } else {
3389 ASSERT(superCtorFunc->IsDerivedConstructor());
3390 newSp[index++] = newTarget.GetRawData();
3391 thisObj = JSTaggedValue::Undefined();
3392 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3393 newSp[index++] = thisObj.GetRawData();
3394
3395 state->function = superCtor;
3396 state->constpool = methodHandle->GetConstantPool();
3397 state->profileTypeInfo = methodHandle->GetProfileTypeInfo();
3398 state->env = superCtorFunc->GetLexicalEnv();
3399 }
3400
3401 // the second condition ensure not push extra args
3402 for (size_t i = 0; i < range && index < numVregs + numDeclaredArgs; ++i) {
3403 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3404 newSp[index++] = GET_VREG(v0 + i);
3405 }
3406
3407 // set undefined to the extra prats of declare
3408 for (size_t i = index; i < numVregs + numDeclaredArgs; ++i) {
3409 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3410 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3411 }
3412
3413 state->base.prev = sp;
3414 state->base.type = FrameType::INTERPRETER_FAST_NEW_FRAME;
3415 state->thisObj = thisObj;
3416 state->pc = pc = methodHandle->GetBytecodeArray();
3417 sp = newSp;
3418 state->acc = JSTaggedValue::Hole();
3419
3420 thread->SetCurrentSPFrame(newSp);
3421 LOG_INST() << "Entry: Runtime SuperCall " << std::hex << reinterpret_cast<uintptr_t>(sp)
3422 << " " << std::hex << reinterpret_cast<uintptr_t>(pc);
3423 DISPATCH_OFFSET(0);
3424 }
3425 }
3426
3427 SAVE_PC();
3428 JSTaggedValue res = SlowRuntimeStub::SuperCall(thread, thisFunc, newTarget, v0, range);
3429 INTERPRETER_RETURN_IF_ABRUPT(res);
3430 SET_ACC(res);
3431 DISPATCH(WIDE_SUPERCALLTHISRANGE_PREF_IMM16_V8);
3432 }
3433 HANDLE_OPCODE(SUPERCALLARROWRANGE_IMM8_IMM8_V8) {
3434 uint16_t range = READ_INST_8_1();
3435 uint16_t v0 = READ_INST_8_2();
3436 LOG_INST() << "intrinsics::supercall"
3437 << " range: " << range << " v" << v0;
3438
3439 JSTaggedValue thisFunc = GET_ACC();
3440 JSTaggedValue newTarget = GetNewTarget(sp);
3441
3442 SAVE_PC();
3443 JSTaggedValue superCtor = SlowRuntimeStub::GetSuperConstructor(thread, thisFunc);
3444 INTERPRETER_RETURN_IF_ABRUPT(superCtor);
3445
3446 if (superCtor.IsJSFunction() && superCtor.IsConstructor() && !newTarget.IsUndefined()) {
3447 JSFunction *superCtorFunc = JSFunction::Cast(superCtor.GetTaggedObject());
3448 methodHandle.Update(superCtorFunc->GetMethod());
3449 if (superCtorFunc->IsBuiltinConstructor()) {
3450 ASSERT(methodHandle->GetNumVregsWithCallField() == 0);
3451 size_t frameSize =
3452 InterpretedFrame::NumOfMembers() + range + NUM_MANDATORY_JSFUNC_ARGS + 2; // 2:thread & numArgs
3453 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3454 JSTaggedType *newSp = sp - frameSize;
3455 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
3456 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3457 }
3458 // copy args
3459 uint32_t index = 0;
3460 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3461 EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo *>(newSp);
3462 newSp[index++] = ToUintPtr(thread);
3463 newSp[index++] = range + NUM_MANDATORY_JSFUNC_ARGS;
3464 // func
3465 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3466 newSp[index++] = superCtor.GetRawData();
3467 // newTarget
3468 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3469 newSp[index++] = newTarget.GetRawData();
3470 // this
3471 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3472 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3473 for (size_t i = 0; i < range; ++i) {
3474 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3475 newSp[index++] = GET_VREG(v0 + i);
3476 }
3477
3478 InterpretedBuiltinFrame *state = GET_BUILTIN_FRAME(newSp);
3479 state->base.prev = sp;
3480 state->base.type = FrameType::INTERPRETER_BUILTIN_FRAME;
3481 state->pc = nullptr;
3482 state->function = superCtor;
3483 thread->SetCurrentSPFrame(newSp);
3484 LOG_INST() << "Entry: Runtime SuperCall ";
3485 JSTaggedValue retValue = reinterpret_cast<EcmaEntrypoint>(
3486 const_cast<void *>(methodHandle->GetNativePointer()))(ecmaRuntimeCallInfo);
3487 thread->SetCurrentSPFrame(sp);
3488
3489 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3490 LOG_INST() << "Exit: Runtime SuperCall ";
3491 SET_ACC(retValue);
3492 DISPATCH(SUPERCALLARROWRANGE_IMM8_IMM8_V8);
3493 }
3494
3495 if (IsFastNewFrameEnter(superCtorFunc, methodHandle)) {
3496 SAVE_PC();
3497 uint32_t numVregs = methodHandle->GetNumVregsWithCallField();
3498 uint32_t numDeclaredArgs = superCtorFunc->IsBase() ?
3499 methodHandle->GetNumArgsWithCallField() + 1 : // +1 for this
3500 methodHandle->GetNumArgsWithCallField() + 2; // +2 for newTarget and this
3501 size_t frameSize = InterpretedFrame::NumOfMembers() + numVregs + numDeclaredArgs;
3502 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3503 JSTaggedType *newSp = sp - frameSize;
3504 InterpretedFrame *state = GET_FRAME(newSp);
3505
3506 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
3507 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3508 }
3509
3510 uint32_t index = 0;
3511 // initialize vregs value
3512 for (size_t i = 0; i < numVregs; ++i) {
3513 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3514 }
3515
3516 // this
3517 JSTaggedValue thisObj;
3518 if (superCtorFunc->IsBase()) {
3519 thisObj = FastRuntimeStub::NewThisObject(thread, superCtor, newTarget, state);
3520 INTERPRETER_RETURN_IF_ABRUPT(thisObj);
3521 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3522 newSp[index++] = thisObj.GetRawData();
3523 } else {
3524 ASSERT(superCtorFunc->IsDerivedConstructor());
3525 newSp[index++] = newTarget.GetRawData();
3526 thisObj = JSTaggedValue::Undefined();
3527 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3528 newSp[index++] = thisObj.GetRawData();
3529
3530 state->function = superCtor;
3531 state->constpool = methodHandle->GetConstantPool();
3532 state->profileTypeInfo = methodHandle->GetProfileTypeInfo();
3533 state->env = superCtorFunc->GetLexicalEnv();
3534 }
3535
3536 // the second condition ensure not push extra args
3537 for (size_t i = 0; i < range && index < numVregs + numDeclaredArgs; ++i) {
3538 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3539 newSp[index++] = GET_VREG(v0 + i);
3540 }
3541
3542 // set undefined to the extra prats of declare
3543 for (size_t i = index; i < numVregs + numDeclaredArgs; ++i) {
3544 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3545 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3546 }
3547
3548 state->base.prev = sp;
3549 state->base.type = FrameType::INTERPRETER_FAST_NEW_FRAME;
3550 state->thisObj = thisObj;
3551 state->pc = pc = methodHandle->GetBytecodeArray();
3552 sp = newSp;
3553 state->acc = JSTaggedValue::Hole();
3554
3555 thread->SetCurrentSPFrame(newSp);
3556 LOG_INST() << "Entry: Runtime SuperCall " << std::hex << reinterpret_cast<uintptr_t>(sp)
3557 << " " << std::hex << reinterpret_cast<uintptr_t>(pc);
3558 DISPATCH_OFFSET(0);
3559 }
3560 }
3561
3562 SAVE_PC();
3563 JSTaggedValue res = SlowRuntimeStub::SuperCall(thread, thisFunc, newTarget, v0, range);
3564 INTERPRETER_RETURN_IF_ABRUPT(res);
3565 SET_ACC(res);
3566 DISPATCH(SUPERCALLARROWRANGE_IMM8_IMM8_V8);
3567 }
3568 HANDLE_OPCODE(WIDE_SUPERCALLARROWRANGE_PREF_IMM16_V8) {
3569 uint16_t range = READ_INST_16_1();
3570 uint16_t v0 = READ_INST_8_3();
3571 LOG_INST() << "intrinsics::supercall"
3572 << " range: " << range << " v" << v0;
3573
3574 JSTaggedValue thisFunc = GET_ACC();
3575 JSTaggedValue newTarget = GetNewTarget(sp);
3576
3577 SAVE_PC();
3578 JSTaggedValue superCtor = SlowRuntimeStub::GetSuperConstructor(thread, thisFunc);
3579 INTERPRETER_RETURN_IF_ABRUPT(superCtor);
3580
3581 if (superCtor.IsJSFunction() && superCtor.IsConstructor() && !newTarget.IsUndefined()) {
3582 JSFunction *superCtorFunc = JSFunction::Cast(superCtor.GetTaggedObject());
3583 methodHandle.Update(superCtorFunc->GetMethod());
3584 if (superCtorFunc->IsBuiltinConstructor()) {
3585 ASSERT(methodHandle->GetNumVregsWithCallField() == 0);
3586 size_t frameSize =
3587 InterpretedFrame::NumOfMembers() + range + NUM_MANDATORY_JSFUNC_ARGS + 2; // 2:thread & numArgs
3588 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3589 JSTaggedType *newSp = sp - frameSize;
3590 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
3591 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3592 }
3593 // copy args
3594 uint32_t index = 0;
3595 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3596 EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo *>(newSp);
3597 newSp[index++] = ToUintPtr(thread);
3598 newSp[index++] = range + NUM_MANDATORY_JSFUNC_ARGS;
3599 // func
3600 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3601 newSp[index++] = superCtor.GetRawData();
3602 // newTarget
3603 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3604 newSp[index++] = newTarget.GetRawData();
3605 // this
3606 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3607 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3608 for (size_t i = 0; i < range; ++i) {
3609 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3610 newSp[index++] = GET_VREG(v0 + i);
3611 }
3612
3613 InterpretedBuiltinFrame *state = GET_BUILTIN_FRAME(newSp);
3614 state->base.prev = sp;
3615 state->base.type = FrameType::INTERPRETER_BUILTIN_FRAME;
3616 state->pc = nullptr;
3617 state->function = superCtor;
3618 thread->SetCurrentSPFrame(newSp);
3619 LOG_INST() << "Entry: Runtime SuperCall ";
3620 JSTaggedValue retValue = reinterpret_cast<EcmaEntrypoint>(
3621 const_cast<void *>(methodHandle->GetNativePointer()))(ecmaRuntimeCallInfo);
3622 thread->SetCurrentSPFrame(sp);
3623
3624 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3625 LOG_INST() << "Exit: Runtime SuperCall ";
3626 SET_ACC(retValue);
3627 DISPATCH(WIDE_SUPERCALLARROWRANGE_PREF_IMM16_V8);
3628 }
3629
3630 if (IsFastNewFrameEnter(superCtorFunc, methodHandle)) {
3631 SAVE_PC();
3632 uint32_t numVregs = methodHandle->GetNumVregsWithCallField();
3633 uint32_t numDeclaredArgs = superCtorFunc->IsBase() ?
3634 methodHandle->GetNumArgsWithCallField() + 1 : // +1 for this
3635 methodHandle->GetNumArgsWithCallField() + 2; // +2 for newTarget and this
3636 size_t frameSize = InterpretedFrame::NumOfMembers() + numVregs + numDeclaredArgs;
3637 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3638 JSTaggedType *newSp = sp - frameSize;
3639 InterpretedFrame *state = GET_FRAME(newSp);
3640
3641 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
3642 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3643 }
3644
3645 uint32_t index = 0;
3646 // initialize vregs value
3647 for (size_t i = 0; i < numVregs; ++i) {
3648 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3649 }
3650
3651 // this
3652 JSTaggedValue thisObj;
3653 if (superCtorFunc->IsBase()) {
3654 thisObj = FastRuntimeStub::NewThisObject(thread, superCtor, newTarget, state);
3655 INTERPRETER_RETURN_IF_ABRUPT(thisObj);
3656 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3657 newSp[index++] = thisObj.GetRawData();
3658 } else {
3659 ASSERT(superCtorFunc->IsDerivedConstructor());
3660 newSp[index++] = newTarget.GetRawData();
3661 thisObj = JSTaggedValue::Undefined();
3662 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3663 newSp[index++] = thisObj.GetRawData();
3664
3665 state->function = superCtor;
3666 state->constpool = methodHandle->GetConstantPool();
3667 state->profileTypeInfo = methodHandle->GetProfileTypeInfo();
3668 state->env = superCtorFunc->GetLexicalEnv();
3669 }
3670
3671 // the second condition ensure not push extra args
3672 for (size_t i = 0; i < range && index < numVregs + numDeclaredArgs; ++i) {
3673 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3674 newSp[index++] = GET_VREG(v0 + i);
3675 }
3676
3677 // set undefined to the extra prats of declare
3678 for (size_t i = index; i < numVregs + numDeclaredArgs; ++i) {
3679 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3680 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3681 }
3682
3683 state->base.prev = sp;
3684 state->base.type = FrameType::INTERPRETER_FAST_NEW_FRAME;
3685 state->thisObj = thisObj;
3686 state->pc = pc = methodHandle->GetBytecodeArray();
3687 sp = newSp;
3688 state->acc = JSTaggedValue::Hole();
3689
3690 thread->SetCurrentSPFrame(newSp);
3691 LOG_INST() << "Entry: Runtime SuperCall " << std::hex << reinterpret_cast<uintptr_t>(sp)
3692 << " " << std::hex << reinterpret_cast<uintptr_t>(pc);
3693 DISPATCH_OFFSET(0);
3694 }
3695 }
3696
3697 SAVE_PC();
3698 JSTaggedValue res = SlowRuntimeStub::SuperCall(thread, thisFunc, newTarget, v0, range);
3699 INTERPRETER_RETURN_IF_ABRUPT(res);
3700 SET_ACC(res);
3701 DISPATCH(WIDE_SUPERCALLARROWRANGE_PREF_IMM16_V8);
3702 }
3703 HANDLE_OPCODE(SUPERCALLSPREAD_IMM8_V8) {
3704 uint16_t v0 = READ_INST_8_1();
3705 LOG_INST() << "intrinsic::supercallspread"
3706 << " array: v" << v0;
3707
3708 JSTaggedValue thisFunc = GET_ACC();
3709 JSTaggedValue newTarget = GetNewTarget(sp);
3710 JSTaggedValue array = GET_VREG_VALUE(v0);
3711
3712 SAVE_PC();
3713 JSTaggedValue res = SlowRuntimeStub::SuperCallSpread(thread, thisFunc, newTarget, array);
3714 INTERPRETER_RETURN_IF_ABRUPT(res);
3715 SET_ACC(res);
3716 DISPATCH(SUPERCALLSPREAD_IMM8_V8);
3717 }
3718 HANDLE_OPCODE(DEPRECATED_CREATEOBJECTHAVINGMETHOD_PREF_IMM16) {
3719 uint16_t imm = READ_INST_16_1();
3720 LOG_INST() << "intrinsics::createobjecthavingmethod"
3721 << " imm:" << imm;
3722 SAVE_ACC();
3723 auto constpool = GetConstantPool(sp);
3724 JSObject *result = JSObject::Cast(GET_METHOD_FROM_CACHE(imm).GetTaggedObject());
3725 RESTORE_ACC();
3726 JSTaggedValue env = GET_ACC();
3727
3728 SAVE_PC();
3729 JSTaggedValue res = SlowRuntimeStub::CreateObjectHavingMethod(thread, factory, result, env);
3730 INTERPRETER_RETURN_IF_ABRUPT(res);
3731 SET_ACC(res);
3732 DISPATCH(DEPRECATED_CREATEOBJECTHAVINGMETHOD_PREF_IMM16);
3733 }
3734 HANDLE_OPCODE(DEPRECATED_LDHOMEOBJECT_PREF_NONE) {
3735 LOG_INST() << "intrinsics::ldhomeobject";
3736
3737 JSTaggedValue thisFunc = GetFunction(sp);
3738 JSTaggedValue homeObject = JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject();
3739
3740 SET_ACC(homeObject);
3741 DISPATCH(DEPRECATED_LDHOMEOBJECT_PREF_NONE);
3742 }
3743 HANDLE_OPCODE(DEBUGGER) {
3744 LOG_INST() << "intrinsics::debugger";
3745 NotifyDebuggerStmt(thread);
3746 DISPATCH(DEBUGGER);
3747 }
3748 HANDLE_OPCODE(ISTRUE) {
3749 LOG_INST() << "intrinsics::istrue";
3750 if (GET_ACC().ToBoolean()) {
3751 SET_ACC(JSTaggedValue::True());
3752 } else {
3753 SET_ACC(JSTaggedValue::False());
3754 }
3755 DISPATCH(ISTRUE);
3756 }
3757 HANDLE_OPCODE(ISFALSE) {
3758 LOG_INST() << "intrinsics::isfalse";
3759 if (!GET_ACC().ToBoolean()) {
3760 SET_ACC(JSTaggedValue::True());
3761 } else {
3762 SET_ACC(JSTaggedValue::False());
3763 }
3764 DISPATCH(ISFALSE);
3765 }
3766 NOPRINT_HANDLE_OPCODE(EXCEPTION) {
3767 FrameHandler frameHandler(thread);
3768 uint32_t pcOffset = panda_file::INVALID_OFFSET;
3769 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
3770 if (frameHandler.IsEntryFrame()) {
3771 return;
3772 }
3773 auto method = frameHandler.GetMethod();
3774 pcOffset = method->FindCatchBlock(frameHandler.GetBytecodeOffset());
3775 if (pcOffset != INVALID_INDEX) {
3776 sp = frameHandler.GetSp();
3777 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3778 pc = method->GetBytecodeArray() + pcOffset;
3779 break;
3780 }
3781 }
3782 if (pcOffset == INVALID_INDEX) {
3783 return;
3784 }
3785
3786 auto exception = thread->GetException();
3787 SET_ACC(exception);
3788 thread->ClearException();
3789 thread->SetCurrentSPFrame(sp);
3790 DISPATCH_OFFSET(0);
3791 }
3792 HANDLE_OPCODE(OVERFLOW) {
3793 LOG_INTERPRETER(FATAL) << "opcode overflow";
3794 }
3795 HANDLE_OPCODE(NOP) {
3796 LOG_INST() << "intrinsics::nop";
3797 DISPATCH(NOP);
3798 }
3799 NOPRINT_HANDLE_OPCODE(THROW) {
3800 DISPATCH_THROW();
3801 }
3802 NOPRINT_HANDLE_OPCODE(WIDE) {
3803 DISPATCH_WIDE();
3804 }
3805 NOPRINT_HANDLE_OPCODE(DEPRECATED) {
3806 DISPATCH_DEPRECATED();
3807 }
3808 NOPRINT_HANDLE_OPCODE(CALLRUNTIME) {
3809 DISPATCH_CALLRUNTIME();
3810 }
3811 HANDLE_OPCODE(THROW_PREF_NONE) {
3812 LOG_INST() << "intrinsics::throw";
3813 SAVE_PC();
3814 SlowRuntimeStub::Throw(thread, GET_ACC());
3815 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3816 }
3817 HANDLE_OPCODE(THROW_CONSTASSIGNMENT_PREF_V8) {
3818 uint16_t v0 = READ_INST_8_1();
3819 LOG_INST() << "throwconstassignment"
3820 << " v" << v0;
3821 SAVE_PC();
3822 SlowRuntimeStub::ThrowConstAssignment(thread, GET_VREG_VALUE(v0));
3823 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3824 }
3825 HANDLE_OPCODE(THROW_NOTEXISTS_PREF_NONE) {
3826 LOG_INST() << "throwthrownotexists";
3827
3828 SAVE_PC();
3829 SlowRuntimeStub::ThrowThrowNotExists(thread);
3830 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3831 }
3832 HANDLE_OPCODE(THROW_PATTERNNONCOERCIBLE_PREF_NONE) {
3833 LOG_INST() << "throwpatternnoncoercible";
3834
3835 SAVE_PC();
3836 SlowRuntimeStub::ThrowPatternNonCoercible(thread);
3837 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3838 }
3839 HANDLE_OPCODE(THROW_IFNOTOBJECT_PREF_V8) {
3840 LOG_INST() << "throwifnotobject";
3841 uint16_t v0 = READ_INST_8_1();
3842
3843 JSTaggedValue value = GET_VREG_VALUE(v0);
3844 // fast path
3845 if (value.IsECMAObject()) {
3846 DISPATCH(THROW_IFNOTOBJECT_PREF_V8);
3847 }
3848
3849 // slow path
3850 SAVE_PC();
3851 SlowRuntimeStub::ThrowIfNotObject(thread);
3852 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3853 }
3854 HANDLE_OPCODE(THROW_UNDEFINEDIFHOLE_PREF_V8_V8) {
3855 uint16_t v0 = READ_INST_8_1();
3856 uint16_t v1 = READ_INST_8_2();
3857 LOG_INST() << "intrinsic::throwundefinedifhole"
3858 << " v" << v0 << " v" << v1;
3859 JSTaggedValue hole = GET_VREG_VALUE(v0);
3860 if (!hole.IsHole()) {
3861 DISPATCH(THROW_UNDEFINEDIFHOLE_PREF_V8_V8);
3862 }
3863 JSTaggedValue obj = GET_VREG_VALUE(v1);
3864 ASSERT(obj.IsString());
3865 SAVE_PC();
3866 SlowRuntimeStub::ThrowUndefinedIfHole(thread, obj);
3867 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3868 }
3869 HANDLE_OPCODE(THROW_UNDEFINEDIFHOLEWITHNAME_PREF_ID16) {
3870 JSTaggedValue hole = acc;
3871 if (!hole.IsHole()) {
3872 DISPATCH(THROW_UNDEFINEDIFHOLEWITHNAME_PREF_ID16);
3873 }
3874
3875 uint16_t stringId = READ_INST_16_1();
3876 LOG_INST() << "intrinsic::throwundefinedifholewithname" << std::hex << stringId;
3877 JSTaggedValue constpool = GetConstantPool(sp);
3878 JSTaggedValue obj = GET_STR_FROM_CACHE(stringId);
3879 ASSERT(obj.IsString());
3880 SAVE_PC();
3881 SlowRuntimeStub::ThrowUndefinedIfHole(thread, obj);
3882 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3883 }
3884 HANDLE_OPCODE(THROW_DELETESUPERPROPERTY_PREF_NONE) {
3885 LOG_INST() << "throwdeletesuperproperty";
3886
3887 SAVE_PC();
3888 SlowRuntimeStub::ThrowDeleteSuperProperty(thread);
3889 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3890 }
3891 HANDLE_OPCODE(THROW_IFSUPERNOTCORRECTCALL_PREF_IMM8) {
3892 uint8_t imm = READ_INST_8_1();
3893 JSTaggedValue thisValue = GET_ACC();
3894 LOG_INST() << "intrinsic::throwifsupernotcorrectcall"
3895 << " imm:" << imm;
3896 SAVE_PC();
3897 JSTaggedValue res = SlowRuntimeStub::ThrowIfSuperNotCorrectCall(thread, imm, thisValue);
3898 INTERPRETER_RETURN_IF_ABRUPT(res);
3899 DISPATCH(THROW_IFSUPERNOTCORRECTCALL_PREF_IMM8);
3900 }
3901 HANDLE_OPCODE(THROW_IFSUPERNOTCORRECTCALL_PREF_IMM16) {
3902 uint16_t imm = READ_INST_16_1();
3903 JSTaggedValue thisValue = GET_ACC();
3904 LOG_INST() << "intrinsic::throwifsupernotcorrectcall"
3905 << " imm:" << imm;
3906 SAVE_PC();
3907 JSTaggedValue res = SlowRuntimeStub::ThrowIfSuperNotCorrectCall(thread, imm, thisValue);
3908 INTERPRETER_RETURN_IF_ABRUPT(res);
3909 DISPATCH(THROW_IFSUPERNOTCORRECTCALL_PREF_IMM16);
3910 }
3911 HANDLE_OPCODE(CREATEOBJECTWITHEXCLUDEDKEYS_IMM8_V8_V8) {
3912 uint8_t numKeys = READ_INST_8_0();
3913 uint16_t v0 = READ_INST_8_1();
3914 uint16_t firstArgRegIdx = READ_INST_8_2();
3915 LOG_INST() << "intrinsics::createobjectwithexcludedkeys " << numKeys << " v" << firstArgRegIdx;
3916
3917 JSTaggedValue obj = GET_VREG_VALUE(v0);
3918
3919 SAVE_PC();
3920 JSTaggedValue res = SlowRuntimeStub::CreateObjectWithExcludedKeys(thread, numKeys, obj, firstArgRegIdx);
3921 INTERPRETER_RETURN_IF_ABRUPT(res);
3922 SET_ACC(res);
3923 DISPATCH(CREATEOBJECTWITHEXCLUDEDKEYS_IMM8_V8_V8);
3924 }
3925 HANDLE_OPCODE(WIDE_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8) {
3926 uint16_t numKeys = READ_INST_16_1();
3927 uint16_t v0 = READ_INST_8_3();
3928 uint16_t firstArgRegIdx = READ_INST_8_4();
3929 LOG_INST() << "intrinsics::createobjectwithexcludedkeys " << numKeys << " v" << firstArgRegIdx;
3930
3931 JSTaggedValue obj = GET_VREG_VALUE(v0);
3932
3933 SAVE_PC();
3934 JSTaggedValue res = SlowRuntimeStub::CreateObjectWithExcludedKeys(thread, numKeys, obj, firstArgRegIdx);
3935 INTERPRETER_RETURN_IF_ABRUPT(res);
3936 SET_ACC(res);
3937 DISPATCH(WIDE_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8);
3938 }
3939 HANDLE_OPCODE(NEWOBJRANGE_IMM8_IMM8_V8) {
3940 uint16_t numArgs = READ_INST_8_1();
3941 uint16_t firstArgRegIdx = READ_INST_8_2();
3942 LOG_INST() << "intrinsics::newobjRange " << numArgs << " v" << firstArgRegIdx;
3943 JSTaggedValue ctor = GET_VREG_VALUE(firstArgRegIdx);
3944
3945 if (ctor.IsJSFunction() && ctor.IsConstructor()) {
3946 JSFunction *ctorFunc = JSFunction::Cast(ctor.GetTaggedObject());
3947 methodHandle.Update(ctorFunc->GetMethod());
3948 if (ctorFunc->IsBuiltinConstructor()) {
3949 ASSERT(methodHandle->GetNumVregsWithCallField() == 0);
3950 size_t frameSize = InterpretedFrame::NumOfMembers() + numArgs + 4; // 2: numArgs & thread
3951 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3952 JSTaggedType *newSp = sp - frameSize;
3953 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
3954 INTERPRETER_GOTO_EXCEPTION_HANDLER();
3955 }
3956 // copy args
3957 uint32_t index = 0;
3958 // numArgs
3959 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3960 EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo*>(newSp);
3961 newSp[index++] = ToUintPtr(thread);
3962 newSp[index++] = numArgs + 2; // 2: for newtarget / this
3963 // func
3964 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3965 newSp[index++] = ctor.GetRawData();
3966 // newTarget
3967 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3968 newSp[index++] = ctor.GetRawData();
3969 // this
3970 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3971 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
3972 for (size_t i = 1; i < numArgs; ++i) {
3973 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3974 newSp[index++] = GET_VREG(firstArgRegIdx + i);
3975 }
3976
3977 InterpretedBuiltinFrame *state = GET_BUILTIN_FRAME(newSp);
3978 state->base.prev = sp;
3979 state->base.type = FrameType::INTERPRETER_BUILTIN_FRAME;
3980 state->pc = nullptr;
3981 state->function = ctor;
3982 thread->SetCurrentSPFrame(newSp);
3983
3984 LOG_INST() << "Entry: Runtime New.";
3985 SAVE_PC();
3986 JSTaggedValue retValue = reinterpret_cast<EcmaEntrypoint>(
3987 const_cast<void *>(methodHandle->GetNativePointer()))(ecmaRuntimeCallInfo);
3988 thread->SetCurrentSPFrame(sp);
3989 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3990 LOG_INST() << "Exit: Runtime New.";
3991 SET_ACC(retValue);
3992 DISPATCH(NEWOBJRANGE_IMM8_IMM8_V8);
3993 }
3994
3995 if (IsFastNewFrameEnter(ctorFunc, methodHandle)) {
3996 SAVE_PC();
3997 uint32_t numVregs = methodHandle->GetNumVregsWithCallField();
3998 uint32_t numDeclaredArgs = ctorFunc->IsBase() ?
3999 methodHandle->GetNumArgsWithCallField() + 1 : // +1 for this
4000 methodHandle->GetNumArgsWithCallField() + 2; // +2 for newTarget and this
4001 size_t frameSize = InterpretedFrame::NumOfMembers() + numVregs + numDeclaredArgs;
4002 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4003 JSTaggedType *newSp = sp - frameSize;
4004 InterpretedFrame *state = GET_FRAME(newSp);
4005
4006 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
4007 INTERPRETER_GOTO_EXCEPTION_HANDLER();
4008 }
4009
4010 uint32_t index = 0;
4011 // initialize vregs value
4012 for (size_t i = 0; i < numVregs; ++i) {
4013 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
4014 }
4015
4016 // this
4017 JSTaggedValue thisObj;
4018 if (ctorFunc->IsBase()) {
4019 thisObj = FastRuntimeStub::NewThisObject(thread, ctor, ctor, state);
4020 INTERPRETER_RETURN_IF_ABRUPT(thisObj);
4021 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4022 newSp[index++] = thisObj.GetRawData();
4023 } else {
4024 ASSERT(ctorFunc->IsDerivedConstructor());
4025 newSp[index++] = ctor.GetRawData();
4026 thisObj = JSTaggedValue::Undefined();
4027 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4028 newSp[index++] = thisObj.GetRawData();
4029
4030 state->function = ctor;
4031 state->constpool = methodHandle->GetConstantPool();
4032 state->profileTypeInfo = methodHandle->GetProfileTypeInfo();
4033 state->env = ctorFunc->GetLexicalEnv();
4034 }
4035
4036 // the second condition ensure not push extra args
4037 for (size_t i = 1; i < numArgs && index < numVregs + numDeclaredArgs; ++i) {
4038 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4039 newSp[index++] = GET_VREG(firstArgRegIdx + i);
4040 }
4041
4042 // set undefined to the extra prats of declare
4043 for (size_t i = index; i < numVregs + numDeclaredArgs; ++i) {
4044 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4045 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
4046 }
4047
4048 state->base.prev = sp;
4049 state->base.type = FrameType::INTERPRETER_FAST_NEW_FRAME;
4050 state->thisObj = thisObj;
4051 state->pc = pc = methodHandle->GetBytecodeArray();
4052 sp = newSp;
4053 state->acc = JSTaggedValue::Hole();
4054
4055 thread->SetCurrentSPFrame(newSp);
4056 LOG_INST() << "Entry: Runtime New " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
4057 << std::hex << reinterpret_cast<uintptr_t>(pc);
4058 DISPATCH_OFFSET(0);
4059 }
4060 }
4061
4062 // bound function, proxy, other call types, enter slow path
4063 constexpr uint16_t firstArgOffset = 1;
4064 // Exclude func and newTarget
4065 uint16_t firstArgIdx = firstArgRegIdx + firstArgOffset;
4066 uint16_t length = numArgs - firstArgOffset;
4067
4068 SAVE_PC();
4069 JSTaggedValue res = SlowRuntimeStub::NewObjRange(thread, ctor, ctor, firstArgIdx, length);
4070 INTERPRETER_RETURN_IF_ABRUPT(res);
4071 SET_ACC(res);
4072 DISPATCH(NEWOBJRANGE_IMM8_IMM8_V8);
4073 }
4074 HANDLE_OPCODE(NEWOBJRANGE_IMM16_IMM8_V8) {
4075 uint16_t numArgs = READ_INST_8_2();
4076 uint16_t firstArgRegIdx = READ_INST_8_3();
4077 LOG_INST() << "intrinsics::newobjRange " << numArgs << " v" << firstArgRegIdx;
4078 JSTaggedValue ctor = GET_VREG_VALUE(firstArgRegIdx);
4079
4080 if (ctor.IsJSFunction() && ctor.IsConstructor()) {
4081 JSFunction *ctorFunc = JSFunction::Cast(ctor.GetTaggedObject());
4082 methodHandle.Update(ctorFunc->GetMethod());
4083 if (ctorFunc->IsBuiltinConstructor()) {
4084 ASSERT(methodHandle->GetNumVregsWithCallField() == 0);
4085 size_t frameSize =
4086 InterpretedFrame::NumOfMembers() + numArgs + 4; // 4: newtarget/this & numArgs & thread
4087 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4088 JSTaggedType *newSp = sp - frameSize;
4089 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
4090 INTERPRETER_GOTO_EXCEPTION_HANDLER();
4091 }
4092 // copy args
4093 uint32_t index = 0;
4094 // numArgs
4095 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4096 EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo*>(newSp);
4097 newSp[index++] = ToUintPtr(thread);
4098 newSp[index++] = numArgs + 2; // 2: for newtarget/this
4099 // func
4100 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4101 newSp[index++] = ctor.GetRawData();
4102 // newTarget
4103 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4104 newSp[index++] = ctor.GetRawData();
4105 // this
4106 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4107 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
4108 for (size_t i = 1; i < numArgs; ++i) { // 1: func
4109 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4110 newSp[index++] = GET_VREG(firstArgRegIdx + i);
4111 }
4112
4113 InterpretedBuiltinFrame *state = GET_BUILTIN_FRAME(newSp);
4114 state->base.prev = sp;
4115 state->base.type = FrameType::INTERPRETER_BUILTIN_FRAME;
4116 state->pc = nullptr;
4117 state->function = ctor;
4118 thread->SetCurrentSPFrame(newSp);
4119
4120 LOG_INST() << "Entry: Runtime New.";
4121 SAVE_PC();
4122 JSTaggedValue retValue = reinterpret_cast<EcmaEntrypoint>(
4123 const_cast<void *>(methodHandle->GetNativePointer()))(ecmaRuntimeCallInfo);
4124 thread->SetCurrentSPFrame(sp);
4125 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4126 LOG_INST() << "Exit: Runtime New.";
4127 SET_ACC(retValue);
4128 DISPATCH(NEWOBJRANGE_IMM16_IMM8_V8);
4129 }
4130
4131 if (IsFastNewFrameEnter(ctorFunc, methodHandle)) {
4132 SAVE_PC();
4133 uint32_t numVregs = methodHandle->GetNumVregsWithCallField();
4134 uint32_t numDeclaredArgs = ctorFunc->IsBase() ?
4135 methodHandle->GetNumArgsWithCallField() + 1 : // +1 for this
4136 methodHandle->GetNumArgsWithCallField() + 2; // +2 for newTarget and this
4137 size_t frameSize = InterpretedFrame::NumOfMembers() + numVregs + numDeclaredArgs;
4138 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4139 JSTaggedType *newSp = sp - frameSize;
4140 InterpretedFrame *state = GET_FRAME(newSp);
4141
4142 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
4143 INTERPRETER_GOTO_EXCEPTION_HANDLER();
4144 }
4145
4146 uint32_t index = 0;
4147 // initialize vregs value
4148 for (size_t i = 0; i < numVregs; ++i) {
4149 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
4150 }
4151
4152 // this
4153 JSTaggedValue thisObj;
4154 if (ctorFunc->IsBase()) {
4155 thisObj = FastRuntimeStub::NewThisObject(thread, ctor, ctor, state);
4156 INTERPRETER_RETURN_IF_ABRUPT(thisObj);
4157 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4158 newSp[index++] = thisObj.GetRawData();
4159 } else {
4160 ASSERT(ctorFunc->IsDerivedConstructor());
4161 newSp[index++] = ctor.GetRawData();
4162 thisObj = JSTaggedValue::Undefined();
4163 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4164 newSp[index++] = thisObj.GetRawData();
4165
4166 state->function = ctor;
4167 state->constpool = methodHandle->GetConstantPool();
4168 state->profileTypeInfo = methodHandle->GetProfileTypeInfo();
4169 state->env = ctorFunc->GetLexicalEnv();
4170 }
4171
4172 // the second condition ensure not push extra args
4173 for (size_t i = 1; i < numArgs && index < numVregs + numDeclaredArgs; ++i) { // 2: func and newTarget
4174 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4175 newSp[index++] = GET_VREG(firstArgRegIdx + i);
4176 }
4177
4178 // set undefined to the extra prats of declare
4179 for (size_t i = index; i < numVregs + numDeclaredArgs; ++i) {
4180 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4181 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
4182 }
4183
4184 state->base.prev = sp;
4185 state->base.type = FrameType::INTERPRETER_FAST_NEW_FRAME;
4186 state->thisObj = thisObj;
4187 state->pc = pc = methodHandle->GetBytecodeArray();
4188 sp = newSp;
4189 state->acc = JSTaggedValue::Hole();
4190
4191 thread->SetCurrentSPFrame(newSp);
4192 LOG_INST() << "Entry: Runtime New " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
4193 << std::hex << reinterpret_cast<uintptr_t>(pc);
4194 DISPATCH_OFFSET(0);
4195 }
4196 }
4197
4198 // bound function, proxy, other call types, enter slow path
4199 constexpr uint16_t firstArgOffset = 1;
4200 // Exclude func and newTarget
4201 uint16_t firstArgIdx = firstArgRegIdx + firstArgOffset;
4202 uint16_t length = numArgs - firstArgOffset;
4203
4204 SAVE_PC();
4205 JSTaggedValue res = SlowRuntimeStub::NewObjRange(thread, ctor, ctor, firstArgIdx, length);
4206 INTERPRETER_RETURN_IF_ABRUPT(res);
4207 SET_ACC(res);
4208 DISPATCH(NEWOBJRANGE_IMM16_IMM8_V8);
4209 }
4210 HANDLE_OPCODE(WIDE_NEWOBJRANGE_PREF_IMM16_V8) {
4211 uint16_t numArgs = READ_INST_16_1();
4212 uint16_t firstArgRegIdx = READ_INST_8_3();
4213 LOG_INST() << "intrinsics::newobjRange " << numArgs << " v" << firstArgRegIdx;
4214 JSTaggedValue ctor = GET_VREG_VALUE(firstArgRegIdx);
4215
4216 if (ctor.IsJSFunction() && ctor.IsConstructor()) {
4217 JSFunction *ctorFunc = JSFunction::Cast(ctor.GetTaggedObject());
4218 methodHandle.Update(ctorFunc->GetMethod());
4219 if (ctorFunc->IsBuiltinConstructor()) {
4220 ASSERT(methodHandle->GetNumVregsWithCallField() == 0);
4221 size_t frameSize = InterpretedFrame::NumOfMembers() + numArgs + 4; // 3: this & numArgs & thread
4222 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4223 JSTaggedType *newSp = sp - frameSize;
4224 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
4225 INTERPRETER_GOTO_EXCEPTION_HANDLER();
4226 }
4227 // copy args
4228 uint32_t index = 0;
4229 // numArgs
4230 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4231 EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo*>(newSp);
4232 newSp[index++] = ToUintPtr(thread);
4233 newSp[index++] = numArgs + 2; // +1 for this
4234 // func
4235 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4236 newSp[index++] = ctor.GetRawData();
4237 // newTarget
4238 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4239 newSp[index++] = ctor.GetRawData();
4240 // this
4241 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4242 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
4243 for (size_t i = 1; i < numArgs; ++i) {
4244 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4245 newSp[index++] = GET_VREG(firstArgRegIdx + i);
4246 }
4247
4248 InterpretedBuiltinFrame *state = GET_BUILTIN_FRAME(newSp);
4249 state->base.prev = sp;
4250 state->base.type = FrameType::INTERPRETER_BUILTIN_FRAME;
4251 state->pc = nullptr;
4252 state->function = ctor;
4253 thread->SetCurrentSPFrame(newSp);
4254
4255 LOG_INST() << "Entry: Runtime New.";
4256 SAVE_PC();
4257 JSTaggedValue retValue = reinterpret_cast<EcmaEntrypoint>(
4258 const_cast<void *>(methodHandle->GetNativePointer()))(ecmaRuntimeCallInfo);
4259 thread->SetCurrentSPFrame(sp);
4260 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4261 LOG_INST() << "Exit: Runtime New.";
4262 SET_ACC(retValue);
4263 DISPATCH(WIDE_NEWOBJRANGE_PREF_IMM16_V8);
4264 }
4265
4266 if (IsFastNewFrameEnter(ctorFunc, methodHandle)) {
4267 SAVE_PC();
4268 uint32_t numVregs = methodHandle->GetNumVregsWithCallField();
4269 uint32_t numDeclaredArgs = ctorFunc->IsBase() ?
4270 methodHandle->GetNumArgsWithCallField() + 1 : // +1 for this
4271 methodHandle->GetNumArgsWithCallField() + 2; // +2 for newTarget and this
4272 size_t frameSize = InterpretedFrame::NumOfMembers() + numVregs + numDeclaredArgs;
4273 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4274 JSTaggedType *newSp = sp - frameSize;
4275 InterpretedFrame *state = GET_FRAME(newSp);
4276
4277 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
4278 INTERPRETER_GOTO_EXCEPTION_HANDLER();
4279 }
4280
4281 uint32_t index = 0;
4282 // initialize vregs value
4283 for (size_t i = 0; i < numVregs; ++i) {
4284 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
4285 }
4286
4287 // this
4288 JSTaggedValue thisObj;
4289 if (ctorFunc->IsBase()) {
4290 thisObj = FastRuntimeStub::NewThisObject(thread, ctor, ctor, state);
4291 INTERPRETER_RETURN_IF_ABRUPT(thisObj);
4292 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4293 newSp[index++] = thisObj.GetRawData();
4294 } else {
4295 ASSERT(ctorFunc->IsDerivedConstructor());
4296 newSp[index++] = ctor.GetRawData();
4297 thisObj = JSTaggedValue::Undefined();
4298 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4299 newSp[index++] = thisObj.GetRawData();
4300
4301 state->function = ctor;
4302 state->constpool = methodHandle->GetConstantPool();
4303 state->profileTypeInfo = methodHandle->GetProfileTypeInfo();
4304 state->env = ctorFunc->GetLexicalEnv();
4305 }
4306
4307 // the second condition ensure not push extra args
4308 for (size_t i = 1; i < numArgs && index < numVregs + numDeclaredArgs; ++i) {
4309 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4310 newSp[index++] = GET_VREG(firstArgRegIdx + i);
4311 }
4312
4313 // set undefined to the extra prats of declare
4314 for (size_t i = index; i < numVregs + numDeclaredArgs; ++i) {
4315 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
4316 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
4317 }
4318
4319 state->base.prev = sp;
4320 state->base.type = FrameType::INTERPRETER_FAST_NEW_FRAME;
4321 state->thisObj = thisObj;
4322 state->pc = pc = methodHandle->GetBytecodeArray();
4323 sp = newSp;
4324 state->acc = JSTaggedValue::Hole();
4325
4326 thread->SetCurrentSPFrame(newSp);
4327 LOG_INST() << "Entry: Runtime New " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
4328 << std::hex << reinterpret_cast<uintptr_t>(pc);
4329 DISPATCH_OFFSET(0);
4330 }
4331 }
4332
4333 // bound function, proxy, other call types, enter slow path
4334 constexpr uint16_t firstArgOffset = 1;
4335 // Exclude func and newTarget
4336 uint16_t firstArgIdx = firstArgRegIdx + firstArgOffset;
4337 uint16_t length = numArgs - firstArgOffset;
4338
4339 SAVE_PC();
4340 JSTaggedValue res = SlowRuntimeStub::NewObjRange(thread, ctor, ctor, firstArgIdx, length);
4341 INTERPRETER_RETURN_IF_ABRUPT(res);
4342 SET_ACC(res);
4343 DISPATCH(WIDE_NEWOBJRANGE_PREF_IMM16_V8);
4344 }
4345 HANDLE_OPCODE(NEWLEXENV_IMM8) {
4346 uint8_t numVars = READ_INST_8_0();
4347 LOG_INST() << "intrinsics::newlexenv"
4348 << " imm " << numVars;
4349
4350 JSTaggedValue res = FastRuntimeStub::NewLexicalEnv(thread, factory, numVars);
4351 if (res.IsHole()) {
4352 SAVE_PC();
4353 res = SlowRuntimeStub::NewLexicalEnv(thread, numVars);
4354 INTERPRETER_RETURN_IF_ABRUPT(res);
4355 }
4356 SET_ACC(res);
4357 GET_FRAME(sp)->env = res;
4358 DISPATCH(NEWLEXENV_IMM8);
4359 }
4360 HANDLE_OPCODE(WIDE_NEWLEXENV_PREF_IMM16) {
4361 uint16_t numVars = READ_INST_16_1();
4362 LOG_INST() << "intrinsics::newlexenv"
4363 << " imm " << numVars;
4364
4365 JSTaggedValue res = FastRuntimeStub::NewLexicalEnv(thread, factory, numVars);
4366 if (res.IsHole()) {
4367 SAVE_PC();
4368 res = SlowRuntimeStub::NewLexicalEnv(thread, numVars);
4369 INTERPRETER_RETURN_IF_ABRUPT(res);
4370 }
4371 SET_ACC(res);
4372 GET_FRAME(sp)->env = res;
4373 DISPATCH(WIDE_NEWLEXENV_PREF_IMM16);
4374 }
4375 HANDLE_OPCODE(NEWLEXENVWITHNAME_IMM8_ID16) {
4376 uint16_t numVars = READ_INST_8_0();
4377 uint16_t scopeId = READ_INST_16_1();
4378 LOG_INST() << "intrinsics::newlexenvwithname"
4379 << " numVars " << numVars << " scopeId " << scopeId;
4380
4381 SAVE_PC();
4382 JSTaggedValue res = SlowRuntimeStub::NewLexicalEnvWithName(thread, numVars, scopeId);
4383 INTERPRETER_RETURN_IF_ABRUPT(res);
4384
4385 SET_ACC(res);
4386 GET_FRAME(sp)->env = res;
4387 DISPATCH(NEWLEXENVWITHNAME_IMM8_ID16);
4388 }
4389 HANDLE_OPCODE(WIDE_NEWLEXENVWITHNAME_PREF_IMM16_ID16) {
4390 uint16_t numVars = READ_INST_16_1();
4391 uint16_t scopeId = READ_INST_16_3();
4392 LOG_INST() << "intrinsics::newlexenvwithname"
4393 << " numVars " << numVars << " scopeId " << scopeId;
4394
4395 SAVE_PC();
4396 JSTaggedValue res = SlowRuntimeStub::NewLexicalEnvWithName(thread, numVars, scopeId);
4397 INTERPRETER_RETURN_IF_ABRUPT(res);
4398
4399 SET_ACC(res);
4400 GET_FRAME(sp)->env = res;
4401 DISPATCH(WIDE_NEWLEXENVWITHNAME_PREF_IMM16_ID16);
4402 }
4403 HANDLE_OPCODE(DEPRECATED_LDLEXENV_PREF_NONE) {
4404 LOG_INST() << "intrinsics::ldlexenv ";
4405 InterpretedFrame *state = GET_FRAME(sp);
4406 JSTaggedValue currentLexenv = state->env;
4407 SET_ACC(currentLexenv);
4408 DISPATCH(DEPRECATED_LDLEXENV_PREF_NONE);
4409 }
4410 HANDLE_OPCODE(POPLEXENV) {
4411 InterpretedFrame *state = GET_FRAME(sp);
4412 JSTaggedValue currentLexenv = state->env;
4413 JSTaggedValue parentLexenv = LexicalEnv::Cast(currentLexenv.GetTaggedObject())->GetParentEnv();
4414 GET_FRAME(sp)->env = parentLexenv;
4415 DISPATCH(POPLEXENV);
4416 }
4417 HANDLE_OPCODE(DEPRECATED_POPLEXENV_PREF_NONE) {
4418 InterpretedFrame *state = GET_FRAME(sp);
4419 JSTaggedValue currentLexenv = state->env;
4420 JSTaggedValue parentLexenv = LexicalEnv::Cast(currentLexenv.GetTaggedObject())->GetParentEnv();
4421 GET_FRAME(sp)->env = parentLexenv;
4422 DISPATCH(DEPRECATED_POPLEXENV_PREF_NONE);
4423 }
4424 HANDLE_OPCODE(GETITERATOR_IMM8) {
4425 LOG_INST() << "intrinsics::getiterator";
4426 JSTaggedValue obj = GET_ACC();
4427 // slow path
4428 SAVE_PC();
4429 JSTaggedValue res = SlowRuntimeStub::GetIterator(thread, obj);
4430 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4431 SET_ACC(res);
4432 DISPATCH(GETITERATOR_IMM8);
4433 }
4434 HANDLE_OPCODE(GETITERATOR_IMM16) {
4435 LOG_INST() << "intrinsics::getiterator";
4436 JSTaggedValue obj = GET_ACC();
4437 // slow path
4438 SAVE_PC();
4439 JSTaggedValue res = SlowRuntimeStub::GetIterator(thread, obj);
4440 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4441 SET_ACC(res);
4442 DISPATCH(GETITERATOR_IMM16);
4443 }
4444 HANDLE_OPCODE(GETASYNCITERATOR_IMM8) {
4445 LOG_INST() << "intrinsics::getasynciterator";
4446 JSTaggedValue obj = GET_ACC();
4447 // slow path
4448 SAVE_PC();
4449 JSTaggedValue res = SlowRuntimeStub::GetAsyncIterator(thread, obj);
4450 HANDLE_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4451 SET_ACC(res);
4452 DISPATCH(GETASYNCITERATOR_IMM8);
4453 }
4454 HANDLE_OPCODE(DEPRECATED_GETITERATORNEXT_PREF_V8_V8) {
4455 uint16_t v0 = READ_INST_8_1();
4456 uint16_t v1 = READ_INST_8_2();
4457 LOG_INST() << "intrinsic::getiteratornext"
4458 << " v" << v0 << " v" << v1;
4459 JSTaggedValue obj = GET_VREG_VALUE(v0);
4460 JSTaggedValue method = GET_VREG_VALUE(v1);
4461 SAVE_PC();
4462 JSTaggedValue res = SlowRuntimeStub::GetIteratorNext(thread, obj, method);
4463 INTERPRETER_RETURN_IF_ABRUPT(res);
4464 SET_ACC(res);
4465 DISPATCH(DEPRECATED_GETITERATORNEXT_PREF_V8_V8);
4466 }
4467 HANDLE_OPCODE(CREATEARRAYWITHBUFFER_IMM8_ID16) {
4468 uint16_t imm = READ_INST_16_1();
4469 LOG_INST() << "intrinsics::createarraywithbuffer"
4470 << " imm:" << imm;
4471 auto constpool = GetConstantPool(sp);
4472 JSArray *result = JSArray::Cast(GET_LITERA_FROM_CACHE(imm, ConstPoolType::ARRAY_LITERAL,
4473 GetEcmaModule(sp)).GetTaggedObject());
4474 SAVE_PC();
4475 JSTaggedValue res = SlowRuntimeStub::CreateArrayWithBuffer(thread, factory, result);
4476 INTERPRETER_RETURN_IF_ABRUPT(res);
4477 SET_ACC(res);
4478 DISPATCH(CREATEARRAYWITHBUFFER_IMM8_ID16);
4479 }
4480 HANDLE_OPCODE(CREATEARRAYWITHBUFFER_IMM16_ID16) {
4481 uint16_t imm = READ_INST_16_2();
4482 LOG_INST() << "intrinsics::createarraywithbuffer"
4483 << " imm:" << imm;
4484 auto constpool = GetConstantPool(sp);
4485 JSArray *result = JSArray::Cast(GET_LITERA_FROM_CACHE(imm, ConstPoolType::ARRAY_LITERAL,
4486 GetEcmaModule(sp)).GetTaggedObject());
4487 SAVE_PC();
4488 JSTaggedValue res = SlowRuntimeStub::CreateArrayWithBuffer(thread, factory, result);
4489 INTERPRETER_RETURN_IF_ABRUPT(res);
4490 SET_ACC(res);
4491 DISPATCH(CREATEARRAYWITHBUFFER_IMM16_ID16);
4492 }
4493 HANDLE_OPCODE(DEPRECATED_CREATEARRAYWITHBUFFER_PREF_IMM16) {
4494 uint16_t imm = READ_INST_16_1();
4495 LOG_INST() << "intrinsics::createarraywithbuffer"
4496 << " imm:" << imm;
4497 auto constpool = GetConstantPool(sp);
4498 JSArray *result = JSArray::Cast(GET_METHOD_FROM_CACHE(imm).GetTaggedObject());
4499 SAVE_PC();
4500 JSTaggedValue res = SlowRuntimeStub::CreateArrayWithBuffer(thread, factory, result);
4501 INTERPRETER_RETURN_IF_ABRUPT(res);
4502 SET_ACC(res);
4503 DISPATCH(DEPRECATED_CREATEARRAYWITHBUFFER_PREF_IMM16);
4504 }
4505 HANDLE_OPCODE(CREATEOBJECTWITHBUFFER_IMM8_ID16) {
4506 uint16_t imm = READ_INST_16_1();
4507 LOG_INST() << "intrinsics::createobjectwithbuffer"
4508 << " imm:" << imm;
4509 auto constpool = GetConstantPool(sp);
4510 JSObject *result = JSObject::Cast(GET_LITERA_FROM_CACHE(imm, ConstPoolType::OBJECT_LITERAL,
4511 GetEcmaModule(sp)).GetTaggedObject());
4512 SAVE_PC();
4513 InterpretedFrame *state = GET_FRAME(sp);
4514 JSTaggedValue res = SlowRuntimeStub::CreateObjectHavingMethod(thread, factory, result, state->env);
4515 INTERPRETER_RETURN_IF_ABRUPT(res);
4516 SET_ACC(res);
4517 DISPATCH(CREATEOBJECTWITHBUFFER_IMM8_ID16);
4518 }
4519 HANDLE_OPCODE(CREATEOBJECTWITHBUFFER_IMM16_ID16) {
4520 uint16_t imm = READ_INST_16_2();
4521 LOG_INST() << "intrinsics::createobjectwithbuffer"
4522 << " imm:" << imm;
4523 auto constpool = GetConstantPool(sp);
4524 JSObject *result = JSObject::Cast(GET_LITERA_FROM_CACHE(imm, ConstPoolType::OBJECT_LITERAL,
4525 GetEcmaModule(sp)).GetTaggedObject());
4526 SAVE_PC();
4527 InterpretedFrame *state = GET_FRAME(sp);
4528 JSTaggedValue res = SlowRuntimeStub::CreateObjectHavingMethod(thread, factory, result, state->env);
4529 INTERPRETER_RETURN_IF_ABRUPT(res);
4530 SET_ACC(res);
4531 DISPATCH(CREATEOBJECTWITHBUFFER_IMM16_ID16);
4532 }
4533 HANDLE_OPCODE(DEPRECATED_CREATEOBJECTWITHBUFFER_PREF_IMM16) {
4534 uint16_t imm = READ_INST_16_1();
4535 LOG_INST() << "intrinsics::createobjectwithbuffer"
4536 << " imm:" << imm;
4537 auto constpool = GetConstantPool(sp);
4538 JSObject *result = JSObject::Cast(GET_METHOD_FROM_CACHE(imm).GetTaggedObject());
4539
4540 SAVE_PC();
4541 JSTaggedValue res = SlowRuntimeStub::CreateObjectWithBuffer(thread, factory, result);
4542 INTERPRETER_RETURN_IF_ABRUPT(res);
4543 SET_ACC(res);
4544 DISPATCH(DEPRECATED_CREATEOBJECTWITHBUFFER_PREF_IMM16);
4545 }
4546 HANDLE_OPCODE(TONUMBER_IMM8) {
4547 LOG_INST() << "intrinsics::tonumber";
4548 JSTaggedValue value = GET_ACC();
4549 if (value.IsNumber()) {
4550 // fast path
4551 SET_ACC(value);
4552 } else {
4553 // slow path
4554 SAVE_PC();
4555 JSTaggedValue res = SlowRuntimeStub::ToNumber(thread, value);
4556 INTERPRETER_RETURN_IF_ABRUPT(res);
4557 SET_ACC(res);
4558 }
4559 DISPATCH(TONUMBER_IMM8);
4560 }
4561 HANDLE_OPCODE(DEPRECATED_TONUMBER_PREF_V8) {
4562 uint16_t v0 = READ_INST_8_1();
4563
4564 LOG_INST() << "intrinsics::tonumber"
4565 << " v" << v0;
4566 JSTaggedValue value = GET_VREG_VALUE(v0);
4567 if (value.IsNumber()) {
4568 // fast path
4569 SET_ACC(value);
4570 } else {
4571 // slow path
4572 SAVE_PC();
4573 JSTaggedValue res = SlowRuntimeStub::ToNumber(thread, value);
4574 INTERPRETER_RETURN_IF_ABRUPT(res);
4575 SET_ACC(res);
4576 }
4577 DISPATCH(DEPRECATED_TONUMBER_PREF_V8);
4578 }
4579 HANDLE_OPCODE(TONUMERIC_IMM8) {
4580 LOG_INST() << "intrinsics::tonumeric";
4581 JSTaggedValue value = GET_ACC();
4582 if (value.IsNumber() || value.IsBigInt()) {
4583 // fast path
4584 SET_ACC(value);
4585 } else {
4586 // slow path
4587 SAVE_PC();
4588 JSTaggedValue res = SlowRuntimeStub::ToNumeric(thread, value);
4589 INTERPRETER_RETURN_IF_ABRUPT(res);
4590 SET_ACC(res);
4591 }
4592 DISPATCH(TONUMERIC_IMM8);
4593 }
4594 HANDLE_OPCODE(DEPRECATED_TONUMERIC_PREF_V8) {
4595 uint16_t v0 = READ_INST_8_1();
4596 LOG_INST() << "intrinsics::tonumeric"
4597 << " v" << v0;
4598 JSTaggedValue value = GET_VREG_VALUE(v0);
4599 if (value.IsNumber() || value.IsBigInt()) {
4600 // fast path
4601 SET_ACC(value);
4602 } else {
4603 // slow path
4604 SAVE_PC();
4605 JSTaggedValue res = SlowRuntimeStub::ToNumeric(thread, value);
4606 INTERPRETER_RETURN_IF_ABRUPT(res);
4607 SET_ACC(res);
4608 }
4609 DISPATCH(DEPRECATED_TONUMERIC_PREF_V8);
4610 }
4611 HANDLE_OPCODE(NEG_IMM8) {
4612 LOG_INST() << "intrinsics::neg";
4613 JSTaggedValue value = GET_ACC();
4614 // fast path
4615 if (value.IsInt()) {
4616 if (value.GetInt() == 0) {
4617 SET_ACC(JSTaggedValue(-0.0));
4618 } else if (value.GetInt() == INT32_MIN) {
4619 SET_ACC(JSTaggedValue(-static_cast<double>(INT32_MIN)));
4620 } else {
4621 SET_ACC(JSTaggedValue(-value.GetInt()));
4622 }
4623 } else if (value.IsDouble()) {
4624 SET_ACC(JSTaggedValue(-value.GetDouble()));
4625 } else { // slow path
4626 SAVE_PC();
4627 JSTaggedValue res = SlowRuntimeStub::Neg(thread, value);
4628 INTERPRETER_RETURN_IF_ABRUPT(res);
4629 SET_ACC(res);
4630 }
4631 DISPATCH(NEG_IMM8);
4632 }
4633 HANDLE_OPCODE(DEPRECATED_NEG_PREF_V8) {
4634 uint16_t v0 = READ_INST_8_1();
4635 LOG_INST() << "intrinsics::neg"
4636 << " v" << v0;
4637 JSTaggedValue value = GET_VREG_VALUE(v0);
4638 // fast path
4639 if (value.IsInt()) {
4640 if (value.GetInt() == 0) {
4641 SET_ACC(JSTaggedValue(-0.0));
4642 } else {
4643 SET_ACC(JSTaggedValue(-value.GetInt()));
4644 }
4645 } else if (value.IsDouble()) {
4646 SET_ACC(JSTaggedValue(-value.GetDouble()));
4647 } else { // slow path
4648 SAVE_PC();
4649 JSTaggedValue res = SlowRuntimeStub::Neg(thread, value);
4650 INTERPRETER_RETURN_IF_ABRUPT(res);
4651 SET_ACC(res);
4652 }
4653 DISPATCH(DEPRECATED_NEG_PREF_V8);
4654 }
4655 HANDLE_OPCODE(NOT_IMM8) {
4656 LOG_INST() << "intrinsics::not";
4657 JSTaggedValue value = GET_ACC();
4658 int32_t number;
4659 // number, fast path
4660 if (value.IsInt()) {
4661 number = static_cast<int32_t>(value.GetInt());
4662 SET_ACC(JSTaggedValue(~number)); // NOLINT(hicpp-signed-bitwise);
4663 } else if (value.IsDouble()) {
4664 number = base::NumberHelper::DoubleToInt(value.GetDouble(), base::INT32_BITS);
4665 SET_ACC(JSTaggedValue(~number)); // NOLINT(hicpp-signed-bitwise);
4666 } else {
4667 // slow path
4668 SAVE_PC();
4669 JSTaggedValue res = SlowRuntimeStub::Not(thread, value);
4670 INTERPRETER_RETURN_IF_ABRUPT(res);
4671 SET_ACC(res);
4672 }
4673 DISPATCH(NOT_IMM8);
4674 }
4675 HANDLE_OPCODE(DEPRECATED_NOT_PREF_V8) {
4676 uint16_t v0 = READ_INST_8_1();
4677
4678 LOG_INST() << "intrinsics::not"
4679 << " v" << v0;
4680 JSTaggedValue value = GET_VREG_VALUE(v0);
4681 int32_t number;
4682 // number, fast path
4683 if (value.IsInt()) {
4684 number = static_cast<int32_t>(value.GetInt());
4685 SET_ACC(JSTaggedValue(~number)); // NOLINT(hicpp-signed-bitwise);
4686 } else if (value.IsDouble()) {
4687 number = base::NumberHelper::DoubleToInt(value.GetDouble(), base::INT32_BITS);
4688 SET_ACC(JSTaggedValue(~number)); // NOLINT(hicpp-signed-bitwise);
4689 } else {
4690 // slow path
4691 SAVE_PC();
4692 JSTaggedValue res = SlowRuntimeStub::Not(thread, value);
4693 INTERPRETER_RETURN_IF_ABRUPT(res);
4694 SET_ACC(res);
4695 }
4696 DISPATCH(DEPRECATED_NOT_PREF_V8);
4697 }
4698 HANDLE_OPCODE(INC_IMM8) {
4699 LOG_INST() << "intrinsics::inc";
4700
4701 JSTaggedValue value = GET_ACC();
4702 // number fast path
4703 if (value.IsInt()) {
4704 int32_t a0 = value.GetInt();
4705 if (UNLIKELY(a0 == INT32_MAX)) {
4706 auto ret = static_cast<double>(a0) + 1.0;
4707 SET_ACC(JSTaggedValue(ret));
4708 } else {
4709 SET_ACC(JSTaggedValue(a0 + 1));
4710 }
4711 } else if (value.IsDouble()) {
4712 SET_ACC(JSTaggedValue(value.GetDouble() + 1.0));
4713 } else {
4714 // slow path
4715 SAVE_PC();
4716 JSTaggedValue res = SlowRuntimeStub::Inc(thread, value);
4717 INTERPRETER_RETURN_IF_ABRUPT(res);
4718 SET_ACC(res);
4719 }
4720 DISPATCH(INC_IMM8);
4721 }
4722 HANDLE_OPCODE(DEPRECATED_INC_PREF_V8) {
4723 uint16_t v0 = READ_INST_8_1();
4724
4725 LOG_INST() << "intrinsics::inc"
4726 << " v" << v0;
4727
4728 JSTaggedValue value = GET_VREG_VALUE(v0);
4729 // number fast path
4730 if (value.IsInt()) {
4731 int32_t a0 = value.GetInt();
4732 if (UNLIKELY(a0 == INT32_MAX)) {
4733 auto ret = static_cast<double>(a0) + 1.0;
4734 SET_ACC(JSTaggedValue(ret));
4735 } else {
4736 SET_ACC(JSTaggedValue(a0 + 1));
4737 }
4738 } else if (value.IsDouble()) {
4739 SET_ACC(JSTaggedValue(value.GetDouble() + 1.0));
4740 } else {
4741 // slow path
4742 SAVE_PC();
4743 JSTaggedValue res = SlowRuntimeStub::Inc(thread, value);
4744 INTERPRETER_RETURN_IF_ABRUPT(res);
4745 SET_ACC(res);
4746 }
4747 DISPATCH(DEPRECATED_INC_PREF_V8);
4748 }
4749 HANDLE_OPCODE(DEC_IMM8) {
4750 LOG_INST() << "intrinsics::dec";
4751
4752 JSTaggedValue value = GET_ACC();
4753 // number, fast path
4754 if (value.IsInt()) {
4755 int32_t a0 = value.GetInt();
4756 if (UNLIKELY(a0 == INT32_MIN)) {
4757 auto ret = static_cast<double>(a0) - 1.0;
4758 SET_ACC(JSTaggedValue(ret));
4759 } else {
4760 SET_ACC(JSTaggedValue(a0 - 1));
4761 }
4762 } else if (value.IsDouble()) {
4763 SET_ACC(JSTaggedValue(value.GetDouble() - 1.0));
4764 } else {
4765 // slow path
4766 SAVE_PC();
4767 JSTaggedValue res = SlowRuntimeStub::Dec(thread, value);
4768 INTERPRETER_RETURN_IF_ABRUPT(res);
4769 SET_ACC(res);
4770 }
4771 DISPATCH(DEC_IMM8);
4772 }
4773 HANDLE_OPCODE(DEPRECATED_DEC_PREF_V8) {
4774 uint16_t v0 = READ_INST_8_1();
4775 LOG_INST() << "intrinsics::dec"
4776 << " v" << v0;
4777
4778 JSTaggedValue value = GET_VREG_VALUE(v0);
4779 // number, fast path
4780 if (value.IsInt()) {
4781 int32_t a0 = value.GetInt();
4782 if (UNLIKELY(a0 == INT32_MIN)) {
4783 auto ret = static_cast<double>(a0) - 1.0;
4784 SET_ACC(JSTaggedValue(ret));
4785 } else {
4786 SET_ACC(JSTaggedValue(a0 - 1));
4787 }
4788 } else if (value.IsDouble()) {
4789 SET_ACC(JSTaggedValue(value.GetDouble() - 1.0));
4790 } else {
4791 // slow path
4792 SAVE_PC();
4793 JSTaggedValue res = SlowRuntimeStub::Dec(thread, value);
4794 INTERPRETER_RETURN_IF_ABRUPT(res);
4795 SET_ACC(res);
4796 }
4797 DISPATCH(DEPRECATED_DEC_PREF_V8);
4798 }
4799 HANDLE_OPCODE(DEFINEFUNC_IMM8_ID16_IMM8) {
4800 uint16_t methodId = READ_INST_16_1();
4801 uint16_t length = READ_INST_8_3();
4802 LOG_INST() << "intrinsics::definefunc length: " << length;
4803 auto constpool = GetConstantPool(sp);
4804 Method *method = Method::Cast(GET_METHOD_FROM_CACHE(methodId).GetTaggedObject());
4805 ASSERT(method != nullptr);
4806
4807 auto res = SlowRuntimeStub::DefineFunc(thread, method);
4808 JSFunction *jsFunc = JSFunction::Cast(res.GetTaggedObject());
4809
4810 jsFunc->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length));
4811 InterpretedFrame *state = GET_FRAME(sp);
4812 JSTaggedValue envHandle = state->env;
4813 jsFunc->SetLexicalEnv(thread, envHandle);
4814
4815 JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
4816 jsFunc->SetModule(thread, currentFunc->GetModule());
4817 jsFunc->SetHomeObject(thread, currentFunc->GetHomeObject());
4818 SET_ACC(JSTaggedValue(jsFunc));
4819
4820 DISPATCH(DEFINEFUNC_IMM8_ID16_IMM8);
4821 }
4822 HANDLE_OPCODE(DEFINEFUNC_IMM16_ID16_IMM8) {
4823 uint16_t methodId = READ_INST_16_2();
4824 uint16_t length = READ_INST_8_4();
4825 LOG_INST() << "intrinsics::definefunc length: " << length;
4826
4827 auto constpool = GetConstantPool(sp);
4828 Method *method = Method::Cast(GET_METHOD_FROM_CACHE(methodId).GetTaggedObject());
4829 ASSERT(method != nullptr);
4830
4831 auto res = SlowRuntimeStub::DefineFunc(thread, method);
4832 JSFunction *jsFunc = JSFunction::Cast(res.GetTaggedObject());
4833
4834 jsFunc->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length));
4835 InterpretedFrame *state = GET_FRAME(sp);
4836 JSTaggedValue envHandle = state->env;
4837 jsFunc->SetLexicalEnv(thread, envHandle);
4838
4839 JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
4840 jsFunc->SetModule(thread, currentFunc->GetModule());
4841 jsFunc->SetHomeObject(thread, currentFunc->GetHomeObject());
4842 SET_ACC(JSTaggedValue(jsFunc));
4843
4844 DISPATCH(DEFINEFUNC_IMM16_ID16_IMM8);
4845 }
4846 HANDLE_OPCODE(DEFINEMETHOD_IMM8_ID16_IMM8) {
4847 uint16_t methodId = READ_INST_16_1();
4848 uint16_t length = READ_INST_8_3();
4849 LOG_INST() << "intrinsics::definemethod length: " << length;
4850 SAVE_ACC();
4851 auto constpool = GetConstantPool(sp);
4852 Method *method = Method::Cast(GET_METHOD_FROM_CACHE(methodId).GetTaggedObject());
4853 ASSERT(method != nullptr);
4854 RESTORE_ACC();
4855
4856 SAVE_PC();
4857 JSTaggedValue homeObject = GET_ACC();
4858 auto res = SlowRuntimeStub::DefineMethod(thread, method, homeObject);
4859 INTERPRETER_RETURN_IF_ABRUPT(res);
4860 JSFunction *result = JSFunction::Cast(res.GetTaggedObject());
4861
4862 result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length));
4863 InterpretedFrame *state = GET_FRAME(sp);
4864 JSTaggedValue taggedCurEnv = state->env;
4865 result->SetLexicalEnv(thread, taggedCurEnv);
4866
4867 JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
4868 result->SetModule(thread, currentFunc->GetModule());
4869 SET_ACC(JSTaggedValue(result));
4870
4871 DISPATCH(DEFINEMETHOD_IMM8_ID16_IMM8);
4872 }
4873 HANDLE_OPCODE(DEFINEMETHOD_IMM16_ID16_IMM8) {
4874 uint16_t methodId = READ_INST_16_2();
4875 uint16_t length = READ_INST_8_4();
4876 LOG_INST() << "intrinsics::definemethod length: " << length;
4877 SAVE_ACC();
4878 auto constpool = GetConstantPool(sp);
4879 Method *method = Method::Cast(GET_METHOD_FROM_CACHE(methodId).GetTaggedObject());
4880 ASSERT(method != nullptr);
4881 RESTORE_ACC();
4882
4883 SAVE_PC();
4884 JSTaggedValue homeObject = GET_ACC();
4885 auto res = SlowRuntimeStub::DefineMethod(thread, method, homeObject);
4886 INTERPRETER_RETURN_IF_ABRUPT(res);
4887 JSFunction *result = JSFunction::Cast(res.GetTaggedObject());
4888
4889 result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length));
4890 InterpretedFrame *state = GET_FRAME(sp);
4891 JSTaggedValue taggedCurEnv = state->env;
4892 result->SetLexicalEnv(thread, taggedCurEnv);
4893
4894 JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
4895 result->SetModule(thread, currentFunc->GetModule());
4896 SET_ACC(JSTaggedValue(result));
4897
4898 DISPATCH(DEFINEMETHOD_IMM16_ID16_IMM8);
4899 }
4900 HANDLE_OPCODE(DEFINECLASSWITHBUFFER_IMM8_ID16_ID16_IMM16_V8) {
4901 uint16_t methodId = READ_INST_16_1();
4902 uint16_t literaId = READ_INST_16_3();
4903 uint16_t length = READ_INST_16_5();
4904 uint16_t v0 = READ_INST_8_7();
4905 LOG_INST() << "intrinsics::defineclasswithbuffer"
4906 << " method id:" << methodId << " lexenv: v" << v0;
4907
4908 JSTaggedValue proto = GET_VREG_VALUE(v0);
4909
4910 SAVE_PC();
4911 InterpretedFrame *state = GET_FRAME(sp);
4912 JSTaggedValue res =
4913 SlowRuntimeStub::CreateClassWithBuffer(thread, proto, state->env, GetConstantPool(sp),
4914 methodId, literaId, GetEcmaModule(sp));
4915
4916 INTERPRETER_RETURN_IF_ABRUPT(res);
4917 ASSERT(res.IsClassConstructor());
4918 JSFunction *cls = JSFunction::Cast(res.GetTaggedObject());
4919
4920 cls->SetLexicalEnv(thread, state->env);
4921 cls->SetModule(thread, GetEcmaModule(sp));
4922
4923 SlowRuntimeStub::SetClassConstructorLength(thread, res, JSTaggedValue(length));
4924
4925 SET_ACC(res);
4926 DISPATCH(DEFINECLASSWITHBUFFER_IMM8_ID16_ID16_IMM16_V8);
4927 }
4928 HANDLE_OPCODE(DEFINECLASSWITHBUFFER_IMM16_ID16_ID16_IMM16_V8) {
4929 uint16_t methodId = READ_INST_16_2();
4930 uint16_t literaId = READ_INST_16_4();
4931 uint16_t length = READ_INST_16_6();
4932 uint16_t v0 = READ_INST_8_8();
4933 LOG_INST() << "intrinsics::defineclasswithbuffer"
4934 << " method id:" << methodId << " lexenv: v" << v0;
4935
4936 InterpretedFrame *state = GET_FRAME(sp);
4937 JSTaggedValue proto = GET_VREG_VALUE(v0);
4938
4939 SAVE_PC();
4940 JSTaggedValue res =
4941 SlowRuntimeStub::CreateClassWithBuffer(thread, proto, state->env, GetConstantPool(sp),
4942 methodId, literaId, GetEcmaModule(sp));
4943
4944 INTERPRETER_RETURN_IF_ABRUPT(res);
4945 ASSERT(res.IsClassConstructor());
4946 JSFunction *cls = JSFunction::Cast(res.GetTaggedObject());
4947
4948 cls->SetLexicalEnv(thread, state->env);
4949
4950 cls->SetModule(thread, GetEcmaModule(sp));
4951
4952 SlowRuntimeStub::SetClassConstructorLength(thread, res, JSTaggedValue(length));
4953
4954 SET_ACC(res);
4955 DISPATCH(DEFINECLASSWITHBUFFER_IMM16_ID16_ID16_IMM16_V8);
4956 }
4957 HANDLE_OPCODE(DEPRECATED_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8) {
4958 uint16_t methodId = READ_INST_16_1();
4959 uint16_t length = READ_INST_16_5();
4960 uint16_t v0 = READ_INST_8_7();
4961 uint16_t v1 = READ_INST_8_8();
4962 LOG_INST() << "intrinsics::defineclasswithbuffer"
4963 << " method id:" << methodId << " lexenv: v" << v0 << " parent: v" << v1;
4964
4965 JSTaggedValue lexenv = GET_VREG_VALUE(v0);
4966 JSTaggedValue proto = GET_VREG_VALUE(v1);
4967
4968 SAVE_PC();
4969 JSTaggedValue res =
4970 SlowRuntimeStub::CreateClassWithBuffer(thread, proto, lexenv, GetConstantPool(sp),
4971 methodId, methodId + 1, GetEcmaModule(sp));
4972
4973 INTERPRETER_RETURN_IF_ABRUPT(res);
4974 ASSERT(res.IsClassConstructor());
4975 JSFunction *cls = JSFunction::Cast(res.GetTaggedObject());
4976
4977 lexenv = GET_VREG_VALUE(v0); // slow runtime may gc
4978 cls->SetLexicalEnv(thread, lexenv);
4979 cls->SetModule(thread, GetEcmaModule(sp));
4980
4981 SlowRuntimeStub::SetClassConstructorLength(thread, res, JSTaggedValue(length));
4982
4983 SET_ACC(res);
4984 DISPATCH(DEPRECATED_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8);
4985 }
4986 HANDLE_OPCODE(RESUMEGENERATOR) {
4987 LOG_INST() << "intrinsics::resumegenerator";
4988 JSTaggedValue objVal = GET_ACC();
4989
4990 if (objVal.IsAsyncGeneratorObject()) {
4991 JSAsyncGeneratorObject *obj = JSAsyncGeneratorObject::Cast(objVal.GetTaggedObject());
4992 SET_ACC(obj->GetResumeResult());
4993 } else {
4994 JSGeneratorObject *obj = JSGeneratorObject::Cast(objVal.GetTaggedObject());
4995 SET_ACC(obj->GetResumeResult());
4996 }
4997 DISPATCH(RESUMEGENERATOR);
4998 }
4999 HANDLE_OPCODE(DEPRECATED_RESUMEGENERATOR_PREF_V8) {
5000 LOG_INST() << "intrinsics::resumegenerator";
5001 uint16_t vs = READ_INST_8_1();
5002 JSTaggedValue objVal = GET_VREG_VALUE(vs);
5003
5004 if (objVal.IsAsyncGeneratorObject()) {
5005 JSAsyncGeneratorObject *obj = JSAsyncGeneratorObject::Cast(objVal.GetTaggedObject());
5006 SET_ACC(obj->GetResumeResult());
5007 } else {
5008 JSGeneratorObject *obj = JSGeneratorObject::Cast(objVal.GetTaggedObject());
5009 SET_ACC(obj->GetResumeResult());
5010 }
5011 DISPATCH(DEPRECATED_RESUMEGENERATOR_PREF_V8);
5012 }
5013 HANDLE_OPCODE(GETRESUMEMODE) {
5014 LOG_INST() << "intrinsics::getresumemode";
5015 JSTaggedValue objVal = GET_ACC();
5016
5017 if (objVal.IsAsyncGeneratorObject()) {
5018 JSAsyncGeneratorObject *obj = JSAsyncGeneratorObject::Cast(objVal.GetTaggedObject());
5019 SET_ACC(JSTaggedValue(static_cast<int>(obj->GetResumeMode())));
5020 } else {
5021 JSGeneratorObject *obj = JSGeneratorObject::Cast(objVal.GetTaggedObject());
5022 SET_ACC(JSTaggedValue(static_cast<int>(obj->GetResumeMode())));
5023 }
5024 DISPATCH(GETRESUMEMODE);
5025 }
5026 HANDLE_OPCODE(DEPRECATED_GETRESUMEMODE_PREF_V8) {
5027 LOG_INST() << "intrinsics::getresumemode";
5028 uint16_t vs = READ_INST_8_1();
5029 JSTaggedValue objVal = GET_VREG_VALUE(vs);
5030
5031 if (objVal.IsAsyncGeneratorObject()) {
5032 JSAsyncGeneratorObject *obj = JSAsyncGeneratorObject::Cast(objVal.GetTaggedObject());
5033 SET_ACC(JSTaggedValue(static_cast<int>(obj->GetResumeMode())));
5034 } else {
5035 JSGeneratorObject *obj = JSGeneratorObject::Cast(objVal.GetTaggedObject());
5036 SET_ACC(JSTaggedValue(static_cast<int>(obj->GetResumeMode())));
5037 }
5038 DISPATCH(DEPRECATED_GETRESUMEMODE_PREF_V8);
5039 }
5040 HANDLE_OPCODE(GETTEMPLATEOBJECT_IMM8) {
5041 LOG_INST() << "intrinsic::gettemplateobject";
5042
5043 JSTaggedValue literal = GET_ACC();
5044 SAVE_PC();
5045 JSTaggedValue res = SlowRuntimeStub::GetTemplateObject(thread, literal);
5046 INTERPRETER_RETURN_IF_ABRUPT(res);
5047 SET_ACC(res);
5048 DISPATCH(GETTEMPLATEOBJECT_IMM8);
5049 }
5050 HANDLE_OPCODE(GETTEMPLATEOBJECT_IMM16) {
5051 LOG_INST() << "intrinsic::gettemplateobject";
5052
5053 JSTaggedValue literal = GET_ACC();
5054 SAVE_PC();
5055 JSTaggedValue res = SlowRuntimeStub::GetTemplateObject(thread, literal);
5056 INTERPRETER_RETURN_IF_ABRUPT(res);
5057 SET_ACC(res);
5058 DISPATCH(GETTEMPLATEOBJECT_IMM16);
5059 }
5060 HANDLE_OPCODE(DEPRECATED_GETTEMPLATEOBJECT_PREF_V8) {
5061 uint16_t v0 = READ_INST_8_1();
5062 LOG_INST() << "intrinsic::gettemplateobject"
5063 << " v" << v0;
5064
5065 JSTaggedValue literal = GET_VREG_VALUE(v0);
5066 SAVE_PC();
5067 JSTaggedValue res = SlowRuntimeStub::GetTemplateObject(thread, literal);
5068 INTERPRETER_RETURN_IF_ABRUPT(res);
5069 SET_ACC(res);
5070 DISPATCH(DEPRECATED_GETTEMPLATEOBJECT_PREF_V8);
5071 }
5072 HANDLE_OPCODE(DELOBJPROP_V8) {
5073 uint16_t v0 = READ_INST_8_0();
5074 LOG_INST() << "intrinsics::delobjprop"
5075 << " v0" << v0;
5076
5077 JSTaggedValue obj = GET_VREG_VALUE(v0);
5078 JSTaggedValue prop = GET_ACC();
5079 SAVE_PC();
5080 JSTaggedValue res = SlowRuntimeStub::DelObjProp(thread, obj, prop);
5081 INTERPRETER_RETURN_IF_ABRUPT(res);
5082 SET_ACC(res);
5083
5084 DISPATCH(DELOBJPROP_V8);
5085 }
5086 HANDLE_OPCODE(DEPRECATED_DELOBJPROP_PREF_V8_V8) {
5087 uint16_t v0 = READ_INST_8_1();
5088 uint16_t v1 = READ_INST_8_2();
5089 LOG_INST() << "intrinsics::delobjprop"
5090 << " v0" << v0 << " v1" << v1;
5091
5092 JSTaggedValue obj = GET_VREG_VALUE(v0);
5093 JSTaggedValue prop = GET_VREG_VALUE(v1);
5094 SAVE_PC();
5095 JSTaggedValue res = SlowRuntimeStub::DelObjProp(thread, obj, prop);
5096 INTERPRETER_RETURN_IF_ABRUPT(res);
5097 SET_ACC(res);
5098
5099 DISPATCH(DEPRECATED_DELOBJPROP_PREF_V8_V8);
5100 }
5101 HANDLE_OPCODE(SUSPENDGENERATOR_V8) {
5102 uint16_t v0 = READ_INST_8_0();
5103 LOG_INST() << "intrinsics::suspendgenerator"
5104 << " v" << v0;
5105 JSTaggedValue genObj = GET_VREG_VALUE(v0);
5106 JSTaggedValue value = GET_ACC();
5107 // suspend will record bytecode offset
5108 SAVE_PC();
5109 SAVE_ACC();
5110 JSTaggedValue res = SlowRuntimeStub::SuspendGenerator(thread, genObj, value);
5111 INTERPRETER_RETURN_IF_ABRUPT(res);
5112 SET_ACC(res);
5113
5114 InterpretedFrame *state = GET_FRAME(sp);
5115 methodHandle.Update(JSFunction::Cast(state->function.GetTaggedObject())->GetMethod());
5116 [[maybe_unused]] auto fistPC = methodHandle->GetBytecodeArray();
5117 UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
5118 LOG_INST() << "Exit: SuspendGenerator " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
5119 << std::hex << reinterpret_cast<uintptr_t>(state->pc);
5120 sp = state->base.prev;
5121 ASSERT(sp != nullptr);
5122 InterpretedFrame *prevState = GET_FRAME(sp);
5123 pc = prevState->pc;
5124 // entry frame
5125 if (FrameHandler::IsEntryFrame(pc)) {
5126 state->acc = acc;
5127 return;
5128 }
5129
5130 thread->SetCurrentSPFrame(sp);
5131
5132 INTERPRETER_HANDLE_RETURN();
5133 }
5134 HANDLE_OPCODE(DEPRECATED_SUSPENDGENERATOR_PREF_V8_V8) {
5135 uint16_t v0 = READ_INST_8_1();
5136 uint16_t v1 = READ_INST_8_2();
5137 LOG_INST() << "intrinsics::suspendgenerator"
5138 << " v" << v0 << " v" << v1;
5139 JSTaggedValue genObj = GET_VREG_VALUE(v0);
5140 JSTaggedValue value = GET_VREG_VALUE(v1);
5141 // suspend will record bytecode offset
5142 SAVE_PC();
5143 SAVE_ACC();
5144 JSTaggedValue res = SlowRuntimeStub::SuspendGenerator(thread, genObj, value);
5145 INTERPRETER_RETURN_IF_ABRUPT(res);
5146 SET_ACC(res);
5147
5148 InterpretedFrame *state = GET_FRAME(sp);
5149 Method *method = JSFunction::Cast(state->function.GetTaggedObject())->GetCallTarget();
5150 [[maybe_unused]] auto fistPC = method->GetBytecodeArray();
5151 UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
5152 LOG_INST() << "Exit: SuspendGenerator " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
5153 << std::hex << reinterpret_cast<uintptr_t>(state->pc);
5154 sp = state->base.prev;
5155 ASSERT(sp != nullptr);
5156 InterpretedFrame *prevState = GET_FRAME(sp);
5157 pc = prevState->pc;
5158 // entry frame
5159 if (FrameHandler::IsEntryFrame(pc)) {
5160 state->acc = acc;
5161 return;
5162 }
5163
5164 thread->SetCurrentSPFrame(sp);
5165
5166 INTERPRETER_HANDLE_RETURN();
5167 }
5168 HANDLE_OPCODE(SETGENERATORSTATE_IMM8) {
5169 uint16_t index = READ_INST_8_0();
5170 LOG_INST() << "intrinsics::setgeneratorstate index" << index;
5171 JSTaggedValue objVal = GET_ACC();
5172 SAVE_PC();
5173 SAVE_ACC();
5174 SlowRuntimeStub::SetGeneratorState(thread, objVal, index);
5175 RESTORE_ACC();
5176 DISPATCH(SETGENERATORSTATE_IMM8);
5177 }
5178 HANDLE_OPCODE(ASYNCFUNCTIONAWAITUNCAUGHT_V8) {
5179 uint16_t v0 = READ_INST_8_0();
5180 LOG_INST() << "intrinsics::asyncfunctionawaituncaught"
5181 << " v" << v0;
5182 JSTaggedValue asyncFuncObj = GET_VREG_VALUE(v0);
5183 JSTaggedValue value = GET_ACC();
5184 SAVE_PC();
5185 JSTaggedValue res = SlowRuntimeStub::AsyncFunctionAwaitUncaught(thread, asyncFuncObj, value);
5186 INTERPRETER_RETURN_IF_ABRUPT(res);
5187 SET_ACC(res);
5188 DISPATCH(ASYNCFUNCTIONAWAITUNCAUGHT_V8);
5189 }
5190 HANDLE_OPCODE(DEPRECATED_ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8) {
5191 uint16_t v0 = READ_INST_8_1();
5192 uint16_t v1 = READ_INST_8_2();
5193 LOG_INST() << "intrinsics::asyncfunctionawaituncaught"
5194 << " v" << v0 << " v" << v1;
5195 JSTaggedValue asyncFuncObj = GET_VREG_VALUE(v0);
5196 JSTaggedValue value = GET_VREG_VALUE(v1);
5197 SAVE_PC();
5198 JSTaggedValue res = SlowRuntimeStub::AsyncFunctionAwaitUncaught(thread, asyncFuncObj, value);
5199 INTERPRETER_RETURN_IF_ABRUPT(res);
5200 SET_ACC(res);
5201 DISPATCH(DEPRECATED_ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8);
5202 }
5203 HANDLE_OPCODE(COPYDATAPROPERTIES_V8) {
5204 uint16_t v0 = READ_INST_8_0();
5205 LOG_INST() << "intrinsic::copydataproperties"
5206 << " v" << v0;
5207 JSTaggedValue dst = GET_VREG_VALUE(v0);
5208 JSTaggedValue src = GET_ACC();
5209 SAVE_PC();
5210 JSTaggedValue res = SlowRuntimeStub::CopyDataProperties(thread, dst, src);
5211 INTERPRETER_RETURN_IF_ABRUPT(res);
5212 SET_ACC(res);
5213 DISPATCH(COPYDATAPROPERTIES_V8);
5214 }
5215 HANDLE_OPCODE(DEPRECATED_COPYDATAPROPERTIES_PREF_V8_V8) {
5216 uint16_t v0 = READ_INST_8_1();
5217 uint16_t v1 = READ_INST_8_2();
5218 LOG_INST() << "intrinsic::copydataproperties"
5219 << " v" << v0 << " v" << v1;
5220 JSTaggedValue dst = GET_VREG_VALUE(v0);
5221 JSTaggedValue src = GET_VREG_VALUE(v1);
5222 SAVE_PC();
5223 JSTaggedValue res = SlowRuntimeStub::CopyDataProperties(thread, dst, src);
5224 INTERPRETER_RETURN_IF_ABRUPT(res);
5225 SET_ACC(res);
5226 DISPATCH(DEPRECATED_COPYDATAPROPERTIES_PREF_V8_V8);
5227 }
5228 HANDLE_OPCODE(SETOBJECTWITHPROTO_IMM8_V8) {
5229 uint16_t v0 = READ_INST_8_1();
5230 LOG_INST() << "intrinsics::setobjectwithproto"
5231 << " v" << v0;
5232 JSTaggedValue proto = GET_VREG_VALUE(v0);
5233 JSTaggedValue obj = GET_ACC();
5234 SAVE_ACC();
5235 SAVE_PC();
5236 JSTaggedValue res = SlowRuntimeStub::SetObjectWithProto(thread, proto, obj);
5237 INTERPRETER_RETURN_IF_ABRUPT(res);
5238 RESTORE_ACC();
5239 DISPATCH(SETOBJECTWITHPROTO_IMM8_V8);
5240 }
5241 HANDLE_OPCODE(SETOBJECTWITHPROTO_IMM16_V8) {
5242 uint16_t v0 = READ_INST_8_2();
5243 LOG_INST() << "intrinsics::setobjectwithproto"
5244 << " v" << v0;
5245 JSTaggedValue proto = GET_VREG_VALUE(v0);
5246 JSTaggedValue obj = GET_ACC();
5247 SAVE_ACC();
5248 SAVE_PC();
5249 JSTaggedValue res = SlowRuntimeStub::SetObjectWithProto(thread, proto, obj);
5250 INTERPRETER_RETURN_IF_ABRUPT(res);
5251 RESTORE_ACC();
5252 DISPATCH(SETOBJECTWITHPROTO_IMM16_V8);
5253 }
5254 HANDLE_OPCODE(DEPRECATED_SETOBJECTWITHPROTO_PREF_V8_V8) {
5255 uint16_t v0 = READ_INST_8_1();
5256 uint16_t v1 = READ_INST_8_2();
5257 LOG_INST() << "intrinsics::setobjectwithproto"
5258 << " v" << v0 << " v" << v1;
5259 JSTaggedValue proto = GET_VREG_VALUE(v0);
5260 JSTaggedValue obj = GET_VREG_VALUE(v1);
5261 SAVE_ACC();
5262 SAVE_PC();
5263 JSTaggedValue res = SlowRuntimeStub::SetObjectWithProto(thread, proto, obj);
5264 INTERPRETER_RETURN_IF_ABRUPT(res);
5265 RESTORE_ACC();
5266 DISPATCH(DEPRECATED_SETOBJECTWITHPROTO_PREF_V8_V8);
5267 }
5268 HANDLE_OPCODE(LDOBJBYVALUE_IMM8_V8) {
5269 uint32_t v0 = READ_INST_8_1();
5270 LOG_INST() << "intrinsics::Ldobjbyvalue"
5271 << " v" << v0;
5272
5273 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5274 JSTaggedValue propKey = GET_ACC();
5275
5276 #if ECMASCRIPT_ENABLE_IC
5277 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
5278 if (!profileTypeInfo.IsUndefined()) {
5279 uint16_t slotId = READ_INST_8_0();
5280 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
5281 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
5282 JSTaggedValue res = JSTaggedValue::Hole();
5283
5284 if (LIKELY(firstValue.IsHeapObject())) {
5285 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
5286 res = ICRuntimeStub::TryLoadICByValue(thread, receiver, propKey, firstValue, secondValue);
5287 }
5288 // IC miss and not enter the megamorphic state, store as polymorphic
5289 if (res.IsHole() && !firstValue.IsHole()) {
5290 res = ICRuntimeStub::LoadICByValue(thread,
5291 profileTypeArray,
5292 receiver, propKey, slotId);
5293 }
5294
5295 if (LIKELY(!res.IsHole())) {
5296 INTERPRETER_RETURN_IF_ABRUPT(res);
5297 SET_ACC(res);
5298 DISPATCH(LDOBJBYVALUE_IMM8_V8);
5299 }
5300 }
5301 #endif
5302 // fast path
5303 if (LIKELY(receiver.IsHeapObject())) {
5304 JSTaggedValue res = FastRuntimeStub::GetPropertyByValue(thread, receiver, propKey);
5305 if (!res.IsHole()) {
5306 ASSERT(!res.IsAccessor());
5307 INTERPRETER_RETURN_IF_ABRUPT(res);
5308 SET_ACC(res);
5309 DISPATCH(LDOBJBYVALUE_IMM8_V8);
5310 }
5311 }
5312 // slow path
5313 SAVE_PC();
5314 JSTaggedValue res = SlowRuntimeStub::LdObjByValue(thread, receiver, propKey, false, JSTaggedValue::Undefined());
5315 INTERPRETER_RETURN_IF_ABRUPT(res);
5316 SET_ACC(res);
5317 DISPATCH(LDOBJBYVALUE_IMM8_V8);
5318 }
5319 HANDLE_OPCODE(LDOBJBYVALUE_IMM16_V8) {
5320 uint32_t v0 = READ_INST_8_2();
5321 LOG_INST() << "intrinsics::Ldobjbyvalue"
5322 << " v" << v0;
5323
5324 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5325 JSTaggedValue propKey = GET_ACC();
5326
5327 #if ECMASCRIPT_ENABLE_IC
5328 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
5329 if (!profileTypeInfo.IsUndefined()) {
5330 uint16_t slotId = READ_INST_16_0();
5331 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
5332 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
5333 JSTaggedValue res = JSTaggedValue::Hole();
5334
5335 if (LIKELY(firstValue.IsHeapObject())) {
5336 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
5337 res = ICRuntimeStub::TryLoadICByValue(thread, receiver, propKey, firstValue, secondValue);
5338 }
5339 // IC miss and not enter the megamorphic state, store as polymorphic
5340 if (res.IsHole() && !firstValue.IsHole()) {
5341 res = ICRuntimeStub::LoadICByValue(thread,
5342 profileTypeArray,
5343 receiver, propKey, slotId);
5344 }
5345
5346 if (LIKELY(!res.IsHole())) {
5347 INTERPRETER_RETURN_IF_ABRUPT(res);
5348 SET_ACC(res);
5349 DISPATCH(LDOBJBYVALUE_IMM16_V8);
5350 }
5351 }
5352 #endif
5353 // fast path
5354 if (LIKELY(receiver.IsHeapObject())) {
5355 JSTaggedValue res = FastRuntimeStub::GetPropertyByValue(thread, receiver, propKey);
5356 if (!res.IsHole()) {
5357 ASSERT(!res.IsAccessor());
5358 INTERPRETER_RETURN_IF_ABRUPT(res);
5359 SET_ACC(res);
5360 DISPATCH(LDOBJBYVALUE_IMM16_V8);
5361 }
5362 }
5363 // slow path
5364 SAVE_PC();
5365 JSTaggedValue res = SlowRuntimeStub::LdObjByValue(thread, receiver, propKey, false, JSTaggedValue::Undefined());
5366 INTERPRETER_RETURN_IF_ABRUPT(res);
5367 SET_ACC(res);
5368 DISPATCH(LDOBJBYVALUE_IMM16_V8);
5369 }
5370 HANDLE_OPCODE(DEPRECATED_LDOBJBYVALUE_PREF_V8_V8) {
5371 uint32_t v0 = READ_INST_8_1();
5372 uint32_t v1 = READ_INST_8_2();
5373 LOG_INST() << "intrinsics::Ldobjbyvalue"
5374 << " v" << v0 << " v" << v1;
5375
5376 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5377 JSTaggedValue propKey = GET_VREG_VALUE(v1);
5378
5379 // fast path
5380 if (LIKELY(receiver.IsHeapObject())) {
5381 JSTaggedValue res = FastRuntimeStub::GetPropertyByValue(thread, receiver, propKey);
5382 if (!res.IsHole()) {
5383 ASSERT(!res.IsAccessor());
5384 INTERPRETER_RETURN_IF_ABRUPT(res);
5385 SET_ACC(res);
5386 DISPATCH(DEPRECATED_LDOBJBYVALUE_PREF_V8_V8);
5387 }
5388 }
5389 // slow path
5390 SAVE_PC();
5391 JSTaggedValue res = SlowRuntimeStub::LdObjByValue(thread, receiver, propKey, false, JSTaggedValue::Undefined());
5392 INTERPRETER_RETURN_IF_ABRUPT(res);
5393 SET_ACC(res);
5394 DISPATCH(DEPRECATED_LDOBJBYVALUE_PREF_V8_V8);
5395 }
5396 HANDLE_OPCODE(LDSUPERBYVALUE_IMM8_V8) {
5397 uint32_t v0 = READ_INST_8_1();
5398 LOG_INST() << "intrinsics::Ldsuperbyvalue"
5399 << " v" << v0;
5400
5401 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5402 JSTaggedValue propKey = GET_ACC();
5403
5404 // slow path
5405 SAVE_PC();
5406 JSTaggedValue thisFunc = GetFunction(sp);
5407 JSTaggedValue res = SlowRuntimeStub::LdSuperByValue(thread, receiver, propKey, thisFunc);
5408 INTERPRETER_RETURN_IF_ABRUPT(res);
5409 SET_ACC(res);
5410 DISPATCH(LDSUPERBYVALUE_IMM8_V8);
5411 }
5412 HANDLE_OPCODE(LDSUPERBYVALUE_IMM16_V8) {
5413 uint32_t v0 = READ_INST_8_2();
5414 LOG_INST() << "intrinsics::Ldsuperbyvalue"
5415 << " v" << v0;
5416
5417 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5418 JSTaggedValue propKey = GET_ACC();
5419
5420 // slow path
5421 SAVE_PC();
5422 JSTaggedValue thisFunc = GetFunction(sp);
5423 JSTaggedValue res = SlowRuntimeStub::LdSuperByValue(thread, receiver, propKey, thisFunc);
5424 INTERPRETER_RETURN_IF_ABRUPT(res);
5425 SET_ACC(res);
5426 DISPATCH(LDSUPERBYVALUE_IMM16_V8);
5427 }
5428 HANDLE_OPCODE(DEPRECATED_LDSUPERBYVALUE_PREF_V8_V8) {
5429 uint32_t v0 = READ_INST_8_1();
5430 uint32_t v1 = READ_INST_8_2();
5431 LOG_INST() << "intrinsics::Ldsuperbyvalue"
5432 << " v" << v0 << " v" << v1;
5433
5434 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5435 JSTaggedValue propKey = GET_VREG_VALUE(v1);
5436
5437 // slow path
5438 SAVE_PC();
5439 JSTaggedValue thisFunc = GetFunction(sp);
5440 JSTaggedValue res = SlowRuntimeStub::LdSuperByValue(thread, receiver, propKey, thisFunc);
5441 INTERPRETER_RETURN_IF_ABRUPT(res);
5442 SET_ACC(res);
5443 DISPATCH(DEPRECATED_LDSUPERBYVALUE_PREF_V8_V8);
5444 }
5445 HANDLE_OPCODE(LDOBJBYINDEX_IMM8_IMM16) {
5446 uint32_t idx = READ_INST_16_1();
5447 LOG_INST() << "intrinsics::ldobjbyindex"
5448 << " imm" << idx;
5449
5450 JSTaggedValue receiver = GET_ACC();
5451 // fast path
5452 if (LIKELY(receiver.IsHeapObject())) {
5453 JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, receiver, idx);
5454 if (!res.IsHole()) {
5455 INTERPRETER_RETURN_IF_ABRUPT(res);
5456 SET_ACC(res);
5457 DISPATCH(LDOBJBYINDEX_IMM8_IMM16);
5458 }
5459 }
5460 // not meet fast condition or fast path return hole, walk slow path
5461 // slow stub not need receiver
5462 SAVE_PC();
5463 JSTaggedValue res = SlowRuntimeStub::LdObjByIndex(thread, receiver, idx, false, JSTaggedValue::Undefined());
5464 INTERPRETER_RETURN_IF_ABRUPT(res);
5465 SET_ACC(res);
5466 DISPATCH(LDOBJBYINDEX_IMM8_IMM16);
5467 }
5468 HANDLE_OPCODE(LDOBJBYINDEX_IMM16_IMM16) {
5469 uint32_t idx = READ_INST_16_2();
5470 LOG_INST() << "intrinsics::ldobjbyindex"
5471 << " imm" << idx;
5472
5473 JSTaggedValue receiver = GET_ACC();
5474 // fast path
5475 if (LIKELY(receiver.IsHeapObject())) {
5476 JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, receiver, idx);
5477 if (!res.IsHole()) {
5478 INTERPRETER_RETURN_IF_ABRUPT(res);
5479 SET_ACC(res);
5480 DISPATCH(LDOBJBYINDEX_IMM16_IMM16);
5481 }
5482 }
5483 // not meet fast condition or fast path return hole, walk slow path
5484 // slow stub not need receiver
5485 SAVE_PC();
5486 JSTaggedValue res = SlowRuntimeStub::LdObjByIndex(thread, receiver, idx, false, JSTaggedValue::Undefined());
5487 INTERPRETER_RETURN_IF_ABRUPT(res);
5488 SET_ACC(res);
5489 DISPATCH(LDOBJBYINDEX_IMM16_IMM16);
5490 }
5491 HANDLE_OPCODE(WIDE_LDOBJBYINDEX_PREF_IMM32) {
5492 uint32_t idx = READ_INST_32_1();
5493 LOG_INST() << "intrinsics::ldobjbyindex"
5494 << " imm" << idx;
5495
5496 JSTaggedValue receiver = GET_ACC();
5497 // fast path
5498 if (LIKELY(receiver.IsHeapObject())) {
5499 JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, receiver, idx);
5500 if (!res.IsHole()) {
5501 INTERPRETER_RETURN_IF_ABRUPT(res);
5502 SET_ACC(res);
5503 DISPATCH(WIDE_LDOBJBYINDEX_PREF_IMM32);
5504 }
5505 }
5506 // not meet fast condition or fast path return hole, walk slow path
5507 // slow stub not need receiver
5508 SAVE_PC();
5509 JSTaggedValue res = SlowRuntimeStub::LdObjByIndex(thread, receiver, idx, false, JSTaggedValue::Undefined());
5510 INTERPRETER_RETURN_IF_ABRUPT(res);
5511 SET_ACC(res);
5512 DISPATCH(WIDE_LDOBJBYINDEX_PREF_IMM32);
5513 }
5514 HANDLE_OPCODE(DEPRECATED_LDOBJBYINDEX_PREF_V8_IMM32) {
5515 uint16_t v0 = READ_INST_8_1();
5516 uint32_t idx = READ_INST_32_2();
5517 LOG_INST() << "intrinsics::ldobjbyindex"
5518 << " v" << v0 << " imm" << idx;
5519
5520 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5521 // fast path
5522 if (LIKELY(receiver.IsHeapObject())) {
5523 JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, receiver, idx);
5524 if (!res.IsHole()) {
5525 INTERPRETER_RETURN_IF_ABRUPT(res);
5526 SET_ACC(res);
5527 DISPATCH(DEPRECATED_LDOBJBYINDEX_PREF_V8_IMM32);
5528 }
5529 }
5530 // not meet fast condition or fast path return hole, walk slow path
5531 // slow stub not need receiver
5532 SAVE_PC();
5533 JSTaggedValue res = SlowRuntimeStub::LdObjByIndex(thread, receiver, idx, false, JSTaggedValue::Undefined());
5534 INTERPRETER_RETURN_IF_ABRUPT(res);
5535 SET_ACC(res);
5536 DISPATCH(DEPRECATED_LDOBJBYINDEX_PREF_V8_IMM32);
5537 }
5538 HANDLE_OPCODE(STOBJBYINDEX_IMM8_V8_IMM16) {
5539 uint8_t v0 = READ_INST_8_1();
5540 uint16_t index = READ_INST_16_2();
5541 LOG_INST() << "intrinsics::stobjbyindex"
5542 << " v" << v0 << " imm" << index;
5543
5544 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5545 if (receiver.IsHeapObject()) {
5546 SAVE_ACC();
5547 JSTaggedValue value = GET_ACC();
5548 // fast path
5549 JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value);
5550 if (!res.IsHole()) {
5551 INTERPRETER_RETURN_IF_ABRUPT(res);
5552 RESTORE_ACC();
5553 DISPATCH(STOBJBYINDEX_IMM8_V8_IMM16);
5554 }
5555 RESTORE_ACC();
5556 }
5557 // slow path
5558 SAVE_ACC();
5559 SAVE_PC();
5560 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
5561 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
5562 JSTaggedValue res = SlowRuntimeStub::StObjByIndex(thread, receiver, index, value);
5563 INTERPRETER_RETURN_IF_ABRUPT(res);
5564 RESTORE_ACC();
5565 DISPATCH(STOBJBYINDEX_IMM8_V8_IMM16);
5566 }
5567 HANDLE_OPCODE(STOBJBYINDEX_IMM16_V8_IMM16) {
5568 uint8_t v0 = READ_INST_8_2();
5569 uint16_t index = READ_INST_16_3();
5570 LOG_INST() << "intrinsics::stobjbyindex"
5571 << " v" << v0 << " imm" << index;
5572
5573 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5574 if (receiver.IsHeapObject()) {
5575 SAVE_ACC();
5576 JSTaggedValue value = GET_ACC();
5577 // fast path
5578 JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value);
5579 if (!res.IsHole()) {
5580 INTERPRETER_RETURN_IF_ABRUPT(res);
5581 RESTORE_ACC();
5582 DISPATCH(STOBJBYINDEX_IMM16_V8_IMM16);
5583 }
5584 RESTORE_ACC();
5585 }
5586 // slow path
5587 SAVE_ACC();
5588 SAVE_PC();
5589 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
5590 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
5591 JSTaggedValue res = SlowRuntimeStub::StObjByIndex(thread, receiver, index, value);
5592 INTERPRETER_RETURN_IF_ABRUPT(res);
5593 RESTORE_ACC();
5594 DISPATCH(STOBJBYINDEX_IMM16_V8_IMM16);
5595 }
5596 HANDLE_OPCODE(WIDE_STOBJBYINDEX_PREF_V8_IMM32) {
5597 uint8_t v0 = READ_INST_8_1();
5598 uint32_t index = READ_INST_32_2();
5599 LOG_INST() << "intrinsics::stobjbyindex"
5600 << " v" << v0 << " imm" << index;
5601
5602 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5603 if (receiver.IsHeapObject()) {
5604 SAVE_ACC();
5605 JSTaggedValue value = GET_ACC();
5606 // fast path
5607 JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value);
5608 if (!res.IsHole()) {
5609 INTERPRETER_RETURN_IF_ABRUPT(res);
5610 RESTORE_ACC();
5611 DISPATCH(WIDE_STOBJBYINDEX_PREF_V8_IMM32);
5612 }
5613 RESTORE_ACC();
5614 }
5615 // slow path
5616 SAVE_ACC();
5617 SAVE_PC();
5618 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
5619 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
5620 JSTaggedValue res = SlowRuntimeStub::StObjByIndex(thread, receiver, index, value);
5621 INTERPRETER_RETURN_IF_ABRUPT(res);
5622 RESTORE_ACC();
5623 DISPATCH(WIDE_STOBJBYINDEX_PREF_V8_IMM32);
5624 }
5625 HANDLE_OPCODE(STOWNBYINDEX_IMM8_V8_IMM16) {
5626 uint8_t v0 = READ_INST_8_1();
5627 uint16_t index = READ_INST_16_2();
5628 LOG_INST() << "intrinsics::stownbyindex"
5629 << " v" << v0 << " imm" << index;
5630 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5631 // fast path
5632 if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
5633 SAVE_ACC();
5634 JSTaggedValue value = GET_ACC();
5635 // fast path
5636 JSTaggedValue res =
5637 FastRuntimeStub::SetPropertyByIndex<true>(thread, receiver, index, value);
5638 if (!res.IsHole()) {
5639 INTERPRETER_RETURN_IF_ABRUPT(res);
5640 RESTORE_ACC();
5641 DISPATCH(STOWNBYINDEX_IMM8_V8_IMM16);
5642 }
5643 RESTORE_ACC();
5644 }
5645 SAVE_ACC();
5646 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
5647 auto value = GET_ACC(); // Maybe moved by GC
5648 SAVE_PC();
5649 JSTaggedValue res = SlowRuntimeStub::StOwnByIndex(thread, receiver, index, value);
5650 INTERPRETER_RETURN_IF_ABRUPT(res);
5651 RESTORE_ACC();
5652 DISPATCH(STOWNBYINDEX_IMM8_V8_IMM16);
5653 }
5654 HANDLE_OPCODE(STOWNBYINDEX_IMM16_V8_IMM16) {
5655 uint8_t v0 = READ_INST_8_2();
5656 uint16_t index = READ_INST_16_3();
5657 LOG_INST() << "intrinsics::stownbyindex"
5658 << " v" << v0 << " imm" << index;
5659 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5660 // fast path
5661 if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
5662 SAVE_ACC();
5663 JSTaggedValue value = GET_ACC();
5664 // fast path
5665 JSTaggedValue res =
5666 FastRuntimeStub::SetPropertyByIndex<true>(thread, receiver, index, value);
5667 if (!res.IsHole()) {
5668 INTERPRETER_RETURN_IF_ABRUPT(res);
5669 RESTORE_ACC();
5670 DISPATCH(STOWNBYINDEX_IMM16_V8_IMM16);
5671 }
5672 RESTORE_ACC();
5673 }
5674 SAVE_ACC();
5675 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
5676 auto value = GET_ACC(); // Maybe moved by GC
5677 SAVE_PC();
5678 JSTaggedValue res = SlowRuntimeStub::StOwnByIndex(thread, receiver, index, value);
5679 INTERPRETER_RETURN_IF_ABRUPT(res);
5680 RESTORE_ACC();
5681 DISPATCH(STOWNBYINDEX_IMM16_V8_IMM16);
5682 }
5683 HANDLE_OPCODE(WIDE_STOWNBYINDEX_PREF_V8_IMM32) {
5684 uint8_t v0 = READ_INST_8_1();
5685 uint32_t index = READ_INST_32_2();
5686 LOG_INST() << "intrinsics::stownbyindex"
5687 << " v" << v0 << " imm" << index;
5688 JSTaggedValue receiver = GET_VREG_VALUE(v0);
5689 // fast path
5690 if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
5691 SAVE_ACC();
5692 JSTaggedValue value = GET_ACC();
5693 // fast path
5694 JSTaggedValue res =
5695 FastRuntimeStub::SetPropertyByIndex<true>(thread, receiver, index, value);
5696 if (!res.IsHole()) {
5697 INTERPRETER_RETURN_IF_ABRUPT(res);
5698 RESTORE_ACC();
5699 DISPATCH(WIDE_STOWNBYINDEX_PREF_V8_IMM32);
5700 }
5701 RESTORE_ACC();
5702 }
5703 SAVE_ACC();
5704 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
5705 auto value = GET_ACC(); // Maybe moved by GC
5706 SAVE_PC();
5707 JSTaggedValue res = SlowRuntimeStub::StOwnByIndex(thread, receiver, index, value);
5708 INTERPRETER_RETURN_IF_ABRUPT(res);
5709 RESTORE_ACC();
5710 DISPATCH(WIDE_STOWNBYINDEX_PREF_V8_IMM32);
5711 }
5712 HANDLE_OPCODE(COPYRESTARGS_IMM8) {
5713 uint8_t restIdx = READ_INST_8_0();
5714 LOG_INST() << "intrinsics::copyrestargs"
5715 << " index: " << restIdx;
5716
5717 uint32_t startIdx = 0;
5718 uint32_t restNumArgs = GetNumArgs(sp, restIdx, startIdx);
5719
5720 SAVE_PC();
5721 JSTaggedValue res = SlowRuntimeStub::CopyRestArgs(thread, sp, restNumArgs, startIdx);
5722 INTERPRETER_RETURN_IF_ABRUPT(res);
5723 SET_ACC(res);
5724 DISPATCH(COPYRESTARGS_IMM8);
5725 }
5726 HANDLE_OPCODE(WIDE_COPYRESTARGS_PREF_IMM16) {
5727 uint16_t restIdx = READ_INST_16_1();
5728 LOG_INST() << "intrinsics::copyrestargs"
5729 << " index: " << restIdx;
5730
5731 uint32_t startIdx = 0;
5732 uint32_t restNumArgs = GetNumArgs(sp, restIdx, startIdx);
5733
5734 SAVE_PC();
5735 JSTaggedValue res = SlowRuntimeStub::CopyRestArgs(thread, sp, restNumArgs, startIdx);
5736 INTERPRETER_RETURN_IF_ABRUPT(res);
5737 SET_ACC(res);
5738 DISPATCH(WIDE_COPYRESTARGS_PREF_IMM16);
5739 }
5740 HANDLE_OPCODE(LDLEXVAR_IMM4_IMM4) {
5741 uint16_t level = READ_INST_4_0();
5742 uint16_t slot = READ_INST_4_1();
5743
5744 LOG_INST() << "intrinsics::ldlexvar"
5745 << " level:" << level << " slot:" << slot;
5746 InterpretedFrame *state = GET_FRAME(sp);
5747 JSTaggedValue currentLexenv = state->env;
5748 JSTaggedValue env(currentLexenv);
5749 for (uint32_t i = 0; i < level; i++) {
5750 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
5751 ASSERT(!taggedParentEnv.IsUndefined());
5752 env = taggedParentEnv;
5753 }
5754 SET_ACC(LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot));
5755 DISPATCH(LDLEXVAR_IMM4_IMM4);
5756 }
5757 HANDLE_OPCODE(LDLEXVAR_IMM8_IMM8) {
5758 uint16_t level = READ_INST_8_0();
5759 uint16_t slot = READ_INST_8_1();
5760
5761 LOG_INST() << "intrinsics::ldlexvar"
5762 << " level:" << level << " slot:" << slot;
5763 InterpretedFrame *state = GET_FRAME(sp);
5764 JSTaggedValue currentLexenv = state->env;
5765 JSTaggedValue env(currentLexenv);
5766 for (uint32_t i = 0; i < level; i++) {
5767 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
5768 ASSERT(!taggedParentEnv.IsUndefined());
5769 env = taggedParentEnv;
5770 }
5771 SET_ACC(LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot));
5772 DISPATCH(LDLEXVAR_IMM8_IMM8);
5773 }
5774 HANDLE_OPCODE(WIDE_LDLEXVAR_PREF_IMM16_IMM16) {
5775 uint16_t level = READ_INST_16_1();
5776 uint16_t slot = READ_INST_16_3();
5777
5778 LOG_INST() << "intrinsics::ldlexvar"
5779 << " level:" << level << " slot:" << slot;
5780 InterpretedFrame *state = GET_FRAME(sp);
5781 JSTaggedValue currentLexenv = state->env;
5782 JSTaggedValue env(currentLexenv);
5783 for (uint32_t i = 0; i < level; i++) {
5784 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
5785 ASSERT(!taggedParentEnv.IsUndefined());
5786 env = taggedParentEnv;
5787 }
5788 SET_ACC(LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot));
5789 DISPATCH(WIDE_LDLEXVAR_PREF_IMM16_IMM16);
5790 }
5791 HANDLE_OPCODE(STLEXVAR_IMM4_IMM4) {
5792 uint16_t level = READ_INST_4_0();
5793 uint16_t slot = READ_INST_4_1();
5794 LOG_INST() << "intrinsics::stlexvar"
5795 << " level:" << level << " slot:" << slot;
5796
5797 JSTaggedValue value = GET_ACC();
5798 InterpretedFrame *state = GET_FRAME(sp);
5799 JSTaggedValue env = state->env;
5800 for (uint32_t i = 0; i < level; i++) {
5801 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
5802 ASSERT(!taggedParentEnv.IsUndefined());
5803 env = taggedParentEnv;
5804 }
5805 LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value);
5806
5807 DISPATCH(STLEXVAR_IMM4_IMM4);
5808 }
5809 HANDLE_OPCODE(STLEXVAR_IMM8_IMM8) {
5810 uint16_t level = READ_INST_8_0();
5811 uint16_t slot = READ_INST_8_1();
5812 LOG_INST() << "intrinsics::stlexvar"
5813 << " level:" << level << " slot:" << slot;
5814
5815 JSTaggedValue value = GET_ACC();
5816 InterpretedFrame *state = GET_FRAME(sp);
5817 JSTaggedValue env = state->env;
5818 for (uint32_t i = 0; i < level; i++) {
5819 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
5820 ASSERT(!taggedParentEnv.IsUndefined());
5821 env = taggedParentEnv;
5822 }
5823 LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value);
5824
5825 DISPATCH(STLEXVAR_IMM8_IMM8);
5826 }
5827 HANDLE_OPCODE(WIDE_STLEXVAR_PREF_IMM16_IMM16) {
5828 uint16_t level = READ_INST_16_1();
5829 uint16_t slot = READ_INST_16_3();
5830 LOG_INST() << "intrinsics::stlexvar"
5831 << " level:" << level << " slot:" << slot;
5832
5833 JSTaggedValue value = GET_ACC();
5834 InterpretedFrame *state = GET_FRAME(sp);
5835 JSTaggedValue env = state->env;
5836 for (uint32_t i = 0; i < level; i++) {
5837 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
5838 ASSERT(!taggedParentEnv.IsUndefined());
5839 env = taggedParentEnv;
5840 }
5841 LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value);
5842
5843 DISPATCH(WIDE_STLEXVAR_PREF_IMM16_IMM16);
5844 }
5845 HANDLE_OPCODE(DEPRECATED_STLEXVAR_PREF_IMM4_IMM4_V8) {
5846 uint16_t level = READ_INST_4_2();
5847 uint16_t slot = READ_INST_4_3();
5848 uint16_t v0 = READ_INST_8_2();
5849 LOG_INST() << "intrinsics::stlexvar"
5850 << " level:" << level << " slot:" << slot << " v" << v0;
5851
5852 JSTaggedValue value = GET_VREG_VALUE(v0);
5853 InterpretedFrame *state = GET_FRAME(sp);
5854 JSTaggedValue env = state->env;
5855 for (uint32_t i = 0; i < level; i++) {
5856 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
5857 ASSERT(!taggedParentEnv.IsUndefined());
5858 env = taggedParentEnv;
5859 }
5860 LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value);
5861
5862 DISPATCH(DEPRECATED_STLEXVAR_PREF_IMM4_IMM4_V8);
5863 }
5864 HANDLE_OPCODE(DEPRECATED_STLEXVAR_PREF_IMM8_IMM8_V8) {
5865 uint16_t level = READ_INST_8_1();
5866 uint16_t slot = READ_INST_8_2();
5867 uint16_t v0 = READ_INST_8_3();
5868 LOG_INST() << "intrinsics::stlexvar"
5869 << " level:" << level << " slot:" << slot << " v" << v0;
5870
5871 JSTaggedValue value = GET_VREG_VALUE(v0);
5872 InterpretedFrame *state = GET_FRAME(sp);
5873 JSTaggedValue env = state->env;
5874 for (uint32_t i = 0; i < level; i++) {
5875 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
5876 ASSERT(!taggedParentEnv.IsUndefined());
5877 env = taggedParentEnv;
5878 }
5879 LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value);
5880
5881 DISPATCH(DEPRECATED_STLEXVAR_PREF_IMM8_IMM8_V8);
5882 }
5883 HANDLE_OPCODE(DEPRECATED_STLEXVAR_PREF_IMM16_IMM16_V8) {
5884 uint16_t level = READ_INST_16_1();
5885 uint16_t slot = READ_INST_16_3();
5886 uint16_t v0 = READ_INST_8_5();
5887 LOG_INST() << "intrinsics::stlexvar"
5888 << " level:" << level << " slot:" << slot << " v" << v0;
5889
5890 JSTaggedValue value = GET_VREG_VALUE(v0);
5891 InterpretedFrame *state = GET_FRAME(sp);
5892 JSTaggedValue env = state->env;
5893 for (uint32_t i = 0; i < level; i++) {
5894 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
5895 ASSERT(!taggedParentEnv.IsUndefined());
5896 env = taggedParentEnv;
5897 }
5898 LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value);
5899
5900 DISPATCH(DEPRECATED_STLEXVAR_PREF_IMM16_IMM16_V8);
5901 }
5902 HANDLE_OPCODE(GETMODULENAMESPACE_IMM8) {
5903 int32_t index = READ_INST_8_0();
5904
5905 LOG_INST() << "intrinsics::getmodulenamespace index:" << index;
5906
5907 JSTaggedValue moduleNamespace = SlowRuntimeStub::GetModuleNamespace(thread, index);
5908 INTERPRETER_RETURN_IF_ABRUPT(moduleNamespace);
5909 SET_ACC(moduleNamespace);
5910 DISPATCH(GETMODULENAMESPACE_IMM8);
5911 }
5912 HANDLE_OPCODE(WIDE_GETMODULENAMESPACE_PREF_IMM16) {
5913 int32_t index = READ_INST_16_1();
5914
5915 LOG_INST() << "intrinsics::getmodulenamespace index:" << index;
5916
5917 JSTaggedValue moduleNamespace = SlowRuntimeStub::GetModuleNamespace(thread, index);
5918 INTERPRETER_RETURN_IF_ABRUPT(moduleNamespace);
5919 SET_ACC(moduleNamespace);
5920 DISPATCH(WIDE_GETMODULENAMESPACE_PREF_IMM16);
5921 }
5922 HANDLE_OPCODE(DEPRECATED_GETMODULENAMESPACE_PREF_ID32) {
5923 uint16_t stringId = READ_INST_32_1();
5924 auto constpool = GetConstantPool(sp);
5925 auto localName = GET_STR_FROM_CACHE(stringId);
5926
5927 LOG_INST() << "intrinsics::getmodulenamespace "
5928 << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(localName.GetTaggedObject()));
5929
5930 JSTaggedValue moduleNamespace = SlowRuntimeStub::GetModuleNamespace(thread, localName);
5931 INTERPRETER_RETURN_IF_ABRUPT(moduleNamespace);
5932 SET_ACC(moduleNamespace);
5933 DISPATCH(DEPRECATED_GETMODULENAMESPACE_PREF_ID32);
5934 }
5935 HANDLE_OPCODE(STMODULEVAR_IMM8) {
5936 int32_t index = READ_INST_8_0();
5937
5938 LOG_INST() << "intrinsics::stmodulevar index:" << index;
5939
5940 JSTaggedValue value = GET_ACC();
5941
5942 SAVE_ACC();
5943 SlowRuntimeStub::StModuleVar(thread, index, value);
5944 RESTORE_ACC();
5945 DISPATCH(STMODULEVAR_IMM8);
5946 }
5947 HANDLE_OPCODE(WIDE_STMODULEVAR_PREF_IMM16) {
5948 int32_t index = READ_INST_16_1();
5949
5950 LOG_INST() << "intrinsics::stmodulevar index:" << index;
5951
5952 JSTaggedValue value = GET_ACC();
5953
5954 SAVE_ACC();
5955 SlowRuntimeStub::StModuleVar(thread, index, value);
5956 RESTORE_ACC();
5957 DISPATCH(WIDE_STMODULEVAR_PREF_IMM16);
5958 }
5959 HANDLE_OPCODE(DEPRECATED_STMODULEVAR_PREF_ID32) {
5960 uint16_t stringId = READ_INST_32_1();
5961 SAVE_ACC();
5962 auto constpool = GetConstantPool(sp);
5963 auto key = GET_STR_FROM_CACHE(stringId);
5964 RESTORE_ACC();
5965
5966 LOG_INST() << "intrinsics::stmodulevar "
5967 << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(key.GetTaggedObject()));
5968
5969 JSTaggedValue value = GET_ACC();
5970
5971 SlowRuntimeStub::StModuleVar(thread, key, value);
5972 RESTORE_ACC();
5973 DISPATCH(DEPRECATED_STMODULEVAR_PREF_ID32);
5974 }
5975 HANDLE_OPCODE(LDLOCALMODULEVAR_IMM8) {
5976 int32_t index = READ_INST_8_0();
5977
5978 LOG_INST() << "intrinsics::ldmodulevar index:" << index;
5979
5980 JSTaggedValue moduleVar = SlowRuntimeStub::LdLocalModuleVar(thread, index);
5981 INTERPRETER_RETURN_IF_ABRUPT(moduleVar);
5982 SET_ACC(moduleVar);
5983 DISPATCH(LDLOCALMODULEVAR_IMM8);
5984 }
5985 HANDLE_OPCODE(WIDE_LDLOCALMODULEVAR_PREF_IMM16) {
5986 int32_t index = READ_INST_16_1();
5987 LOG_INST() << "intrinsics::ldmodulevar index:" << index;
5988
5989 JSTaggedValue moduleVar = SlowRuntimeStub::LdLocalModuleVar(thread, index);
5990 INTERPRETER_RETURN_IF_ABRUPT(moduleVar);
5991 SET_ACC(moduleVar);
5992 DISPATCH(WIDE_LDLOCALMODULEVAR_PREF_IMM16);
5993 }
5994 HANDLE_OPCODE(LDEXTERNALMODULEVAR_IMM8) {
5995 int32_t index = READ_INST_8_0();
5996 LOG_INST() << "intrinsics::ldmodulevar index:" << index;
5997
5998 JSTaggedValue moduleVar = SlowRuntimeStub::LdExternalModuleVar(thread, index);
5999 INTERPRETER_RETURN_IF_ABRUPT(moduleVar);
6000 SET_ACC(moduleVar);
6001 DISPATCH(LDEXTERNALMODULEVAR_IMM8);
6002 }
6003 HANDLE_OPCODE(WIDE_LDEXTERNALMODULEVAR_PREF_IMM16) {
6004 int32_t index = READ_INST_16_1();
6005
6006 LOG_INST() << "intrinsics::ldmodulevar index:" << index;
6007
6008 JSTaggedValue moduleVar = SlowRuntimeStub::LdExternalModuleVar(thread, index);
6009 INTERPRETER_RETURN_IF_ABRUPT(moduleVar);
6010 SET_ACC(moduleVar);
6011 DISPATCH(WIDE_LDEXTERNALMODULEVAR_PREF_IMM16);
6012 }
6013 HANDLE_OPCODE(STCONSTTOGLOBALRECORD_IMM16_ID16) {
6014 uint16_t stringId = READ_INST_16_2();
6015 SAVE_ACC();
6016 auto constpool = GetConstantPool(sp);
6017 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6018 RESTORE_ACC();
6019 LOG_INST() << "intrinsics::stconsttoglobalrecord"
6020 << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
6021
6022 JSTaggedValue value = GET_ACC();
6023 SAVE_PC();
6024 JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, true);
6025 INTERPRETER_RETURN_IF_ABRUPT(res);
6026 RESTORE_ACC();
6027 DISPATCH(STCONSTTOGLOBALRECORD_IMM16_ID16);
6028 }
6029 HANDLE_OPCODE(DEPRECATED_STCONSTTOGLOBALRECORD_PREF_ID32) {
6030 uint16_t stringId = READ_INST_32_1();
6031 SAVE_ACC();
6032 auto constpool = GetConstantPool(sp);
6033 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6034 RESTORE_ACC();
6035 LOG_INST() << "intrinsics::stconsttoglobalrecord"
6036 << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
6037
6038 JSTaggedValue value = GET_ACC();
6039 SAVE_PC();
6040 JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, true);
6041 INTERPRETER_RETURN_IF_ABRUPT(res);
6042 RESTORE_ACC();
6043 DISPATCH(DEPRECATED_STCONSTTOGLOBALRECORD_PREF_ID32);
6044 }
6045 HANDLE_OPCODE(STTOGLOBALRECORD_IMM16_ID16) {
6046 uint16_t stringId = READ_INST_16_2();
6047 SAVE_ACC();
6048 auto constpool = GetConstantPool(sp);
6049 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6050 RESTORE_ACC();
6051 LOG_INST() << "intrinsics::stlettoglobalrecord"
6052 << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
6053
6054 JSTaggedValue value = GET_ACC();
6055 SAVE_PC();
6056 JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, false);
6057 INTERPRETER_RETURN_IF_ABRUPT(res);
6058 RESTORE_ACC();
6059 DISPATCH(STTOGLOBALRECORD_IMM16_ID16);
6060 }
6061 HANDLE_OPCODE(DEPRECATED_STLETTOGLOBALRECORD_PREF_ID32) {
6062 uint16_t stringId = READ_INST_32_1();
6063 SAVE_ACC();
6064 auto constpool = GetConstantPool(sp);
6065 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6066 RESTORE_ACC();
6067 LOG_INST() << "intrinsics::stlettoglobalrecord"
6068 << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
6069
6070 JSTaggedValue value = GET_ACC();
6071 SAVE_PC();
6072 JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, false);
6073 INTERPRETER_RETURN_IF_ABRUPT(res);
6074 RESTORE_ACC();
6075 DISPATCH(DEPRECATED_STLETTOGLOBALRECORD_PREF_ID32);
6076 }
6077 HANDLE_OPCODE(DEPRECATED_STCLASSTOGLOBALRECORD_PREF_ID32) {
6078 uint16_t stringId = READ_INST_32_1();
6079 SAVE_ACC();
6080 auto constpool = GetConstantPool(sp);
6081 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6082 RESTORE_ACC();
6083 LOG_INST() << "intrinsics::stclasstoglobalrecord"
6084 << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
6085
6086 JSTaggedValue value = GET_ACC();
6087 SAVE_PC();
6088 JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, false);
6089 INTERPRETER_RETURN_IF_ABRUPT(res);
6090 RESTORE_ACC();
6091 DISPATCH(DEPRECATED_STCLASSTOGLOBALRECORD_PREF_ID32);
6092 }
6093 HANDLE_OPCODE(DEPRECATED_LDMODULEVAR_PREF_ID32_IMM8) {
6094 uint16_t stringId = READ_INST_16_1();
6095 uint8_t innerFlag = READ_INST_8_5();
6096
6097 auto constpool = GetConstantPool(sp);
6098 JSTaggedValue key = GET_STR_FROM_CACHE(stringId);
6099 LOG_INST() << "intrinsics::ldmodulevar "
6100 << "string_id:" << stringId << ", "
6101 << "key: " << ConvertToString(EcmaString::Cast(key.GetTaggedObject()));
6102
6103 JSTaggedValue moduleVar = SlowRuntimeStub::LdModuleVar(thread, key, innerFlag != 0);
6104 INTERPRETER_RETURN_IF_ABRUPT(moduleVar);
6105 SET_ACC(moduleVar);
6106 DISPATCH(DEPRECATED_LDMODULEVAR_PREF_ID32_IMM8);
6107 }
6108 HANDLE_OPCODE(LDOBJBYNAME_IMM8_ID16) {
6109 #if ECMASCRIPT_ENABLE_IC
6110 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6111 if (!profileTypeInfo.IsUndefined()) {
6112 uint16_t slotId = READ_INST_8_0();
6113 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6114 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
6115 JSTaggedValue res = JSTaggedValue::Hole();
6116
6117 JSTaggedValue receiver = GET_ACC();
6118 if (LIKELY(firstValue.IsHeapObject())) {
6119 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
6120 res = ICRuntimeStub::TryLoadICByName(thread, receiver, firstValue, secondValue);
6121 }
6122 if (LIKELY(!res.IsHole())) {
6123 INTERPRETER_RETURN_IF_ABRUPT(res);
6124 SET_ACC(res);
6125 DISPATCH(LDOBJBYNAME_IMM8_ID16);
6126 } else if (!firstValue.IsHole()) { // IC miss and not enter the megamorphic state, store as polymorphic
6127 uint16_t stringId = READ_INST_16_1();
6128 SAVE_ACC();
6129 auto constpool = GetConstantPool(sp);
6130 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6131 RESTORE_ACC();
6132 receiver = GET_ACC();
6133 profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6134 profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6135 res = ICRuntimeStub::LoadICByName(thread,
6136 profileTypeArray,
6137 receiver, propKey, slotId);
6138 INTERPRETER_RETURN_IF_ABRUPT(res);
6139 SET_ACC(res);
6140 DISPATCH(LDOBJBYNAME_IMM8_ID16);
6141 }
6142 }
6143 #endif
6144 uint16_t stringId = READ_INST_16_1();
6145 SAVE_ACC();
6146 auto constpool = GetConstantPool(sp);
6147 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6148 RESTORE_ACC();
6149 JSTaggedValue receiver = GET_ACC();
6150 LOG_INST() << "intrinsics::ldobjbyname stringId:" << stringId << ", "
6151 << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << receiver.GetRawData();
6152 if (LIKELY(receiver.IsHeapObject())) {
6153 // fast path
6154 JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, receiver, propKey);
6155 if (!res.IsHole()) {
6156 ASSERT(!res.IsAccessor());
6157 INTERPRETER_RETURN_IF_ABRUPT(res);
6158 SET_ACC(res);
6159 DISPATCH(LDOBJBYNAME_IMM8_ID16);
6160 }
6161 }
6162 // not meet fast condition or fast path return hole, walk slow path
6163 // slow stub not need receiver
6164 SAVE_PC();
6165 JSTaggedValue res = SlowRuntimeStub::LdObjByName(thread, receiver, propKey, false, JSTaggedValue::Undefined());
6166 INTERPRETER_RETURN_IF_ABRUPT(res);
6167 SET_ACC(res);
6168 DISPATCH(LDOBJBYNAME_IMM8_ID16);
6169 }
6170 HANDLE_OPCODE(LDOBJBYNAME_IMM16_ID16) {
6171 #if ECMASCRIPT_ENABLE_IC
6172 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6173 if (!profileTypeInfo.IsUndefined()) {
6174 uint16_t slotId = READ_INST_16_0();
6175 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6176 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
6177 JSTaggedValue res = JSTaggedValue::Hole();
6178
6179 JSTaggedValue receiver = GET_ACC();
6180 if (LIKELY(firstValue.IsHeapObject())) {
6181 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
6182 res = ICRuntimeStub::TryLoadICByName(thread, receiver, firstValue, secondValue);
6183 }
6184 if (LIKELY(!res.IsHole())) {
6185 INTERPRETER_RETURN_IF_ABRUPT(res);
6186 SET_ACC(res);
6187 DISPATCH(LDOBJBYNAME_IMM16_ID16);
6188 } else if (!firstValue.IsHole()) { // IC miss and not enter the megamorphic state, store as polymorphic
6189 uint16_t stringId = READ_INST_16_2();
6190 SAVE_ACC();
6191 auto constpool = GetConstantPool(sp);
6192 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6193 RESTORE_ACC();
6194 receiver = GET_ACC();
6195 profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6196 profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6197 res = ICRuntimeStub::LoadICByName(thread,
6198 profileTypeArray,
6199 receiver, propKey, slotId);
6200 INTERPRETER_RETURN_IF_ABRUPT(res);
6201 SET_ACC(res);
6202 DISPATCH(LDOBJBYNAME_IMM16_ID16);
6203 }
6204 }
6205 #endif
6206 uint16_t stringId = READ_INST_16_2();
6207 SAVE_ACC();
6208 auto constpool = GetConstantPool(sp);
6209 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6210 RESTORE_ACC();
6211 JSTaggedValue receiver = GET_ACC();
6212 LOG_INST() << "intrinsics::ldobjbyname stringId:" << stringId << ", "
6213 << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << receiver.GetRawData();
6214
6215 if (LIKELY(receiver.IsHeapObject())) {
6216 // fast path
6217 JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, receiver, propKey);
6218 if (!res.IsHole()) {
6219 ASSERT(!res.IsAccessor());
6220 INTERPRETER_RETURN_IF_ABRUPT(res);
6221 SET_ACC(res);
6222 DISPATCH(LDOBJBYNAME_IMM16_ID16);
6223 }
6224 }
6225 // not meet fast condition or fast path return hole, walk slow path
6226 // slow stub not need receiver
6227 SAVE_PC();
6228 JSTaggedValue res = SlowRuntimeStub::LdObjByName(thread, receiver, propKey, false, JSTaggedValue::Undefined());
6229 INTERPRETER_RETURN_IF_ABRUPT(res);
6230 SET_ACC(res);
6231 DISPATCH(LDOBJBYNAME_IMM16_ID16);
6232 }
6233 HANDLE_OPCODE(DEPRECATED_LDOBJBYNAME_PREF_ID32_V8) {
6234 uint32_t v0 = READ_INST_8_5();
6235
6236 uint16_t stringId = READ_INST_32_1();
6237 auto constpool = GetConstantPool(sp);
6238 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6239 JSTaggedValue receiver = GET_VREG_VALUE(v0);
6240 LOG_INST() << "intrinsics::ldobjbyname "
6241 << "v" << v0 << " stringId:" << stringId << ", "
6242 << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << receiver.GetRawData();
6243
6244 if (LIKELY(receiver.IsHeapObject())) {
6245 // fast path
6246 JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, receiver, propKey);
6247 if (!res.IsHole()) {
6248 ASSERT(!res.IsAccessor());
6249 INTERPRETER_RETURN_IF_ABRUPT(res);
6250 SET_ACC(res);
6251 DISPATCH(DEPRECATED_LDOBJBYNAME_PREF_ID32_V8);
6252 }
6253 }
6254 // not meet fast condition or fast path return hole, walk slow path
6255 // slow stub not need receiver
6256 SAVE_PC();
6257 JSTaggedValue res = SlowRuntimeStub::LdObjByName(thread, receiver, propKey, false, JSTaggedValue::Undefined());
6258 INTERPRETER_RETURN_IF_ABRUPT(res);
6259 SET_ACC(res);
6260 DISPATCH(DEPRECATED_LDOBJBYNAME_PREF_ID32_V8);
6261 }
6262 HANDLE_OPCODE(LDSUPERBYNAME_IMM8_ID16) {
6263 uint16_t stringId = READ_INST_16_1();
6264 SAVE_ACC();
6265 auto constpool = GetConstantPool(sp);
6266 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6267 RESTORE_ACC();
6268
6269 JSTaggedValue obj = GET_ACC();
6270 LOG_INST() << "intrinsics::ldsuperbyname stringId:" << stringId << ", "
6271 << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << obj.GetRawData();
6272
6273 SAVE_PC();
6274 JSTaggedValue thisFunc = GetFunction(sp);
6275 JSTaggedValue res = SlowRuntimeStub::LdSuperByValue(thread, obj, propKey, thisFunc);
6276
6277 INTERPRETER_RETURN_IF_ABRUPT(res);
6278 SET_ACC(res);
6279 DISPATCH(LDSUPERBYNAME_IMM8_ID16);
6280 }
6281 HANDLE_OPCODE(LDSUPERBYNAME_IMM16_ID16) {
6282 uint16_t stringId = READ_INST_16_2();
6283 SAVE_ACC();
6284 auto constpool = GetConstantPool(sp);
6285 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6286 RESTORE_ACC();
6287 JSTaggedValue obj = GET_ACC();
6288
6289 LOG_INST() << "intrinsics::ldsuperbyname stringId:" << stringId << ", "
6290 << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << obj.GetRawData();
6291
6292 SAVE_PC();
6293 JSTaggedValue thisFunc = GetFunction(sp);
6294 JSTaggedValue res = SlowRuntimeStub::LdSuperByValue(thread, obj, propKey, thisFunc);
6295
6296 INTERPRETER_RETURN_IF_ABRUPT(res);
6297 SET_ACC(res);
6298 DISPATCH(LDSUPERBYNAME_IMM16_ID16);
6299 }
6300 HANDLE_OPCODE(DEPRECATED_LDSUPERBYNAME_PREF_ID32_V8) {
6301 uint32_t stringId = READ_INST_32_1();
6302 uint32_t v0 = READ_INST_8_5();
6303 auto constpool = GetConstantPool(sp);
6304 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6305 JSTaggedValue obj = GET_VREG_VALUE(v0);
6306
6307 LOG_INST() << "intrinsics::ldsuperbyname"
6308 << "v" << v0 << " stringId:" << stringId << ", "
6309 << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << obj.GetRawData();
6310
6311 SAVE_PC();
6312 JSTaggedValue thisFunc = GetFunction(sp);
6313 JSTaggedValue res = SlowRuntimeStub::LdSuperByValue(thread, obj, propKey, thisFunc);
6314
6315 INTERPRETER_RETURN_IF_ABRUPT(res);
6316 SET_ACC(res);
6317 DISPATCH(DEPRECATED_LDSUPERBYNAME_PREF_ID32_V8);
6318 }
6319 HANDLE_OPCODE(ASYNCFUNCTIONRESOLVE_V8) {
6320 uint16_t v0 = READ_INST_8_0();
6321 LOG_INST() << "intrinsics::asyncfunctionresolve"
6322 << " v" << v0;
6323
6324 JSTaggedValue asyncFuncObj = GET_VREG_VALUE(v0);
6325 JSTaggedValue value = GET_ACC();
6326 SAVE_PC();
6327 JSTaggedValue res = SlowRuntimeStub::AsyncFunctionResolveOrReject(thread, asyncFuncObj, value, true);
6328 INTERPRETER_RETURN_IF_ABRUPT(res);
6329 SET_ACC(res);
6330 DISPATCH(ASYNCFUNCTIONRESOLVE_V8);
6331 }
6332 HANDLE_OPCODE(DEPRECATED_ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8) {
6333 uint16_t v0 = READ_INST_8_1();
6334 uint16_t v1 = READ_INST_8_2();
6335 uint16_t v2 = READ_INST_8_3();
6336 LOG_INST() << "intrinsics::asyncfunctionresolve"
6337 << " v" << v0 << " v" << v1 << " v" << v2;
6338
6339 JSTaggedValue asyncFuncObj = GET_VREG_VALUE(v0);
6340 JSTaggedValue value = GET_VREG_VALUE(v2);
6341 SAVE_PC();
6342 JSTaggedValue res = SlowRuntimeStub::AsyncFunctionResolveOrReject(thread, asyncFuncObj, value, true);
6343 INTERPRETER_RETURN_IF_ABRUPT(res);
6344 SET_ACC(res);
6345 DISPATCH(DEPRECATED_ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8);
6346 }
6347 HANDLE_OPCODE(ASYNCFUNCTIONREJECT_V8) {
6348 uint16_t v0 = READ_INST_8_0();
6349 LOG_INST() << "intrinsics::asyncfunctionreject"
6350 << " v" << v0;
6351
6352 JSTaggedValue asyncFuncObj = GET_VREG_VALUE(v0);
6353 JSTaggedValue value = GET_ACC();
6354 SAVE_PC();
6355 JSTaggedValue res = SlowRuntimeStub::AsyncFunctionResolveOrReject(thread, asyncFuncObj, value, false);
6356 INTERPRETER_RETURN_IF_ABRUPT(res);
6357 SET_ACC(res);
6358 DISPATCH(ASYNCFUNCTIONREJECT_V8);
6359 }
6360 HANDLE_OPCODE(DEPRECATED_ASYNCFUNCTIONREJECT_PREF_V8_V8_V8) {
6361 uint16_t v0 = READ_INST_8_1();
6362 uint16_t v1 = READ_INST_8_2();
6363 uint16_t v2 = READ_INST_8_3();
6364 LOG_INST() << "intrinsics::asyncfunctionreject"
6365 << " v" << v0 << " v" << v1 << " v" << v2;
6366
6367 JSTaggedValue asyncFuncObj = GET_VREG_VALUE(v0);
6368 JSTaggedValue value = GET_VREG_VALUE(v2);
6369 SAVE_PC();
6370 JSTaggedValue res = SlowRuntimeStub::AsyncFunctionResolveOrReject(thread, asyncFuncObj, value, false);
6371 INTERPRETER_RETURN_IF_ABRUPT(res);
6372 SET_ACC(res);
6373 DISPATCH(DEPRECATED_ASYNCFUNCTIONREJECT_PREF_V8_V8_V8);
6374 }
6375 HANDLE_OPCODE(CLOSEITERATOR_IMM16_V8) {
6376 uint16_t v0 = READ_INST_8_2();
6377 LOG_INST() << "intrinsics::closeiterator"
6378 << " v" << v0;
6379 SAVE_PC();
6380 JSTaggedValue iter = GET_VREG_VALUE(v0);
6381 JSTaggedValue res = SlowRuntimeStub::CloseIterator(thread, iter);
6382 INTERPRETER_RETURN_IF_ABRUPT(res);
6383 SET_ACC(res);
6384 DISPATCH(CLOSEITERATOR_IMM16_V8);
6385 }
6386 HANDLE_OPCODE(STOWNBYVALUE_IMM16_V8_V8) {
6387 uint32_t v0 = READ_INST_8_2();
6388 uint32_t v1 = READ_INST_8_3();
6389 LOG_INST() << "intrinsics::stownbyvalue"
6390 << " v" << v0 << " v" << v1;
6391
6392 JSTaggedValue receiver = GET_VREG_VALUE(v0);
6393 if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
6394 SAVE_ACC();
6395 JSTaggedValue propKey = GET_VREG_VALUE(v1);
6396 JSTaggedValue value = GET_ACC();
6397 // fast path
6398 JSTaggedValue res = FastRuntimeStub::SetPropertyByValue<true>(thread, receiver, propKey, value);
6399
6400 // SetPropertyByValue maybe gc need update the value
6401 RESTORE_ACC();
6402 propKey = GET_VREG_VALUE(v1);
6403 value = GET_ACC();
6404 if (!res.IsHole()) {
6405 INTERPRETER_RETURN_IF_ABRUPT(res);
6406 RESTORE_ACC();
6407 DISPATCH(STOWNBYVALUE_IMM16_V8_V8);
6408 }
6409 }
6410
6411 // slow path
6412 SAVE_ACC();
6413 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
6414 auto propKey = GET_VREG_VALUE(v1); // Maybe moved by GC
6415 auto value = GET_ACC(); // Maybe moved by GC
6416 SAVE_PC();
6417 JSTaggedValue res = SlowRuntimeStub::StOwnByValue(thread, receiver, propKey, value);
6418 RESTORE_ACC();
6419 INTERPRETER_RETURN_IF_ABRUPT(res);
6420 DISPATCH(STOWNBYVALUE_IMM16_V8_V8);
6421 }
6422 HANDLE_OPCODE(STSUPERBYVALUE_IMM16_V8_V8) {
6423 uint32_t v0 = READ_INST_8_2();
6424 uint32_t v1 = READ_INST_8_3();
6425
6426 LOG_INST() << "intrinsics::stsuperbyvalue"
6427 << " v" << v0 << " v" << v1;
6428 JSTaggedValue receiver = GET_VREG_VALUE(v0);
6429 JSTaggedValue propKey = GET_VREG_VALUE(v1);
6430 JSTaggedValue value = GET_ACC();
6431
6432 // slow path
6433 SAVE_ACC();
6434 SAVE_PC();
6435 JSTaggedValue thisFunc = GetFunction(sp);
6436 JSTaggedValue res = SlowRuntimeStub::StSuperByValue(thread, receiver, propKey, value, thisFunc);
6437 INTERPRETER_RETURN_IF_ABRUPT(res);
6438 RESTORE_ACC();
6439 DISPATCH(STSUPERBYVALUE_IMM16_V8_V8);
6440 }
6441 HANDLE_OPCODE(TRYSTGLOBALBYNAME_IMM16_ID16) {
6442 uint16_t stringId = READ_INST_16_2();
6443 auto constpool = GetConstantPool(sp);
6444 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6445 LOG_INST() << "intrinsics::trystglobalbyname"
6446 << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
6447
6448 #if ECMASCRIPT_ENABLE_IC
6449 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6450 if (!profileTypeInfo.IsUndefined()) {
6451 uint16_t slotId = READ_INST_16_0();
6452 JSTaggedValue value = GET_ACC();
6453 SAVE_ACC();
6454 JSTaggedValue res = ICRuntimeStub::StoreGlobalICByName(thread,
6455 ProfileTypeInfo::Cast(
6456 profileTypeInfo.GetTaggedObject()),
6457 globalObj, propKey, value, slotId, true);
6458 INTERPRETER_RETURN_IF_ABRUPT(res);
6459 RESTORE_ACC();
6460 DISPATCH(TRYSTGLOBALBYNAME_IMM16_ID16);
6461 }
6462 #endif
6463
6464 auto recordResult = SlowRuntimeStub::LdGlobalRecord(thread, propKey);
6465 SAVE_PC();
6466 // 1. find from global record
6467 if (!recordResult.IsUndefined()) {
6468 JSTaggedValue value = GET_ACC();
6469 SAVE_ACC();
6470 JSTaggedValue res = SlowRuntimeStub::TryUpdateGlobalRecord(thread, propKey, value);
6471 INTERPRETER_RETURN_IF_ABRUPT(res);
6472 RESTORE_ACC();
6473 } else {
6474 // 2. find from global object
6475 SAVE_ACC();
6476 auto globalResult = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, propKey);
6477 if (globalResult.IsHole()) {
6478 auto result = SlowRuntimeStub::ThrowReferenceError(thread, propKey, " is not defined");
6479 INTERPRETER_RETURN_IF_ABRUPT(result);
6480 }
6481 constpool = GetConstantPool(sp); // Maybe moved by GC
6482 propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
6483 RESTORE_ACC();
6484 JSTaggedValue value = GET_ACC();
6485 JSTaggedValue res = SlowRuntimeStub::StGlobalVar(thread, propKey, value);
6486 INTERPRETER_RETURN_IF_ABRUPT(res);
6487 RESTORE_ACC();
6488 }
6489 DISPATCH(TRYSTGLOBALBYNAME_IMM16_ID16);
6490 }
6491 HANDLE_OPCODE(STSUPERBYNAME_IMM16_ID16_V8) {
6492 uint16_t stringId = READ_INST_16_2();
6493 uint32_t v0 = READ_INST_8_4();
6494 auto constpool = GetConstantPool(sp);
6495
6496 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6497 JSTaggedValue obj = GET_VREG_VALUE(v0);
6498 JSTaggedValue value = GET_ACC();
6499
6500 LOG_INST() << "intrinsics::stsuperbyname"
6501 << "v" << v0 << " stringId:" << stringId << ", "
6502 << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << obj.GetRawData()
6503 << ", value:" << value.GetRawData();
6504
6505 // slow path
6506 SAVE_ACC();
6507 SAVE_PC();
6508 JSTaggedValue thisFunc = GetFunction(sp);
6509 JSTaggedValue res = SlowRuntimeStub::StSuperByValue(thread, obj, propKey, value, thisFunc);
6510 INTERPRETER_RETURN_IF_ABRUPT(res);
6511 RESTORE_ACC();
6512 DISPATCH(STSUPERBYNAME_IMM16_ID16_V8);
6513 }
6514 HANDLE_OPCODE(STOWNBYVALUEWITHNAMESET_IMM16_V8_V8) {
6515 uint32_t v0 = READ_INST_8_2();
6516 uint32_t v1 = READ_INST_8_3();
6517 LOG_INST() << "intrinsics::stownbyvaluewithnameset"
6518 << " v" << v0 << " v" << v1;
6519 JSTaggedValue receiver = GET_VREG_VALUE(v0);
6520 if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
6521 SAVE_ACC();
6522 JSTaggedValue propKey = GET_VREG_VALUE(v1);
6523 JSTaggedValue value = GET_ACC();
6524 // fast path
6525 JSTaggedValue res = FastRuntimeStub::SetPropertyByValue<true>(thread, receiver, propKey, value);
6526
6527 // SetPropertyByValue maybe gc need update the value
6528 RESTORE_ACC();
6529 propKey = GET_VREG_VALUE(v1);
6530 value = GET_ACC();
6531 if (!res.IsHole()) {
6532 INTERPRETER_RETURN_IF_ABRUPT(res);
6533 JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey);
6534 RESTORE_ACC();
6535 DISPATCH(STOWNBYVALUEWITHNAMESET_IMM16_V8_V8);
6536 }
6537 }
6538
6539 // slow path
6540 SAVE_ACC();
6541 SAVE_PC();
6542 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
6543 auto propKey = GET_VREG_VALUE(v1); // Maybe moved by GC
6544 auto value = GET_ACC(); // Maybe moved by GC
6545 JSTaggedValue res = SlowRuntimeStub::StOwnByValueWithNameSet(thread, receiver, propKey, value);
6546 RESTORE_ACC();
6547 INTERPRETER_RETURN_IF_ABRUPT(res);
6548 DISPATCH(STOWNBYVALUEWITHNAMESET_IMM16_V8_V8);
6549 }
6550 HANDLE_OPCODE(STOWNBYNAMEWITHNAMESET_IMM16_ID16_V8) {
6551 uint16_t stringId = READ_INST_16_2();
6552 uint32_t v0 = READ_INST_8_4();
6553 auto constpool = GetConstantPool(sp);
6554 LOG_INST() << "intrinsics::stownbynamewithnameset "
6555 << "v" << v0 << " stringId:" << stringId;
6556
6557 JSTaggedValue receiver = GET_VREG_VALUE(v0);
6558 if (receiver.IsJSObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
6559 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6560 receiver = GET_VREG_VALUE(v0);
6561 JSTaggedValue value = GET_ACC();
6562 // fast path
6563 SAVE_ACC();
6564 JSTaggedValue res = FastRuntimeStub::SetPropertyByName<true>(thread, receiver, propKey, value);
6565 if (!res.IsHole()) {
6566 INTERPRETER_RETURN_IF_ABRUPT(res);
6567 JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey);
6568 RESTORE_ACC();
6569 DISPATCH(STOWNBYNAMEWITHNAMESET_IMM16_ID16_V8);
6570 }
6571 RESTORE_ACC();
6572 }
6573
6574 SAVE_ACC();
6575 SAVE_PC();
6576 auto propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
6577 receiver = GET_VREG_VALUE(v0); // Maybe moved by GC
6578 auto value = GET_ACC(); // Maybe moved by GC
6579 JSTaggedValue res = SlowRuntimeStub::StOwnByNameWithNameSet(thread, receiver, propKey, value);
6580 RESTORE_ACC();
6581 INTERPRETER_RETURN_IF_ABRUPT(res);
6582 DISPATCH(STOWNBYNAMEWITHNAMESET_IMM16_ID16_V8);
6583 }
6584 HANDLE_OPCODE(JSTRICTEQZ_IMM8) {
6585 LOG_FULL(FATAL) << "not implement";
6586 DISPATCH(JSTRICTEQZ_IMM8);
6587 }
6588 HANDLE_OPCODE(JSTRICTEQZ_IMM16) {
6589 LOG_FULL(FATAL) << "not implement";
6590 DISPATCH(JSTRICTEQZ_IMM16);
6591 }
6592 HANDLE_OPCODE(JNSTRICTEQZ_IMM8) {
6593 LOG_FULL(FATAL) << "not implement";
6594 DISPATCH(JNSTRICTEQZ_IMM8);
6595 }
6596 HANDLE_OPCODE(JNSTRICTEQZ_IMM16) {
6597 LOG_FULL(FATAL) << "not implement";
6598 DISPATCH(JNSTRICTEQZ_IMM16);
6599 }
6600 HANDLE_OPCODE(JEQNULL_IMM8) {
6601 LOG_FULL(FATAL) << "not implement";
6602 DISPATCH(JEQNULL_IMM8);
6603 }
6604 HANDLE_OPCODE(JEQNULL_IMM16) {
6605 LOG_FULL(FATAL) << "not implement";
6606 DISPATCH(JEQNULL_IMM16);
6607 }
6608 HANDLE_OPCODE(JNENULL_IMM8) {
6609 LOG_FULL(FATAL) << "not implement";
6610 DISPATCH(JNENULL_IMM8);
6611 }
6612 HANDLE_OPCODE(JNENULL_IMM16) {
6613 LOG_FULL(FATAL) << "not implement";
6614 DISPATCH(JNENULL_IMM16);
6615 }
6616 HANDLE_OPCODE(JSTRICTEQNULL_IMM8) {
6617 LOG_FULL(FATAL) << "not implement";
6618 DISPATCH(JSTRICTEQNULL_IMM8);
6619 }
6620 HANDLE_OPCODE(JSTRICTEQNULL_IMM16) {
6621 LOG_FULL(FATAL) << "not implement";
6622 DISPATCH(JSTRICTEQNULL_IMM16);
6623 }
6624 HANDLE_OPCODE(JNSTRICTEQNULL_IMM8) {
6625 LOG_FULL(FATAL) << "not implement";
6626 DISPATCH(JNSTRICTEQNULL_IMM8);
6627 }
6628 HANDLE_OPCODE(JNSTRICTEQNULL_IMM16) {
6629 LOG_FULL(FATAL) << "not implement";
6630 DISPATCH(JNSTRICTEQNULL_IMM16);
6631 }
6632 HANDLE_OPCODE(JEQUNDEFINED_IMM8) {
6633 LOG_FULL(FATAL) << "not implement";
6634 DISPATCH(JEQUNDEFINED_IMM8);
6635 }
6636 HANDLE_OPCODE(JEQUNDEFINED_IMM16) {
6637 LOG_FULL(FATAL) << "not implement";
6638 DISPATCH(JEQUNDEFINED_IMM16);
6639 }
6640 HANDLE_OPCODE(JNEUNDEFINED_IMM8) {
6641 LOG_FULL(FATAL) << "not implement";
6642 DISPATCH(JNEUNDEFINED_IMM8);
6643 }
6644 HANDLE_OPCODE(JNEUNDEFINED_IMM16) {
6645 LOG_FULL(FATAL) << "not implement";
6646 DISPATCH(JNEUNDEFINED_IMM16);
6647 }
6648 HANDLE_OPCODE(JSTRICTEQUNDEFINED_IMM8) {
6649 LOG_FULL(FATAL) << "not implement";
6650 DISPATCH(JSTRICTEQUNDEFINED_IMM8);
6651 }
6652 HANDLE_OPCODE(JSTRICTEQUNDEFINED_IMM16) {
6653 LOG_FULL(FATAL) << "not implement";
6654 DISPATCH(JSTRICTEQUNDEFINED_IMM16);
6655 }
6656 HANDLE_OPCODE(JNSTRICTEQUNDEFINED_IMM8) {
6657 LOG_FULL(FATAL) << "not implement";
6658 DISPATCH(JNSTRICTEQUNDEFINED_IMM8);
6659 }
6660 HANDLE_OPCODE(JNSTRICTEQUNDEFINED_IMM16) {
6661 LOG_FULL(FATAL) << "not implement";
6662 DISPATCH(JNSTRICTEQUNDEFINED_IMM16);
6663 }
6664 HANDLE_OPCODE(JEQ_V8_IMM8) {
6665 LOG_FULL(FATAL) << "not implement";
6666 DISPATCH(JEQ_V8_IMM8);
6667 }
6668 HANDLE_OPCODE(JEQ_V8_IMM16) {
6669 LOG_FULL(FATAL) << "not implement";
6670 DISPATCH(JEQ_V8_IMM16);
6671 }
6672 HANDLE_OPCODE(JNE_V8_IMM8) {
6673 LOG_FULL(FATAL) << "not implement";
6674 DISPATCH(JNE_V8_IMM8);
6675 }
6676 HANDLE_OPCODE(JNE_V8_IMM16) {
6677 LOG_FULL(FATAL) << "not implement";
6678 DISPATCH(JNE_V8_IMM16);
6679 }
6680 HANDLE_OPCODE(JSTRICTEQ_V8_IMM8) {
6681 LOG_FULL(FATAL) << "not implement";
6682 DISPATCH(JSTRICTEQ_V8_IMM8);
6683 }
6684 HANDLE_OPCODE(JSTRICTEQ_V8_IMM16) {
6685 LOG_FULL(FATAL) << "not implement";
6686 DISPATCH(JSTRICTEQ_V8_IMM16);
6687 }
6688 HANDLE_OPCODE(JNSTRICTEQ_V8_IMM8) {
6689 LOG_FULL(FATAL) << "not implement";
6690 DISPATCH(JNSTRICTEQ_V8_IMM8);
6691 }
6692 HANDLE_OPCODE(JNSTRICTEQ_V8_IMM16) {
6693 LOG_FULL(FATAL) << "not implement";
6694 DISPATCH(JNSTRICTEQ_V8_IMM16);
6695 }
6696 HANDLE_OPCODE(LDNEWTARGET) {
6697 LOG_FULL(FATAL) << "not implement";
6698 DISPATCH(LDNEWTARGET);
6699 }
6700 HANDLE_OPCODE(LDTHIS) {
6701 LOG_INST() << "intrinsic::ldthis";
6702 SET_ACC(GetThis(sp));
6703 DISPATCH(LDTHIS);
6704 }
6705 HANDLE_OPCODE(LDTHISBYVALUE_IMM8) {
6706 LOG_INST() << "intrinsics::Ldthisbyvalue";
6707
6708 JSTaggedValue receiver = GetThis(sp);
6709 JSTaggedValue propKey = GET_ACC();
6710
6711 #if ECMASCRIPT_ENABLE_IC
6712 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6713 if (!profileTypeInfo.IsUndefined()) {
6714 uint16_t slotId = READ_INST_8_0();
6715 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6716 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
6717 JSTaggedValue res = JSTaggedValue::Hole();
6718
6719 if (LIKELY(firstValue.IsHeapObject())) {
6720 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
6721 res = ICRuntimeStub::TryLoadICByValue(thread, receiver, propKey, firstValue, secondValue);
6722 }
6723 // IC miss and not enter the megamorphic state, store as polymorphic
6724 if (res.IsHole() && !firstValue.IsHole()) {
6725 res = ICRuntimeStub::LoadICByValue(thread,
6726 profileTypeArray,
6727 receiver, propKey, slotId);
6728 }
6729
6730 if (LIKELY(!res.IsHole())) {
6731 INTERPRETER_RETURN_IF_ABRUPT(res);
6732 SET_ACC(res);
6733 DISPATCH(LDTHISBYVALUE_IMM8);
6734 }
6735 }
6736 #endif
6737 // fast path
6738 if (LIKELY(receiver.IsHeapObject())) {
6739 JSTaggedValue res = FastRuntimeStub::GetPropertyByValue(thread, receiver, propKey);
6740 if (!res.IsHole()) {
6741 ASSERT(!res.IsAccessor());
6742 INTERPRETER_RETURN_IF_ABRUPT(res);
6743 SET_ACC(res);
6744 DISPATCH(LDTHISBYVALUE_IMM8);
6745 }
6746 }
6747 // slow path
6748 SAVE_PC();
6749 JSTaggedValue res = SlowRuntimeStub::LdObjByValue(thread, receiver, propKey, false, JSTaggedValue::Undefined());
6750 INTERPRETER_RETURN_IF_ABRUPT(res);
6751 SET_ACC(res);
6752 DISPATCH(LDTHISBYVALUE_IMM8);
6753 }
6754 HANDLE_OPCODE(LDTHISBYVALUE_IMM16) {
6755 LOG_INST() << "intrinsics::Ldthisbyvalue";
6756
6757 JSTaggedValue receiver = GetThis(sp);
6758 JSTaggedValue propKey = GET_ACC();
6759
6760 #if ECMASCRIPT_ENABLE_IC
6761 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6762 if (!profileTypeInfo.IsUndefined()) {
6763 uint16_t slotId = READ_INST_16_0();
6764 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6765 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
6766 JSTaggedValue res = JSTaggedValue::Hole();
6767
6768 if (LIKELY(firstValue.IsHeapObject())) {
6769 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
6770 res = ICRuntimeStub::TryLoadICByValue(thread, receiver, propKey, firstValue, secondValue);
6771 }
6772 // IC miss and not enter the megamorphic state, store as polymorphic
6773 if (res.IsHole() && !firstValue.IsHole()) {
6774 res = ICRuntimeStub::LoadICByValue(thread,
6775 profileTypeArray,
6776 receiver, propKey, slotId);
6777 }
6778
6779 if (LIKELY(!res.IsHole())) {
6780 INTERPRETER_RETURN_IF_ABRUPT(res);
6781 SET_ACC(res);
6782 DISPATCH(LDTHISBYVALUE_IMM16);
6783 }
6784 }
6785 #endif
6786 if (LIKELY(receiver.IsHeapObject())) {
6787 // fast path
6788 JSTaggedValue res = FastRuntimeStub::GetPropertyByValue(thread, receiver, propKey);
6789 if (!res.IsHole()) {
6790 ASSERT(!res.IsAccessor());
6791 INTERPRETER_RETURN_IF_ABRUPT(res);
6792 SET_ACC(res);
6793 DISPATCH(LDTHISBYVALUE_IMM16);
6794 }
6795 }
6796 // slow path
6797 SAVE_PC();
6798 JSTaggedValue res = SlowRuntimeStub::LdObjByValue(thread, receiver, propKey, false, JSTaggedValue::Undefined());
6799 INTERPRETER_RETURN_IF_ABRUPT(res);
6800 SET_ACC(res);
6801 DISPATCH(LDTHISBYVALUE_IMM16);
6802 }
6803 HANDLE_OPCODE(STTHISBYVALUE_IMM8_V8) {
6804 uint32_t v0 = READ_INST_8_1();
6805
6806 LOG_INST() << "intrinsics::stthisbyvalue"
6807 << " v" << v0;
6808
6809 JSTaggedValue receiver = GetThis(sp);
6810 #if ECMASCRIPT_ENABLE_IC
6811 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6812 if (!profileTypeInfo.IsUndefined()) {
6813 uint16_t slotId = READ_INST_8_0();
6814 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6815 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
6816 JSTaggedValue propKey = GET_VREG_VALUE(v0);
6817 JSTaggedValue value = GET_ACC();
6818 JSTaggedValue res = JSTaggedValue::Hole();
6819 SAVE_ACC();
6820
6821 if (LIKELY(firstValue.IsHeapObject())) {
6822 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
6823 res = ICRuntimeStub::TryStoreICByValue(thread, receiver, propKey, firstValue, secondValue, value);
6824 }
6825 // IC miss and not enter the megamorphic state, store as polymorphic
6826 if (res.IsHole() && !firstValue.IsHole()) {
6827 res = ICRuntimeStub::StoreICByValue(thread,
6828 profileTypeArray,
6829 receiver, propKey, value, slotId);
6830 }
6831
6832 if (LIKELY(!res.IsHole())) {
6833 INTERPRETER_RETURN_IF_ABRUPT(res);
6834 RESTORE_ACC();
6835 DISPATCH(STTHISBYVALUE_IMM8_V8);
6836 }
6837 }
6838 #endif
6839 if (LIKELY(receiver.IsHeapObject())) {
6840 SAVE_ACC();
6841 JSTaggedValue propKey = GET_VREG_VALUE(v0);
6842 JSTaggedValue value = GET_ACC();
6843 // fast path
6844 JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, propKey, value);
6845 if (!res.IsHole()) {
6846 INTERPRETER_RETURN_IF_ABRUPT(res);
6847 RESTORE_ACC();
6848 DISPATCH(STTHISBYVALUE_IMM8_V8);
6849 }
6850 RESTORE_ACC();
6851 }
6852 {
6853 // slow path
6854 SAVE_ACC();
6855 SAVE_PC();
6856 receiver = GetThis(sp); // Maybe moved by GC
6857 JSTaggedValue propKey = GET_VREG_VALUE(v0); // Maybe moved by GC
6858 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
6859 JSTaggedValue res = SlowRuntimeStub::StObjByValue(thread, receiver, propKey, value);
6860 INTERPRETER_RETURN_IF_ABRUPT(res);
6861 RESTORE_ACC();
6862 }
6863 DISPATCH(STTHISBYVALUE_IMM8_V8);
6864 }
6865 HANDLE_OPCODE(STTHISBYVALUE_IMM16_V8) {
6866 uint32_t v0 = READ_INST_8_2();
6867
6868 LOG_INST() << "intrinsics::stthisbyvalue"
6869 << " v" << v0;
6870
6871 JSTaggedValue receiver = GetThis(sp);
6872 #if ECMASCRIPT_ENABLE_IC
6873 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6874 if (!profileTypeInfo.IsUndefined()) {
6875 uint16_t slotId = READ_INST_16_0();
6876 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6877 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
6878 JSTaggedValue propKey = GET_VREG_VALUE(v0);
6879 JSTaggedValue value = GET_ACC();
6880 JSTaggedValue res = JSTaggedValue::Hole();
6881 SAVE_ACC();
6882
6883 if (LIKELY(firstValue.IsHeapObject())) {
6884 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
6885 res = ICRuntimeStub::TryStoreICByValue(thread, receiver, propKey, firstValue, secondValue, value);
6886 }
6887 // IC miss and not enter the megamorphic state, store as polymorphic
6888 if (res.IsHole() && !firstValue.IsHole()) {
6889 res = ICRuntimeStub::StoreICByValue(thread,
6890 profileTypeArray,
6891 receiver, propKey, value, slotId);
6892 }
6893
6894 if (LIKELY(!res.IsHole())) {
6895 INTERPRETER_RETURN_IF_ABRUPT(res);
6896 RESTORE_ACC();
6897 DISPATCH(STTHISBYVALUE_IMM16_V8);
6898 }
6899 }
6900 #endif
6901 if (LIKELY(receiver.IsHeapObject())) {
6902 SAVE_ACC();
6903 JSTaggedValue propKey = GET_VREG_VALUE(v0);
6904 JSTaggedValue value = GET_ACC();
6905 // fast path
6906 JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, propKey, value);
6907 if (!res.IsHole()) {
6908 INTERPRETER_RETURN_IF_ABRUPT(res);
6909 RESTORE_ACC();
6910 DISPATCH(STTHISBYVALUE_IMM16_V8);
6911 }
6912 RESTORE_ACC();
6913 }
6914 {
6915 // slow path
6916 SAVE_ACC();
6917 SAVE_PC();
6918 receiver = GetThis(sp); // Maybe moved by GC
6919 JSTaggedValue propKey = GET_VREG_VALUE(v0); // Maybe moved by GC
6920 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
6921 JSTaggedValue res = SlowRuntimeStub::StObjByValue(thread, receiver, propKey, value);
6922 INTERPRETER_RETURN_IF_ABRUPT(res);
6923 RESTORE_ACC();
6924 }
6925 DISPATCH(STTHISBYVALUE_IMM16_V8);
6926 }
6927 HANDLE_OPCODE(LDTHISBYNAME_IMM8_ID16) {
6928 #if ECMASCRIPT_ENABLE_IC
6929 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6930 if (!profileTypeInfo.IsUndefined()) {
6931 uint16_t slotId = READ_INST_8_0();
6932 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6933 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
6934 JSTaggedValue res = JSTaggedValue::Hole();
6935
6936 JSTaggedValue receiver = GetThis(sp);
6937 if (LIKELY(firstValue.IsHeapObject())) {
6938 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
6939 res = ICRuntimeStub::TryLoadICByName(thread, receiver, firstValue, secondValue);
6940 }
6941 if (LIKELY(!res.IsHole())) {
6942 INTERPRETER_RETURN_IF_ABRUPT(res);
6943 SET_ACC(res);
6944 DISPATCH(LDTHISBYNAME_IMM8_ID16);
6945 } else if (!firstValue.IsHole()) { // IC miss and not enter the megamorphic state, store as polymorphic
6946 uint16_t stringId = READ_INST_16_1();
6947 auto constpool = GetConstantPool(sp);
6948 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6949 receiver = GetThis(sp);
6950 profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6951 profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6952 res = ICRuntimeStub::LoadICByName(thread,
6953 profileTypeArray,
6954 receiver, propKey, slotId);
6955 INTERPRETER_RETURN_IF_ABRUPT(res);
6956 SET_ACC(res);
6957 DISPATCH(LDTHISBYNAME_IMM8_ID16);
6958 }
6959 }
6960 #endif
6961 uint16_t stringId = READ_INST_16_1();
6962 auto constpool = GetConstantPool(sp);
6963 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
6964 JSTaggedValue receiver = GetThis(sp);
6965 LOG_INST() << "intrinsics::ldthisbyname stringId:" << stringId << ", "
6966 << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << receiver.GetRawData();
6967
6968 if (LIKELY(receiver.IsHeapObject())) {
6969 // fast path
6970 JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, receiver, propKey);
6971 if (!res.IsHole()) {
6972 ASSERT(!res.IsAccessor());
6973 INTERPRETER_RETURN_IF_ABRUPT(res);
6974 SET_ACC(res);
6975 DISPATCH(LDTHISBYNAME_IMM8_ID16);
6976 }
6977 }
6978 // slow path
6979 SAVE_PC();
6980 JSTaggedValue res = SlowRuntimeStub::LdObjByName(thread, receiver, propKey, false, JSTaggedValue::Undefined());
6981 INTERPRETER_RETURN_IF_ABRUPT(res);
6982 SET_ACC(res);
6983 DISPATCH(LDTHISBYNAME_IMM8_ID16);
6984 }
6985 HANDLE_OPCODE(LDTHISBYNAME_IMM16_ID16) {
6986 #if ECMASCRIPT_ENABLE_IC
6987 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
6988 if (!profileTypeInfo.IsUndefined()) {
6989 uint16_t slotId = READ_INST_16_0();
6990 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
6991 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
6992 JSTaggedValue res = JSTaggedValue::Hole();
6993
6994 JSTaggedValue receiver = GetThis(sp);
6995 if (LIKELY(firstValue.IsHeapObject())) {
6996 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
6997 res = ICRuntimeStub::TryLoadICByName(thread, receiver, firstValue, secondValue);
6998 }
6999 if (LIKELY(!res.IsHole())) {
7000 INTERPRETER_RETURN_IF_ABRUPT(res);
7001 SET_ACC(res);
7002 DISPATCH(LDTHISBYNAME_IMM16_ID16);
7003 } else if (!firstValue.IsHole()) { // IC miss and not enter the megamorphic state, store as polymorphic
7004 uint16_t stringId = READ_INST_16_2();
7005 auto constpool = GetConstantPool(sp);
7006 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
7007 receiver = GetThis(sp);
7008 profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
7009 profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
7010 res = ICRuntimeStub::LoadICByName(thread,
7011 profileTypeArray,
7012 receiver, propKey, slotId);
7013 INTERPRETER_RETURN_IF_ABRUPT(res);
7014 SET_ACC(res);
7015 DISPATCH(LDTHISBYNAME_IMM16_ID16);
7016 }
7017 }
7018 #endif
7019 uint16_t stringId = READ_INST_16_2();
7020 auto constpool = GetConstantPool(sp);
7021 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
7022 JSTaggedValue receiver = GetThis(sp);
7023 LOG_INST() << "intrinsics::ldthisbyname stringId:" << stringId << ", "
7024 << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << receiver.GetRawData();
7025
7026 if (LIKELY(receiver.IsHeapObject())) {
7027 // fast path
7028 JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, receiver, propKey);
7029 if (!res.IsHole()) {
7030 ASSERT(!res.IsAccessor());
7031 INTERPRETER_RETURN_IF_ABRUPT(res);
7032 SET_ACC(res);
7033 DISPATCH(LDTHISBYNAME_IMM16_ID16);
7034 }
7035 }
7036 // slow path
7037 SAVE_PC();
7038 JSTaggedValue res = SlowRuntimeStub::LdObjByName(thread, receiver, propKey, false, JSTaggedValue::Undefined());
7039 INTERPRETER_RETURN_IF_ABRUPT(res);
7040 SET_ACC(res);
7041 DISPATCH(LDTHISBYNAME_IMM16_ID16);
7042 }
7043 HANDLE_OPCODE(STTHISBYNAME_IMM8_ID16) {
7044 #if ECMASCRIPT_ENABLE_IC
7045 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
7046 if (!profileTypeInfo.IsUndefined()) {
7047 uint16_t slotId = READ_INST_8_0();
7048 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
7049 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
7050 JSTaggedValue res = JSTaggedValue::Hole();
7051 SAVE_ACC();
7052
7053 JSTaggedValue receiver = GetThis(sp);
7054 JSTaggedValue value = GET_ACC();
7055 if (LIKELY(firstValue.IsHeapObject())) {
7056 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
7057 res = ICRuntimeStub::TryStoreICByName(thread, receiver, firstValue, secondValue, value);
7058 }
7059 if (LIKELY(!res.IsHole())) {
7060 INTERPRETER_RETURN_IF_ABRUPT(res);
7061 RESTORE_ACC();
7062 DISPATCH(STTHISBYNAME_IMM8_ID16);
7063 } else if (!firstValue.IsHole()) { // IC miss and not enter the megamorphic state, store as polymorphic
7064 uint16_t stringId = READ_INST_16_1();
7065 SAVE_ACC();
7066 auto constpool = GetConstantPool(sp);
7067 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
7068 RESTORE_ACC();
7069 value = GET_ACC();
7070 receiver = GetThis(sp);
7071 profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
7072 profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
7073 res = ICRuntimeStub::StoreICByName(thread,
7074 profileTypeArray,
7075 receiver, propKey, value, slotId);
7076 INTERPRETER_RETURN_IF_ABRUPT(res);
7077 RESTORE_ACC();
7078 DISPATCH(STTHISBYNAME_IMM8_ID16);
7079 }
7080 }
7081 #endif
7082 uint16_t stringId = READ_INST_16_1();
7083 LOG_INST() << "intrinsics::stthisbyname "
7084 << " stringId:" << stringId;
7085 JSTaggedValue receiver = GetThis(sp);
7086 if (receiver.IsHeapObject()) {
7087 SAVE_ACC();
7088 auto constpool = GetConstantPool(sp);
7089 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
7090 RESTORE_ACC();
7091 JSTaggedValue value = GET_ACC();
7092 receiver = GetThis(sp);
7093 // fast path
7094 JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value);
7095 if (!res.IsHole()) {
7096 INTERPRETER_RETURN_IF_ABRUPT(res);
7097 RESTORE_ACC();
7098 DISPATCH(STTHISBYNAME_IMM8_ID16);
7099 }
7100 RESTORE_ACC();
7101 }
7102 // slow path
7103 SAVE_ACC();
7104 SAVE_PC();
7105 auto constpool = GetConstantPool(sp); // Maybe moved by GC
7106 auto propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
7107 RESTORE_ACC();
7108 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
7109 receiver = GetThis(sp);
7110 JSTaggedValue res = SlowRuntimeStub::StObjByName(thread, receiver, propKey, value);
7111 INTERPRETER_RETURN_IF_ABRUPT(res);
7112 RESTORE_ACC();
7113 DISPATCH(STTHISBYNAME_IMM8_ID16);
7114 }
7115 HANDLE_OPCODE(STTHISBYNAME_IMM16_ID16) {
7116 #if ECMASCRIPT_ENABLE_IC
7117 auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
7118 if (!profileTypeInfo.IsUndefined()) {
7119 uint16_t slotId = READ_INST_16_0();
7120 auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
7121 JSTaggedValue firstValue = profileTypeArray->Get(slotId);
7122 JSTaggedValue res = JSTaggedValue::Hole();
7123 SAVE_ACC();
7124
7125 JSTaggedValue receiver = GetThis(sp);
7126 JSTaggedValue value = GET_ACC();
7127 if (LIKELY(firstValue.IsHeapObject())) {
7128 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
7129 res = ICRuntimeStub::TryStoreICByName(thread, receiver, firstValue, secondValue, value);
7130 }
7131 if (LIKELY(!res.IsHole())) {
7132 INTERPRETER_RETURN_IF_ABRUPT(res);
7133 RESTORE_ACC();
7134 DISPATCH(STTHISBYNAME_IMM16_ID16);
7135 } else if (!firstValue.IsHole()) { // IC miss and not enter the megamorphic state, store as polymorphic
7136 uint16_t stringId = READ_INST_16_2();
7137 SAVE_ACC();
7138 auto constpool = GetConstantPool(sp);
7139 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
7140 RESTORE_ACC();
7141 value = GET_ACC();
7142 receiver = GetThis(sp);
7143 profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
7144 profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
7145 res = ICRuntimeStub::StoreICByName(thread,
7146 profileTypeArray,
7147 receiver, propKey, value, slotId);
7148 INTERPRETER_RETURN_IF_ABRUPT(res);
7149 RESTORE_ACC();
7150 DISPATCH(STTHISBYNAME_IMM16_ID16);
7151 }
7152 }
7153 #endif
7154 uint16_t stringId = READ_INST_16_2();
7155 LOG_INST() << "intrinsics::stthisbyname "
7156 << " stringId:" << stringId;
7157 JSTaggedValue receiver = GetThis(sp);
7158 if (receiver.IsHeapObject()) {
7159 SAVE_ACC();
7160 auto constpool = GetConstantPool(sp);
7161 JSTaggedValue propKey = GET_STR_FROM_CACHE(stringId);
7162 RESTORE_ACC();
7163 JSTaggedValue value = GET_ACC();
7164 receiver = GetThis(sp);
7165 // fast path
7166 JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value);
7167 if (!res.IsHole()) {
7168 INTERPRETER_RETURN_IF_ABRUPT(res);
7169 RESTORE_ACC();
7170 DISPATCH(STTHISBYNAME_IMM16_ID16);
7171 }
7172 RESTORE_ACC();
7173 }
7174 // slow path
7175 SAVE_ACC();
7176 SAVE_PC();
7177 auto constpool = GetConstantPool(sp); // Maybe moved by GC
7178 auto propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
7179 RESTORE_ACC();
7180 JSTaggedValue value = GET_ACC(); // Maybe moved by GC
7181 receiver = GetThis(sp);
7182 JSTaggedValue res = SlowRuntimeStub::StObjByName(thread, receiver, propKey, value);
7183 INTERPRETER_RETURN_IF_ABRUPT(res);
7184 RESTORE_ACC();
7185 DISPATCH(STTHISBYNAME_IMM16_ID16);
7186 }
7187 HANDLE_OPCODE(WIDE_LDPATCHVAR_PREF_IMM16) {
7188 uint16_t index = READ_INST_16_1();
7189 LOG_INST() << "intrinsics::ldpatchvar" << " imm: " << index;
7190
7191 SAVE_PC();
7192 JSTaggedValue res = SlowRuntimeStub::LdPatchVar(thread, index);
7193 INTERPRETER_RETURN_IF_ABRUPT(res);
7194 SET_ACC(res);
7195 DISPATCH(WIDE_LDPATCHVAR_PREF_IMM16);
7196 }
7197 HANDLE_OPCODE(WIDE_STPATCHVAR_PREF_IMM16) {
7198 uint16_t index = READ_INST_16_1();
7199 LOG_INST() << "intrinsics::stpatchvar" << " imm: " << index;
7200 JSTaggedValue value = GET_ACC();
7201
7202 SAVE_ACC();
7203 SAVE_PC();
7204 JSTaggedValue res = SlowRuntimeStub::StPatchVar(thread, index, value);
7205 INTERPRETER_RETURN_IF_ABRUPT(res);
7206 RESTORE_ACC();
7207 DISPATCH(WIDE_STPATCHVAR_PREF_IMM16);
7208 }
7209 HANDLE_OPCODE(DYNAMICIMPORT) {
7210 LOG_INST() << "intrinsics::dynamicimport";
7211 JSTaggedValue specifier = GET_ACC();
7212 JSTaggedValue thisFunc = GetFunction(sp);
7213 SAVE_PC();
7214 JSTaggedValue res = SlowRuntimeStub::DynamicImport(thread, specifier, thisFunc);
7215 INTERPRETER_RETURN_IF_ABRUPT(res);
7216 SET_ACC(res);
7217 DISPATCH(DYNAMICIMPORT);
7218 }
7219 HANDLE_OPCODE(DEPRECATED_DYNAMICIMPORT_PREF_V8) {
7220 uint16_t v0 = READ_INST_8_1();
7221 LOG_INST() << "intrinsics::dynamicimport";
7222 JSTaggedValue specifier = GET_VREG_VALUE(v0);
7223 JSTaggedValue thisFunc = GetFunction(sp);
7224 SAVE_PC();
7225 JSTaggedValue res = SlowRuntimeStub::DynamicImport(thread, specifier, thisFunc);
7226 INTERPRETER_RETURN_IF_ABRUPT(res);
7227 SET_ACC(res);
7228 DISPATCH(DEPRECATED_DYNAMICIMPORT_PREF_V8);
7229 }
7230 HANDLE_OPCODE(CALLRUNTIME_NOTIFYCONCURRENTRESULT_PREF_NONE) {
7231 LOG_INST() << "intrinsics::callruntime.notifyconcurrentresult";
7232 JSTaggedValue funcObj = GetFunction(sp);
7233 SlowRuntimeStub::NotifyConcurrentResult(thread, acc, funcObj);
7234 DISPATCH(CALLRUNTIME_NOTIFYCONCURRENTRESULT_PREF_NONE);
7235 }
7236 #include "templates/debugger_instruction_handler.inl"
7237 }
7238 #endif
7239
InitStackFrame(JSThread * thread)7240 void EcmaInterpreter::InitStackFrame(JSThread *thread)
7241 {
7242 if (thread->IsAsmInterpreter()) {
7243 return InterpreterAssembly::InitStackFrame(thread);
7244 }
7245 InitStackFrameForSP(const_cast<JSTaggedType *>(thread->GetCurrentSPFrame()));
7246 }
7247
InitStackFrame(EcmaContext * context)7248 void EcmaInterpreter::InitStackFrame(EcmaContext *context)
7249 {
7250 if (context->GetJSThread()->IsAsmInterpreter()) {
7251 return InterpreterAssembly::InitStackFrame(context);
7252 }
7253 InitStackFrameForSP(const_cast<JSTaggedType *>(context->GetCurrentFrame()));
7254 }
7255
InitStackFrameForSP(JSTaggedType * prevSp)7256 void EcmaInterpreter::InitStackFrameForSP(JSTaggedType *prevSp)
7257 {
7258 InterpretedFrame *state = GET_FRAME(prevSp);
7259 state->pc = nullptr;
7260 state->function = JSTaggedValue::Hole();
7261 state->thisObj = JSTaggedValue::Hole();
7262 state->acc = JSTaggedValue::Hole();
7263 state->constpool = JSTaggedValue::Hole();
7264 state->profileTypeInfo = JSTaggedValue::Undefined();
7265 state->base.type = FrameType::INTERPRETER_FRAME;
7266 state->base.prev = nullptr;
7267 }
7268
GetFunction(JSTaggedType * sp)7269 JSTaggedValue EcmaInterpreter::GetFunction(JSTaggedType *sp)
7270 {
7271 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7272 InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
7273 return state->function;
7274 }
7275
GetThis(JSTaggedType * sp)7276 JSTaggedValue EcmaInterpreter::GetThis(JSTaggedType *sp)
7277 {
7278 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7279 InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
7280 return state->thisObj;
7281 }
7282
GetNewTarget(JSTaggedType * sp)7283 JSTaggedValue EcmaInterpreter::GetNewTarget(JSTaggedType *sp)
7284 {
7285 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7286 InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
7287 Method *method = JSFunction::Cast(state->function.GetTaggedObject())->GetCallTarget();
7288 ASSERT(method->HaveNewTargetWithCallField());
7289 uint32_t numVregs = method->GetNumVregsWithCallField();
7290 bool haveFunc = method->HaveFuncWithCallField();
7291 return JSTaggedValue(sp[numVregs + haveFunc]);
7292 }
7293
GetNumArgs(JSTaggedType * sp,uint32_t restIdx,uint32_t & startIdx)7294 uint32_t EcmaInterpreter::GetNumArgs(JSTaggedType *sp, uint32_t restIdx, uint32_t &startIdx)
7295 {
7296 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7297 InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
7298 Method *method = JSFunction::Cast(state->function.GetTaggedObject())->GetCallTarget();
7299 ASSERT(method->HaveExtraWithCallField());
7300
7301 uint32_t numVregs = method->GetNumVregsWithCallField();
7302 bool haveFunc = method->HaveFuncWithCallField();
7303 bool haveNewTarget = method->HaveNewTargetWithCallField();
7304 bool haveThis = method->HaveThisWithCallField();
7305 uint32_t copyArgs = haveFunc + haveNewTarget + haveThis;
7306 uint32_t numArgs = method->GetNumArgsWithCallField();
7307
7308 JSTaggedType *lastFrame = state->base.prev;
7309 // The prev frame of InterpretedFrame may entry frame or interpreter frame.
7310 if (FrameHandler::GetFrameType(state->base.prev) == FrameType::INTERPRETER_ENTRY_FRAME) {
7311 lastFrame = lastFrame - InterpretedEntryFrame::NumOfMembers();
7312 } else {
7313 lastFrame = lastFrame - InterpretedFrame::NumOfMembers();
7314 }
7315
7316 if (static_cast<uint32_t>(lastFrame - sp) > numVregs + copyArgs + numArgs) {
7317 // In this case, actualNumArgs is in the end
7318 // If not, then actualNumArgs == declaredNumArgs, therefore do nothing
7319 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7320 numArgs = static_cast<uint32_t>(JSTaggedValue(*(lastFrame - 1)).GetInt());
7321 }
7322 startIdx = numVregs + copyArgs + restIdx;
7323 return ((numArgs > restIdx) ? (numArgs - restIdx) : 0);
7324 }
7325
GetJumpSizeAfterCall(const uint8_t * prevPc)7326 size_t EcmaInterpreter::GetJumpSizeAfterCall(const uint8_t *prevPc)
7327 {
7328 auto op = BytecodeInstruction(prevPc).GetOpcode();
7329 size_t jumpSize = BytecodeInstruction::Size(op);
7330 return jumpSize;
7331 }
7332
GetRuntimeProfileTypeInfo(JSTaggedType * sp)7333 JSTaggedValue EcmaInterpreter::GetRuntimeProfileTypeInfo(JSTaggedType *sp)
7334 {
7335 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7336 InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
7337 return state->profileTypeInfo;
7338 }
7339
GetEcmaModule(JSTaggedType * sp)7340 JSTaggedValue EcmaInterpreter::GetEcmaModule(JSTaggedType *sp)
7341 {
7342 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7343 JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
7344 return currentFunc->GetModule();
7345 }
7346
GetConstantPool(JSTaggedType * sp)7347 JSTaggedValue EcmaInterpreter::GetConstantPool(JSTaggedType *sp)
7348 {
7349 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7350 InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
7351 return state->constpool;
7352 }
7353
UpdateHotnessCounter(JSThread * thread,JSTaggedType * sp,JSTaggedValue acc,int32_t offset)7354 bool EcmaInterpreter::UpdateHotnessCounter(JSThread* thread, JSTaggedType *sp, JSTaggedValue acc, int32_t offset)
7355 {
7356 InterpretedFrame *state = GET_FRAME(sp);
7357 auto method = JSFunction::Cast(state->function.GetTaggedObject())->GetCallTarget();
7358 auto hotnessCounter = method->GetHotnessCounter();
7359
7360 hotnessCounter += offset;
7361 if (UNLIKELY(hotnessCounter <= 0)) {
7362 bool needRestoreAcc = false;
7363 SAVE_ACC();
7364 needRestoreAcc = thread->CheckSafepoint();
7365 RESTORE_ACC();
7366 method = JSFunction::Cast(state->function.GetTaggedObject())->GetCallTarget();
7367 if (state->profileTypeInfo.IsUndefined()) {
7368 state->acc = acc;
7369 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7370 auto thisFunc = JSFunction::Cast(state->function.GetTaggedObject());
7371 method = thisFunc->GetCallTarget(); // for CheckSafepoint, method need retrieve.
7372 method->SetHotnessCounter(EcmaInterpreter::METHOD_HOTNESS_THRESHOLD);
7373 auto res = SlowRuntimeStub::NotifyInlineCache(thread, method);
7374 state->profileTypeInfo = res;
7375 return true;
7376 } else {
7377 method->SetHotnessCounter(EcmaInterpreter::METHOD_HOTNESS_THRESHOLD);
7378 return needRestoreAcc;
7379 }
7380 }
7381 method->SetHotnessCounter(hotnessCounter);
7382 return false;
7383 }
7384
IsFastNewFrameEnter(JSFunction * ctor,JSHandle<Method> method)7385 bool EcmaInterpreter::IsFastNewFrameEnter(JSFunction *ctor, JSHandle<Method> method)
7386 {
7387 if (method->IsNativeWithCallField()) {
7388 return false;
7389 }
7390
7391 if (ctor->IsBase()) {
7392 return method->OnlyHaveThisWithCallField();
7393 }
7394
7395 if (ctor->IsDerivedConstructor()) {
7396 return method->OnlyHaveNewTagetAndThisWithCallField();
7397 }
7398
7399 return false;
7400 }
7401
GetInterpreterFrameEnd(JSThread * thread,JSTaggedType * sp)7402 JSTaggedType *EcmaInterpreter::GetInterpreterFrameEnd(JSThread *thread, JSTaggedType *sp)
7403 {
7404 JSTaggedType *newSp;
7405 if (thread->IsAsmInterpreter()) {
7406 newSp = sp - InterpretedEntryFrame::NumOfMembers();
7407 } else {
7408 if (FrameHandler::GetFrameType(sp) == FrameType::INTERPRETER_FRAME ||
7409 FrameHandler::GetFrameType(sp) == FrameType::INTERPRETER_FAST_NEW_FRAME) {
7410 // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7411 newSp = sp - InterpretedFrame::NumOfMembers();
7412 } else if (FrameHandler::GetFrameType(sp) == FrameType::INTERPRETER_BUILTIN_FRAME) {
7413 // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7414 newSp = sp - InterpretedBuiltinFrame::NumOfMembers();
7415 } else {
7416 // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
7417 newSp = sp - InterpretedEntryFrame::NumOfMembers();
7418 }
7419 }
7420 return newSp;
7421 }
7422
IsFastNewFrameExit(JSTaggedType * sp)7423 bool EcmaInterpreter::IsFastNewFrameExit(JSTaggedType *sp)
7424 {
7425 return GET_FRAME(sp)->base.type == FrameType::INTERPRETER_FAST_NEW_FRAME;
7426 }
7427
GetHotnessCounter(uint32_t codeSize)7428 int16_t EcmaInterpreter::GetHotnessCounter(uint32_t codeSize)
7429 {
7430 auto result = codeSize * METHOD_HOTNESS_THRESHOLD_FACTOR;
7431 return (result > METHOD_HOTNESS_THRESHOLD) ?
7432 METHOD_HOTNESS_THRESHOLD : static_cast<int16_t>(result);
7433 }
7434
7435 #undef LOG_INST
7436 #undef HANDLE_OPCODE
7437 #undef ADVANCE_PC
7438 #undef GOTO_NEXT
7439 #undef DISPATCH
7440 #undef DISPATCH_OFFSET
7441 #undef GET_FRAME
7442 #undef GET_ENTRY_FRAME
7443 #undef SAVE_PC
7444 #undef SAVE_ACC
7445 #undef RESTORE_ACC
7446 #undef INTERPRETER_GOTO_EXCEPTION_HANDLER
7447 #undef CHECK_SWITCH_TO_DEBUGGER_TABLE
7448 #undef REAL_GOTO_DISPATCH_OPCODE
7449 #undef REAL_GOTO_EXCEPTION_HANDLER
7450 #undef INTERPRETER_RETURN_IF_ABRUPT
7451 #undef NOTIFY_DEBUGGER_EVENT
7452 #undef DEPRECATED_CALL_INITIALIZE
7453 #undef CALL_PUSH_UNDEFINED
7454 #undef DEPRECATED_CALL_PUSH_ARGS_0
7455 #undef DEPRECATED_CALL_PUSH_ARGS_1
7456 #undef DEPRECATED_CALL_PUSH_ARGS_2
7457 #undef DEPRECATED_CALL_PUSH_ARGS_3
7458 #undef DEPRECATED_CALL_PUSH_ARGS_RANGE
7459 #undef DEPRECATED_CALL_PUSH_ARGS_THISRANGE
7460 #undef DEPRECATED_CALL_PUSH_ARGS_0_NO_EXTRA
7461 #undef DEPRECATED_CALL_PUSH_ARGS_1_NO_EXTRA
7462 #undef DEPRECATED_CALL_PUSH_ARGS_2_NO_EXTRA
7463 #undef DEPRECATED_CALL_PUSH_ARGS_3_NO_EXTRA
7464 #undef DEPRECATED_CALL_PUSH_ARGS_RANGE_NO_EXTRA
7465 #undef DEPRECATED_CALL_PUSH_ARGS_THISRANGE_NO_EXTRA
7466 #undef DEPRECATED_CALL_PUSH_ARGS
7467 #undef UPDATE_HOTNESS_COUNTER_NON_ACC
7468 #undef UPDATE_HOTNESS_COUNTER
7469 #undef GET_VREG
7470 #undef GET_VREG_VALUE
7471 #undef SET_VREG
7472 #undef GET_ACC
7473 #undef SET_ACC
7474 #if defined(__clang__)
7475 #pragma clang diagnostic pop
7476 #elif defined(__GNUC__)
7477 #pragma GCC diagnostic pop
7478 #endif
7479 } // namespace panda::ecmascript
7480 #endif // ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H
7481