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