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