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