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