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