• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H
17 #define ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H
18 
19 #include "ecmascript/jspandafile/program_object-inl.h"
20 #include "ecmascript/cpu_profiler/cpu_profiler.h"
21 #include "ecmascript/jspandafile/program_object-inl.h"
22 #include "ecmascript/ecma_string.h"
23 #include "ecmascript/ecma_vm.h"
24 #include "ecmascript/global_env.h"
25 #include "ecmascript/ic/ic_runtime_stub-inl.h"
26 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
27 #include "ecmascript/interpreter/interpreter.h"
28 #include "ecmascript/interpreter/interpreter_assembly.h"
29 #include "ecmascript/interpreter/frame_handler.h"
30 #include "ecmascript/interpreter/slow_runtime_stub.h"
31 #include "ecmascript/js_generator_object.h"
32 #include "ecmascript/js_tagged_value.h"
33 #include "ecmascript/literal_data_extractor.h"
34 #include "ecmascript/mem/concurrent_marker.h"
35 #include "ecmascript/runtime_call_id.h"
36 #include "ecmascript/template_string.h"
37 #include "ecmascript/tooling/interface/js_debugger_manager.h"
38 #include "libpandafile/code_data_accessor.h"
39 #include "libpandafile/file.h"
40 #include "libpandafile/method_data_accessor.h"
41 
42 namespace panda::ecmascript {
43 #if defined(__clang__)
44 #pragma clang diagnostic push
45 #pragma clang diagnostic ignored "-Wvoid-ptr-dereference"
46 #pragma clang diagnostic ignored "-Wgnu-label-as-value"
47 #elif defined(__GNUC__)
48 #pragma GCC diagnostic push
49 #pragma GCC diagnostic ignored "-Wpedantic"
50 #endif
51 
52 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
53 #define LOG_INST() LOG(DEBUG, INTERPRETER) << ": "
54 
55 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
56 #define HANDLE_OPCODE(handle_opcode) \
57     handle_opcode:  // NOLINT(clang-diagnostic-gnu-label-as-value, cppcoreguidelines-macro-usage)
58 
59 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
60 #define ADVANCE_PC(offset) \
61     pc += (offset);  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic, cppcoreguidelines-macro-usage)
62 
63 #define GOTO_NEXT()  // NOLINT(clang-diagnostic-gnu-label-as-value, cppcoreguidelines-macro-usage)
64 
65 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
66 #define DISPATCH(format)                                       \
67     do {                                                       \
68         ADVANCE_PC(BytecodeInstruction::Size(format))          \
69         opcode = READ_INST_OP(); goto * dispatchTable[opcode]; \
70     } while (false)
71 
72 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
73 #define DISPATCH_OFFSET(offset)                                \
74     do {                                                       \
75         ADVANCE_PC(offset)                                     \
76         opcode = READ_INST_OP(); goto * dispatchTable[opcode]; \
77     } while (false)
78 
79 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
80 #define GET_FRAME(CurrentSp) \
81     (reinterpret_cast<InterpretedFrame *>(CurrentSp) - 1)  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
82 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
83 #define SAVE_PC() (GET_FRAME(sp)->pc = pc)  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
84 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
85 #define SAVE_ACC() (GET_FRAME(sp)->acc = acc)  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
86 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
87 #define RESTORE_ACC() (acc = GET_FRAME(sp)->acc)  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
88 
89 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
90 #define INTERPRETER_GOTO_EXCEPTION_HANDLER()          \
91     do {                                              \
92         SAVE_PC();                                    \
93         goto *dispatchTable[EcmaOpcode::LAST_OPCODE]; \
94     } while (false)
95 
96 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
97 #define INTERPRETER_HANDLE_RETURN()                                                     \
98     do {                                                                                \
99         size_t jumpSize = GetJumpSizeAfterCall(pc);                                     \
100         DISPATCH_OFFSET(jumpSize);                                                      \
101     } while (false)
102 
103 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
104 #define CHECK_SWITCH_TO_DEBUGGER_TABLE()        \
105     if (ecmaVm->GetJsDebuggerManager()->IsDebugMode()) { \
106         dispatchTable = debugDispatchTable;     \
107     }
108 
109 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
110 #define REAL_GOTO_DISPATCH_OPCODE(opcode) \
111     do {                                  \
112         goto *instDispatchTable[opcode];  \
113     } while (false)
114 
115 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
116 #define REAL_GOTO_EXCEPTION_HANDLER()                     \
117     do {                                                  \
118         SAVE_PC();                                        \
119         goto *instDispatchTable[EcmaOpcode::LAST_OPCODE]; \
120     } while (false)
121 
122 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
123 #define INTERPRETER_RETURN_IF_ABRUPT(result)      \
124     do {                                          \
125         if (result.IsException()) {               \
126             INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
127         }                                         \
128     } while (false)
129 
130 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
131 #define NOTIFY_DEBUGGER_EVENT()          \
132     do {                                 \
133         SAVE_ACC();                      \
134         SAVE_PC();                       \
135         NotifyBytecodePcChanged(thread); \
136         RESTORE_ACC();                   \
137     } while (false)
138 
139 /*
140  * reasons of set acc with hole:
141  * 1. acc will become illegal when new error
142  * 2. debugger logic will save acc, so illegal acc will set to frame
143  * 3. when debugger trigger gc, will mark an invalid acc and crash
144  * 4. acc will set to exception later, so it can set to hole template
145  */
146 #define NOTIFY_DEBUGGER_EXCEPTION_EVENT() \
147     do {                                  \
148         SET_ACC(JSTaggedValue::Hole());   \
149         NOTIFY_DEBUGGER_EVENT();          \
150     } while (false)
151 
152 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
153 #define CALL_INITIALIZE()                                             \
154     do {                                                              \
155         SAVE_PC();                                                    \
156         thread->CheckSafepoint();                                     \
157         funcTagged = sp[funcReg];                                     \
158         JSTaggedValue funcValue(funcTagged);                          \
159         if (!funcValue.IsCallable()) {                                \
160             {                                                         \
161                 [[maybe_unused]] EcmaHandleScope handleScope(thread); \
162                 JSHandle<JSObject> error = factory->GetJSError(       \
163                     ErrorType::TYPE_ERROR, "is not callable");        \
164                 thread->SetException(error.GetTaggedValue());         \
165             }                                                         \
166             INTERPRETER_GOTO_EXCEPTION_HANDLER();                     \
167         }                                                             \
168         funcObject = ECMAObject::Cast(funcValue.GetTaggedObject());   \
169         method = funcObject->GetCallTarget();                         \
170         newSp = sp - FRAME_STATE_SIZE;                                \
171     } while (false)
172 
173 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
174 #define CALL_PUSH_UNDEFINED(n)                           \
175     do {                                                 \
176         for (int i = 0; i < (n); i++) {                  \
177             *(--newSp) = JSTaggedValue::VALUE_UNDEFINED; \
178         }                                                \
179     } while (false)
180 
181 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
182 #define CALL_PUSH_ARGS_0()          \
183     do {                            \
184         /* do nothing when 0 arg */ \
185     } while (false)
186 
187 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
188 #define CALL_PUSH_ARGS_1()   \
189     do {                     \
190         *(--newSp) = sp[a0]; \
191     } while (false)
192 
193 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
194 #define CALL_PUSH_ARGS_2()   \
195     do {                     \
196         *(--newSp) = sp[a1]; \
197         CALL_PUSH_ARGS_1();  \
198     } while (false)
199 
200 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
201 #define CALL_PUSH_ARGS_3()   \
202     do {                     \
203         *(--newSp) = sp[a2]; \
204         CALL_PUSH_ARGS_2();  \
205     } while (false)
206 
207 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
208 #define CALL_PUSH_ARGS_I()                        \
209     do {                                          \
210         for (int i = actualNumArgs; i > 0; i--) { \
211             *(--newSp) = sp[funcReg + i];         \
212         }                                         \
213     } while (false)
214 
215 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
216 #define CALL_PUSH_ARGS_I_THIS()                       \
217     do {                                              \
218         /* 1: skip this */                            \
219         for (int i = actualNumArgs + 1; i > 1; i--) { \
220             *(--newSp) = sp[funcReg + i];             \
221         }                                             \
222     } while (false)
223 
224 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
225 #define CALL_PUSH_ARGS_0_NO_EXTRA() \
226     do {                            \
227         /* do nothing when 0 arg */ \
228     } while (false)
229 
230 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
231 #define CALL_PUSH_ARGS_1_NO_EXTRA()                             \
232     do {                                                        \
233         if (declaredNumArgs >= ActualNumArgsOfCall::CALLARG1) { \
234             *(--newSp) = sp[a0];                                \
235         }                                                       \
236     } while (false)
237 
238 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
239 #define CALL_PUSH_ARGS_2_NO_EXTRA()                              \
240     do {                                                         \
241         if (declaredNumArgs >= ActualNumArgsOfCall::CALLARGS2) { \
242             *(--newSp) = sp[a1];                                 \
243         }                                                        \
244         CALL_PUSH_ARGS_1_NO_EXTRA();                             \
245     } while (false)
246 
247 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
248 #define CALL_PUSH_ARGS_3_NO_EXTRA()                              \
249     do {                                                         \
250         if (declaredNumArgs >= ActualNumArgsOfCall::CALLARGS3) { \
251             *(--newSp) = sp[a2];                                 \
252         }                                                        \
253         CALL_PUSH_ARGS_2_NO_EXTRA();                             \
254     } while (false)
255 
256 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
257 #define CALL_PUSH_ARGS_I_NO_EXTRA()                                          \
258     do {                                                                     \
259         for (int i = std::min(actualNumArgs, declaredNumArgs); i > 0; i--) { \
260             *(--newSp) = sp[funcReg + i];                                    \
261         }                                                                    \
262     } while (false)
263 
264 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
265 #define CALL_PUSH_ARGS_I_THIS_NO_EXTRA()                                         \
266     do {                                                                         \
267         /* 1: skip this */                                                       \
268         for (int i = std::min(actualNumArgs, declaredNumArgs) + 1; i > 1; i--) { \
269             *(--newSp) = sp[funcReg + i];                                        \
270         }                                                                        \
271     } while (false)
272 
273 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
274 #define CALL_PUSH_ARGS(ARG_TYPE)                                                   \
275     do {                                                                           \
276         if (method->IsNativeWithCallField()) {                                     \
277             /* native, just push all args directly */                              \
278             CALL_PUSH_ARGS_##ARG_TYPE();                                           \
279             goto setVregsAndFrameNative;                                           \
280         }                                                                          \
281         int32_t declaredNumArgs = static_cast<int32_t>(                            \
282             method->GetNumArgsWithCallField());                                    \
283         if (actualNumArgs == declaredNumArgs) {                                    \
284             /* fast path, just push all args directly */                           \
285             CALL_PUSH_ARGS_##ARG_TYPE();                                           \
286             goto setVregsAndFrameNotNative;                                        \
287         }                                                                          \
288         /* slow path */                                                            \
289         if (!method->HaveExtraWithCallField()) {                                 \
290             /* push length = declaredNumArgs, may push undefined */                \
291             CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs);                  \
292             CALL_PUSH_ARGS_##ARG_TYPE##_NO_EXTRA();                                \
293         } else {                                                                   \
294             /* push actualNumArgs in the end, then all args, may push undefined */ \
295             *(--newSp) = JSTaggedValue(actualNumArgs).GetRawData();                \
296             CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs);                  \
297             CALL_PUSH_ARGS_##ARG_TYPE();                                           \
298         }                                                                          \
299         goto setVregsAndFrameNotNative;                                            \
300     } while (false)
301 
302 #if ECMASCRIPT_ENABLE_IC
303 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
304 #define UPDATE_HOTNESS_COUNTER_NON_ACC(offset)   (UpdateHotnessCounter(thread, sp, acc, offset))
305 
306 #define UPDATE_HOTNESS_COUNTER(offset)                       \
307     do {                                                     \
308         if (UpdateHotnessCounter(thread, sp, acc, offset)) { \
309             RESTORE_ACC();                                   \
310         }                                                    \
311     } while (false)
312 #else
313 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
314 #define UPDATE_HOTNESS_COUNTER(offset) static_cast<void>(0)
315 #define UPDATE_HOTNESS_COUNTER_NON_ACC(offset) static_cast<void>(0)
316 #endif
317 
318 #define READ_INST_OP() READ_INST_8(0)               // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
319 #define READ_INST_4_0() (READ_INST_8(1) & 0xf)      // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
320 #define READ_INST_4_1() (READ_INST_8(1) >> 4 & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
321 #define READ_INST_4_2() (READ_INST_8(2) & 0xf)      // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
322 #define READ_INST_4_3() (READ_INST_8(2) >> 4 & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
323 #define READ_INST_8_0() READ_INST_8(1)              // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
324 #define READ_INST_8_1() READ_INST_8(2)              // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
325 #define READ_INST_8_2() READ_INST_8(3)              // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
326 #define READ_INST_8_3() READ_INST_8(4)              // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
327 #define READ_INST_8_4() READ_INST_8(5)              // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
328 #define READ_INST_8_5() READ_INST_8(6)              // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
329 #define READ_INST_8_6() READ_INST_8(7)              // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
330 #define READ_INST_8_7() READ_INST_8(8)              // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
331 #define READ_INST_8_8() READ_INST_8(9)              // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage)
332 #define READ_INST_8(offset) (*(pc + (offset)))
333 #define MOVE_AND_READ_INST_8(currentInst, offset) \
334     currentInst <<= 8;                            \
335     currentInst += READ_INST_8(offset);           \
336 
337 #define READ_INST_16_0() READ_INST_16(2)
338 #define READ_INST_16_1() READ_INST_16(3)
339 #define READ_INST_16_2() READ_INST_16(4)
340 #define READ_INST_16_3() READ_INST_16(5)
341 #define READ_INST_16_5() READ_INST_16(7)
342 #define READ_INST_16(offset)                          \
343     ({                                                \
344         uint16_t currentInst = READ_INST_8(offset);   \
345         MOVE_AND_READ_INST_8(currentInst, offset - 1) \
346     })
347 
348 #define READ_INST_32_0() READ_INST_32(4)
349 #define READ_INST_32_1() READ_INST_32(5)
350 #define READ_INST_32_2() READ_INST_32(6)
351 #define READ_INST_32(offset)                          \
352     ({                                                \
353         uint32_t currentInst = READ_INST_8(offset);   \
354         MOVE_AND_READ_INST_8(currentInst, offset - 1) \
355         MOVE_AND_READ_INST_8(currentInst, offset - 2) \
356         MOVE_AND_READ_INST_8(currentInst, offset - 3) \
357     })
358 
359 #define READ_INST_64_0()                       \
360     ({                                         \
361         uint64_t currentInst = READ_INST_8(8); \
362         MOVE_AND_READ_INST_8(currentInst, 7)   \
363         MOVE_AND_READ_INST_8(currentInst, 6)   \
364         MOVE_AND_READ_INST_8(currentInst, 5)   \
365         MOVE_AND_READ_INST_8(currentInst, 4)   \
366         MOVE_AND_READ_INST_8(currentInst, 3)   \
367         MOVE_AND_READ_INST_8(currentInst, 2)   \
368         MOVE_AND_READ_INST_8(currentInst, 1)   \
369     })
370 
371 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
372 #define GET_VREG(idx) (sp[idx])  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
373 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
374 #define GET_VREG_VALUE(idx) (JSTaggedValue(sp[idx]))  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
375 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
376 #define SET_VREG(idx, val) (sp[idx] = (val));  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
377 #define GET_ACC() (acc)                        // NOLINT(cppcoreguidelines-macro-usage)
378 #define SET_ACC(val) (acc = val);              // NOLINT(cppcoreguidelines-macro-usage)
379 
ExecuteNative(JSThread * thread,const CallParams & params)380 JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& params)
381 {
382     INTERPRETER_TRACE(thread, ExecuteNative);
383     JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
384 
385     JSMethod *method = params.callTarget->GetCallTarget();
386     ASSERT(method->GetNumVregsWithCallField() == 0);
387     uint32_t numActualArgs = params.argc + RESERVED_CALL_ARGCOUNT;
388     // Tags and values of thread, new_tgt and argv_length are put into frames too for native frames
389     // NOLINTNEXTLINE(hicpp-signed-bitwise)
390     size_t frameSize = FRAME_STATE_SIZE + numActualArgs;
391     JSTaggedType *newSp = sp - frameSize;  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
392     if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) {
393         return JSTaggedValue::Undefined();
394     }
395 
396     EcmaRuntimeCallInfo ecmaRuntimeCallInfo(thread, numActualArgs, reinterpret_cast<JSTaggedValue *>(newSp));
397     newSp[RESERVED_INDEX_CALL_TARGET] = reinterpret_cast<JSTaggedType>(params.callTarget);
398     newSp[RESERVED_INDEX_NEW_TARGET] = params.newTarget;
399     newSp[RESERVED_INDEX_THIS] = params.thisArg;
400     for (size_t i = 0; i < params.argc; i++) {
401         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
402         newSp[i + RESERVED_CALL_ARGCOUNT] = params.argv[i];
403     }
404 
405     InterpretedFrame *state = GET_FRAME(newSp);
406     state->base.prev = sp;
407     state->base.type = FrameType::INTERPRETER_FRAME;
408     state->pc = nullptr;
409     state->sp = newSp;
410     state->function = JSTaggedValue(params.callTarget);
411     thread->SetCurrentSPFrame(newSp);
412 #if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER
413     CpuProfiler::IsNeedAndGetStack(thread);
414 #endif
415     thread->CheckSafepoint();
416     LOG(DEBUG, INTERPRETER) << "Entry: Runtime Call.";
417     JSTaggedValue tagged =
418         reinterpret_cast<EcmaEntrypoint>(const_cast<void *>(method->GetNativePointer()))(&ecmaRuntimeCallInfo);
419     LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call.";
420     thread->SetCurrentSPFrame(sp);
421 #if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER
422     CpuProfiler::IsNeedAndGetStack(thread);
423 #endif
424     return tagged;
425 }
426 
GetCurrentFrameState(JSTaggedType * sp)427 JSTaggedType* EcmaInterpreter::GetCurrentFrameState(JSTaggedType *sp)
428 {
429     return sp - FRAME_STATE_SIZE;
430 }
431 
Execute(JSThread * thread,const CallParams & params)432 JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& params)
433 {
434     INTERPRETER_TRACE(thread, Execute);
435     JSMethod *method = params.callTarget->GetCallTarget();
436     if (method->IsNativeWithCallField()) {
437         return EcmaInterpreter::ExecuteNative(thread, params);
438     }
439     JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
440     JSTaggedType *newSp = GetCurrentFrameState(sp);
441     // push break state
442     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
443     if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) {
444         return JSTaggedValue::Undefined();
445     }
446     InterpretedFrame *breakState = GET_FRAME(newSp);
447     breakState->pc = nullptr;
448     breakState->sp = nullptr;
449     breakState->function = JSTaggedValue::Hole();
450     breakState->base.prev = sp;
451     breakState->base.type = FrameType::INTERPRETER_FRAME;
452     JSTaggedType *prevSp = newSp;
453 
454     int32_t actualNumArgs = static_cast<int32_t>(params.argc);
455     int32_t declaredNumArgs = static_cast<int32_t>(method->GetNumArgsWithCallField());
456     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
457     newSp -= FRAME_STATE_SIZE;
458     // push args
459     if (actualNumArgs == declaredNumArgs) {
460         // fast path, just push all args directly
461         for (int i = actualNumArgs - 1; i >= 0; i--) {
462             // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
463             *(--newSp) = params.argv[i];
464         }
465     } else {
466         // slow path
467         if (!method->HaveExtraWithCallField()) {
468             // push length = declaredNumArgs, may push undefined
469             CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs);
470             for (int i = std::min(actualNumArgs, declaredNumArgs) - 1; i >= 0; i--) {
471                 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
472                 *(--newSp) = params.argv[i];
473             }
474         } else {
475             // push actualNumArgs in the end, then all args, may push undefined
476             // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
477             *(--newSp) = JSTaggedValue(actualNumArgs).GetRawData();
478             CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs);
479             for (int i = actualNumArgs - 1; i >= 0; i--) {
480                 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
481                 *(--newSp) = params.argv[i];
482             }
483         }
484     }
485     uint64_t callField = method->GetCallField();
486     if ((callField & CALL_TYPE_MASK) != 0) {
487         // not normal call type, setting func/newTarget/this cannot be skipped
488         if (method->HaveThisWithCallField()) {
489             // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
490             *(--newSp) = params.thisArg;  // push this
491         }
492         if (method->HaveNewTargetWithCallField()) {
493             // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
494             *(--newSp) = params.newTarget;  // push new target
495         }
496         if (method->HaveFuncWithCallField()) {
497             // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
498             *(--newSp) = reinterpret_cast<JSTaggedType>(params.callTarget);  // push func
499         }
500     }
501     int32_t numVregs = static_cast<int32_t>(method->GetNumVregsWithCallField());
502     // push vregs
503     CALL_PUSH_UNDEFINED(numVregs);
504     if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
505         return JSTaggedValue::Undefined();
506     }
507 
508     const uint8_t *pc = method->GetBytecodeArray();
509     InterpretedFrame *state = GET_FRAME(newSp);
510     state->pc = pc;
511     state->sp = newSp;
512     state->function = JSTaggedValue(params.callTarget);
513     state->acc = JSTaggedValue::Hole();
514     JSHandle<JSTaggedValue> callTargetHandle(thread, params.callTarget);
515     JSHandle<JSFunction> thisFunc = JSHandle<JSFunction>::Cast(callTargetHandle);
516     JSTaggedValue constpool = thisFunc->GetConstantPool();
517     state->constpool = constpool;
518     state->profileTypeInfo = thisFunc->GetProfileTypeInfo();
519     state->base.prev = prevSp;
520     state->base.type = FrameType::INTERPRETER_FRAME;
521 
522     JSTaggedValue env = thisFunc->GetLexicalEnv();
523     state->env = env;
524     thread->SetCurrentSPFrame(newSp);
525 #if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER
526     CpuProfiler::IsNeedAndGetStack(thread);
527 #endif
528     thread->CheckSafepoint();
529     LOG(DEBUG, INTERPRETER) << "break Entry: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(newSp) << " "
530                             << std::hex << reinterpret_cast<uintptr_t>(pc);
531 
532 #if ECMASCRIPT_ENABLE_INTERPRETER_ASM
533     InterpreterAssembly::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), pc, newSp);
534 #else
535     EcmaInterpreter::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), pc, newSp);
536 #endif
537 
538     // NOLINTNEXTLINE(readability-identifier-naming)
539     const JSTaggedValue resAcc = state->acc;
540     // pop frame
541     thread->SetCurrentSPFrame(sp);
542 #if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER
543     CpuProfiler::IsNeedAndGetStack(thread);
544 #endif
545     return resAcc;
546 }
547 
GeneratorReEnterInterpreter(JSThread * thread,JSHandle<GeneratorContext> context)548 JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSHandle<GeneratorContext> context)
549 {
550     [[maybe_unused]] EcmaHandleScope handleScope(thread);
551     JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(JSHandle<JSTaggedValue>(thread, context->GetMethod()));
552     JSMethod *method = func->GetCallTarget();
553 
554     JSTaggedType *currentSp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
555 
556     // push break frame
557     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
558     JSTaggedType *breakSp = currentSp - FRAME_STATE_SIZE;
559     if (thread->DoStackOverflowCheck(breakSp) || thread->HasPendingException()) {
560         return JSTaggedValue::Exception();
561     }
562     InterpretedFrame *breakState = GET_FRAME(breakSp);
563     breakState->pc = nullptr;
564     breakState->sp = nullptr;
565     breakState->function = JSTaggedValue::Hole();
566     breakState->base.prev = currentSp;
567     breakState->base.type = FrameType::INTERPRETER_FRAME;
568 
569     // create new frame and resume sp and pc
570     uint32_t nregs = context->GetNRegs();
571     size_t newFrameSize = FRAME_STATE_SIZE + nregs;
572     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic
573     JSTaggedType *newSp = breakSp - newFrameSize;
574     if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) {
575         return JSTaggedValue::Exception();
576     }
577     JSHandle<TaggedArray> regsArray(thread, context->GetRegsArray());
578     for (size_t i = 0; i < nregs; i++) {
579         newSp[i] = regsArray->Get(i).GetRawData();  // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
580     }
581     JSTaggedValue constpool = func->GetConstantPool();
582     uint32_t pcOffset = context->GetBCOffset();
583     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
584     const uint8_t *resumePc = method->GetBytecodeArray() + pcOffset +
585                               BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8);
586 
587     InterpretedFrame *state = GET_FRAME(newSp);
588     state->pc = resumePc;
589     state->sp = newSp;
590     state->function = func.GetTaggedValue();
591     state->constpool = constpool;
592     state->profileTypeInfo = func->GetProfileTypeInfo();
593     state->acc = context->GetAcc();
594     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
595     state->base.prev = breakSp;
596     state->base.type = FrameType::INTERPRETER_FRAME;
597     JSTaggedValue env = context->GetLexicalEnv();
598     state->env = env;
599     // execute interpreter
600     thread->SetCurrentSPFrame(newSp);
601 
602 #if ECMASCRIPT_ENABLE_INTERPRETER_ASM
603     InterpreterAssembly::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), resumePc, newSp);
604 #else
605     EcmaInterpreter::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), resumePc, newSp);
606 #endif
607 
608     JSTaggedValue res = state->acc;
609     // pop frame
610     thread->SetCurrentSPFrame(currentSp);
611     return res;
612 }
613 
ChangeGenContext(JSThread * thread,JSHandle<GeneratorContext> context)614 void EcmaInterpreter::ChangeGenContext(JSThread *thread, JSHandle<GeneratorContext> context)
615 {
616     [[maybe_unused]] EcmaHandleScope handleScope(thread);
617     JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(JSHandle<JSTaggedValue>(thread, context->GetMethod()));
618     JSMethod *method = func->GetCallTarget();
619 
620     JSTaggedType *currentSp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
621 
622     // push break frame
623     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
624     JSTaggedType *breakSp = currentSp - FRAME_STATE_SIZE;
625     if (thread->DoStackOverflowCheck(breakSp) || thread->HasPendingException()) {
626         return;
627     }
628     InterpretedFrame *breakState = GET_FRAME(breakSp);
629     breakState->pc = nullptr;
630     breakState->sp = nullptr;
631     breakState->function = JSTaggedValue::Hole();
632     breakState->base.prev = currentSp;
633     breakState->base.type = FrameType::INTERPRETER_FRAME;
634 
635     // create new frame and resume sp and pc
636     uint32_t nregs = context->GetNRegs();
637     size_t newFrameSize = FRAME_STATE_SIZE + nregs;
638 
639     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic
640     JSTaggedType *newSp = breakSp - newFrameSize;
641     if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) {
642         return;
643     }
644     JSHandle<TaggedArray> regsArray(thread, context->GetRegsArray());
645     for (size_t i = 0; i < nregs; i++) {
646         newSp[i] = regsArray->Get(i).GetRawData();  // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
647     }
648     JSTaggedValue constpool = func->GetConstantPool();
649     uint32_t pcOffset = context->GetBCOffset();
650     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
651     const uint8_t *pc = method->GetBytecodeArray() + pcOffset;
652 
653     InterpretedFrame *state = GET_FRAME(newSp);
654     state->pc = pc;
655     state->sp = newSp;
656     state->function = func.GetTaggedValue();
657     state->constpool = constpool;
658     state->profileTypeInfo = func->GetProfileTypeInfo();
659     state->acc = context->GetAcc();
660     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
661     state->base.prev = breakSp;
662     state->base.type = FrameType::INTERPRETER_FRAME;
663     state->env = context->GetLexicalEnv();
664 
665     thread->SetCurrentSPFrame(newSp);
666 }
667 
ResumeContext(JSThread * thread)668 void EcmaInterpreter::ResumeContext(JSThread *thread)
669 {
670     JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
671     InterpretedFrame *state = GET_FRAME(sp);
672     thread->SetCurrentSPFrame(state->base.prev);
673 }
674 
NotifyBytecodePcChanged(JSThread * thread)675 void EcmaInterpreter::NotifyBytecodePcChanged(JSThread *thread)
676 {
677     InterpretedFrameHandler frameHandler(thread);
678     for (; frameHandler.HasFrame(); frameHandler.PrevInterpretedFrame()) {
679         if (frameHandler.IsBreakFrame()) {
680             continue;
681         }
682         JSMethod *method = frameHandler.GetMethod();
683         // Skip builtins method
684         if (method->IsNative()) {
685             continue;
686         }
687         auto bcOffset = frameHandler.GetBytecodeOffset();
688         auto *debuggerMgr = thread->GetEcmaVM()->GetJsDebuggerManager();
689         debuggerMgr->GetNotificationManager()->BytecodePcChangedEvent(thread, method, bcOffset);
690         return;
691     }
692 }
693 
694 // NOLINTNEXTLINE(readability-function-size)
RunInternal(JSThread * thread,ConstantPool * constpool,const uint8_t * pc,JSTaggedType * sp)695 NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool *constpool, const uint8_t *pc,
696                                                  JSTaggedType *sp)
697 {
698     INTERPRETER_TRACE(thread, RunInternal);
699     uint8_t opcode = READ_INST_OP();
700     JSTaggedValue acc = JSTaggedValue::Hole();
701     EcmaVM *ecmaVm = thread->GetEcmaVM();
702     JSHandle<GlobalEnv> globalEnv = ecmaVm->GetGlobalEnv();
703     JSTaggedValue globalObj = globalEnv->GetGlobalObject();
704     ObjectFactory *factory = ecmaVm->GetFactory();
705 
706     constexpr size_t numOps = 0x100;
707     static std::array<const void *, numOps> instDispatchTable{
708 #include "templates/instruction_dispatch.inl"
709     };
710 
711     static std::array<const void *, numOps> debugDispatchTable{
712 #include "templates/debugger_instruction_dispatch.inl"
713     };
714 
715     std::array<const void *, numOps> dispatchTable = instDispatchTable;
716     CHECK_SWITCH_TO_DEBUGGER_TABLE();
717     goto *dispatchTable[opcode];
718 
719     HANDLE_OPCODE(HANDLE_MOV_V4_V4) {
720         uint16_t vdst = READ_INST_4_0();
721         uint16_t vsrc = READ_INST_4_1();
722         LOG_INST() << "mov v" << vdst << ", v" << vsrc;
723         uint64_t value = GET_VREG(vsrc);
724         SET_VREG(vdst, value)
725         DISPATCH(BytecodeInstruction::Format::V4_V4);
726     }
727 
728     HANDLE_OPCODE(HANDLE_MOV_DYN_V8_V8) {
729         uint16_t vdst = READ_INST_8_0();
730         uint16_t vsrc = READ_INST_8_1();
731         LOG_INST() << "mov.dyn v" << vdst << ", v" << vsrc;
732         uint64_t value = GET_VREG(vsrc);
733         SET_VREG(vdst, value)
734         DISPATCH(BytecodeInstruction::Format::V8_V8);
735     }
736     HANDLE_OPCODE(HANDLE_MOV_DYN_V16_V16) {
737         uint16_t vdst = READ_INST_16_0();
738         uint16_t vsrc = READ_INST_16_2();
739         LOG_INST() << "mov.dyn v" << vdst << ", v" << vsrc;
740         uint64_t value = GET_VREG(vsrc);
741         SET_VREG(vdst, value)
742         DISPATCH(BytecodeInstruction::Format::V16_V16);
743     }
744     HANDLE_OPCODE(HANDLE_LDA_STR_ID32) {
745         uint32_t stringId = READ_INST_32_0();
746         LOG_INST() << "lda.str " << std::hex << stringId;
747         SET_ACC(constpool->GetObjectFromCache(stringId));
748         DISPATCH(BytecodeInstruction::Format::ID32);
749     }
750     HANDLE_OPCODE(HANDLE_JMP_IMM8) {
751         int8_t offset = READ_INST_8_0();
752         UPDATE_HOTNESS_COUNTER(offset);
753         LOG_INST() << "jmp " << std::hex << static_cast<int32_t>(offset);
754         DISPATCH_OFFSET(offset);
755     }
756     HANDLE_OPCODE(HANDLE_JMP_IMM16) {
757         int16_t offset = READ_INST_16_0();
758         UPDATE_HOTNESS_COUNTER(offset);
759         LOG_INST() << "jmp " << std::hex << static_cast<int32_t>(offset);
760         DISPATCH_OFFSET(offset);
761     }
762     HANDLE_OPCODE(HANDLE_JMP_IMM32) {
763         int32_t offset = READ_INST_32_0();
764         UPDATE_HOTNESS_COUNTER(offset);
765         LOG_INST() << "jmp " << std::hex << offset;
766         DISPATCH_OFFSET(offset);
767     }
768     HANDLE_OPCODE(HANDLE_JEQZ_IMM8) {
769         int8_t offset = READ_INST_8_0();
770         LOG_INST() << "jeqz ->\t"
771                    << "cond jmpz " << std::hex << static_cast<int32_t>(offset);
772         if (GET_ACC() == JSTaggedValue::False() || (GET_ACC().IsInt() && GET_ACC().GetInt() == 0) ||
773             (GET_ACC().IsDouble() && GET_ACC().GetDouble() == 0)) {
774             UPDATE_HOTNESS_COUNTER(offset);
775             DISPATCH_OFFSET(offset);
776         } else {
777             DISPATCH(BytecodeInstruction::Format::PREF_NONE);
778         }
779     }
780     HANDLE_OPCODE(HANDLE_JEQZ_IMM16) {
781         int16_t offset = READ_INST_16_0();
782         LOG_INST() << "jeqz ->\t"
783                    << "cond jmpz " << std::hex << static_cast<int32_t>(offset);
784         if (GET_ACC() == JSTaggedValue::False() || (GET_ACC().IsInt() && GET_ACC().GetInt() == 0) ||
785             (GET_ACC().IsDouble() && GET_ACC().GetDouble() == 0)) {
786             UPDATE_HOTNESS_COUNTER(offset);
787             DISPATCH_OFFSET(offset);
788         } else {
789             DISPATCH(BytecodeInstruction::Format::IMM16);
790         }
791     }
792     HANDLE_OPCODE(HANDLE_JNEZ_IMM8) {
793         int8_t offset = READ_INST_8_0();
794         LOG_INST() << "jnez ->\t"
795                    << "cond jmpz " << std::hex << static_cast<int32_t>(offset);
796         if (GET_ACC() == JSTaggedValue::True() || (GET_ACC().IsInt() && GET_ACC().GetInt() != 0) ||
797             (GET_ACC().IsDouble() && GET_ACC().GetDouble() != 0)) {
798             UPDATE_HOTNESS_COUNTER(offset);
799             DISPATCH_OFFSET(offset);
800         } else {
801             DISPATCH(BytecodeInstruction::Format::PREF_NONE);
802         }
803     }
804     HANDLE_OPCODE(HANDLE_JNEZ_IMM16) {
805         int16_t offset = READ_INST_16_0();
806         LOG_INST() << "jnez ->\t"
807                    << "cond jmpz " << std::hex << static_cast<int32_t>(offset);
808         if (GET_ACC() == JSTaggedValue::True() || (GET_ACC().IsInt() && GET_ACC().GetInt() != 0) ||
809             (GET_ACC().IsDouble() && GET_ACC().GetDouble() != 0)) {
810             UPDATE_HOTNESS_COUNTER(offset);
811             DISPATCH_OFFSET(offset);
812         } else {
813             DISPATCH(BytecodeInstruction::Format::IMM16);
814         }
815     }
816     HANDLE_OPCODE(HANDLE_LDA_DYN_V8) {
817         uint16_t vsrc = READ_INST_8_0();
818         LOG_INST() << "lda.dyn v" << vsrc;
819         uint64_t value = GET_VREG(vsrc);
820         SET_ACC(JSTaggedValue(value))
821         DISPATCH(BytecodeInstruction::Format::V8);
822     }
823     HANDLE_OPCODE(HANDLE_STA_DYN_V8) {
824         uint16_t vdst = READ_INST_8_0();
825         LOG_INST() << "sta.dyn v" << vdst;
826         SET_VREG(vdst, GET_ACC().GetRawData())
827         DISPATCH(BytecodeInstruction::Format::V8);
828     }
829     HANDLE_OPCODE(HANDLE_LDAI_DYN_IMM32) {
830         int32_t imm = READ_INST_32_0();
831         LOG_INST() << "ldai.dyn " << std::hex << imm;
832         SET_ACC(JSTaggedValue(imm))
833         DISPATCH(BytecodeInstruction::Format::IMM32);
834     }
835 
836     HANDLE_OPCODE(HANDLE_FLDAI_DYN_IMM64) {
837         auto imm = bit_cast<double>(READ_INST_64_0());
838         LOG_INST() << "fldai.dyn " << imm;
839         SET_ACC(JSTaggedValue(imm))
840         DISPATCH(BytecodeInstruction::Format::IMM64);
841     }
842     {
843         int32_t actualNumArgs;
844         uint32_t funcReg;
845         JSTaggedType funcTagged;
846         ECMAObject *funcObject;
847         JSMethod *method;
848         JSTaggedType *newSp;
849         bool callThis;
850 
851         HANDLE_OPCODE(HANDLE_CALLARG0DYN_PREF_V8) {
852             actualNumArgs = ActualNumArgsOfCall::CALLARG0;
853             funcReg = READ_INST_8_1();
854             LOG_INST() << "callarg0.dyn "
855                        << "v" << funcReg;
856             CALL_INITIALIZE();
857             callThis = false;
858             CALL_PUSH_ARGS(0);
859         }
860         HANDLE_OPCODE(HANDLE_CALLARG1DYN_PREF_V8_V8) {
861             actualNumArgs = ActualNumArgsOfCall::CALLARG1;
862             funcReg = READ_INST_8_1();
863             uint8_t a0 = READ_INST_8_2();
864             LOG_INST() << "callarg1.dyn "
865                        << "v" << funcReg << ", v" << a0;
866             CALL_INITIALIZE();
867             callThis = false;
868             CALL_PUSH_ARGS(1);
869         }
870         HANDLE_OPCODE(HANDLE_CALLARGS2DYN_PREF_V8_V8_V8) {
871             actualNumArgs = ActualNumArgsOfCall::CALLARGS2;
872             funcReg = READ_INST_8_1();
873             uint8_t a0 = READ_INST_8_2();
874             uint8_t a1 = READ_INST_8_3();
875             LOG_INST() << "callargs2.dyn "
876                        << "v" << funcReg << ", v" << a0 << ", v" << a1;
877             CALL_INITIALIZE();
878             callThis = false;
879             CALL_PUSH_ARGS(2);
880         }
881         HANDLE_OPCODE(HANDLE_CALLARGS3DYN_PREF_V8_V8_V8_V8) {
882             actualNumArgs = ActualNumArgsOfCall::CALLARGS3;
883             funcReg = READ_INST_8_1();
884             uint8_t a0 = READ_INST_8_2();
885             uint8_t a1 = READ_INST_8_3();
886             uint8_t a2 = READ_INST_8_4();
887             LOG_INST() << "callargs3.dyn "
888                        << "v" << funcReg << ", v" << a0 << ", v" << a1 << ", v" << a2;
889             CALL_INITIALIZE();
890             callThis = false;
891             CALL_PUSH_ARGS(3);
892         }
893         HANDLE_OPCODE(HANDLE_CALLITHISRANGEDYN_PREF_IMM16_V8) {
894             actualNumArgs = READ_INST_16_1() - 1;  // 1: exclude this
895             funcReg = READ_INST_8_3();
896             LOG_INST() << "calli.dyn.this.range " << actualNumArgs << ", v" << funcReg;
897             CALL_INITIALIZE();
898             callThis = true;
899             CALL_PUSH_ARGS(I_THIS);
900         }
901         HANDLE_OPCODE(HANDLE_CALLSPREADDYN_PREF_V8_V8_V8) {
902             uint16_t v0 = READ_INST_8_1();
903             uint16_t v1 = READ_INST_8_2();
904             uint16_t v2 = READ_INST_8_3();
905             LOG_INST() << "intrinsics::callspreaddyn"
906                        << " v" << v0 << " v" << v1 << " v" << v2;
907             JSTaggedValue func = GET_VREG_VALUE(v0);
908             JSTaggedValue obj = GET_VREG_VALUE(v1);
909             JSTaggedValue array = GET_VREG_VALUE(v2);
910 
911             SAVE_PC();
912             JSTaggedValue res = SlowRuntimeStub::CallSpreadDyn(thread, func, obj, array);
913             INTERPRETER_RETURN_IF_ABRUPT(res);
914             SET_ACC(res);
915 
916             DISPATCH(BytecodeInstruction::Format::PREF_V8_V8_V8);
917         }
918         HANDLE_OPCODE(HANDLE_CALLIRANGEDYN_PREF_IMM16_V8) {
919             actualNumArgs = READ_INST_16_1();
920             funcReg = READ_INST_8_3();
921             LOG_INST() << "calli.rangedyn " << actualNumArgs << ", v" << funcReg;
922             CALL_INITIALIZE();
923             callThis = false;
924             CALL_PUSH_ARGS(I);
925         }
926         setVregsAndFrameNative: {
927             // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
928             *(--newSp) = (callThis ? sp[funcReg + callThis] : JSTaggedValue::VALUE_UNDEFINED);  // push this
929             *(--newSp) = JSTaggedValue::VALUE_UNDEFINED;  // push new target
930             *(--newSp) = static_cast<JSTaggedType>(ToUintPtr(funcObject));  // push func
931             ASSERT(method->GetNumVregsWithCallField() == 0);  // no need to push vregs
932             if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
933                 INTERPRETER_GOTO_EXCEPTION_HANDLER();
934             }
935             EcmaRuntimeCallInfo ecmaRuntimeCallInfo(thread, actualNumArgs + NUM_MANDATORY_JSFUNC_ARGS,
936                                                     reinterpret_cast<JSTaggedValue *>(newSp));
937 
938             InterpretedFrame *state = GET_FRAME(newSp);
939             state->base.prev = sp;
940             state->base.type = FrameType::INTERPRETER_FRAME;
941             state->pc = nullptr;
942             state->sp = newSp;
943             state->function = JSTaggedValue(funcTagged);
944             thread->SetCurrentSPFrame(newSp);
945             LOG(DEBUG, INTERPRETER) << "Entry: Runtime Call.";
946             JSTaggedValue retValue = reinterpret_cast<EcmaEntrypoint>(
947                 const_cast<void *>(method->GetNativePointer()))(&ecmaRuntimeCallInfo);
948 
949             thread->SetCurrentSPFrame(sp);
950             if (UNLIKELY(thread->HasPendingException())) {
951                 INTERPRETER_GOTO_EXCEPTION_HANDLER();
952             }
953             LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call.";
954             SET_ACC(retValue);
955             INTERPRETER_HANDLE_RETURN();
956         }
957         setVregsAndFrameNotNative: {
958             if (JSFunction::Cast(funcObject)->IsClassConstructor()) {
959                 {
960                     [[maybe_unused]] EcmaHandleScope handleScope(thread);
961                     JSHandle<JSObject> error =
962                         factory->GetJSError(ErrorType::TYPE_ERROR, "class constructor cannot called without 'new'");
963                     thread->SetException(error.GetTaggedValue());
964                 }
965                 INTERPRETER_GOTO_EXCEPTION_HANDLER();
966             }
967             uint64_t callField = method->GetCallField();
968             if ((callField & CALL_TYPE_MASK) != 0) {
969                 // not normal call type, setting func/newTarget/this cannot be skipped
970                 if (method->HaveThisWithCallField()) {
971                     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
972                     *(--newSp) = (callThis ? sp[funcReg + callThis] : JSTaggedValue::VALUE_UNDEFINED);  // push this
973                 }
974                 if (method->HaveNewTargetWithCallField()) {
975                     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
976                     *(--newSp) = JSTaggedValue::VALUE_UNDEFINED;  // push new target
977                 }
978                 if (method->HaveFuncWithCallField()) {
979                     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
980                     *(--newSp) = static_cast<JSTaggedType>(ToUintPtr(funcObject));  // push func
981                 }
982             }
983             int32_t numVregs = static_cast<int32_t>(method->GetNumVregsWithCallField());
984             // push vregs
985             CALL_PUSH_UNDEFINED(numVregs);
986             SAVE_PC();
987             if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
988                 INTERPRETER_GOTO_EXCEPTION_HANDLER();
989             }
990 
991             InterpretedFrame *state = GET_FRAME(newSp);
992             state->base.prev = sp;
993             state->base.type = FrameType::INTERPRETER_FRAME;
994             state->pc = pc = JSMethod::Cast(method)->GetBytecodeArray();
995             state->sp = sp = newSp;
996             state->function = JSTaggedValue(funcTagged);
997             state->acc = JSTaggedValue::Hole();
998             state->constpool = JSFunction::Cast(funcObject)->GetConstantPool();
999             constpool = ConstantPool::Cast(state->constpool.GetTaggedObject());
1000             state->profileTypeInfo = JSFunction::Cast(funcObject)->GetProfileTypeInfo();
1001             JSTaggedValue env = JSFunction::Cast(funcObject)->GetLexicalEnv();
1002             state->env = env;
1003             thread->SetCurrentSPFrame(newSp);
1004             LOG(DEBUG, INTERPRETER) << "Entry: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
1005                                     << std::hex << reinterpret_cast<uintptr_t>(pc);
1006             DISPATCH_OFFSET(0);
1007         }
1008     }
1009     HANDLE_OPCODE(HANDLE_RETURN_DYN) {
1010         LOG_INST() << "returnla ";
1011         InterpretedFrame *state = GET_FRAME(sp);
1012         LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(state->sp) << " "
1013                                 << std::hex << reinterpret_cast<uintptr_t>(state->pc);
1014         JSMethod *method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
1015         [[maybe_unused]] auto fistPC = method->GetInstructions();
1016         UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
1017         JSTaggedType *currentSp = sp;
1018         sp = state->base.prev;
1019         ASSERT(sp != nullptr);
1020         InterpretedFrame *prevState = GET_FRAME(sp);
1021         pc = prevState->pc;
1022 
1023         // break frame
1024         if (pc == nullptr) {
1025             state->acc = acc;
1026             return;
1027         }
1028         thread->SetCurrentSPFrame(sp);
1029 
1030         constpool = ConstantPool::Cast(prevState->constpool.GetTaggedObject());
1031 
1032         if (IsFastNewFrameExit(currentSp)) {
1033             JSFunction *func = JSFunction::Cast(GetThisFunction(currentSp).GetTaggedObject());
1034             if (acc.IsECMAObject()) {
1035                 INTERPRETER_HANDLE_RETURN();
1036             }
1037 
1038             if (func->IsBase()) {
1039                 JSTaggedValue thisObject = GetThisObjectFromFastNewFrame(currentSp);
1040                 SET_ACC(thisObject);
1041                 INTERPRETER_HANDLE_RETURN();
1042             }
1043 
1044             if (!acc.IsUndefined()) {
1045                 {
1046                     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1047                     JSHandle<JSObject> error = factory->GetJSError(ErrorType::TYPE_ERROR,
1048                         "Derived constructor must return object or undefined");
1049                     thread->SetException(error.GetTaggedValue());
1050                 }
1051                 INTERPRETER_GOTO_EXCEPTION_HANDLER();
1052             }
1053 
1054             JSTaggedValue thisObject = GetThisObjectFromFastNewFrame(currentSp);
1055             SET_ACC(thisObject);
1056             INTERPRETER_HANDLE_RETURN();
1057         }
1058 
1059         INTERPRETER_HANDLE_RETURN();
1060     }
1061     HANDLE_OPCODE(HANDLE_RETURNUNDEFINED_PREF) {
1062         LOG_INST() << "return.undefined";
1063         InterpretedFrame *state = GET_FRAME(sp);
1064         LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
1065                                 << std::hex << reinterpret_cast<uintptr_t>(state->pc);
1066         JSMethod *method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
1067         [[maybe_unused]] auto fistPC = method->GetInstructions();
1068         UPDATE_HOTNESS_COUNTER_NON_ACC(-(pc - fistPC));
1069         JSTaggedType *currentSp = sp;
1070         sp = state->base.prev;
1071         ASSERT(sp != nullptr);
1072         InterpretedFrame *prevState = GET_FRAME(sp);
1073         pc = prevState->pc;
1074 
1075         // break frame
1076         if (pc == nullptr) {
1077             state->acc = JSTaggedValue::Undefined();
1078             return;
1079         }
1080         thread->SetCurrentSPFrame(sp);
1081 
1082         constpool = ConstantPool::Cast(prevState->constpool.GetTaggedObject());
1083 
1084         if (IsFastNewFrameExit(currentSp)) {
1085             JSFunction *func = JSFunction::Cast(GetThisFunction(currentSp).GetTaggedObject());
1086             if (func->IsBase()) {
1087                 JSTaggedValue thisObject = GetThisObjectFromFastNewFrame(currentSp);
1088                 SET_ACC(thisObject);
1089                 INTERPRETER_HANDLE_RETURN();
1090             }
1091 
1092             if (!acc.IsUndefined()) {
1093                 {
1094                     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1095                     JSHandle<JSObject> error = factory->GetJSError(ErrorType::TYPE_ERROR,
1096                         "Derived constructor must return object or undefined");
1097                     thread->SetException(error.GetTaggedValue());
1098                 }
1099                 INTERPRETER_GOTO_EXCEPTION_HANDLER();
1100             }
1101 
1102             JSTaggedValue thisObject = GetThisObjectFromFastNewFrame(currentSp);
1103             SET_ACC(thisObject);
1104             INTERPRETER_HANDLE_RETURN();
1105         } else {
1106             SET_ACC(JSTaggedValue::Undefined());
1107         }
1108         INTERPRETER_HANDLE_RETURN();
1109     }
1110     HANDLE_OPCODE(HANDLE_LDNAN_PREF) {
1111         LOG_INST() << "intrinsics::ldnan";
1112         SET_ACC(JSTaggedValue(base::NAN_VALUE));
1113         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1114     }
1115     HANDLE_OPCODE(HANDLE_LDINFINITY_PREF) {
1116         LOG_INST() << "intrinsics::ldinfinity";
1117         SET_ACC(JSTaggedValue(base::POSITIVE_INFINITY));
1118         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1119     }
1120     HANDLE_OPCODE(HANDLE_LDGLOBALTHIS_PREF) {
1121         LOG_INST() << "intrinsics::ldglobalthis";
1122         SET_ACC(globalObj)
1123         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1124     }
1125     HANDLE_OPCODE(HANDLE_LDUNDEFINED_PREF) {
1126         LOG_INST() << "intrinsics::ldundefined";
1127         SET_ACC(JSTaggedValue::Undefined())
1128         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1129     }
1130     HANDLE_OPCODE(HANDLE_LDNULL_PREF) {
1131         LOG_INST() << "intrinsics::ldnull";
1132         SET_ACC(JSTaggedValue::Null())
1133         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1134     }
1135     HANDLE_OPCODE(HANDLE_LDSYMBOL_PREF) {
1136         LOG_INST() << "intrinsics::ldsymbol";
1137         SET_ACC(globalEnv->GetSymbolFunction().GetTaggedValue());
1138         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1139     }
1140     HANDLE_OPCODE(HANDLE_LDGLOBAL_PREF) {
1141         LOG_INST() << "intrinsics::ldglobal";
1142         SET_ACC(globalObj)
1143         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1144     }
1145     HANDLE_OPCODE(HANDLE_LDTRUE_PREF) {
1146         LOG_INST() << "intrinsics::ldtrue";
1147         SET_ACC(JSTaggedValue::True())
1148         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1149     }
1150     HANDLE_OPCODE(HANDLE_LDFALSE_PREF) {
1151         LOG_INST() << "intrinsics::ldfalse";
1152         SET_ACC(JSTaggedValue::False())
1153         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1154     }
1155     HANDLE_OPCODE(HANDLE_LDLEXENVDYN_PREF) {
1156         LOG_INST() << "intrinsics::ldlexenvDyn ";
1157         InterpretedFrame *state = GET_FRAME(sp);
1158         JSTaggedValue currentLexenv = state->env;
1159         SET_ACC(currentLexenv);
1160         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1161     }
1162     HANDLE_OPCODE(HANDLE_GETUNMAPPEDARGS_PREF) {
1163         LOG_INST() << "intrinsics::getunmappedargs";
1164 
1165         uint32_t startIdx = 0;
1166         uint32_t actualNumArgs = GetNumArgs(sp, 0, startIdx);
1167 
1168         SAVE_PC();
1169         JSTaggedValue res = SlowRuntimeStub::GetUnmapedArgs(thread, sp, actualNumArgs, startIdx);
1170         INTERPRETER_RETURN_IF_ABRUPT(res);
1171         SET_ACC(res);
1172         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1173     }
1174     HANDLE_OPCODE(HANDLE_ASYNCFUNCTIONENTER_PREF) {
1175         LOG_INST() << "intrinsics::asyncfunctionenter";
1176         SAVE_PC();
1177         JSTaggedValue res = SlowRuntimeStub::AsyncFunctionEnter(thread);
1178         INTERPRETER_RETURN_IF_ABRUPT(res);
1179         SET_ACC(res);
1180         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1181     }
1182     HANDLE_OPCODE(HANDLE_TONUMBER_PREF_V8) {
1183         uint16_t v0 = READ_INST_8_1();
1184 
1185         LOG_INST() << "intrinsics::tonumber"
1186                    << " v" << v0;
1187         JSTaggedValue value = GET_VREG_VALUE(v0);
1188         if (value.IsNumber() || value.IsBigInt()) {
1189             // fast path
1190             SET_ACC(value);
1191         } else {
1192             // slow path
1193             SAVE_PC();
1194             JSTaggedValue res = SlowRuntimeStub::ToNumber(thread, value);
1195             INTERPRETER_RETURN_IF_ABRUPT(res);
1196             SET_ACC(res);
1197         }
1198         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1199     }
1200     HANDLE_OPCODE(HANDLE_NEGDYN_PREF_V8) {
1201         uint16_t v0 = READ_INST_8_1();
1202         LOG_INST() << "intrinsics::negdyn"
1203                    << " v" << v0;
1204         JSTaggedValue value = GET_VREG_VALUE(v0);
1205         // fast path
1206         if (value.IsInt()) {
1207             if (value.GetInt() == 0) {
1208                 SET_ACC(JSTaggedValue(-0.0));
1209             } else {
1210                 SET_ACC(JSTaggedValue(-value.GetInt()));
1211             }
1212         } else if (value.IsDouble()) {
1213             SET_ACC(JSTaggedValue(-value.GetDouble()));
1214         } else {  // slow path
1215             SAVE_PC();
1216             JSTaggedValue res = SlowRuntimeStub::NegDyn(thread, value);
1217             INTERPRETER_RETURN_IF_ABRUPT(res);
1218             SET_ACC(res);
1219         }
1220         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1221     }
1222     HANDLE_OPCODE(HANDLE_NOTDYN_PREF_V8) {
1223         uint16_t v0 = READ_INST_8_1();
1224 
1225         LOG_INST() << "intrinsics::notdyn"
1226                    << " v" << v0;
1227         JSTaggedValue value = GET_VREG_VALUE(v0);
1228         int32_t number;
1229         // number, fast path
1230         if (value.IsInt()) {
1231             number = static_cast<int32_t>(value.GetInt());
1232             SET_ACC(JSTaggedValue(~number));  // NOLINT(hicpp-signed-bitwise)
1233         } else if (value.IsDouble()) {
1234             number = base::NumberHelper::DoubleToInt(value.GetDouble(), base::INT32_BITS);
1235             SET_ACC(JSTaggedValue(~number));  // NOLINT(hicpp-signed-bitwise)
1236         } else {
1237             // slow path
1238             SAVE_PC();
1239             JSTaggedValue res = SlowRuntimeStub::NotDyn(thread, value);
1240             INTERPRETER_RETURN_IF_ABRUPT(res);
1241             SET_ACC(res);
1242         }
1243         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1244     }
1245     HANDLE_OPCODE(HANDLE_INCDYN_PREF_V8) {
1246         uint16_t v0 = READ_INST_8_1();
1247 
1248         LOG_INST() << "intrinsics::incdyn"
1249                    << " v" << v0;
1250 
1251         JSTaggedValue value = GET_VREG_VALUE(v0);
1252         // number fast path
1253         if (value.IsInt()) {
1254             int32_t a0 = value.GetInt();
1255             if (UNLIKELY(a0 == INT32_MAX)) {
1256                 auto ret = static_cast<double>(a0) + 1.0;
1257                 SET_ACC(JSTaggedValue(ret))
1258             } else {
1259                 SET_ACC(JSTaggedValue(a0 + 1))
1260             }
1261         } else if (value.IsDouble()) {
1262             SET_ACC(JSTaggedValue(value.GetDouble() + 1.0))
1263         } else {
1264             // slow path
1265             SAVE_PC();
1266             JSTaggedValue res = SlowRuntimeStub::IncDyn(thread, value);
1267             INTERPRETER_RETURN_IF_ABRUPT(res);
1268             SET_ACC(res);
1269         }
1270         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1271     }
1272     HANDLE_OPCODE(HANDLE_DECDYN_PREF_V8) {
1273         uint16_t v0 = READ_INST_8_1();
1274         LOG_INST() << "intrinsics::decdyn"
1275                    << " v" << v0;
1276 
1277         JSTaggedValue value = GET_VREG_VALUE(v0);
1278         // number, fast path
1279         if (value.IsInt()) {
1280             int32_t a0 = value.GetInt();
1281             if (UNLIKELY(a0 == INT32_MIN)) {
1282                 auto ret = static_cast<double>(a0) - 1.0;
1283                 SET_ACC(JSTaggedValue(ret))
1284             } else {
1285                 SET_ACC(JSTaggedValue(a0 - 1))
1286             }
1287         } else if (value.IsDouble()) {
1288             SET_ACC(JSTaggedValue(value.GetDouble() - 1.0))
1289         } else {
1290             // slow path
1291             SAVE_PC();
1292             JSTaggedValue res = SlowRuntimeStub::DecDyn(thread, value);
1293             INTERPRETER_RETURN_IF_ABRUPT(res);
1294             SET_ACC(res);
1295         }
1296         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1297     }
1298     HANDLE_OPCODE(HANDLE_THROWDYN_PREF) {
1299         LOG_INST() << "intrinsics::throwdyn";
1300         SAVE_PC();
1301         SlowRuntimeStub::ThrowDyn(thread, GET_ACC());
1302         INTERPRETER_GOTO_EXCEPTION_HANDLER();
1303     }
1304     HANDLE_OPCODE(HANDLE_TYPEOFDYN_PREF) {
1305         LOG_INST() << "intrinsics::typeofdyn";
1306 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
1307         auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(FastTypeOf));
1308         typedef JSTaggedType (*PFFastTypeOf)(uintptr_t, JSTaggedType);
1309         auto fastTypeOfPtr = reinterpret_cast<PFFastTypeOf>(stubAddr);
1310         JSTaggedValue res = JSTaggedValue(fastTypeOfPtr(thread->GetGlueAddr(), GET_ACC().GetRawData()));
1311 #else
1312         JSTaggedValue res = FastRuntimeStub::FastTypeOf(thread, GET_ACC());
1313 #endif
1314         SET_ACC(res);
1315         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1316     }
1317     HANDLE_OPCODE(HANDLE_GETPROPITERATOR_PREF) {
1318         LOG_INST() << "intrinsics::getpropiterator";
1319         SAVE_PC();
1320         JSTaggedValue res = SlowRuntimeStub::GetPropIterator(thread, GET_ACC());
1321         INTERPRETER_RETURN_IF_ABRUPT(res);
1322         SET_ACC(res);
1323         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1324     }
1325     HANDLE_OPCODE(HANDLE_RESUMEGENERATOR_PREF_V8) {
1326         LOG_INST() << "intrinsics::resumegenerator";
1327         uint16_t vs = READ_INST_8_1();
1328         JSGeneratorObject *obj = JSGeneratorObject::Cast(GET_VREG_VALUE(vs).GetTaggedObject());
1329         SET_ACC(obj->GetResumeResult());
1330         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1331     }
1332     HANDLE_OPCODE(HANDLE_GETRESUMEMODE_PREF_V8) {
1333         LOG_INST() << "intrinsics::getresumemode";
1334         uint16_t vs = READ_INST_8_1();
1335         JSGeneratorObject *obj = JSGeneratorObject::Cast(GET_VREG_VALUE(vs).GetTaggedObject());
1336         SET_ACC(JSTaggedValue(static_cast<int>(obj->GetResumeMode())));
1337         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1338     }
1339     HANDLE_OPCODE(HANDLE_GETITERATOR_PREF) {
1340         LOG_INST() << "intrinsics::getiterator";
1341         JSTaggedValue obj = GET_ACC();
1342 
1343         // fast path: Generator obj is already store in acc
1344         if (!obj.IsGeneratorObject()) {
1345             // slow path
1346             SAVE_PC();
1347             JSTaggedValue res = SlowRuntimeStub::GetIterator(thread, obj);
1348             INTERPRETER_RETURN_IF_ABRUPT(res);
1349             SET_ACC(res);
1350         }
1351         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
1352     }
1353     HANDLE_OPCODE(HANDLE_THROWCONSTASSIGNMENT_PREF_V8) {
1354         uint16_t v0 = READ_INST_8_1();
1355         LOG_INST() << "throwconstassignment"
1356                    << " v" << v0;
1357         SAVE_PC();
1358         SlowRuntimeStub::ThrowConstAssignment(thread, GET_VREG_VALUE(v0));
1359         INTERPRETER_GOTO_EXCEPTION_HANDLER();
1360     }
1361     HANDLE_OPCODE(HANDLE_THROWTHROWNOTEXISTS_PREF) {
1362         LOG_INST() << "throwthrownotexists";
1363 
1364         SAVE_PC();
1365         SlowRuntimeStub::ThrowThrowNotExists(thread);
1366         INTERPRETER_GOTO_EXCEPTION_HANDLER();
1367     }
1368     HANDLE_OPCODE(HANDLE_THROWPATTERNNONCOERCIBLE_PREF) {
1369         LOG_INST() << "throwpatternnoncoercible";
1370 
1371         SAVE_PC();
1372         SlowRuntimeStub::ThrowPatternNonCoercible(thread);
1373         INTERPRETER_GOTO_EXCEPTION_HANDLER();
1374     }
1375     HANDLE_OPCODE(HANDLE_THROWIFNOTOBJECT_PREF_V8) {
1376         LOG_INST() << "throwifnotobject";
1377         uint16_t v0 = READ_INST_8_1();
1378 
1379         JSTaggedValue value = GET_VREG_VALUE(v0);
1380         // fast path
1381         if (value.IsECMAObject()) {
1382             DISPATCH(BytecodeInstruction::Format::PREF_V8);
1383         }
1384 
1385         // slow path
1386         SAVE_PC();
1387         SlowRuntimeStub::ThrowIfNotObject(thread);
1388         INTERPRETER_GOTO_EXCEPTION_HANDLER();
1389     }
1390     HANDLE_OPCODE(HANDLE_ITERNEXT_PREF_V8) {
1391         uint16_t v0 = READ_INST_8_1();
1392         LOG_INST() << "intrinsics::iternext"
1393                    << " v" << v0;
1394         SAVE_PC();
1395         JSTaggedValue iter = GET_VREG_VALUE(v0);
1396         JSTaggedValue res = SlowRuntimeStub::IterNext(thread, iter);
1397         INTERPRETER_RETURN_IF_ABRUPT(res);
1398         SET_ACC(res);
1399         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1400     }
1401     HANDLE_OPCODE(HANDLE_CLOSEITERATOR_PREF_V8) {
1402         uint16_t v0 = READ_INST_8_1();
1403         LOG_INST() << "intrinsics::closeiterator"
1404                    << " v" << v0;
1405         SAVE_PC();
1406         JSTaggedValue iter = GET_VREG_VALUE(v0);
1407         JSTaggedValue res = SlowRuntimeStub::CloseIterator(thread, iter);
1408         INTERPRETER_RETURN_IF_ABRUPT(res);
1409         SET_ACC(res);
1410         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1411     }
1412     HANDLE_OPCODE(HANDLE_ADD2DYN_PREF_V8) {
1413         uint16_t v0 = READ_INST_8_1();
1414         LOG_INST() << "intrinsics::add2dyn"
1415                    << " v" << v0;
1416         int32_t a0;
1417         int32_t a1;
1418         JSTaggedValue left = GET_VREG_VALUE(v0);
1419         JSTaggedValue right = GET_ACC();
1420         // number, fast path
1421         if (left.IsInt() && right.IsInt()) {
1422             a0 = left.GetInt();
1423             a1 = right.GetInt();
1424             if ((a0 > 0 && a1 > INT32_MAX - a0) || (a0 < 0 && a1 < INT32_MIN - a0)) {
1425                 auto ret = static_cast<double>(a0) + static_cast<double>(a1);
1426                 SET_ACC(JSTaggedValue(ret))
1427             } else {
1428                 SET_ACC(JSTaggedValue(a0 + a1))
1429             }
1430         } else if (left.IsNumber() && right.IsNumber()) {
1431             double a0Double = left.IsInt() ? left.GetInt() : left.GetDouble();
1432             double a1Double = right.IsInt() ? right.GetInt() : right.GetDouble();
1433             double ret = a0Double + a1Double;
1434             SET_ACC(JSTaggedValue(ret))
1435         } else {
1436             // one or both are not number, slow path
1437             SAVE_PC();
1438             JSTaggedValue res = SlowRuntimeStub::Add2Dyn(thread, ecmaVm, left, right);
1439             INTERPRETER_RETURN_IF_ABRUPT(res);
1440             SET_ACC(res);
1441         }
1442         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1443     }
1444     HANDLE_OPCODE(HANDLE_SUB2DYN_PREF_V8) {
1445         uint16_t v0 = READ_INST_8_1();
1446         LOG_INST() << "intrinsics::sub2dyn"
1447                    << " v" << v0;
1448         int32_t a0;
1449         int32_t a1;
1450         JSTaggedValue left = GET_VREG_VALUE(v0);
1451         JSTaggedValue right = GET_ACC();
1452         if (left.IsInt() && right.IsInt()) {
1453             a0 = left.GetInt();
1454             a1 = -right.GetInt();
1455             if ((a0 > 0 && a1 > INT32_MAX - a0) || (a0 < 0 && a1 < INT32_MIN - a0)) {
1456                 auto ret = static_cast<double>(a0) + static_cast<double>(a1);
1457                 SET_ACC(JSTaggedValue(ret))
1458             } else {
1459                 SET_ACC(JSTaggedValue(a0 + a1))
1460             }
1461         } else if (left.IsNumber() && right.IsNumber()) {
1462             double a0Double = left.IsInt() ? left.GetInt() : left.GetDouble();
1463             double a1Double = right.IsInt() ? right.GetInt() : right.GetDouble();
1464             double ret = a0Double - a1Double;
1465             SET_ACC(JSTaggedValue(ret))
1466         } else {
1467             // one or both are not number, slow path
1468             SAVE_PC();
1469             JSTaggedValue res = SlowRuntimeStub::Sub2Dyn(thread, left, right);
1470             INTERPRETER_RETURN_IF_ABRUPT(res);
1471             SET_ACC(res);
1472         }
1473         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1474     }
1475     HANDLE_OPCODE(HANDLE_MUL2DYN_PREF_V8) {
1476         uint16_t v0 = READ_INST_8_1();
1477         LOG_INST() << "intrinsics::mul2dyn"
1478                    << " v" << v0;
1479         JSTaggedValue left = GET_VREG_VALUE(v0);
1480         JSTaggedValue right = acc;
1481 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
1482         auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(FastMul));
1483         typedef JSTaggedType (*PFFastMul)(JSTaggedType, JSTaggedType);
1484         auto fastMulPtr = reinterpret_cast<PFFastMul>(stubAddr);
1485         JSTaggedValue value = JSTaggedValue(fastMulPtr(left.GetRawData(), right.GetRawData()));
1486 #else
1487         JSTaggedValue value = FastRuntimeStub::FastMul(left, right);
1488 #endif
1489         if (!value.IsHole()) {
1490             SET_ACC(value);
1491         } else {
1492             // slow path
1493             SAVE_PC();
1494             JSTaggedValue res = SlowRuntimeStub::Mul2Dyn(thread, left, right);
1495             INTERPRETER_RETURN_IF_ABRUPT(res);
1496             SET_ACC(res);
1497         }
1498         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1499     }
1500     HANDLE_OPCODE(HANDLE_DIV2DYN_PREF_V8) {
1501         uint16_t v0 = READ_INST_8_1();
1502         LOG_INST() << "intrinsics::div2dyn"
1503                    << " v" << v0;
1504         JSTaggedValue left = GET_VREG_VALUE(v0);
1505         JSTaggedValue right = acc;
1506         // fast path
1507         JSTaggedValue res = FastRuntimeStub::FastDiv(left, right);
1508         if (!res.IsHole()) {
1509             SET_ACC(res);
1510         } else {
1511             // slow path
1512             SAVE_PC();
1513             JSTaggedValue slowRes = SlowRuntimeStub::Div2Dyn(thread, left, right);
1514             INTERPRETER_RETURN_IF_ABRUPT(slowRes);
1515             SET_ACC(slowRes);
1516         }
1517         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1518     }
1519     HANDLE_OPCODE(HANDLE_MOD2DYN_PREF_V8) {
1520         uint16_t vs = READ_INST_8_1();
1521         LOG_INST() << "intrinsics::mod2dyn"
1522                    << " v" << vs;
1523         JSTaggedValue left = GET_VREG_VALUE(vs);
1524         JSTaggedValue right = GET_ACC();
1525 
1526 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
1527         auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(FastMod));
1528         typedef JSTaggedType (*PFFastMod)(uintptr_t, JSTaggedType, JSTaggedType);
1529         auto fastModPtr = reinterpret_cast<PFFastMod>(stubAddr);
1530         JSTaggedValue res = JSTaggedValue(fastModPtr(thread->GetGlueAddr(), left.GetRawData(), right.GetRawData()));
1531 #else
1532         JSTaggedValue res = FastRuntimeStub::FastMod(left, right);
1533 #endif
1534         if (!res.IsHole()) {
1535             SET_ACC(res);
1536         } else {
1537             // slow path
1538             SAVE_PC();
1539             JSTaggedValue slowRes = SlowRuntimeStub::Mod2Dyn(thread, left, right);
1540             INTERPRETER_RETURN_IF_ABRUPT(slowRes);
1541             SET_ACC(slowRes);
1542         }
1543         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1544     }
1545     HANDLE_OPCODE(HANDLE_EQDYN_PREF_V8) {
1546         uint16_t v0 = READ_INST_8_1();
1547 
1548         LOG_INST() << "intrinsics::eqdyn"
1549                    << " v" << v0;
1550         JSTaggedValue left = GET_VREG_VALUE(v0);
1551         JSTaggedValue right = acc;
1552 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
1553         auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(FastEqual));
1554         typedef JSTaggedType (*PFFastEqual)(JSTaggedType, JSTaggedType);
1555         auto fastEqualPtr = reinterpret_cast<PFFastEqual>(stubAddr);
1556         JSTaggedValue res = JSTaggedValue(fastEqualPtr(left.GetRawData(), right.GetRawData()));
1557 #else
1558         JSTaggedValue res = FastRuntimeStub::FastEqual(left, right);
1559 #endif
1560         if (!res.IsHole()) {
1561             SET_ACC(res);
1562         } else {
1563             // slow path
1564             SAVE_PC();
1565             res = SlowRuntimeStub::EqDyn(thread, left, right);
1566             INTERPRETER_RETURN_IF_ABRUPT(res);
1567             SET_ACC(res);
1568         }
1569 
1570         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1571     }
1572     HANDLE_OPCODE(HANDLE_NOTEQDYN_PREF_V8) {
1573         uint16_t v0 = READ_INST_8_1();
1574 
1575         LOG_INST() << "intrinsics::noteqdyn"
1576                    << " v" << v0;
1577         JSTaggedValue left = GET_VREG_VALUE(v0);
1578         JSTaggedValue right = acc;
1579 
1580         JSTaggedValue res = FastRuntimeStub::FastEqual(left, right);
1581         if (!res.IsHole()) {
1582             res = res.IsTrue() ? JSTaggedValue::False() : JSTaggedValue::True();
1583             SET_ACC(res);
1584         } else {
1585             // slow path
1586             SAVE_PC();
1587             res = SlowRuntimeStub::NotEqDyn(thread, left, right);
1588             INTERPRETER_RETURN_IF_ABRUPT(res);
1589             SET_ACC(res);
1590         }
1591         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1592     }
1593     HANDLE_OPCODE(HANDLE_LESSDYN_PREF_V8) {
1594         uint16_t v0 = READ_INST_8_1();
1595 
1596         LOG_INST() << "intrinsics::lessdyn"
1597                    << " v" << v0;
1598         JSTaggedValue left = GET_VREG_VALUE(v0);
1599         JSTaggedValue right = GET_ACC();
1600         if (left.IsNumber() && right.IsNumber()) {
1601             // fast path
1602             double valueA = left.IsInt() ? static_cast<double>(left.GetInt()) : left.GetDouble();
1603             double valueB = right.IsInt() ? static_cast<double>(right.GetInt()) : right.GetDouble();
1604             bool ret = JSTaggedValue::StrictNumberCompare(valueA, valueB) == ComparisonResult::LESS;
1605             SET_ACC(ret ? JSTaggedValue::True() : JSTaggedValue::False())
1606         } else if (left.IsBigInt() && right.IsBigInt()) {
1607             bool result = BigInt::LessThan(left, right);
1608             SET_ACC(JSTaggedValue(result));
1609         } else {
1610             // slow path
1611             SAVE_PC();
1612             JSTaggedValue res = SlowRuntimeStub::LessDyn(thread, left, right);
1613             INTERPRETER_RETURN_IF_ABRUPT(res);
1614             SET_ACC(res);
1615         }
1616         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1617     }
1618     HANDLE_OPCODE(HANDLE_LESSEQDYN_PREF_V8) {
1619         uint16_t vs = READ_INST_8_1();
1620         LOG_INST() << "intrinsics::lesseqdyn "
1621                    << " v" << vs;
1622         JSTaggedValue left = GET_VREG_VALUE(vs);
1623         JSTaggedValue right = GET_ACC();
1624         if (left.IsNumber() && right.IsNumber()) {
1625             // fast path
1626             double valueA = left.IsInt() ? static_cast<double>(left.GetInt()) : left.GetDouble();
1627             double valueB = right.IsInt() ? static_cast<double>(right.GetInt()) : right.GetDouble();
1628             bool ret = JSTaggedValue::StrictNumberCompare(valueA, valueB) <= ComparisonResult::EQUAL;
1629             SET_ACC(ret ? JSTaggedValue::True() : JSTaggedValue::False())
1630         } else if (left.IsBigInt() && right.IsBigInt()) {
1631             bool result = BigInt::LessThan(left, right) || BigInt::Equal(left, right);
1632             SET_ACC(JSTaggedValue(result));
1633         } else {
1634             // slow path
1635             SAVE_PC();
1636             JSTaggedValue res = SlowRuntimeStub::LessEqDyn(thread, left, right);
1637             INTERPRETER_RETURN_IF_ABRUPT(res);
1638             SET_ACC(res);
1639         }
1640         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1641     }
1642     HANDLE_OPCODE(HANDLE_GREATERDYN_PREF_V8) {
1643         uint16_t v0 = READ_INST_8_1();
1644 
1645         LOG_INST() << "intrinsics::greaterdyn"
1646                    << " v" << v0;
1647         JSTaggedValue left = GET_VREG_VALUE(v0);
1648         JSTaggedValue right = acc;
1649         if (left.IsNumber() && right.IsNumber()) {
1650             // fast path
1651             double valueA = left.IsInt() ? static_cast<double>(left.GetInt()) : left.GetDouble();
1652             double valueB = right.IsInt() ? static_cast<double>(right.GetInt()) : right.GetDouble();
1653             bool ret = JSTaggedValue::StrictNumberCompare(valueA, valueB) == ComparisonResult::GREAT;
1654             SET_ACC(ret ? JSTaggedValue::True() : JSTaggedValue::False())
1655         } else if (left.IsBigInt() && right.IsBigInt()) {
1656             bool result = BigInt::LessThan(right, left);
1657             SET_ACC(JSTaggedValue(result));
1658         } else {
1659             // slow path
1660             SAVE_PC();
1661             JSTaggedValue res = SlowRuntimeStub::GreaterDyn(thread, left, right);
1662             INTERPRETER_RETURN_IF_ABRUPT(res);
1663             SET_ACC(res);
1664         }
1665         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1666     }
1667     HANDLE_OPCODE(HANDLE_GREATEREQDYN_PREF_V8) {
1668         uint16_t vs = READ_INST_8_1();
1669         LOG_INST() << "intrinsics::greateqdyn "
1670                    << " v" << vs;
1671         JSTaggedValue left = GET_VREG_VALUE(vs);
1672         JSTaggedValue right = GET_ACC();
1673         if (left.IsNumber() && right.IsNumber()) {
1674             // fast path
1675             double valueA = left.IsInt() ? static_cast<double>(left.GetInt()) : left.GetDouble();
1676             double valueB = right.IsInt() ? static_cast<double>(right.GetInt()) : right.GetDouble();
1677             ComparisonResult comparison = JSTaggedValue::StrictNumberCompare(valueA, valueB);
1678             bool ret = (comparison == ComparisonResult::GREAT) || (comparison == ComparisonResult::EQUAL);
1679             SET_ACC(ret ? JSTaggedValue::True() : JSTaggedValue::False())
1680         } else if (left.IsBigInt() && right.IsBigInt()) {
1681             bool result = BigInt::LessThan(right, left) || BigInt::Equal(right, left);
1682             SET_ACC(JSTaggedValue(result))
1683         } else {
1684             // slow path
1685             SAVE_PC();
1686             JSTaggedValue res = SlowRuntimeStub::GreaterEqDyn(thread, left, right);
1687             INTERPRETER_RETURN_IF_ABRUPT(res);
1688             SET_ACC(res);
1689         }
1690         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1691     }
1692     HANDLE_OPCODE(HANDLE_SHL2DYN_PREF_V8) {
1693         uint16_t v0 = READ_INST_8_1();
1694 
1695         LOG_INST() << "intrinsics::shl2dyn"
1696                    << " v" << v0;
1697         JSTaggedValue left = GET_VREG_VALUE(v0);
1698         JSTaggedValue right = GET_ACC();
1699         // both number, fast path
1700         if (left.IsInt() && right.IsInt()) {
1701             int32_t opNumber0 = left.GetInt();
1702             int32_t opNumber1 = right.GetInt();
1703             uint32_t shift =
1704                 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1705             using unsigned_type = std::make_unsigned_t<int32_t>;
1706             auto ret =
1707                 static_cast<int32_t>(static_cast<unsigned_type>(opNumber0) << shift); // NOLINT(hicpp-signed-bitwise)
1708             SET_ACC(JSTaggedValue(ret))
1709         } else if (left.IsNumber() && right.IsNumber()) {
1710             int32_t opNumber0 =
1711                 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
1712             int32_t opNumber1 =
1713                 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
1714             uint32_t shift =
1715                 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1716             using unsigned_type = std::make_unsigned_t<int32_t>;
1717             auto ret =
1718                 static_cast<int32_t>(static_cast<unsigned_type>(opNumber0) << shift); // NOLINT(hicpp-signed-bitwise)
1719             SET_ACC(JSTaggedValue(ret))
1720         } else {
1721             // slow path
1722             SAVE_PC();
1723             JSTaggedValue res = SlowRuntimeStub::Shl2Dyn(thread, left, right);
1724             INTERPRETER_RETURN_IF_ABRUPT(res);
1725             SET_ACC(res);
1726         }
1727         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1728     }
1729     HANDLE_OPCODE(HANDLE_SHR2DYN_PREF_V8) {
1730         uint16_t v0 = READ_INST_8_1();
1731 
1732         LOG_INST() << "intrinsics::shr2dyn"
1733                    << " v" << v0;
1734         JSTaggedValue left = GET_VREG_VALUE(v0);
1735         JSTaggedValue right = GET_ACC();
1736         // both number, fast path
1737         if (left.IsInt() && right.IsInt()) {
1738             int32_t opNumber0 = left.GetInt();
1739             int32_t opNumber1 = right.GetInt();
1740             uint32_t shift =
1741             static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1742                 auto ret = static_cast<int32_t>(opNumber0 >> shift); // NOLINT(hicpp-signed-bitwise)
1743             SET_ACC(JSTaggedValue(ret))
1744         } else if (left.IsNumber() && right.IsNumber()) {
1745             int32_t opNumber0 =
1746                 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
1747             int32_t opNumber1 =
1748                 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
1749             uint32_t shift =
1750                 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1751             auto ret = static_cast<int32_t>(opNumber0 >> shift); // NOLINT(hicpp-signed-bitwise)
1752             SET_ACC(JSTaggedValue(ret))
1753         } else {
1754             // slow path
1755             SAVE_PC();
1756             JSTaggedValue res = SlowRuntimeStub::Shr2Dyn(thread, left, right);
1757             INTERPRETER_RETURN_IF_ABRUPT(res);
1758             SET_ACC(res);
1759         }
1760         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1761     }
1762     HANDLE_OPCODE(HANDLE_ASHR2DYN_PREF_V8) {
1763         uint16_t v0 = READ_INST_8_1();
1764 
1765         LOG_INST() << "intrinsics::ashr2dyn"
1766                    << " v" << v0;
1767         JSTaggedValue left = GET_VREG_VALUE(v0);
1768         JSTaggedValue right = GET_ACC();
1769         if (left.IsInt() && right.IsInt()) {
1770             int32_t opNumber0 = left.GetInt();
1771             int32_t opNumber1 = right.GetInt();
1772             uint32_t shift =
1773                 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1774             using unsigned_type = std::make_unsigned_t<uint32_t>;
1775             auto ret =
1776                 static_cast<uint32_t>(static_cast<unsigned_type>(opNumber0) >> shift); // NOLINT(hicpp-signed-bitwise)
1777             SET_ACC(JSTaggedValue(ret))
1778         } else if (left.IsNumber() && right.IsNumber()) {
1779             int32_t opNumber0 =
1780                 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
1781             int32_t opNumber1 =
1782                 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
1783             uint32_t shift =
1784                 static_cast<uint32_t>(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers)
1785             using unsigned_type = std::make_unsigned_t<uint32_t>;
1786             auto ret =
1787                 static_cast<uint32_t>(static_cast<unsigned_type>(opNumber0) >> shift); // NOLINT(hicpp-signed-bitwise)
1788         SET_ACC(JSTaggedValue(ret))
1789         } else {
1790             // slow path
1791             SAVE_PC();
1792             JSTaggedValue res = SlowRuntimeStub::Ashr2Dyn(thread, left, right);
1793             INTERPRETER_RETURN_IF_ABRUPT(res);
1794             SET_ACC(res);
1795         }
1796         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1797     }
1798     HANDLE_OPCODE(HANDLE_AND2DYN_PREF_V8) {
1799         uint16_t v0 = READ_INST_8_1();
1800 
1801         LOG_INST() << "intrinsics::and2dyn"
1802                    << " v" << v0;
1803         JSTaggedValue left = GET_VREG_VALUE(v0);
1804         JSTaggedValue right = GET_ACC();
1805         // both number, fast path
1806         if (left.IsInt() && right.IsInt()) {
1807             int32_t opNumber0 = left.GetInt();
1808             int32_t opNumber1 = right.GetInt();
1809             // NOLINT(hicpp-signed-bitwise)
1810             auto ret = static_cast<uint32_t>(opNumber0) & static_cast<uint32_t>(opNumber1);
1811             SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)))
1812         } else if (left.IsNumber() && right.IsNumber()) {
1813             int32_t opNumber0 =
1814                 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
1815             int32_t opNumber1 =
1816                 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
1817             // NOLINT(hicpp-signed-bitwise)
1818             auto ret = static_cast<uint32_t>(opNumber0) & static_cast<uint32_t>(opNumber1);
1819             SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)))
1820         } else {
1821             // slow path
1822             SAVE_PC();
1823             JSTaggedValue res = SlowRuntimeStub::And2Dyn(thread, left, right);
1824             INTERPRETER_RETURN_IF_ABRUPT(res);
1825             SET_ACC(res);
1826         }
1827         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1828     }
1829     HANDLE_OPCODE(HANDLE_OR2DYN_PREF_V8) {
1830         uint16_t v0 = READ_INST_8_1();
1831 
1832         LOG_INST() << "intrinsics::or2dyn"
1833                    << " v" << v0;
1834         JSTaggedValue left = GET_VREG_VALUE(v0);
1835         JSTaggedValue right = GET_ACC();
1836         // both number, fast path
1837         if (left.IsInt() && right.IsInt()) {
1838             int32_t opNumber0 = left.GetInt();
1839             int32_t opNumber1 = right.GetInt();
1840             // NOLINT(hicpp-signed-bitwise)
1841             auto ret = static_cast<uint32_t>(opNumber0) | static_cast<uint32_t>(opNumber1);
1842             SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)))
1843         } else if (left.IsNumber() && right.IsNumber()) {
1844             int32_t opNumber0 =
1845                 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
1846             int32_t opNumber1 =
1847                 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
1848             // NOLINT(hicpp-signed-bitwise)
1849             auto ret = static_cast<uint32_t>(opNumber0) | static_cast<uint32_t>(opNumber1);
1850             SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)))
1851         } else {
1852             // slow path
1853             SAVE_PC();
1854             JSTaggedValue res = SlowRuntimeStub::Or2Dyn(thread, left, right);
1855             INTERPRETER_RETURN_IF_ABRUPT(res);
1856             SET_ACC(res);
1857         }
1858         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1859     }
1860     HANDLE_OPCODE(HANDLE_XOR2DYN_PREF_V8) {
1861         uint16_t v0 = READ_INST_8_1();
1862 
1863         LOG_INST() << "intrinsics::xor2dyn"
1864                    << " v" << v0;
1865         JSTaggedValue left = GET_VREG_VALUE(v0);
1866         JSTaggedValue right = GET_ACC();
1867         // both number, fast path
1868         if (left.IsInt() && right.IsInt()) {
1869             int32_t opNumber0 = left.GetInt();
1870             int32_t opNumber1 = right.GetInt();
1871             // NOLINT(hicpp-signed-bitwise)
1872             auto ret = static_cast<uint32_t>(opNumber0) ^ static_cast<uint32_t>(opNumber1);
1873             SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)))
1874         } else if (left.IsNumber() && right.IsNumber()) {
1875             int32_t opNumber0 =
1876                 left.IsInt() ? left.GetInt() : base::NumberHelper::DoubleToInt(left.GetDouble(), base::INT32_BITS);
1877             int32_t opNumber1 =
1878                 right.IsInt() ? right.GetInt() : base::NumberHelper::DoubleToInt(right.GetDouble(), base::INT32_BITS);
1879             // NOLINT(hicpp-signed-bitwise)
1880             auto ret = static_cast<uint32_t>(opNumber0) ^ static_cast<uint32_t>(opNumber1);
1881             SET_ACC(JSTaggedValue(static_cast<int32_t>(ret)))
1882         } else {
1883             // slow path
1884             SAVE_PC();
1885             JSTaggedValue res = SlowRuntimeStub::Xor2Dyn(thread, left, right);
1886             INTERPRETER_RETURN_IF_ABRUPT(res);
1887             SET_ACC(res);
1888         }
1889         DISPATCH(BytecodeInstruction::Format::PREF_V8);
1890     }
1891     HANDLE_OPCODE(HANDLE_DELOBJPROP_PREF_V8_V8) {
1892         uint16_t v0 = READ_INST_8_1();
1893         uint16_t v1 = READ_INST_8_2();
1894         LOG_INST() << "intrinsics::delobjprop"
1895                    << " v0" << v0 << " v1" << v1;
1896 
1897         JSTaggedValue obj = GET_VREG_VALUE(v0);
1898         JSTaggedValue prop = GET_VREG_VALUE(v1);
1899         SAVE_PC();
1900         JSTaggedValue res = SlowRuntimeStub::DelObjProp(thread, obj, prop);
1901         INTERPRETER_RETURN_IF_ABRUPT(res);
1902         SET_ACC(res);
1903 
1904         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
1905     }
1906     HANDLE_OPCODE(HANDLE_DEFINEFUNCDYN_PREF_ID16_IMM16_V8) {
1907         uint16_t methodId = READ_INST_16_1();
1908         uint16_t length = READ_INST_16_3();
1909         uint16_t v0 = READ_INST_8_5();
1910         LOG_INST() << "intrinsics::definefuncDyn length: " << length
1911                    << " v" << v0;
1912         JSFunction *result = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject());
1913         ASSERT(result != nullptr);
1914         if (result->GetResolved()) {
1915             SAVE_PC();
1916             auto res = SlowRuntimeStub::DefinefuncDyn(thread, result);
1917             INTERPRETER_RETURN_IF_ABRUPT(res);
1918             result = JSFunction::Cast(res.GetTaggedObject());
1919             result->SetConstantPool(thread, JSTaggedValue(constpool));
1920         } else {
1921             result->SetResolved(true);
1922         }
1923 
1924         result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length));
1925         JSTaggedValue envHandle = GET_VREG_VALUE(v0);
1926         result->SetLexicalEnv(thread, envHandle);
1927         SET_ACC(JSTaggedValue(result))
1928 
1929         DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8);
1930     }
1931     HANDLE_OPCODE(HANDLE_DEFINENCFUNCDYN_PREF_ID16_IMM16_V8) {
1932         uint16_t methodId = READ_INST_16_1();
1933         uint16_t length = READ_INST_16_3();
1934         uint16_t v0 = READ_INST_8_5();
1935         JSTaggedValue homeObject = GET_ACC();
1936         LOG_INST() << "intrinsics::definencfuncDyn length: " << length
1937                    << " v" << v0;
1938         JSFunction *result = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject());
1939         ASSERT(result != nullptr);
1940         if (result->GetResolved()) {
1941             SAVE_ACC();
1942             SAVE_PC();
1943             auto res = SlowRuntimeStub::DefineNCFuncDyn(thread, result);
1944             INTERPRETER_RETURN_IF_ABRUPT(res);
1945             result = JSFunction::Cast(res.GetTaggedObject());
1946             result->SetConstantPool(thread, JSTaggedValue(constpool));
1947             RESTORE_ACC();
1948             homeObject = GET_ACC();
1949         } else {
1950             result->SetResolved(true);
1951         }
1952 
1953         result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length));
1954         JSTaggedValue env = GET_VREG_VALUE(v0);
1955         result->SetLexicalEnv(thread, env);
1956         result->SetHomeObject(thread, homeObject);
1957         SET_ACC(JSTaggedValue(result));
1958 
1959         DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8);
1960     }
1961     HANDLE_OPCODE(HANDLE_DEFINEMETHOD_PREF_ID16_IMM16_V8) {
1962         uint16_t methodId = READ_INST_16_1();
1963         uint16_t length = READ_INST_16_3();
1964         uint16_t v0 = READ_INST_8_5();
1965         JSTaggedValue homeObject = GET_ACC();
1966         LOG_INST() << "intrinsics::definemethod length: " << length
1967                    << " v" << v0;
1968         JSFunction *result = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject());
1969         ASSERT(result != nullptr);
1970         if (result->GetResolved()) {
1971             SAVE_PC();
1972             auto res = SlowRuntimeStub::DefineMethod(thread, result, homeObject);
1973             INTERPRETER_RETURN_IF_ABRUPT(res);
1974             result = JSFunction::Cast(res.GetTaggedObject());
1975             result->SetConstantPool(thread, JSTaggedValue(constpool));
1976         } else {
1977             result->SetHomeObject(thread, homeObject);
1978             result->SetResolved(true);
1979         }
1980 
1981         result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length));
1982         JSTaggedValue taggedCurEnv = GET_VREG_VALUE(v0);
1983         result->SetLexicalEnv(thread, taggedCurEnv);
1984         SET_ACC(JSTaggedValue(result));
1985 
1986         DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8);
1987     }
1988     HANDLE_OPCODE(HANDLE_NEWOBJDYNRANGE_PREF_IMM16_V8) {
1989         uint16_t numArgs = READ_INST_16_1();
1990         uint16_t firstArgRegIdx = READ_INST_8_3();
1991         LOG_INST() << "intrinsics::newobjDynrange " << numArgs << " v" << firstArgRegIdx;
1992         JSTaggedValue ctor = GET_VREG_VALUE(firstArgRegIdx);
1993         if (ctor.IsJSFunction() && ctor.IsConstructor()) {
1994             thread->CheckSafepoint();
1995             ctor = GET_VREG_VALUE(firstArgRegIdx);  // may be moved by GC
1996             JSFunction *ctorFunc = JSFunction::Cast(ctor.GetTaggedObject());
1997             JSMethod *ctorMethod = ctorFunc->GetMethod();
1998             if (ctorFunc->IsBuiltinsConstructor()) {
1999                 ASSERT(ctorMethod->GetNumVregsWithCallField() == 0);
2000                 size_t frameSize = FRAME_STATE_SIZE + numArgs + 1;  // +1 for this
2001                 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2002                 JSTaggedType *newSp = sp - frameSize;
2003                 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
2004                     INTERPRETER_GOTO_EXCEPTION_HANDLER();
2005                 }
2006                 EcmaRuntimeCallInfo ecmaRuntimeCallInfo(thread, numArgs + 1, reinterpret_cast<JSTaggedValue *>(newSp));
2007                 // copy args
2008                 uint32_t index = 0;
2009                 // func
2010                 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2011                 newSp[index++] = GET_VREG(firstArgRegIdx);
2012                 // newTarget
2013                 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2014                 newSp[index++] = GET_VREG(firstArgRegIdx + 1);
2015                 // this
2016                 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2017                 newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
2018                 for (size_t i = 2; i < numArgs; ++i) {  // 2: func and newTarget
2019                     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2020                     newSp[index++] = GET_VREG(firstArgRegIdx + i);
2021                 }
2022 
2023                 InterpretedFrame *state = GET_FRAME(newSp);
2024                 state->base.prev = sp;
2025                 state->base.type = FrameType::INTERPRETER_FRAME;
2026                 state->pc = nullptr;
2027                 state->sp = newSp;
2028                 state->function = ctor;
2029                 thread->SetCurrentSPFrame(newSp);
2030                 LOG(DEBUG, INTERPRETER) << "Entry: Runtime New.";
2031                 JSTaggedValue retValue = reinterpret_cast<EcmaEntrypoint>(
2032                     const_cast<void *>(ctorMethod->GetNativePointer()))(&ecmaRuntimeCallInfo);
2033 
2034                 thread->SetCurrentSPFrame(sp);
2035                 if (UNLIKELY(thread->HasPendingException())) {
2036                     INTERPRETER_GOTO_EXCEPTION_HANDLER();
2037                 }
2038                 LOG(DEBUG, INTERPRETER) << "Exit: Runtime New.";
2039                 SET_ACC(retValue);
2040                 DISPATCH(BytecodeInstruction::Format::PREF_IMM16_V8);
2041             }
2042 
2043             if (IsFastNewFrameEnter(ctorMethod)) {
2044                 SAVE_PC();
2045                 uint32_t numVregs = ctorMethod->GetNumVregsWithCallField();
2046                 uint32_t numDeclaredArgs = ctorMethod->GetNumArgsWithCallField() + 1;  // +1 for this
2047                 // +1 for hidden this, explicit this may be overwritten after bc optimizer
2048                 size_t frameSize = FRAME_STATE_SIZE + numVregs + numDeclaredArgs + 1;
2049                 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2050                 JSTaggedType *newSp = sp - frameSize;
2051                 InterpretedFrame *state = GET_FRAME(newSp);
2052 
2053                 if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
2054                     INTERPRETER_GOTO_EXCEPTION_HANDLER();
2055                 }
2056 
2057                 uint32_t index = 0;
2058                 // initialize vregs value
2059                 for (size_t i = 0; i < numVregs; ++i) {
2060                     newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
2061                 }
2062 
2063                 // this
2064                 JSTaggedValue thisObj;
2065                 if (ctorFunc->IsBase()) {
2066                     JSTaggedValue newTarget = GET_VREG_VALUE(firstArgRegIdx + 1);
2067                     thisObj = FastRuntimeStub::NewThisObject(thread, ctor, newTarget, state);
2068                     INTERPRETER_RETURN_IF_ABRUPT(thisObj);
2069                     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2070                     newSp[index++] = thisObj.GetRawData();
2071                 } else {
2072                     ASSERT(ctorFunc->IsDerivedConstructor());
2073                     thisObj = JSTaggedValue::Undefined();
2074                     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2075                     newSp[index++] = thisObj.GetRawData();
2076 
2077                     state->function = ctor;
2078                     state->constpool = ctorFunc->GetConstantPool();
2079                     state->profileTypeInfo = ctorFunc->GetProfileTypeInfo();
2080                     state->env = ctorFunc->GetLexicalEnv();
2081                 }
2082 
2083                 // the second condition ensure not push extra args
2084                 for (size_t i = 2; i < numArgs && index < numVregs + numDeclaredArgs; ++i) {  // 2: func and newTarget
2085                     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2086                     newSp[index++] = GET_VREG(firstArgRegIdx + i);
2087                 }
2088 
2089                 // set undefined to the extra prats of declare
2090                 for (size_t i = index; i < numVregs + numDeclaredArgs; ++i) {
2091                     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2092                     newSp[index++] = JSTaggedValue::VALUE_UNDEFINED;
2093                 }
2094 
2095                 // hidden this object
2096                 newSp[index] = thisObj.GetRawData();
2097 
2098                 state->base.prev = sp;
2099                 state->base.type = FrameType::INTERPRETER_FAST_NEW_FRAME;
2100                 state->pc = pc = ctorMethod->GetBytecodeArray();
2101                 state->sp = sp = newSp;
2102                 state->acc = JSTaggedValue::Hole();
2103                 constpool = ConstantPool::Cast(state->constpool.GetTaggedObject());
2104 
2105                 thread->SetCurrentSPFrame(newSp);
2106                 LOG(DEBUG, INTERPRETER) << "Entry: Runtime New " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
2107                                         << std::hex << reinterpret_cast<uintptr_t>(pc);
2108                 DISPATCH_OFFSET(0);
2109             }
2110         }
2111 
2112         // bound function, proxy, other call types, enter slow path
2113         constexpr uint16_t firstArgOffset = 2;
2114         JSTaggedValue newTarget = GET_VREG_VALUE(firstArgRegIdx + 1);
2115         // Exclude func and newTarget
2116         uint16_t firstArgIdx = firstArgRegIdx + firstArgOffset;
2117         uint16_t length = numArgs - firstArgOffset;
2118 
2119         SAVE_PC();
2120         JSTaggedValue res = SlowRuntimeStub::NewObjDynRange(thread, ctor, newTarget, firstArgIdx, length);
2121         INTERPRETER_RETURN_IF_ABRUPT(res);
2122         SET_ACC(res);
2123         DISPATCH(BytecodeInstruction::Format::PREF_IMM16_V8);
2124     }
2125     HANDLE_OPCODE(HANDLE_EXPDYN_PREF_V8) {
2126         uint16_t v0 = READ_INST_8_1();
2127         LOG_INST() << "intrinsics::expdyn"
2128                    << " v" << v0;
2129         JSTaggedValue base = GET_VREG_VALUE(v0);
2130         JSTaggedValue exponent = GET_ACC();
2131         if (base.IsNumber() && exponent.IsNumber()) {
2132             // fast path
2133             double doubleBase = base.IsInt() ? base.GetInt() : base.GetDouble();
2134             double doubleExponent = exponent.IsInt() ? exponent.GetInt() : exponent.GetDouble();
2135             if (std::abs(doubleBase) == 1 && std::isinf(doubleExponent)) {
2136                 SET_ACC(JSTaggedValue(base::NAN_VALUE));
2137             }
2138             if ((doubleBase == 0 &&
2139                 ((bit_cast<uint64_t>(doubleBase)) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) &&
2140                 std::isfinite(doubleExponent) && base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent &&
2141                 base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF ==  // 2 : half
2142                 (doubleExponent / 2)) {  // 2 : half
2143                 if (doubleExponent > 0) {
2144                     SET_ACC(JSTaggedValue(-0.0));
2145                 }
2146                 if (doubleExponent < 0) {
2147                     SET_ACC(JSTaggedValue(-base::POSITIVE_INFINITY));
2148                 }
2149             }
2150             SET_ACC(JSTaggedValue(std::pow(doubleBase, doubleExponent)));
2151         } else {
2152             // slow path
2153             SAVE_PC();
2154             JSTaggedValue res = SlowRuntimeStub::ExpDyn(thread, base, exponent);
2155             INTERPRETER_RETURN_IF_ABRUPT(res);
2156             SET_ACC(res);
2157         }
2158         DISPATCH(BytecodeInstruction::Format::PREF_V8);
2159     }
2160     HANDLE_OPCODE(HANDLE_ISINDYN_PREF_V8) {
2161         uint16_t v0 = READ_INST_8_1();
2162         LOG_INST() << "intrinsics::isindyn"
2163                    << " v" << v0;
2164         JSTaggedValue prop = GET_VREG_VALUE(v0);
2165         JSTaggedValue obj = GET_ACC();
2166         SAVE_PC();
2167         JSTaggedValue res = SlowRuntimeStub::IsInDyn(thread, prop, obj);
2168         INTERPRETER_RETURN_IF_ABRUPT(res);
2169         SET_ACC(res);
2170         DISPATCH(BytecodeInstruction::Format::PREF_V8);
2171     }
2172     HANDLE_OPCODE(HANDLE_INSTANCEOFDYN_PREF_V8) {
2173         uint16_t v0 = READ_INST_8_1();
2174         LOG_INST() << "intrinsics::instanceofdyn"
2175                    << " v" << v0;
2176         JSTaggedValue obj = GET_VREG_VALUE(v0);
2177         JSTaggedValue target = GET_ACC();
2178         SAVE_PC();
2179         JSTaggedValue res = SlowRuntimeStub::InstanceofDyn(thread, obj, target);
2180         INTERPRETER_RETURN_IF_ABRUPT(res);
2181         SET_ACC(res);
2182         DISPATCH(BytecodeInstruction::Format::PREF_V8);
2183     }
2184     HANDLE_OPCODE(HANDLE_STRICTNOTEQDYN_PREF_V8) {
2185         uint16_t v0 = READ_INST_8_1();
2186         LOG_INST() << "intrinsics::strictnoteq"
2187                    << " v" << v0;
2188         JSTaggedValue left = GET_VREG_VALUE(v0);
2189         JSTaggedValue right = GET_ACC();
2190         bool res = FastRuntimeStub::FastStrictEqual(left, right);
2191         SET_ACC(JSTaggedValue(!res));
2192         DISPATCH(BytecodeInstruction::Format::PREF_V8);
2193     }
2194     HANDLE_OPCODE(HANDLE_STRICTEQDYN_PREF_V8) {
2195         uint16_t v0 = READ_INST_8_1();
2196         LOG_INST() << "intrinsics::stricteq"
2197                    << " v" << v0;
2198         JSTaggedValue left = GET_VREG_VALUE(v0);
2199         JSTaggedValue right = GET_ACC();
2200         bool res = FastRuntimeStub::FastStrictEqual(left, right);
2201         SET_ACC(JSTaggedValue(res));
2202         DISPATCH(BytecodeInstruction::Format::PREF_V8);
2203     }
2204     HANDLE_OPCODE(HANDLE_LDLEXVARDYN_PREF_IMM16_IMM16) {
2205         uint16_t level = READ_INST_16_1();
2206         uint16_t slot = READ_INST_16_3();
2207 
2208         LOG_INST() << "intrinsics::ldlexvardyn"
2209                    << " level:" << level << " slot:" << slot;
2210         InterpretedFrame *state = GET_FRAME(sp);
2211         JSTaggedValue currentLexenv = state->env;
2212         JSTaggedValue env(currentLexenv);
2213         for (int i = 0; i < level; i++) {
2214             JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
2215             ASSERT(!taggedParentEnv.IsUndefined());
2216             env = taggedParentEnv;
2217         }
2218         SET_ACC(LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot));
2219         DISPATCH(BytecodeInstruction::Format::PREF_IMM16_IMM16);
2220     }
2221     HANDLE_OPCODE(HANDLE_LDLEXVARDYN_PREF_IMM8_IMM8) {
2222         uint16_t level = READ_INST_8_1();
2223         uint16_t slot = READ_INST_8_2();
2224 
2225         LOG_INST() << "intrinsics::ldlexvardyn"
2226                    << " level:" << level << " slot:" << slot;
2227         InterpretedFrame *state = GET_FRAME(sp);
2228         JSTaggedValue currentLexenv = state->env;
2229         JSTaggedValue env(currentLexenv);
2230         for (int i = 0; i < level; i++) {
2231             JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
2232             ASSERT(!taggedParentEnv.IsUndefined());
2233             env = taggedParentEnv;
2234         }
2235         SET_ACC(LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot));
2236         DISPATCH(BytecodeInstruction::Format::PREF_IMM8_IMM8);
2237     }
2238     HANDLE_OPCODE(HANDLE_LDLEXVARDYN_PREF_IMM4_IMM4) {
2239         uint16_t level = READ_INST_4_2();
2240         uint16_t slot = READ_INST_4_3();
2241 
2242         LOG_INST() << "intrinsics::ldlexvardyn"
2243                    << " level:" << level << " slot:" << slot;
2244         InterpretedFrame *state = GET_FRAME(sp);
2245         JSTaggedValue currentLexenv = state->env;
2246         JSTaggedValue env(currentLexenv);
2247         for (int i = 0; i < level; i++) {
2248             JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
2249             ASSERT(!taggedParentEnv.IsUndefined());
2250             env = taggedParentEnv;
2251         }
2252         SET_ACC(LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot));
2253         DISPATCH(BytecodeInstruction::Format::PREF_IMM4_IMM4);
2254     }
2255     HANDLE_OPCODE(HANDLE_STLEXVARDYN_PREF_IMM16_IMM16_V8) {
2256         uint16_t level = READ_INST_16_1();
2257         uint16_t slot = READ_INST_16_3();
2258         uint16_t v0 = READ_INST_8_5();
2259         LOG_INST() << "intrinsics::stlexvardyn"
2260                    << " level:" << level << " slot:" << slot << " v" << v0;
2261 
2262         JSTaggedValue value = GET_VREG_VALUE(v0);
2263         InterpretedFrame *state = GET_FRAME(sp);
2264         JSTaggedValue env = state->env;
2265         for (int i = 0; i < level; i++) {
2266             JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
2267             ASSERT(!taggedParentEnv.IsUndefined());
2268             env = taggedParentEnv;
2269         }
2270         LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value);
2271 
2272         DISPATCH(BytecodeInstruction::Format::PREF_IMM16_IMM16_V8);
2273     }
2274     HANDLE_OPCODE(HANDLE_NEWLEXENVWITHNAMEDYN_PREF_IMM16_IMM16) {
2275         uint16_t numVars = READ_INST_16_1();
2276         uint16_t scopeId = READ_INST_16_3();
2277         LOG_INST() << "intrinsics::newlexenvwithnamedyn"
2278                    << " numVars " << numVars << " scopeId " << scopeId;
2279 
2280         SAVE_PC();
2281         JSTaggedValue res = SlowRuntimeStub::NewLexicalEnvWithNameDyn(thread, numVars, scopeId);
2282         INTERPRETER_RETURN_IF_ABRUPT(res);
2283 
2284         SET_ACC(res);
2285         GET_FRAME(sp)->env = res;
2286         DISPATCH(BytecodeInstruction::Format::PREF_IMM16_IMM16);
2287     }
2288     HANDLE_OPCODE(HANDLE_STLEXVARDYN_PREF_IMM8_IMM8_V8) {
2289         uint16_t level = READ_INST_8_1();
2290         uint16_t slot = READ_INST_8_2();
2291         uint16_t v0 = READ_INST_8_3();
2292         LOG_INST() << "intrinsics::stlexvardyn"
2293                    << " level:" << level << " slot:" << slot << " v" << v0;
2294 
2295         JSTaggedValue value = GET_VREG_VALUE(v0);
2296         InterpretedFrame *state = GET_FRAME(sp);
2297         JSTaggedValue env = state->env;
2298         for (int i = 0; i < level; i++) {
2299             JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
2300             ASSERT(!taggedParentEnv.IsUndefined());
2301             env = taggedParentEnv;
2302         }
2303         LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value);
2304 
2305         DISPATCH(BytecodeInstruction::Format::PREF_IMM8_IMM8_V8);
2306     }
2307     HANDLE_OPCODE(HANDLE_STLEXVARDYN_PREF_IMM4_IMM4_V8) {
2308         uint16_t level = READ_INST_4_2();
2309         uint16_t slot = READ_INST_4_3();
2310         uint16_t v0 = READ_INST_8_2();
2311         LOG_INST() << "intrinsics::stlexvardyn"
2312                    << " level:" << level << " slot:" << slot << " v" << v0;
2313 
2314         JSTaggedValue value = GET_VREG_VALUE(v0);
2315         InterpretedFrame *state = GET_FRAME(sp);
2316         JSTaggedValue env = state->env;
2317         for (int i = 0; i < level; i++) {
2318             JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
2319             ASSERT(!taggedParentEnv.IsUndefined());
2320             env = taggedParentEnv;
2321         }
2322         LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value);
2323 
2324         DISPATCH(BytecodeInstruction::Format::PREF_IMM4_IMM4_V8);
2325     }
2326     HANDLE_OPCODE(HANDLE_NEWLEXENVDYN_PREF_IMM16) {
2327         uint16_t numVars = READ_INST_16_1();
2328         LOG_INST() << "intrinsics::newlexenvdyn"
2329                    << " imm " << numVars;
2330 
2331         JSTaggedValue res = FastRuntimeStub::NewLexicalEnvDyn(thread, factory, numVars);
2332         if (res.IsHole()) {
2333             SAVE_PC();
2334             res = SlowRuntimeStub::NewLexicalEnvDyn(thread, numVars);
2335             INTERPRETER_RETURN_IF_ABRUPT(res);
2336         }
2337         SET_ACC(res);
2338         GET_FRAME(sp)->env = res;
2339         DISPATCH(BytecodeInstruction::Format::PREF_IMM16);
2340     }
2341     HANDLE_OPCODE(HANDLE_POPLEXENVDYN_PREF) {
2342         InterpretedFrame *state = GET_FRAME(sp);
2343         JSTaggedValue currentLexenv = state->env;
2344         JSTaggedValue parentLexenv = LexicalEnv::Cast(currentLexenv.GetTaggedObject())->GetParentEnv();
2345         GET_FRAME(sp)->env = parentLexenv;
2346         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
2347     }
2348     HANDLE_OPCODE(HANDLE_CREATEITERRESULTOBJ_PREF_V8_V8) {
2349         uint16_t v0 = READ_INST_8_1();
2350         uint16_t v1 = READ_INST_8_2();
2351         LOG_INST() << "intrinsics::createiterresultobj"
2352                    << " v" << v0 << " v" << v1;
2353         JSTaggedValue value = GET_VREG_VALUE(v0);
2354         JSTaggedValue flag = GET_VREG_VALUE(v1);
2355         SAVE_PC();
2356         JSTaggedValue res = SlowRuntimeStub::CreateIterResultObj(thread, value, flag);
2357         INTERPRETER_RETURN_IF_ABRUPT(res);
2358         SET_ACC(res);
2359         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2360     }
2361     HANDLE_OPCODE(HANDLE_SUSPENDGENERATOR_PREF_V8_V8) {
2362         uint16_t v0 = READ_INST_8_1();
2363         uint16_t v1 = READ_INST_8_2();
2364         LOG_INST() << "intrinsics::suspendgenerator"
2365                    << " v" << v0 << " v" << v1;
2366         JSTaggedValue genObj = GET_VREG_VALUE(v0);
2367         JSTaggedValue value = GET_VREG_VALUE(v1);
2368         // suspend will record bytecode offset
2369         SAVE_PC();
2370         SAVE_ACC();
2371         JSTaggedValue res = SlowRuntimeStub::SuspendGenerator(thread, genObj, value);
2372         INTERPRETER_RETURN_IF_ABRUPT(res);
2373         SET_ACC(res);
2374 
2375         InterpretedFrame *state = GET_FRAME(sp);
2376         JSMethod *method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
2377         [[maybe_unused]] auto fistPC = method->GetInstructions();
2378         UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
2379         LOG(DEBUG, INTERPRETER) << "Exit: SuspendGenerator " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
2380                                 << std::hex << reinterpret_cast<uintptr_t>(state->pc);
2381         sp = state->base.prev;
2382         ASSERT(sp != nullptr);
2383         InterpretedFrame *prevState = GET_FRAME(sp);
2384         pc = prevState->pc;
2385 
2386         // break frame
2387         if (pc == nullptr) {
2388             state->acc = acc;
2389             return;
2390         }
2391         thread->SetCurrentSPFrame(sp);
2392         constpool = ConstantPool::Cast(prevState->constpool.GetTaggedObject());
2393 
2394         INTERPRETER_HANDLE_RETURN();
2395     }
2396     HANDLE_OPCODE(HANDLE_ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8) {
2397         uint16_t v0 = READ_INST_8_1();
2398         uint16_t v1 = READ_INST_8_2();
2399         LOG_INST() << "intrinsics::asyncfunctionawaituncaught"
2400                    << " v" << v0 << " v" << v1;
2401         JSTaggedValue asyncFuncObj = GET_VREG_VALUE(v0);
2402         JSTaggedValue value = GET_VREG_VALUE(v1);
2403         SAVE_PC();
2404         JSTaggedValue res = SlowRuntimeStub::AsyncFunctionAwaitUncaught(thread, asyncFuncObj, value);
2405         INTERPRETER_RETURN_IF_ABRUPT(res);
2406         SET_ACC(res);
2407         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2408     }
2409     HANDLE_OPCODE(HANDLE_ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8) {
2410         uint16_t v0 = READ_INST_8_1();
2411         [[maybe_unused]] uint16_t v1 = READ_INST_8_2();
2412         uint16_t v2 = READ_INST_8_3();
2413         LOG_INST() << "intrinsics::asyncfunctionresolve"
2414                    << " v" << v0 << " v" << v1 << " v" << v2;
2415 
2416         JSTaggedValue asyncFuncObj = GET_VREG_VALUE(v0);
2417         JSTaggedValue value = GET_VREG_VALUE(v2);
2418         SAVE_PC();
2419         JSTaggedValue res = SlowRuntimeStub::AsyncFunctionResolveOrReject(thread, asyncFuncObj, value, true);
2420         INTERPRETER_RETURN_IF_ABRUPT(res);
2421         SET_ACC(res);
2422         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8_V8);
2423     }
2424     HANDLE_OPCODE(HANDLE_ASYNCFUNCTIONREJECT_PREF_V8_V8_V8) {
2425         uint16_t v0 = READ_INST_8_1();
2426         [[maybe_unused]] uint16_t v1 = READ_INST_8_2();
2427         uint16_t v2 = READ_INST_8_3();
2428         LOG_INST() << "intrinsics::asyncfunctionreject"
2429                    << " v" << v0 << " v" << v1 << " v" << v2;
2430 
2431         JSTaggedValue asyncFuncObj = GET_VREG_VALUE(v0);
2432         JSTaggedValue value = GET_VREG_VALUE(v2);
2433         SAVE_ACC();
2434         SAVE_PC();
2435         JSTaggedValue res = SlowRuntimeStub::AsyncFunctionResolveOrReject(thread, asyncFuncObj, value, false);
2436         INTERPRETER_RETURN_IF_ABRUPT(res);
2437         RESTORE_ACC();
2438         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8_V8);
2439     }
2440     HANDLE_OPCODE(HANDLE_NEWOBJSPREADDYN_PREF_V8_V8) {
2441         uint16_t v0 = READ_INST_8_1();
2442         uint16_t v1 = READ_INST_8_2();
2443         LOG_INST() << "intrinsic::newobjspearddyn"
2444                    << " v" << v0 << " v" << v1;
2445         JSTaggedValue func = GET_VREG_VALUE(v0);
2446         JSTaggedValue newTarget = GET_VREG_VALUE(v1);
2447         JSTaggedValue array = GET_ACC();
2448         SAVE_PC();
2449         JSTaggedValue res = SlowRuntimeStub::NewObjSpreadDyn(thread, func, newTarget, array);
2450         INTERPRETER_RETURN_IF_ABRUPT(res);
2451         SET_ACC(res);
2452         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2453     }
2454     HANDLE_OPCODE(HANDLE_THROWUNDEFINEDIFHOLE_PREF_V8_V8) {
2455         uint16_t v0 = READ_INST_8_1();
2456         uint16_t v1 = READ_INST_8_2();
2457         LOG_INST() << "intrinsic::throwundefinedifhole"
2458                    << " v" << v0 << " v" << v1;
2459         JSTaggedValue hole = GET_VREG_VALUE(v0);
2460         if (!hole.IsHole()) {
2461             DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2462         }
2463         JSTaggedValue obj = GET_VREG_VALUE(v1);
2464         ASSERT(obj.IsString());
2465         SAVE_PC();
2466         SlowRuntimeStub::ThrowUndefinedIfHole(thread, obj);
2467         INTERPRETER_GOTO_EXCEPTION_HANDLER();
2468     }
2469     HANDLE_OPCODE(HANDLE_STOWNBYNAME_PREF_ID32_V8) {
2470         uint32_t stringId = READ_INST_32_1();
2471         uint32_t v0 = READ_INST_8_5();
2472         LOG_INST() << "intrinsics::stownbyname "
2473                    << "v" << v0 << " stringId:" << stringId;
2474 
2475         JSTaggedValue receiver = GET_VREG_VALUE(v0);
2476         if (receiver.IsJSObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
2477             JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
2478             JSTaggedValue value = GET_ACC();
2479             // fast path
2480             SAVE_ACC();
2481 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
2482             auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(SetPropertyByNameWithOwn));
2483             typedef JSTaggedType (*PFSetPropertyByName)(uintptr_t, JSTaggedType, JSTaggedType, JSTaggedType);
2484             auto setPropertyByNamePtr = reinterpret_cast<PFSetPropertyByName>(stubAddr);
2485             JSTaggedValue res = JSTaggedValue(setPropertyByNamePtr(thread->GetGlueAddr(),
2486                 receiver.GetRawData(), propKey.GetRawData(), value.GetRawData()));
2487 #else
2488             JSTaggedValue res = FastRuntimeStub::SetPropertyByName<true>(thread, receiver, propKey, value);
2489 #endif
2490             if (!res.IsHole()) {
2491                 INTERPRETER_RETURN_IF_ABRUPT(res);
2492                 RESTORE_ACC();
2493                 DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
2494             }
2495             RESTORE_ACC();
2496         }
2497 
2498         SAVE_ACC();
2499         receiver = GET_VREG_VALUE(v0);                           // Maybe moved by GC
2500         auto propKey = constpool->GetObjectFromCache(stringId);  // Maybe moved by GC
2501         auto value = GET_ACC();                                  // Maybe moved by GC
2502         SAVE_PC();
2503         JSTaggedValue res = SlowRuntimeStub::StOwnByName(thread, receiver, propKey, value);
2504         RESTORE_ACC();
2505         INTERPRETER_RETURN_IF_ABRUPT(res);
2506         DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
2507     }
2508     HANDLE_OPCODE(HANDLE_CREATEEMPTYARRAY_PREF) {
2509         LOG_INST() << "intrinsics::createemptyarray";
2510         SAVE_PC();
2511         JSTaggedValue res = SlowRuntimeStub::CreateEmptyArray(thread, factory, globalEnv);
2512         SET_ACC(res);
2513         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
2514     }
2515     HANDLE_OPCODE(HANDLE_CREATEEMPTYOBJECT_PREF) {
2516         LOG_INST() << "intrinsics::createemptyobject";
2517         SAVE_PC();
2518         JSTaggedValue res = SlowRuntimeStub::CreateEmptyObject(thread, factory, globalEnv);
2519         SET_ACC(res);
2520         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
2521     }
2522     HANDLE_OPCODE(HANDLE_CREATEOBJECTWITHBUFFER_PREF_IMM16) {
2523         uint16_t imm = READ_INST_16_1();
2524         LOG_INST() << "intrinsics::createobjectwithbuffer"
2525                    << " imm:" << imm;
2526         JSObject *result = JSObject::Cast(constpool->GetObjectFromCache(imm).GetTaggedObject());
2527 
2528         SAVE_PC();
2529         JSTaggedValue res = SlowRuntimeStub::CreateObjectWithBuffer(thread, factory, result);
2530         INTERPRETER_RETURN_IF_ABRUPT(res);
2531         SET_ACC(res);
2532         DISPATCH(BytecodeInstruction::Format::PREF_IMM16);
2533     }
2534     HANDLE_OPCODE(HANDLE_SETOBJECTWITHPROTO_PREF_V8_V8) {
2535         uint16_t v0 = READ_INST_8_1();
2536         uint16_t v1 = READ_INST_8_2();
2537         LOG_INST() << "intrinsics::setobjectwithproto"
2538                    << " v" << v0 << " v" << v1;
2539         JSTaggedValue proto = GET_VREG_VALUE(v0);
2540         JSTaggedValue obj = GET_VREG_VALUE(v1);
2541         SAVE_ACC();
2542         SAVE_PC();
2543         JSTaggedValue res = SlowRuntimeStub::SetObjectWithProto(thread, proto, obj);
2544         INTERPRETER_RETURN_IF_ABRUPT(res);
2545         RESTORE_ACC();
2546         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2547     }
2548     HANDLE_OPCODE(HANDLE_CREATEARRAYWITHBUFFER_PREF_IMM16) {
2549         uint16_t imm = READ_INST_16_1();
2550         LOG_INST() << "intrinsics::createarraywithbuffer"
2551                    << " imm:" << imm;
2552         JSArray *result = JSArray::Cast(constpool->GetObjectFromCache(imm).GetTaggedObject());
2553         SAVE_PC();
2554         JSTaggedValue res = SlowRuntimeStub::CreateArrayWithBuffer(thread, factory, result);
2555         INTERPRETER_RETURN_IF_ABRUPT(res);
2556         SET_ACC(res);
2557         DISPATCH(BytecodeInstruction::Format::PREF_IMM16);
2558     }
2559     HANDLE_OPCODE(HANDLE_IMPORTMODULE_PREF_ID32) {
2560         uint32_t stringId = READ_INST_32_1();
2561         auto prop = constpool->GetObjectFromCache(stringId);
2562 
2563         LOG_INST() << "intrinsics::importmodule "
2564                    << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(prop.GetTaggedObject()));
2565 
2566         JSTaggedValue moduleRef = SlowRuntimeStub::ImportModule(thread, prop);
2567         SET_ACC(moduleRef);
2568         DISPATCH(BytecodeInstruction::Format::PREF_ID32);
2569     }
2570     HANDLE_OPCODE(HANDLE_STMODULEVAR_PREF_ID32) {
2571         uint32_t stringId = READ_INST_32_1();
2572         auto prop = constpool->GetObjectFromCache(stringId);
2573 
2574         LOG_INST() << "intrinsics::stmodulevar "
2575                    << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(prop.GetTaggedObject()));
2576 
2577         JSTaggedValue value = GET_ACC();
2578 
2579         SAVE_ACC();
2580         SlowRuntimeStub::StModuleVar(thread, prop, value);
2581         RESTORE_ACC();
2582         DISPATCH(BytecodeInstruction::Format::PREF_ID32);
2583     }
2584     HANDLE_OPCODE(HANDLE_COPYMODULE_PREF_V8) {
2585         uint16_t v0 = READ_INST_8_1();
2586         JSTaggedValue srcModule = GET_VREG_VALUE(v0);
2587 
2588         LOG_INST() << "intrinsics::copymodule ";
2589 
2590         SAVE_ACC();
2591         SlowRuntimeStub::CopyModule(thread, srcModule);
2592         RESTORE_ACC();
2593         DISPATCH(BytecodeInstruction::Format::PREF_V8);
2594     }
2595     HANDLE_OPCODE(HANDLE_LDMODVARBYNAME_PREF_ID32_V8) {
2596         uint32_t stringId = READ_INST_32_1();
2597         uint32_t v0 = READ_INST_8_5();
2598 
2599         JSTaggedValue itemName = constpool->GetObjectFromCache(stringId);
2600         JSTaggedValue moduleObj = GET_VREG_VALUE(v0);
2601         LOG_INST() << "intrinsics::ldmodvarbyname "
2602                    << "string_id:" << stringId << ", "
2603                    << "itemName: " << ConvertToString(EcmaString::Cast(itemName.GetTaggedObject()));
2604 
2605         JSTaggedValue moduleVar = SlowRuntimeStub::LdModvarByName(thread, moduleObj, itemName);
2606         SET_ACC(moduleVar);
2607         DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
2608     }
2609     HANDLE_OPCODE(HANDLE_CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8) {
2610         uint32_t stringId = READ_INST_32_1();
2611         JSTaggedValue pattern = constpool->GetObjectFromCache(stringId);
2612         uint8_t flags = READ_INST_8_5();
2613         LOG_INST() << "intrinsics::createregexpwithliteral "
2614                    << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(pattern.GetTaggedObject()))
2615                    << ", flags:" << flags;
2616         SAVE_PC();
2617         JSTaggedValue res = SlowRuntimeStub::CreateRegExpWithLiteral(thread, pattern, flags);
2618         INTERPRETER_RETURN_IF_ABRUPT(res);
2619         SET_ACC(res);
2620         DISPATCH(BytecodeInstruction::Format::PREF_ID32_IMM8);
2621     }
2622     HANDLE_OPCODE(HANDLE_GETTEMPLATEOBJECT_PREF_V8) {
2623         uint16_t v0 = READ_INST_8_1();
2624         LOG_INST() << "intrinsic::gettemplateobject"
2625                    << " v" << v0;
2626 
2627         JSTaggedValue literal = GET_VREG_VALUE(v0);
2628         SAVE_PC();
2629         JSTaggedValue res = SlowRuntimeStub::GetTemplateObject(thread, literal);
2630         INTERPRETER_RETURN_IF_ABRUPT(res);
2631         SET_ACC(res);
2632         DISPATCH(BytecodeInstruction::Format::PREF_V8);
2633     }
2634     HANDLE_OPCODE(HANDLE_GETNEXTPROPNAME_PREF_V8) {
2635         uint16_t v0 = READ_INST_8_1();
2636         LOG_INST() << "intrinsic::getnextpropname"
2637                    << " v" << v0;
2638         JSTaggedValue iter = GET_VREG_VALUE(v0);
2639         SAVE_PC();
2640         JSTaggedValue res = SlowRuntimeStub::GetNextPropName(thread, iter);
2641         INTERPRETER_RETURN_IF_ABRUPT(res);
2642         SET_ACC(res);
2643         DISPATCH(BytecodeInstruction::Format::PREF_V8);
2644     }
2645     HANDLE_OPCODE(HANDLE_COPYDATAPROPERTIES_PREF_V8_V8) {
2646         uint16_t v0 = READ_INST_8_1();
2647         uint16_t v1 = READ_INST_8_2();
2648         LOG_INST() << "intrinsic::copydataproperties"
2649                    << " v" << v0 << " v" << v1;
2650         JSTaggedValue dst = GET_VREG_VALUE(v0);
2651         JSTaggedValue src = GET_VREG_VALUE(v1);
2652         SAVE_PC();
2653         JSTaggedValue res = SlowRuntimeStub::CopyDataProperties(thread, dst, src);
2654         INTERPRETER_RETURN_IF_ABRUPT(res);
2655         SET_ACC(res);
2656         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2657     }
2658     HANDLE_OPCODE(HANDLE_STOWNBYINDEX_PREF_V8_IMM32) {
2659         uint32_t v0 = READ_INST_8_1();
2660         uint32_t index = READ_INST_32_2();
2661         LOG_INST() << "intrinsics::stownbyindex"
2662                    << " v" << v0 << " imm" << index;
2663         JSTaggedValue receiver = GET_VREG_VALUE(v0);
2664         // fast path
2665         if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
2666             SAVE_ACC();
2667             JSTaggedValue value = GET_ACC();
2668             // fast path
2669             JSTaggedValue res =
2670                 FastRuntimeStub::SetPropertyByIndex<true>(thread, receiver, index, value);
2671             if (!res.IsHole()) {
2672                 INTERPRETER_RETURN_IF_ABRUPT(res);
2673                 RESTORE_ACC();
2674                 DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32);
2675             }
2676             RESTORE_ACC();
2677         }
2678         SAVE_ACC();
2679         receiver = GET_VREG_VALUE(v0);  // Maybe moved by GC
2680         auto value = GET_ACC();         // Maybe moved by GC
2681         SAVE_PC();
2682         JSTaggedValue res = SlowRuntimeStub::StOwnByIndex(thread, receiver, index, value);
2683         INTERPRETER_RETURN_IF_ABRUPT(res);
2684         RESTORE_ACC();
2685         DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32);
2686     }
2687     HANDLE_OPCODE(HANDLE_STOWNBYVALUE_PREF_V8_V8) {
2688         uint32_t v0 = READ_INST_8_1();
2689         uint32_t v1 = READ_INST_8_2();
2690         LOG_INST() << "intrinsics::stownbyvalue"
2691                    << " v" << v0 << " v" << v1;
2692 
2693         JSTaggedValue receiver = GET_VREG_VALUE(v0);
2694         if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
2695             SAVE_ACC();
2696             JSTaggedValue propKey = GET_VREG_VALUE(v1);
2697             JSTaggedValue value = GET_ACC();
2698             // fast path
2699             JSTaggedValue res = FastRuntimeStub::SetPropertyByValue<true>(thread, receiver, propKey, value);
2700 
2701             // SetPropertyByValue maybe gc need update the value
2702             RESTORE_ACC();
2703             propKey = GET_VREG_VALUE(v1);
2704             value = GET_ACC();
2705             if (!res.IsHole()) {
2706                 INTERPRETER_RETURN_IF_ABRUPT(res);
2707                 RESTORE_ACC();
2708                 DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2709             }
2710         }
2711 
2712         // slow path
2713         SAVE_ACC();
2714         receiver = GET_VREG_VALUE(v0);      // Maybe moved by GC
2715         auto propKey = GET_VREG_VALUE(v1);  // Maybe moved by GC
2716         auto value = GET_ACC();             // Maybe moved by GC
2717         SAVE_PC();
2718         JSTaggedValue res = SlowRuntimeStub::StOwnByValue(thread, receiver, propKey, value);
2719         RESTORE_ACC();
2720         INTERPRETER_RETURN_IF_ABRUPT(res);
2721         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2722     }
2723     HANDLE_OPCODE(HANDLE_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8) {
2724         uint16_t numKeys = READ_INST_16_1();
2725         uint16_t v0 = READ_INST_8_3();
2726         uint16_t firstArgRegIdx = READ_INST_8_4();
2727         LOG_INST() << "intrinsics::createobjectwithexcludedkeys " << numKeys << " v" << firstArgRegIdx;
2728 
2729         JSTaggedValue obj = GET_VREG_VALUE(v0);
2730 
2731         SAVE_PC();
2732         JSTaggedValue res = SlowRuntimeStub::CreateObjectWithExcludedKeys(thread, numKeys, obj, firstArgRegIdx);
2733         INTERPRETER_RETURN_IF_ABRUPT(res);
2734         SET_ACC(res);
2735         DISPATCH(BytecodeInstruction::Format::PREF_IMM16_V8_V8);
2736     }
2737     HANDLE_OPCODE(HANDLE_DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8) {
2738         uint16_t methodId = READ_INST_16_1();
2739         uint16_t length = READ_INST_16_3();
2740         uint16_t v0 = READ_INST_8_5();
2741         LOG_INST() << "define gengerator function length: " << length
2742                    << " v" << v0;
2743         JSFunction *result = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject());
2744         ASSERT(result != nullptr);
2745         if (result->GetResolved()) {
2746             SAVE_PC();
2747             auto res = SlowRuntimeStub::DefineGeneratorFunc(thread, result);
2748             INTERPRETER_RETURN_IF_ABRUPT(res);
2749             result = JSFunction::Cast(res.GetTaggedObject());
2750             result->SetConstantPool(thread, JSTaggedValue(constpool));
2751         } else {
2752             result->SetResolved(true);
2753         }
2754 
2755         result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length));
2756         JSTaggedValue env = GET_VREG_VALUE(v0);
2757         result->SetLexicalEnv(thread, env);
2758         SET_ACC(JSTaggedValue(result))
2759         DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8);
2760     }
2761     HANDLE_OPCODE(HANDLE_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8) {
2762         uint16_t methodId = READ_INST_16_1();
2763         uint16_t length = READ_INST_16_3();
2764         uint16_t v0 = READ_INST_8_5();
2765         LOG_INST() << "define async function length: " << length
2766                    << " v" << v0;
2767         JSFunction *result = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject());
2768         ASSERT(result != nullptr);
2769         if (result->GetResolved()) {
2770             SAVE_PC();
2771             auto res = SlowRuntimeStub::DefineAsyncFunc(thread, result);
2772             INTERPRETER_RETURN_IF_ABRUPT(res);
2773             result = JSFunction::Cast(res.GetTaggedObject());
2774             result->SetConstantPool(thread, JSTaggedValue(constpool));
2775         } else {
2776             result->SetResolved(true);
2777         }
2778 
2779         result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length));
2780         JSTaggedValue env = GET_VREG_VALUE(v0);
2781         result->SetLexicalEnv(thread, env);
2782         SET_ACC(JSTaggedValue(result))
2783         DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8);
2784     }
2785     HANDLE_OPCODE(HANDLE_LDHOLE_PREF) {
2786         LOG_INST() << "intrinsic::ldhole";
2787         SET_ACC(JSTaggedValue::Hole());
2788         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
2789     }
2790     HANDLE_OPCODE(HANDLE_COPYRESTARGS_PREF_IMM16) {
2791         uint16_t restIdx = READ_INST_16_1();
2792         LOG_INST() << "intrinsics::copyrestargs"
2793                    << " index: " << restIdx;
2794 
2795         uint32_t startIdx = 0;
2796         uint32_t restNumArgs = GetNumArgs(sp, restIdx, startIdx);
2797 
2798         SAVE_PC();
2799         JSTaggedValue res = SlowRuntimeStub::CopyRestArgs(thread, sp, restNumArgs, startIdx);
2800         INTERPRETER_RETURN_IF_ABRUPT(res);
2801         SET_ACC(res);
2802         DISPATCH(BytecodeInstruction::Format::PREF_IMM16);
2803     }
2804     HANDLE_OPCODE(HANDLE_DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8) {
2805         uint16_t v0 = READ_INST_8_1();
2806         uint16_t v1 = READ_INST_8_2();
2807         uint16_t v2 = READ_INST_8_3();
2808         uint16_t v3 = READ_INST_8_4();
2809         LOG_INST() << "intrinsics::definegettersetterbyvalue"
2810                    << " v" << v0 << " v" << v1 << " v" << v2 << " v" << v3;
2811 
2812         JSTaggedValue obj = GET_VREG_VALUE(v0);
2813         JSTaggedValue prop = GET_VREG_VALUE(v1);
2814         JSTaggedValue getter = GET_VREG_VALUE(v2);
2815         JSTaggedValue setter = GET_VREG_VALUE(v3);
2816         JSTaggedValue flag = GET_ACC();
2817         SAVE_PC();
2818         JSTaggedValue res =
2819             SlowRuntimeStub::DefineGetterSetterByValue(thread, obj, prop, getter, setter, flag.ToBoolean());
2820         INTERPRETER_RETURN_IF_ABRUPT(res);
2821         SET_ACC(res);
2822         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8_V8_V8);
2823     }
2824     HANDLE_OPCODE(HANDLE_LDOBJBYINDEX_PREF_V8_IMM32) {
2825         uint16_t v0 = READ_INST_8_1();
2826         uint32_t idx = READ_INST_32_2();
2827         LOG_INST() << "intrinsics::ldobjbyindex"
2828                    << " v" << v0 << " imm" << idx;
2829 
2830         JSTaggedValue receiver = GET_VREG_VALUE(v0);
2831         // fast path
2832         if (LIKELY(receiver.IsHeapObject())) {
2833 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
2834             auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(GetPropertyByIndex));
2835             typedef JSTaggedType (*PFGetPropertyByIndex)(uintptr_t, JSTaggedType, uint32_t);
2836             auto getPropertyByIndex = reinterpret_cast<PFGetPropertyByIndex>(stubAddr);
2837             JSTaggedValue res = JSTaggedValue(getPropertyByIndex(thread->GetGlueAddr(), receiver.GetRawData(), idx));
2838 #else
2839             JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, receiver, idx);
2840 #endif
2841             if (!res.IsHole()) {
2842                 INTERPRETER_RETURN_IF_ABRUPT(res);
2843                 SET_ACC(res);
2844                 DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32);
2845             }
2846         }
2847         // not meet fast condition or fast path return hole, walk slow path
2848         // slow stub not need receiver
2849         SAVE_PC();
2850         JSTaggedValue res = SlowRuntimeStub::LdObjByIndex(thread, receiver, idx, false, JSTaggedValue::Undefined());
2851         INTERPRETER_RETURN_IF_ABRUPT(res);
2852         SET_ACC(res);
2853         DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32);
2854     }
2855     HANDLE_OPCODE(HANDLE_STOBJBYINDEX_PREF_V8_IMM32) {
2856         uint16_t v0 = READ_INST_8_1();
2857         uint32_t index = READ_INST_32_2();
2858         LOG_INST() << "intrinsics::stobjbyindex"
2859                    << " v" << v0 << " imm" << index;
2860 
2861         JSTaggedValue receiver = GET_VREG_VALUE(v0);
2862         if (receiver.IsHeapObject()) {
2863             SAVE_ACC();
2864             JSTaggedValue value = GET_ACC();
2865             // fast path
2866 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
2867             auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(SetPropertyByIndex));
2868             typedef JSTaggedType (*PFSetPropertyByIndex)(uintptr_t, JSTaggedType, uint32_t, JSTaggedType);
2869             auto setPropertyByIndex = reinterpret_cast<PFSetPropertyByIndex>(stubAddr);
2870             JSTaggedValue res = JSTaggedValue(setPropertyByIndex(thread->GetGlueAddr(),
2871                 receiver.GetRawData(), index, value.GetRawData()));
2872 #else
2873             JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value);
2874 #endif
2875             if (!res.IsHole()) {
2876                 INTERPRETER_RETURN_IF_ABRUPT(res);
2877                 RESTORE_ACC();
2878                 DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32);
2879             }
2880             RESTORE_ACC();
2881         }
2882         // slow path
2883         SAVE_ACC();
2884         SAVE_PC();
2885         receiver = GET_VREG_VALUE(v0);    // Maybe moved by GC
2886         JSTaggedValue value = GET_ACC();  // Maybe moved by GC
2887         JSTaggedValue res = SlowRuntimeStub::StObjByIndex(thread, receiver, index, value);
2888         INTERPRETER_RETURN_IF_ABRUPT(res);
2889         RESTORE_ACC();
2890         DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32);
2891     }
2892     HANDLE_OPCODE(HANDLE_LDOBJBYVALUE_PREF_V8_V8) {
2893         uint32_t v0 = READ_INST_8_1();
2894         uint32_t v1 = READ_INST_8_2();
2895         LOG_INST() << "intrinsics::Ldobjbyvalue"
2896                    << " v" << v0 << " v" << v1;
2897 
2898         JSTaggedValue receiver = GET_VREG_VALUE(v0);
2899         JSTaggedValue propKey = GET_VREG_VALUE(v1);
2900 
2901 #if ECMASCRIPT_ENABLE_IC
2902         auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2903         if (!profileTypeInfo.IsUndefined()) {
2904             uint16_t slotId = READ_INST_8_0();
2905             auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
2906             JSTaggedValue firstValue = profileTypeArray->Get(slotId);
2907             JSTaggedValue res = JSTaggedValue::Hole();
2908 
2909             if (LIKELY(firstValue.IsHeapObject())) {
2910                 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
2911                 res = ICRuntimeStub::TryLoadICByValue(thread, receiver, propKey, firstValue, secondValue);
2912             }
2913             // IC miss and not enter the megamorphic state, store as polymorphic
2914             if (res.IsHole() && !firstValue.IsHole()) {
2915                 res = ICRuntimeStub::LoadICByValue(thread,
2916                                                    profileTypeArray,
2917                                                    receiver, propKey, slotId);
2918             }
2919 
2920             if (LIKELY(!res.IsHole())) {
2921                 INTERPRETER_RETURN_IF_ABRUPT(res);
2922                 SET_ACC(res);
2923                 DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2924             }
2925         }
2926 #endif
2927         // fast path
2928         if (LIKELY(receiver.IsHeapObject())) {
2929 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
2930             auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(GetPropertyByValue));
2931             typedef JSTaggedType (*PFGetPropertyByValue)(uintptr_t, JSTaggedType, JSTaggedType);
2932             auto getPropertyByValuePtr = reinterpret_cast<PFGetPropertyByValue>(stubAddr);
2933             JSTaggedValue res = JSTaggedValue(getPropertyByValuePtr(thread->GetGlueAddr(),
2934                 receiver.GetRawData(), propKey.GetRawData()));
2935 #else
2936             JSTaggedValue res = FastRuntimeStub::GetPropertyByValue(thread, receiver, propKey);
2937 #endif
2938             if (!res.IsHole()) {
2939                 ASSERT(!res.IsAccessor());
2940                 INTERPRETER_RETURN_IF_ABRUPT(res);
2941                 SET_ACC(res);
2942                 DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2943             }
2944         }
2945         // slow path
2946         SAVE_PC();
2947         JSTaggedValue res = SlowRuntimeStub::LdObjByValue(thread, receiver, propKey, false, JSTaggedValue::Undefined());
2948         INTERPRETER_RETURN_IF_ABRUPT(res);
2949         SET_ACC(res);
2950         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2951     }
2952     HANDLE_OPCODE(HANDLE_STOBJBYVALUE_PREF_V8_V8) {
2953         uint32_t v0 = READ_INST_8_1();
2954         uint32_t v1 = READ_INST_8_2();
2955 
2956         LOG_INST() << "intrinsics::stobjbyvalue"
2957                    << " v" << v0 << " v" << v1;
2958 
2959         JSTaggedValue receiver = GET_VREG_VALUE(v0);
2960 #if ECMASCRIPT_ENABLE_IC
2961         auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
2962         if (!profileTypeInfo.IsUndefined()) {
2963             uint16_t slotId = READ_INST_8_0();
2964             auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
2965             JSTaggedValue firstValue = profileTypeArray->Get(slotId);
2966             JSTaggedValue propKey = GET_VREG_VALUE(v1);
2967             JSTaggedValue value = GET_ACC();
2968             JSTaggedValue res = JSTaggedValue::Hole();
2969             SAVE_ACC();
2970 
2971             if (LIKELY(firstValue.IsHeapObject())) {
2972                 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
2973                 res = ICRuntimeStub::TryStoreICByValue(thread, receiver, propKey, firstValue, secondValue, value);
2974             }
2975             // IC miss and not enter the megamorphic state, store as polymorphic
2976             if (res.IsHole() && !firstValue.IsHole()) {
2977                 res = ICRuntimeStub::StoreICByValue(thread,
2978                                                     profileTypeArray,
2979                                                     receiver, propKey, value, slotId);
2980             }
2981 
2982             if (LIKELY(!res.IsHole())) {
2983                 INTERPRETER_RETURN_IF_ABRUPT(res);
2984                 RESTORE_ACC();
2985                 DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2986             }
2987         }
2988 #endif
2989         if (receiver.IsHeapObject()) {
2990             SAVE_ACC();
2991             JSTaggedValue propKey = GET_VREG_VALUE(v1);
2992             JSTaggedValue value = GET_ACC();
2993             // fast path
2994             JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, propKey, value);
2995             if (!res.IsHole()) {
2996                 INTERPRETER_RETURN_IF_ABRUPT(res);
2997                 RESTORE_ACC();
2998                 DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
2999             }
3000             RESTORE_ACC();
3001         }
3002         {
3003             // slow path
3004             SAVE_ACC();
3005             SAVE_PC();
3006             receiver = GET_VREG_VALUE(v0);  // Maybe moved by GC
3007             JSTaggedValue propKey = GET_VREG_VALUE(v1);   // Maybe moved by GC
3008             JSTaggedValue value = GET_ACC();              // Maybe moved by GC
3009             JSTaggedValue res = SlowRuntimeStub::StObjByValue(thread, receiver, propKey, value);
3010             INTERPRETER_RETURN_IF_ABRUPT(res);
3011             RESTORE_ACC();
3012         }
3013         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
3014     }
3015     HANDLE_OPCODE(HANDLE_LDSUPERBYVALUE_PREF_V8_V8) {
3016         uint32_t v0 = READ_INST_8_1();
3017         uint32_t v1 = READ_INST_8_2();
3018         LOG_INST() << "intrinsics::Ldsuperbyvalue"
3019                    << " v" << v0 << " v" << v1;
3020 
3021         JSTaggedValue receiver = GET_VREG_VALUE(v0);
3022         JSTaggedValue propKey = GET_VREG_VALUE(v1);
3023 
3024         // slow path
3025         SAVE_PC();
3026         JSTaggedValue thisFunc = GetThisFunction(sp);
3027         JSTaggedValue res = SlowRuntimeStub::LdSuperByValue(thread, receiver, propKey, thisFunc);
3028         INTERPRETER_RETURN_IF_ABRUPT(res);
3029         SET_ACC(res);
3030         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
3031     }
3032     HANDLE_OPCODE(HANDLE_STSUPERBYVALUE_PREF_V8_V8) {
3033         uint32_t v0 = READ_INST_8_1();
3034         uint32_t v1 = READ_INST_8_2();
3035 
3036         LOG_INST() << "intrinsics::stsuperbyvalue"
3037                    << " v" << v0 << " v" << v1;
3038         JSTaggedValue receiver = GET_VREG_VALUE(v0);
3039         JSTaggedValue propKey = GET_VREG_VALUE(v1);
3040         JSTaggedValue value = GET_ACC();
3041 
3042         // slow path
3043         SAVE_ACC();
3044         SAVE_PC();
3045         JSTaggedValue thisFunc = GetThisFunction(sp);
3046         JSTaggedValue res = SlowRuntimeStub::StSuperByValue(thread, receiver, propKey, value, thisFunc);
3047         INTERPRETER_RETURN_IF_ABRUPT(res);
3048         RESTORE_ACC();
3049         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
3050     }
3051     HANDLE_OPCODE(HANDLE_TRYLDGLOBALBYNAME_PREF_ID32) {
3052         uint32_t stringId = READ_INST_32_1();
3053         auto prop = constpool->GetObjectFromCache(stringId);
3054 
3055         LOG_INST() << "intrinsics::tryldglobalbyname "
3056                    << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(prop.GetTaggedObject()));
3057 
3058 #if ECMASCRIPT_ENABLE_IC
3059         auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
3060         if (!profileTypeInfo.IsUndefined()) {
3061             uint16_t slotId = READ_INST_8_0();
3062             JSTaggedValue res = ICRuntimeStub::LoadGlobalICByName(thread,
3063                                                                   ProfileTypeInfo::Cast(
3064                                                                       profileTypeInfo.GetTaggedObject()),
3065                                                                   globalObj, prop, slotId);
3066             INTERPRETER_RETURN_IF_ABRUPT(res);
3067             SET_ACC(res);
3068             DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3069         }
3070 #endif
3071 
3072         // order: 1. global record 2. global object
3073         JSTaggedValue result = SlowRuntimeStub::LdGlobalRecord(thread, prop);
3074         if (!result.IsUndefined()) {
3075             SET_ACC(PropertyBox::Cast(result.GetTaggedObject())->GetValue());
3076         } else {
3077             JSTaggedValue globalResult = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, prop);
3078             if (!globalResult.IsHole()) {
3079                 SET_ACC(globalResult);
3080             } else {
3081                 // slow path
3082                 SAVE_PC();
3083                 JSTaggedValue res = SlowRuntimeStub::TryLdGlobalByName(thread, globalObj, prop);
3084                 INTERPRETER_RETURN_IF_ABRUPT(res);
3085                 SET_ACC(res);
3086             }
3087         }
3088 
3089         DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3090     }
3091     HANDLE_OPCODE(HANDLE_TRYSTGLOBALBYNAME_PREF_ID32) {
3092         uint32_t stringId = READ_INST_32_1();
3093         JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3094         LOG_INST() << "intrinsics::trystglobalbyname"
3095                    << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
3096 
3097 #if ECMASCRIPT_ENABLE_IC
3098         auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
3099         if (!profileTypeInfo.IsUndefined()) {
3100             uint16_t slotId = READ_INST_8_0();
3101             JSTaggedValue value = GET_ACC();
3102             SAVE_ACC();
3103             JSTaggedValue res = ICRuntimeStub::StoreGlobalICByName(thread,
3104                                                                    ProfileTypeInfo::Cast(
3105                                                                        profileTypeInfo.GetTaggedObject()),
3106                                                                    globalObj, propKey, value, slotId);
3107             INTERPRETER_RETURN_IF_ABRUPT(res);
3108             RESTORE_ACC();
3109             DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3110         }
3111 #endif
3112 
3113         auto recordResult = SlowRuntimeStub::LdGlobalRecord(thread, propKey);
3114         SAVE_PC();
3115         // 1. find from global record
3116         if (!recordResult.IsUndefined()) {
3117             JSTaggedValue value = GET_ACC();
3118             SAVE_ACC();
3119             JSTaggedValue res = SlowRuntimeStub::TryUpdateGlobalRecord(thread, propKey, value);
3120             INTERPRETER_RETURN_IF_ABRUPT(res);
3121             RESTORE_ACC();
3122         } else {
3123             // 2. find from global object
3124             auto globalResult = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, propKey);
3125             if (globalResult.IsHole()) {
3126                 auto result = SlowRuntimeStub::ThrowReferenceError(thread, propKey, " is not defined");
3127                 INTERPRETER_RETURN_IF_ABRUPT(result);
3128             }
3129             JSTaggedValue value = GET_ACC();
3130             SAVE_ACC();
3131             JSTaggedValue res = SlowRuntimeStub::StGlobalVar(thread, propKey, value);
3132             INTERPRETER_RETURN_IF_ABRUPT(res);
3133             RESTORE_ACC();
3134         }
3135         DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3136     }
3137 
3138     HANDLE_OPCODE(HANDLE_STCONSTTOGLOBALRECORD_PREF_ID32) {
3139         uint32_t stringId = READ_INST_32_1();
3140         JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3141         LOG_INST() << "intrinsics::stconsttoglobalrecord"
3142                    << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
3143 
3144         JSTaggedValue value = GET_ACC();
3145         SAVE_ACC();
3146         SAVE_PC();
3147         JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, true);
3148         INTERPRETER_RETURN_IF_ABRUPT(res);
3149         RESTORE_ACC();
3150         DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3151     }
3152 
3153     HANDLE_OPCODE(HANDLE_STLETTOGLOBALRECORD_PREF_ID32) {
3154         uint32_t stringId = READ_INST_32_1();
3155         JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3156         LOG_INST() << "intrinsics::stlettoglobalrecord"
3157                    << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
3158 
3159         JSTaggedValue value = GET_ACC();
3160         SAVE_ACC();
3161         SAVE_PC();
3162         JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, false);
3163         INTERPRETER_RETURN_IF_ABRUPT(res);
3164         RESTORE_ACC();
3165         DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3166     }
3167 
3168     HANDLE_OPCODE(HANDLE_STCLASSTOGLOBALRECORD_PREF_ID32) {
3169         uint32_t stringId = READ_INST_32_1();
3170         JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3171         LOG_INST() << "intrinsics::stclasstoglobalrecord"
3172                    << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject()));
3173 
3174         JSTaggedValue value = GET_ACC();
3175         SAVE_ACC();
3176         SAVE_PC();
3177         JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, false);
3178         INTERPRETER_RETURN_IF_ABRUPT(res);
3179         RESTORE_ACC();
3180         DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3181     }
3182 
3183     HANDLE_OPCODE(HANDLE_STOWNBYVALUEWITHNAMESET_PREF_V8_V8) {
3184         uint32_t v0 = READ_INST_8_1();
3185         uint32_t v1 = READ_INST_8_2();
3186         LOG_INST() << "intrinsics::stownbyvaluewithnameset"
3187                    << " v" << v0 << " v" << v1;
3188         JSTaggedValue receiver = GET_VREG_VALUE(v0);
3189         if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
3190             SAVE_ACC();
3191             JSTaggedValue propKey = GET_VREG_VALUE(v1);
3192             JSTaggedValue value = GET_ACC();
3193             // fast path
3194             JSTaggedValue res = FastRuntimeStub::SetPropertyByValue<true>(thread, receiver, propKey, value);
3195 
3196             // SetPropertyByValue maybe gc need update the value
3197             RESTORE_ACC();
3198             propKey = GET_VREG_VALUE(v1);
3199             value = GET_ACC();
3200             if (!res.IsHole()) {
3201                 INTERPRETER_RETURN_IF_ABRUPT(res);
3202                 JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey);
3203                 RESTORE_ACC();
3204                 DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
3205             }
3206         }
3207 
3208         // slow path
3209         SAVE_ACC();
3210         SAVE_PC();
3211         receiver = GET_VREG_VALUE(v0);      // Maybe moved by GC
3212         auto propKey = GET_VREG_VALUE(v1);  // Maybe moved by GC
3213         auto value = GET_ACC();             // Maybe moved by GC
3214         JSTaggedValue res = SlowRuntimeStub::StOwnByValueWithNameSet(thread, receiver, propKey, value);
3215         RESTORE_ACC();
3216         INTERPRETER_RETURN_IF_ABRUPT(res);
3217         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
3218     }
3219     HANDLE_OPCODE(HANDLE_STOWNBYNAMEWITHNAMESET_PREF_ID32_V8) {
3220         uint32_t stringId = READ_INST_32_1();
3221         uint32_t v0 = READ_INST_8_5();
3222         LOG_INST() << "intrinsics::stownbynamewithnameset "
3223                    << "v" << v0 << " stringId:" << stringId;
3224 
3225         JSTaggedValue receiver = GET_VREG_VALUE(v0);
3226         if (receiver.IsJSObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) {
3227             JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3228             JSTaggedValue value = GET_ACC();
3229             // fast path
3230             SAVE_ACC();
3231 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
3232             auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(SetPropertyByNameWithOwn));
3233             typedef JSTaggedType (*PFSetPropertyByName)(uintptr_t, JSTaggedType, JSTaggedType, JSTaggedType);
3234             auto setPropertyByNamePtr = reinterpret_cast<PFSetPropertyByName>(stubAddr);
3235             JSTaggedValue res = JSTaggedValue(setPropertyByNamePtr(thread->GetGlueAddr(), receiver.GetRawData(),
3236                 propKey.GetRawData(), value.GetRawData()));
3237 #else
3238             JSTaggedValue res = FastRuntimeStub::SetPropertyByName<true>(thread, receiver, propKey, value);
3239 #endif
3240             if (!res.IsHole()) {
3241                 INTERPRETER_RETURN_IF_ABRUPT(res);
3242                 JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey);
3243                 RESTORE_ACC();
3244                 DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3245             }
3246             RESTORE_ACC();
3247         }
3248 
3249         SAVE_ACC();
3250         SAVE_PC();
3251         receiver = GET_VREG_VALUE(v0);                           // Maybe moved by GC
3252         auto propKey = constpool->GetObjectFromCache(stringId);  // Maybe moved by GC
3253         auto value = GET_ACC();                                  // Maybe moved by GC
3254         JSTaggedValue res = SlowRuntimeStub::StOwnByNameWithNameSet(thread, receiver, propKey, value);
3255         RESTORE_ACC();
3256         INTERPRETER_RETURN_IF_ABRUPT(res);
3257         DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3258     }
3259 
3260     HANDLE_OPCODE(HANDLE_LDGLOBALVAR_PREF_ID32) {
3261         uint32_t stringId = READ_INST_32_1();
3262         JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3263 
3264 #if ECMASCRIPT_ENABLE_IC
3265         auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
3266         if (!profileTypeInfo.IsUndefined()) {
3267             uint16_t slotId = READ_INST_8_0();
3268             JSTaggedValue res = ICRuntimeStub::LoadGlobalICByName(thread,
3269                                                                   ProfileTypeInfo::Cast(
3270                                                                       profileTypeInfo.GetTaggedObject()),
3271                                                                   globalObj, propKey, slotId);
3272             INTERPRETER_RETURN_IF_ABRUPT(res);
3273             SET_ACC(res);
3274             DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3275         }
3276 #endif
3277         JSTaggedValue result = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, propKey);
3278         if (!result.IsHole()) {
3279             SET_ACC(result);
3280         } else {
3281             // slow path
3282             SAVE_PC();
3283             JSTaggedValue res = SlowRuntimeStub::LdGlobalVar(thread, globalObj, propKey);
3284             INTERPRETER_RETURN_IF_ABRUPT(res);
3285             SET_ACC(res);
3286         }
3287         DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3288     }
3289     HANDLE_OPCODE(HANDLE_LDOBJBYNAME_PREF_ID32_V8) {
3290         uint32_t v0 = READ_INST_8_5();
3291         JSTaggedValue receiver = GET_VREG_VALUE(v0);
3292 
3293 #if ECMASCRIPT_ENABLE_IC
3294         auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
3295         if (!profileTypeInfo.IsUndefined()) {
3296             uint16_t slotId = READ_INST_8_0();
3297             auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
3298             JSTaggedValue firstValue = profileTypeArray->Get(slotId);
3299             JSTaggedValue res = JSTaggedValue::Hole();
3300 
3301             if (LIKELY(firstValue.IsHeapObject())) {
3302                 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
3303                 res = ICRuntimeStub::TryLoadICByName(thread, receiver, firstValue, secondValue);
3304             }
3305             if (LIKELY(!res.IsHole())) {
3306                 INTERPRETER_RETURN_IF_ABRUPT(res);
3307                 SET_ACC(res);
3308                 DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3309             } else if (!firstValue.IsHole()) { // IC miss and not enter the megamorphic state, store as polymorphic
3310                 uint32_t stringId = READ_INST_32_1();
3311                 JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3312                 res = ICRuntimeStub::LoadICByName(thread,
3313                                                   profileTypeArray,
3314                                                   receiver, propKey, slotId);
3315                 INTERPRETER_RETURN_IF_ABRUPT(res);
3316                 SET_ACC(res);
3317                 DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3318             }
3319         }
3320 #endif
3321         uint32_t stringId = READ_INST_32_1();
3322         JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3323         LOG_INST() << "intrinsics::ldobjbyname "
3324                    << "v" << v0 << " stringId:" << stringId << ", "
3325                    << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << receiver.GetRawData();
3326 
3327         if (LIKELY(receiver.IsHeapObject())) {
3328             // fast path
3329 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
3330             auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(GetPropertyByName));
3331             typedef JSTaggedType (*PFGetPropertyByName)(uintptr_t, JSTaggedType, JSTaggedType);
3332             auto getPropertyByNamePtr = reinterpret_cast<PFGetPropertyByName>(stubAddr);
3333             JSTaggedValue res = JSTaggedValue(getPropertyByNamePtr(thread->GetGlueAddr(), receiver.GetRawData(),
3334                 propKey.GetRawData()));
3335 #else
3336             JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, receiver, propKey);
3337 #endif
3338             if (!res.IsHole()) {
3339                 ASSERT(!res.IsAccessor());
3340                 INTERPRETER_RETURN_IF_ABRUPT(res);
3341                 SET_ACC(res);
3342                 DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3343             }
3344         }
3345         // not meet fast condition or fast path return hole, walk slow path
3346         // slow stub not need receiver
3347         SAVE_PC();
3348         JSTaggedValue res = SlowRuntimeStub::LdObjByName(thread, receiver, propKey, false, JSTaggedValue::Undefined());
3349         INTERPRETER_RETURN_IF_ABRUPT(res);
3350         SET_ACC(res);
3351         DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3352     }
3353     HANDLE_OPCODE(HANDLE_STOBJBYNAME_PREF_ID32_V8) {
3354         uint32_t v0 = READ_INST_8_5();
3355         JSTaggedValue receiver = GET_VREG_VALUE(v0);
3356         JSTaggedValue value = GET_ACC();
3357 #if ECMASCRIPT_ENABLE_IC
3358         auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
3359         if (!profileTypeInfo.IsUndefined()) {
3360             uint16_t slotId = READ_INST_8_0();
3361             auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject());
3362             JSTaggedValue firstValue = profileTypeArray->Get(slotId);
3363             JSTaggedValue res = JSTaggedValue::Hole();
3364             SAVE_ACC();
3365 
3366             if (LIKELY(firstValue.IsHeapObject())) {
3367                 JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1);
3368 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
3369                 auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(TryStoreICByName));
3370                 typedef JSTaggedType (*PFTryStoreICByName)(uintptr_t,
3371                     JSTaggedType, JSTaggedType, JSTaggedType, JSTaggedType);
3372                 auto tryStoreICByNamePtr = reinterpret_cast<PFTryStoreICByName>(stubAddr);
3373                 res = JSTaggedValue(
3374                     tryStoreICByNamePtr(thread->GetGlueAddr(), receiver.GetRawData(),
3375                         firstValue.GetRawData(), secondValue.GetRawData(), value.GetRawData()));
3376 #else
3377                 res = ICRuntimeStub::TryStoreICByName(thread, receiver, firstValue, secondValue, value);
3378 #endif
3379             }
3380             if (LIKELY(!res.IsHole())) {
3381                 INTERPRETER_RETURN_IF_ABRUPT(res);
3382                 RESTORE_ACC();
3383                 DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3384             } else if (!firstValue.IsHole()) { // IC miss and not enter the megamorphic state, store as polymorphic
3385                 uint32_t stringId = READ_INST_32_1();
3386                 JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3387                 res = ICRuntimeStub::StoreICByName(thread,
3388                                                    profileTypeArray,
3389                                                    receiver, propKey, value, slotId);
3390                 INTERPRETER_RETURN_IF_ABRUPT(res);
3391                 RESTORE_ACC();
3392                 DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3393             }
3394         }
3395 #endif
3396         uint32_t stringId = READ_INST_32_1();
3397         LOG_INST() << "intrinsics::stobjbyname "
3398                    << "v" << v0 << " stringId:" << stringId;
3399         if (receiver.IsHeapObject()) {
3400             JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3401             value = GET_ACC();
3402             // fast path
3403             SAVE_ACC();
3404 #ifdef ECMASCRIPT_ENABLE_STUB_AOT
3405             auto stubAddr = thread->GetFastStubEntry(FAST_STUB_ID(SetPropertyByName));
3406             typedef JSTaggedType (*PFSetPropertyByName)(uintptr_t, JSTaggedType, JSTaggedType, JSTaggedType);
3407             auto setPropertyByNamePtr = reinterpret_cast<PFSetPropertyByName>(stubAddr);
3408             JSTaggedValue res = JSTaggedValue(setPropertyByNamePtr(thread->GetGlueAddr(),
3409                 receiver.GetRawData(), propKey.GetRawData(), value.GetRawData()));
3410 #else
3411             JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value);
3412 #endif
3413             if (!res.IsHole()) {
3414                 INTERPRETER_RETURN_IF_ABRUPT(res);
3415                 RESTORE_ACC();
3416                 DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3417             }
3418             RESTORE_ACC();
3419         }
3420         // slow path
3421         SAVE_ACC();
3422         SAVE_PC();
3423         receiver = GET_VREG_VALUE(v0);                           // Maybe moved by GC
3424         auto propKey = constpool->GetObjectFromCache(stringId);  // Maybe moved by GC
3425         value = GET_ACC();                                  // Maybe moved by GC
3426         JSTaggedValue res = SlowRuntimeStub::StObjByName(thread, receiver, propKey, value);
3427         INTERPRETER_RETURN_IF_ABRUPT(res);
3428         RESTORE_ACC();
3429         DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3430     }
3431     HANDLE_OPCODE(HANDLE_LDSUPERBYNAME_PREF_ID32_V8) {
3432         uint32_t stringId = READ_INST_32_1();
3433         uint32_t v0 = READ_INST_8_5();
3434         JSTaggedValue obj = GET_VREG_VALUE(v0);
3435         JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3436 
3437         LOG_INST() << "intrinsics::ldsuperbyname"
3438                    << "v" << v0 << " stringId:" << stringId << ", "
3439                    << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << obj.GetRawData();
3440 
3441         SAVE_PC();
3442         JSTaggedValue thisFunc = GetThisFunction(sp);
3443         JSTaggedValue res = SlowRuntimeStub::LdSuperByValue(thread, obj, propKey, thisFunc);
3444 
3445         INTERPRETER_RETURN_IF_ABRUPT(res);
3446         SET_ACC(res);
3447         DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3448     }
3449     HANDLE_OPCODE(HANDLE_STSUPERBYNAME_PREF_ID32_V8) {
3450         uint32_t stringId = READ_INST_32_1();
3451         uint32_t v0 = READ_INST_8_5();
3452 
3453         JSTaggedValue obj = GET_VREG_VALUE(v0);
3454         JSTaggedValue propKey = constpool->GetObjectFromCache(stringId);
3455         JSTaggedValue value = GET_ACC();
3456 
3457         LOG_INST() << "intrinsics::stsuperbyname"
3458                    << "v" << v0 << " stringId:" << stringId << ", "
3459                    << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << obj.GetRawData()
3460                    << ", value:" << value.GetRawData();
3461 
3462         // slow path
3463         SAVE_ACC();
3464         SAVE_PC();
3465         JSTaggedValue thisFunc = GetThisFunction(sp);
3466         JSTaggedValue res = SlowRuntimeStub::StSuperByValue(thread, obj, propKey, value, thisFunc);
3467         INTERPRETER_RETURN_IF_ABRUPT(res);
3468         RESTORE_ACC();
3469         DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8);
3470     }
3471     HANDLE_OPCODE(HANDLE_STGLOBALVAR_PREF_ID32) {
3472         uint32_t stringId = READ_INST_32_1();
3473         JSTaggedValue prop = constpool->GetObjectFromCache(stringId);
3474         JSTaggedValue value = GET_ACC();
3475 
3476         LOG_INST() << "intrinsics::stglobalvar "
3477                    << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(prop.GetTaggedObject()))
3478                    << ", value:" << value.GetRawData();
3479 #if ECMASCRIPT_ENABLE_IC
3480         auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp);
3481         if (!profileTypeInfo.IsUndefined()) {
3482             uint16_t slotId = READ_INST_8_0();
3483             SAVE_ACC();
3484             JSTaggedValue res = ICRuntimeStub::StoreGlobalICByName(thread,
3485                                                                    ProfileTypeInfo::Cast(
3486                                                                        profileTypeInfo.GetTaggedObject()),
3487                                                                    globalObj, prop, value, slotId);
3488             INTERPRETER_RETURN_IF_ABRUPT(res);
3489             RESTORE_ACC();
3490             DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3491         }
3492 #endif
3493         SAVE_ACC();
3494         SAVE_PC();
3495         JSTaggedValue res = SlowRuntimeStub::StGlobalVar(thread, prop, value);
3496         INTERPRETER_RETURN_IF_ABRUPT(res);
3497         RESTORE_ACC();
3498         DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3499     }
3500     HANDLE_OPCODE(HANDLE_CREATEGENERATOROBJ_PREF_V8) {
3501         uint16_t v0 = READ_INST_8_1();
3502         LOG_INST() << "intrinsics::creategeneratorobj"
3503                    << " v" << v0;
3504         SAVE_PC();
3505         JSTaggedValue genFunc = GET_VREG_VALUE(v0);
3506         JSTaggedValue res = SlowRuntimeStub::CreateGeneratorObj(thread, genFunc);
3507         INTERPRETER_RETURN_IF_ABRUPT(res);
3508         SET_ACC(res);
3509         DISPATCH(BytecodeInstruction::Format::PREF_V8);
3510     }
3511     HANDLE_OPCODE(HANDLE_STARRAYSPREAD_PREF_V8_V8) {
3512         uint16_t v0 = READ_INST_8_1();
3513         uint16_t v1 = READ_INST_8_2();
3514         LOG_INST() << "ecmascript::intrinsics::starrayspread"
3515                    << " v" << v0 << " v" << v1 << "acc";
3516         JSTaggedValue dst = GET_VREG_VALUE(v0);
3517         JSTaggedValue index = GET_VREG_VALUE(v1);
3518         JSTaggedValue src = GET_ACC();
3519         SAVE_PC();
3520         JSTaggedValue res = SlowRuntimeStub::StArraySpread(thread, dst, index, src);
3521         INTERPRETER_RETURN_IF_ABRUPT(res);
3522         SET_ACC(res);
3523         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
3524     }
3525     HANDLE_OPCODE(HANDLE_GETITERATORNEXT_PREF_V8_V8) {
3526         uint16_t v0 = READ_INST_8_1();
3527         uint16_t v1 = READ_INST_8_2();
3528         LOG_INST() << "intrinsic::getiteratornext"
3529                    << " v" << v0 << " v" << v1;
3530         JSTaggedValue obj = GET_VREG_VALUE(v0);
3531         JSTaggedValue method = GET_VREG_VALUE(v1);
3532         SAVE_PC();
3533         JSTaggedValue res = SlowRuntimeStub::GetIteratorNext(thread, obj, method);
3534         INTERPRETER_RETURN_IF_ABRUPT(res);
3535         SET_ACC(res);
3536         DISPATCH(BytecodeInstruction::Format::PREF_V8_V8);
3537     }
3538     HANDLE_OPCODE(HANDLE_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8) {
3539         uint16_t methodId = READ_INST_16_1();
3540         uint16_t imm = READ_INST_16_3();
3541         uint16_t length = READ_INST_16_5();
3542         uint16_t v0 = READ_INST_8_7();
3543         uint16_t v1 = READ_INST_8_8();
3544         LOG_INST() << "intrinsics::defineclasswithbuffer"
3545                    << " method id:" << methodId << " literal id:" << imm << " lexenv: v" << v0 << " parent: v" << v1;
3546         JSFunction *classTemplate = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject());
3547         ASSERT(classTemplate != nullptr);
3548 
3549         JSTaggedValue lexenv = GET_VREG_VALUE(v0);
3550         JSTaggedValue proto = GET_VREG_VALUE(v1);
3551 
3552         JSTaggedValue res;
3553         SAVE_PC();
3554         res = SlowRuntimeStub::CloneClassFromTemplate(thread, JSTaggedValue(classTemplate), proto, lexenv, constpool);
3555         INTERPRETER_RETURN_IF_ABRUPT(res);
3556         ASSERT(res.IsClassConstructor());
3557         JSFunction *cls = JSFunction::Cast(res.GetTaggedObject());
3558 
3559         lexenv = GET_VREG_VALUE(v0);  // slow runtime may gc
3560         cls->SetLexicalEnv(thread, lexenv);
3561 
3562         SlowRuntimeStub::SetClassConstructorLength(thread, res, JSTaggedValue(length));
3563 
3564         SET_ACC(res);
3565         DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_IMM16_V8_V8);
3566     }
3567     HANDLE_OPCODE(HANDLE_LDFUNCTION_PREF) {
3568         LOG_INST() << "intrinsic::ldfunction";
3569         SET_ACC(GetThisFunction(sp));
3570         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
3571     }
3572     HANDLE_OPCODE(HANDLE_LDBIGINT_PREF_ID32) {
3573         uint32_t stringId = READ_INST_32_1();
3574         LOG_INST() << "intrinsic::ldbigint";
3575         JSTaggedValue numberBigInt = constpool->GetObjectFromCache(stringId);
3576         SAVE_PC();
3577         JSTaggedValue res = SlowRuntimeStub::LdBigInt(thread, numberBigInt);
3578         INTERPRETER_RETURN_IF_ABRUPT(res);
3579         SET_ACC(res);
3580         DISPATCH(BytecodeInstruction::Format::PREF_ID32);
3581     }
3582     HANDLE_OPCODE(HANDLE_SUPERCALL_PREF_IMM16_V8) {
3583         uint16_t range = READ_INST_16_1();
3584         uint16_t v0 = READ_INST_8_3();
3585         LOG_INST() << "intrinsics::supercall"
3586                    << " range: " << range << " v" << v0;
3587 
3588         JSTaggedValue thisFunc = GET_ACC();
3589         JSTaggedValue newTarget = GetNewTarget(sp);
3590 
3591         SAVE_PC();
3592         JSTaggedValue res = SlowRuntimeStub::SuperCall(thread, thisFunc, newTarget, v0, range);
3593         INTERPRETER_RETURN_IF_ABRUPT(res);
3594         SET_ACC(res);
3595         DISPATCH(BytecodeInstruction::Format::PREF_IMM16_V8);
3596     }
3597     HANDLE_OPCODE(HANDLE_SUPERCALLSPREAD_PREF_V8) {
3598         uint16_t v0 = READ_INST_8_1();
3599         LOG_INST() << "intrinsic::supercallspread"
3600                    << " array: v" << v0;
3601 
3602         JSTaggedValue thisFunc = GET_ACC();
3603         JSTaggedValue newTarget = GetNewTarget(sp);
3604         JSTaggedValue array = GET_VREG_VALUE(v0);
3605 
3606         SAVE_PC();
3607         JSTaggedValue res = SlowRuntimeStub::SuperCallSpread(thread, thisFunc, newTarget, array);
3608         INTERPRETER_RETURN_IF_ABRUPT(res);
3609         SET_ACC(res);
3610         DISPATCH(BytecodeInstruction::Format::PREF_V8);
3611     }
3612     HANDLE_OPCODE(HANDLE_CREATEOBJECTHAVINGMETHOD_PREF_IMM16) {
3613         uint16_t imm = READ_INST_16_1();
3614         LOG_INST() << "intrinsics::createobjecthavingmethod"
3615                    << " imm:" << imm;
3616         JSObject *result = JSObject::Cast(constpool->GetObjectFromCache(imm).GetTaggedObject());
3617         JSTaggedValue env = GET_ACC();
3618 
3619         SAVE_PC();
3620         JSTaggedValue res = SlowRuntimeStub::CreateObjectHavingMethod(thread, factory, result, env, constpool);
3621         INTERPRETER_RETURN_IF_ABRUPT(res);
3622         SET_ACC(res);
3623         DISPATCH(BytecodeInstruction::Format::PREF_IMM16);
3624     }
3625     HANDLE_OPCODE(HANDLE_THROWIFSUPERNOTCORRECTCALL_PREF_IMM16) {
3626         uint16_t imm = READ_INST_16_1();
3627         JSTaggedValue thisValue = GET_ACC();
3628         LOG_INST() << "intrinsic::throwifsupernotcorrectcall"
3629                    << " imm:" << imm;
3630         SAVE_PC();
3631         JSTaggedValue res = SlowRuntimeStub::ThrowIfSuperNotCorrectCall(thread, imm, thisValue);
3632         INTERPRETER_RETURN_IF_ABRUPT(res);
3633         DISPATCH(BytecodeInstruction::Format::PREF_IMM16);
3634     }
3635     HANDLE_OPCODE(HANDLE_LDHOMEOBJECT_PREF) {
3636         LOG_INST() << "intrinsics::ldhomeobject";
3637 
3638         JSTaggedValue thisFunc = GetThisFunction(sp);
3639         JSTaggedValue homeObject = JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject();
3640 
3641         SET_ACC(homeObject);
3642         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
3643     }
3644     HANDLE_OPCODE(HANDLE_THROWDELETESUPERPROPERTY_PREF) {
3645         LOG_INST() << "throwdeletesuperproperty";
3646 
3647         SAVE_PC();
3648         SlowRuntimeStub::ThrowDeleteSuperProperty(thread);
3649         INTERPRETER_GOTO_EXCEPTION_HANDLER();
3650     }
3651     HANDLE_OPCODE(HANDLE_DEBUGGER_PREF) {
3652         LOG_INST() << "intrinsics::debugger";
3653         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
3654     }
3655     HANDLE_OPCODE(HANDLE_ISTRUE_PREF) {
3656         LOG_INST() << "intrinsics::istrue";
3657         if (GET_ACC().ToBoolean()) {
3658             SET_ACC(JSTaggedValue::True());
3659         } else {
3660             SET_ACC(JSTaggedValue::False());
3661         }
3662         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
3663     }
3664     HANDLE_OPCODE(HANDLE_ISFALSE_PREF) {
3665         LOG_INST() << "intrinsics::isfalse";
3666         if (!GET_ACC().ToBoolean()) {
3667             SET_ACC(JSTaggedValue::True());
3668         } else {
3669             SET_ACC(JSTaggedValue::False());
3670         }
3671         DISPATCH(BytecodeInstruction::Format::PREF_NONE);
3672     }
3673     HANDLE_OPCODE(EXCEPTION_HANDLER) {
3674         InterpretedFrameHandler frameHandler(sp);
3675         uint32_t pcOffset = panda_file::INVALID_OFFSET;
3676         for (; frameHandler.HasFrame(); frameHandler.PrevInterpretedFrame()) {
3677             if (frameHandler.IsBreakFrame()) {
3678                 return;
3679             }
3680             auto method = frameHandler.GetMethod();
3681             pcOffset = FindCatchBlock(method, frameHandler.GetBytecodeOffset());
3682             if (pcOffset != panda_file::INVALID_OFFSET) {
3683                 sp = frameHandler.GetSp();
3684                 constpool = frameHandler.GetConstpool();
3685                 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3686                 pc = method->GetBytecodeArray() + pcOffset;
3687                 break;
3688             }
3689         }
3690         if (pcOffset == panda_file::INVALID_OFFSET) {
3691             return;
3692         }
3693 
3694         auto exception = thread->GetException();
3695         SET_ACC(exception);
3696         thread->ClearException();
3697         thread->SetCurrentSPFrame(sp);
3698         DISPATCH_OFFSET(0);
3699     }
3700     HANDLE_OPCODE(HANDLE_OVERFLOW) {
3701         LOG(FATAL, INTERPRETER) << "opcode overflow";
3702     }
3703 #include "templates/debugger_instruction_handler.inl"
3704 }
3705 
InitStackFrame(JSThread * thread)3706 void EcmaInterpreter::InitStackFrame(JSThread *thread)
3707 {
3708     uint64_t *prevSp = const_cast<uint64_t *>(thread->GetCurrentSPFrame());
3709     InterpretedFrame *state = GET_FRAME(prevSp);
3710     state->pc = nullptr;
3711     state->sp = nullptr;
3712     state->function = JSTaggedValue::Hole();
3713     state->acc = JSTaggedValue::Hole();
3714     state->constpool = JSTaggedValue::Hole();
3715     state->profileTypeInfo = JSTaggedValue::Undefined();
3716     state->base.type = FrameType::INTERPRETER_FRAME;
3717     state->base.prev = nullptr;
3718 }
3719 
FindCatchBlock(JSMethod * caller,uint32_t pc)3720 uint32_t EcmaInterpreter::FindCatchBlock(JSMethod *caller, uint32_t pc)
3721 {
3722     auto *pandaFile = caller->GetPandaFile();
3723     panda_file::MethodDataAccessor mda(*pandaFile, caller->GetFileId());
3724     panda_file::CodeDataAccessor cda(*pandaFile, mda.GetCodeId().value());
3725 
3726     uint32_t pcOffset = panda_file::INVALID_OFFSET;
3727     cda.EnumerateTryBlocks([&pcOffset, pc](panda_file::CodeDataAccessor::TryBlock &try_block) {
3728         if ((try_block.GetStartPc() <= pc) && ((try_block.GetStartPc() + try_block.GetLength()) > pc)) {
3729             try_block.EnumerateCatchBlocks([&](panda_file::CodeDataAccessor::CatchBlock &catch_block) {
3730                 pcOffset = catch_block.GetHandlerPc();
3731                 return false;
3732             });
3733         }
3734         return pcOffset == panda_file::INVALID_OFFSET;
3735     });
3736     return pcOffset;
3737 }
3738 
GetThisFunction(JSTaggedType * sp)3739 JSTaggedValue EcmaInterpreter::GetThisFunction(JSTaggedType *sp)
3740 {
3741     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3742     InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
3743     return state->function;
3744 }
3745 
GetNewTarget(JSTaggedType * sp)3746 JSTaggedValue EcmaInterpreter::GetNewTarget(JSTaggedType *sp)
3747 {
3748     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3749     InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
3750     JSMethod *method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
3751     ASSERT(method->HaveNewTargetWithCallField());
3752     uint32_t numVregs = method->GetNumVregsWithCallField();
3753     bool haveFunc = method->HaveFuncWithCallField();
3754     return JSTaggedValue(sp[numVregs + haveFunc]);
3755 }
3756 
GetNumArgs(JSTaggedType * sp,uint32_t restIdx,uint32_t & startIdx)3757 uint32_t EcmaInterpreter::GetNumArgs(JSTaggedType *sp, uint32_t restIdx, uint32_t &startIdx)
3758 {
3759     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3760     InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
3761     JSMethod *method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
3762     ASSERT(method->HaveExtraWithCallField());
3763     uint32_t numVregs = method->GetNumVregsWithCallField();
3764     bool haveFunc = method->HaveFuncWithCallField();
3765     bool haveNewTarget = method->HaveNewTargetWithCallField();
3766     bool haveThis = method->HaveThisWithCallField();
3767     uint32_t copyArgs = haveFunc + haveNewTarget + haveThis;
3768     uint32_t numArgs = method->GetNumArgsWithCallField();
3769     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3770     JSTaggedType *lastFrame = state->base.prev - FRAME_STATE_SIZE;
3771     if (lastFrame - sp > numVregs + copyArgs + numArgs) {
3772         // In this case, actualNumArgs is in the end
3773         // If not, then actualNumArgs == declaredNumArgs, therefore do nothing
3774         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3775         numArgs = JSTaggedValue(*(lastFrame - 1)).GetInt();
3776     }
3777     startIdx = numVregs + copyArgs + restIdx;
3778     return ((numArgs > restIdx) ? (numArgs - restIdx) : 0);
3779 }
3780 
GetJumpSizeAfterCall(const uint8_t * prevPc)3781 size_t EcmaInterpreter::GetJumpSizeAfterCall(const uint8_t *prevPc)
3782 {
3783     uint8_t op = *prevPc;
3784     size_t jumpSize;
3785     switch (op) {
3786         case (EcmaOpcode::CALLARG0DYN_PREF_V8):
3787             jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8);
3788             break;
3789         case (EcmaOpcode::CALLARG1DYN_PREF_V8_V8):
3790             jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8);
3791             break;
3792         case (EcmaOpcode::CALLARGS2DYN_PREF_V8_V8_V8):
3793             jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8_V8);
3794             break;
3795         case (EcmaOpcode::CALLARGS3DYN_PREF_V8_V8_V8_V8):
3796             jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8_V8_V8);
3797             break;
3798         case (EcmaOpcode::CALLIRANGEDYN_PREF_IMM16_V8):
3799             jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_IMM16_V8);
3800             break;
3801         case (EcmaOpcode::CALLITHISRANGEDYN_PREF_IMM16_V8):
3802         case (EcmaOpcode::NEWOBJDYNRANGE_PREF_IMM16_V8):
3803             jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_IMM16_V8);
3804             break;
3805         default:
3806             UNREACHABLE();
3807     }
3808 
3809     return jumpSize;
3810 }
3811 
GetRuntimeProfileTypeInfo(JSTaggedType * sp)3812 JSTaggedValue EcmaInterpreter::GetRuntimeProfileTypeInfo(JSTaggedType *sp)
3813 {
3814     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3815     InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
3816     return state->profileTypeInfo;
3817 }
3818 
UpdateHotnessCounter(JSThread * thread,JSTaggedType * sp,JSTaggedValue acc,int32_t offset)3819 bool EcmaInterpreter::UpdateHotnessCounter(JSThread* thread, JSTaggedType *sp, JSTaggedValue acc, int32_t offset)
3820 {
3821     InterpretedFrame *state = GET_FRAME(sp);
3822     auto method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
3823     auto hotnessCounter = static_cast<int32_t>(method->GetHotnessCounter());
3824 
3825     hotnessCounter += offset;
3826     if (UNLIKELY(hotnessCounter <= 0)) {
3827         bool needRestoreAcc = false;
3828         SAVE_ACC();
3829         needRestoreAcc = thread->CheckSafepoint();
3830         RESTORE_ACC();
3831         if (state->profileTypeInfo == JSTaggedValue::Undefined()) {
3832             state->acc = acc;
3833             // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3834             auto thisFunc = state->function;
3835             auto res = SlowRuntimeStub::NotifyInlineCache(
3836                 thread, JSFunction::Cast(thisFunc.GetHeapObject()), method);
3837             state->profileTypeInfo = res;
3838             method->SetHotnessCounter(EcmaInterpreter::METHOD_HOTNESS_THRESHOLD);
3839             return true;
3840         } else {
3841             method->SetHotnessCounter(EcmaInterpreter::METHOD_HOTNESS_THRESHOLD);
3842             return needRestoreAcc;
3843         }
3844     }
3845     method->SetHotnessCounter(static_cast<uint32_t>(hotnessCounter));
3846     return false;
3847 }
3848 
3849 // only use for fast new, not universal API
GetThisObjectFromFastNewFrame(JSTaggedType * sp)3850 JSTaggedValue EcmaInterpreter::GetThisObjectFromFastNewFrame(JSTaggedType *sp)
3851 {
3852     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
3853     InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
3854     JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget();
3855     ASSERT(method->OnlyHaveThisWithCallField());
3856     uint32_t numVregs = method->GetNumVregsWithCallField();
3857     uint32_t numDeclaredArgs = method->GetNumArgsWithCallField() + 1;  // 1: explict this object
3858     uint32_t hiddenThisObjectIndex = numVregs + numDeclaredArgs;   // hidden this object in the end of fast new frame
3859     return JSTaggedValue(sp[hiddenThisObjectIndex]);
3860 }
3861 
IsFastNewFrameEnter(JSMethod * method)3862 bool EcmaInterpreter::IsFastNewFrameEnter(JSMethod *method)
3863 {
3864     if (method->IsNativeWithCallField()) {
3865         return false;
3866     }
3867 
3868     return method->OnlyHaveThisWithCallField();
3869 }
3870 
IsFastNewFrameExit(JSTaggedType * sp)3871 bool EcmaInterpreter::IsFastNewFrameExit(JSTaggedType *sp)
3872 {
3873     return GET_FRAME(sp)->base.type == FrameType::INTERPRETER_FAST_NEW_FRAME;
3874 }
3875 
GetEcmaOpcodeStr(EcmaOpcode opcode)3876 std::string GetEcmaOpcodeStr(EcmaOpcode opcode)
3877 {
3878     const std::map<EcmaOpcode, const char *> strMap = {
3879         {LDNAN_PREF, "LDNAN"},
3880         {LDINFINITY_PREF, "LDINFINITY"},
3881         {LDGLOBALTHIS_PREF, "LDGLOBALTHIS"},
3882         {LDUNDEFINED_PREF, "LDUNDEFINED"},
3883         {LDNULL_PREF, "LDNULL"},
3884         {LDSYMBOL_PREF, "LDSYMBOL"},
3885         {LDGLOBAL_PREF, "LDGLOBAL"},
3886         {LDTRUE_PREF, "LDTRUE"},
3887         {LDFALSE_PREF, "LDFALSE"},
3888         {THROWDYN_PREF, "THROWDYN"},
3889         {TYPEOFDYN_PREF, "TYPEOFDYN"},
3890         {LDLEXENVDYN_PREF, "LDLEXENVDYN"},
3891         {POPLEXENVDYN_PREF, "POPLEXENVDYN"},
3892         {GETUNMAPPEDARGS_PREF, "GETUNMAPPEDARGS"},
3893         {GETPROPITERATOR_PREF, "GETPROPITERATOR"},
3894         {ASYNCFUNCTIONENTER_PREF, "ASYNCFUNCTIONENTER"},
3895         {LDHOLE_PREF, "LDHOLE"},
3896         {RETURNUNDEFINED_PREF, "RETURNUNDEFINED"},
3897         {CREATEEMPTYOBJECT_PREF, "CREATEEMPTYOBJECT"},
3898         {CREATEEMPTYARRAY_PREF, "CREATEEMPTYARRAY"},
3899         {GETITERATOR_PREF, "GETITERATOR"},
3900         {THROWTHROWNOTEXISTS_PREF, "THROWTHROWNOTEXISTS"},
3901         {THROWPATTERNNONCOERCIBLE_PREF, "THROWPATTERNNONCOERCIBLE"},
3902         {LDHOMEOBJECT_PREF, "LDHOMEOBJECT"},
3903         {THROWDELETESUPERPROPERTY_PREF, "THROWDELETESUPERPROPERTY"},
3904         {DEBUGGER_PREF, "DEBUGGER"},
3905         {ADD2DYN_PREF_V8, "ADD2DYN"},
3906         {SUB2DYN_PREF_V8, "SUB2DYN"},
3907         {MUL2DYN_PREF_V8, "MUL2DYN"},
3908         {DIV2DYN_PREF_V8, "DIV2DYN"},
3909         {MOD2DYN_PREF_V8, "MOD2DYN"},
3910         {EQDYN_PREF_V8, "EQDYN"},
3911         {NOTEQDYN_PREF_V8, "NOTEQDYN"},
3912         {LESSDYN_PREF_V8, "LESSDYN"},
3913         {LESSEQDYN_PREF_V8, "LESSEQDYN"},
3914         {GREATERDYN_PREF_V8, "GREATERDYN"},
3915         {GREATEREQDYN_PREF_V8, "GREATEREQDYN"},
3916         {SHL2DYN_PREF_V8, "SHL2DYN"},
3917         {SHR2DYN_PREF_V8, "SHR2DYN"},
3918         {ASHR2DYN_PREF_V8, "ASHR2DYN"},
3919         {AND2DYN_PREF_V8, "AND2DYN"},
3920         {OR2DYN_PREF_V8, "OR2DYN"},
3921         {XOR2DYN_PREF_V8, "XOR2DYN"},
3922         {TONUMBER_PREF_V8, "TONUMBER"},
3923         {NEGDYN_PREF_V8, "NEGDYN"},
3924         {NOTDYN_PREF_V8, "NOTDYN"},
3925         {INCDYN_PREF_V8, "INCDYN"},
3926         {DECDYN_PREF_V8, "DECDYN"},
3927         {EXPDYN_PREF_V8, "EXPDYN"},
3928         {ISINDYN_PREF_V8, "ISINDYN"},
3929         {INSTANCEOFDYN_PREF_V8, "INSTANCEOFDYN"},
3930         {STRICTNOTEQDYN_PREF_V8, "STRICTNOTEQDYN"},
3931         {STRICTEQDYN_PREF_V8, "STRICTEQDYN"},
3932         {RESUMEGENERATOR_PREF_V8, "RESUMEGENERATOR"},
3933         {GETRESUMEMODE_PREF_V8, "GETRESUMEMODE"},
3934         {CREATEGENERATOROBJ_PREF_V8, "CREATEGENERATOROBJ"},
3935         {THROWCONSTASSIGNMENT_PREF_V8, "THROWCONSTASSIGNMENT"},
3936         {GETTEMPLATEOBJECT_PREF_V8, "GETTEMPLATEOBJECT"},
3937         {GETNEXTPROPNAME_PREF_V8, "GETNEXTPROPNAME"},
3938         {CALLARG0DYN_PREF_V8, "CALLARG0DYN"},
3939         {THROWIFNOTOBJECT_PREF_V8, "THROWIFNOTOBJECT"},
3940         {ITERNEXT_PREF_V8, "ITERNEXT"},
3941         {CLOSEITERATOR_PREF_V8, "CLOSEITERATOR"},
3942         {COPYMODULE_PREF_V8, "COPYMODULE"},
3943         {SUPERCALLSPREAD_PREF_V8, "SUPERCALLSPREAD"},
3944         {DELOBJPROP_PREF_V8_V8, "DELOBJPROP"},
3945         {NEWOBJSPREADDYN_PREF_V8_V8, "NEWOBJSPREADDYN"},
3946         {CREATEITERRESULTOBJ_PREF_V8_V8, "CREATEITERRESULTOBJ"},
3947         {SUSPENDGENERATOR_PREF_V8_V8, "SUSPENDGENERATOR"},
3948         {ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8, "ASYNCFUNCTIONAWAITUNCAUGHT"},
3949         {THROWUNDEFINEDIFHOLE_PREF_V8_V8, "THROWUNDEFINEDIFHOLE"},
3950         {CALLARG1DYN_PREF_V8_V8, "CALLARG1DYN"},
3951         {COPYDATAPROPERTIES_PREF_V8_V8, "COPYDATAPROPERTIES"},
3952         {STARRAYSPREAD_PREF_V8_V8, "STARRAYSPREAD"},
3953         {GETITERATORNEXT_PREF_V8_V8, "GETITERATORNEXT"},
3954         {SETOBJECTWITHPROTO_PREF_V8_V8, "SETOBJECTWITHPROTO"},
3955         {LDOBJBYVALUE_PREF_V8_V8, "LDOBJBYVALUE"},
3956         {STOBJBYVALUE_PREF_V8_V8, "STOBJBYVALUE"},
3957         {STOWNBYVALUE_PREF_V8_V8, "STOWNBYVALUE"},
3958         {LDSUPERBYVALUE_PREF_V8_V8, "LDSUPERBYVALUE"},
3959         {STSUPERBYVALUE_PREF_V8_V8, "STSUPERBYVALUE"},
3960         {LDOBJBYINDEX_PREF_V8_IMM32, "LDOBJBYINDEX"},
3961         {STOBJBYINDEX_PREF_V8_IMM32, "STOBJBYINDEX"},
3962         {STOWNBYINDEX_PREF_V8_IMM32, "STOWNBYINDEX"},
3963         {CALLSPREADDYN_PREF_V8_V8_V8, "CALLSPREADDYN"},
3964         {ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8, "ASYNCFUNCTIONRESOLVE"},
3965         {ASYNCFUNCTIONREJECT_PREF_V8_V8_V8, "ASYNCFUNCTIONREJECT"},
3966         {CALLARGS2DYN_PREF_V8_V8_V8, "CALLARGS2DYN"},
3967         {CALLARGS3DYN_PREF_V8_V8_V8_V8, "CALLARGS3DYN"},
3968         {DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8, "DEFINEGETTERSETTERBYVALUE"},
3969         {NEWOBJDYNRANGE_PREF_IMM16_V8, "NEWOBJDYNRANGE"},
3970         {CALLIRANGEDYN_PREF_IMM16_V8, "CALLIRANGEDYN"},
3971         {CALLITHISRANGEDYN_PREF_IMM16_V8, "CALLITHISRANGEDYN"},
3972         {SUPERCALL_PREF_IMM16_V8, "SUPERCALL"},
3973         {CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8, "CREATEOBJECTWITHEXCLUDEDKEYS"},
3974         {DEFINEFUNCDYN_PREF_ID16_IMM16_V8, "DEFINEFUNCDYN"},
3975         {DEFINENCFUNCDYN_PREF_ID16_IMM16_V8, "DEFINENCFUNCDYN"},
3976         {DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8, "DEFINEGENERATORFUNC"},
3977         {DEFINEASYNCFUNC_PREF_ID16_IMM16_V8, "DEFINEASYNCFUNC"},
3978         {DEFINEMETHOD_PREF_ID16_IMM16_V8, "DEFINEMETHOD"},
3979         {NEWLEXENVDYN_PREF_IMM16, "NEWLEXENVDYN"},
3980         {COPYRESTARGS_PREF_IMM16, "COPYRESTARGS"},
3981         {CREATEARRAYWITHBUFFER_PREF_IMM16, "CREATEARRAYWITHBUFFER"},
3982         {CREATEOBJECTHAVINGMETHOD_PREF_IMM16, "CREATEOBJECTHAVINGMETHOD"},
3983         {THROWIFSUPERNOTCORRECTCALL_PREF_IMM16, "THROWIFSUPERNOTCORRECTCALL"},
3984         {CREATEOBJECTWITHBUFFER_PREF_IMM16, "CREATEOBJECTWITHBUFFER"},
3985         {LDLEXVARDYN_PREF_IMM4_IMM4, "LDLEXVARDYN"},
3986         {LDLEXVARDYN_PREF_IMM8_IMM8, "LDLEXVARDYN"},
3987         {LDLEXVARDYN_PREF_IMM16_IMM16, "LDLEXVARDYN"},
3988         {STLEXVARDYN_PREF_IMM4_IMM4_V8, "STLEXVARDYN"},
3989         {STLEXVARDYN_PREF_IMM8_IMM8_V8, "STLEXVARDYN"},
3990         {STLEXVARDYN_PREF_IMM16_IMM16_V8, "STLEXVARDYN"},
3991         {NEWLEXENVWITHNAMEDYN_PREF_IMM16_IMM16, "NEWLEXENVWITHNAMEDYN"},
3992         {DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8, "DEFINECLASSWITHBUFFER"},
3993         {IMPORTMODULE_PREF_ID32, "IMPORTMODULE"},
3994         {STMODULEVAR_PREF_ID32, "STMODULEVAR"},
3995         {TRYLDGLOBALBYNAME_PREF_ID32, "TRYLDGLOBALBYNAME"},
3996         {TRYSTGLOBALBYNAME_PREF_ID32, "TRYSTGLOBALBYNAME"},
3997         {LDGLOBALVAR_PREF_ID32, "LDGLOBALVAR"},
3998         {STGLOBALVAR_PREF_ID32, "STGLOBALVAR"},
3999         {LDOBJBYNAME_PREF_ID32_V8, "LDOBJBYNAME"},
4000         {STOBJBYNAME_PREF_ID32_V8, "STOBJBYNAME"},
4001         {STOWNBYNAME_PREF_ID32_V8, "STOWNBYNAME"},
4002         {LDSUPERBYNAME_PREF_ID32_V8, "LDSUPERBYNAME"},
4003         {STSUPERBYNAME_PREF_ID32_V8, "STSUPERBYNAME"},
4004         {LDMODVARBYNAME_PREF_ID32_V8, "LDMODVARBYNAME"},
4005         {CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8, "CREATEREGEXPWITHLITERAL"},
4006         {ISTRUE_PREF, "ISTRUE"},
4007         {ISFALSE_PREF, "ISFALSE"},
4008         {STCONSTTOGLOBALRECORD_PREF_ID32, "STCONSTTOGLOBALRECORD"},
4009         {STLETTOGLOBALRECORD_PREF_ID32, "STLETTOGLOBALRECORD"},
4010         {STCLASSTOGLOBALRECORD_PREF_ID32, "STCLASSTOGLOBALRECORD"},
4011         {STOWNBYVALUEWITHNAMESET_PREF_V8_V8, "STOWNBYVALUEWITHNAMESET"},
4012         {STOWNBYNAMEWITHNAMESET_PREF_ID32_V8, "STOWNBYNAMEWITHNAMESET"},
4013         {LDFUNCTION_PREF, "LDFUNCTION"},
4014         {LDBIGINT_PREF_ID32, "LDBIGINT"},
4015         {MOV_DYN_V8_V8, "MOV_DYN"},
4016         {MOV_DYN_V16_V16, "MOV_DYN"},
4017         {LDA_STR_ID32, "LDA_STR"},
4018         {LDAI_DYN_IMM32, "LDAI_DYN"},
4019         {FLDAI_DYN_IMM64, "FLDAI_DYN"},
4020         {JMP_IMM8, "JMP"},
4021         {JMP_IMM16, "JMP"},
4022         {JMP_IMM32, "JMP"},
4023         {JEQZ_IMM8, "JEQZ"},
4024         {JEQZ_IMM16, "JEQZ"},
4025         {LDA_DYN_V8, "LDA_DYN"},
4026         {STA_DYN_V8, "STA_DYN"},
4027         {RETURN_DYN, "RETURN_DYN"},
4028         {MOV_V4_V4, "MOV"},
4029         {JNEZ_IMM8, "JNEZ"},
4030         {JNEZ_IMM16, "JNEZ"},
4031         {LAST_OPCODE, "LAST_OPCODE"},
4032     };
4033     if (strMap.count(opcode) > 0) {
4034         return strMap.at(opcode);
4035     }
4036     return "bytecode-" + std::to_string(opcode);
4037 }
4038 #if defined(__clang__)
4039 #pragma clang diagnostic pop
4040 #elif defined(__GNUC__)
4041 #pragma GCC diagnostic pop
4042 #endif
4043 }  // namespace panda::ecmascript
4044 #endif  // ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H
4045