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