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