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