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