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