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