1 /*
2 * Copyright (c) 2022-2025 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 #ifndef ECMASCRIPT_COMPILER_STUB_INL_H
17 #define ECMASCRIPT_COMPILER_STUB_INL_H
18
19 #include "ecmascript/compiler/share_gate_meta_data.h"
20 #include "ecmascript/compiler/stub_builder.h"
21
22 #include "ecmascript/accessor_data.h"
23 #include "ecmascript/base/number_helper.h"
24 #include "ecmascript/compiler/assembler_module.h"
25 #include "ecmascript/compiler/bc_call_signature.h"
26 #include "ecmascript/compiler/baseline/baseline_call_signature.h"
27 #include "ecmascript/enum_cache.h"
28 #include "ecmascript/global_dictionary.h"
29 #include "ecmascript/global_env.h"
30 #include "ecmascript/global_env_constants.h"
31 #include "ecmascript/ic/ic_handler.h"
32 #include "ecmascript/ic/mega_ic_cache.h"
33 #include "ecmascript/ic/profile_type_info.h"
34 #include "ecmascript/ic/proto_change_details.h"
35 #include "ecmascript/js_array.h"
36 #include "ecmascript/js_arraybuffer.h"
37 #include "ecmascript/js_function.h"
38 #include "ecmascript/js_for_in_iterator.h"
39 #include "ecmascript/js_generator_object.h"
40 #include "ecmascript/js_object.h"
41 #include "ecmascript/js_tagged_value.h"
42 #include "ecmascript/jspandafile/program_object.h"
43 #include "ecmascript/layout_info.h"
44 #include "ecmascript/message_string.h"
45 #include "ecmascript/mem/slots.h"
46 #include "ecmascript/mem/visitor.h"
47 #include "ecmascript/ic/properties_cache.h"
48 #include "ecmascript/property_attributes.h"
49
50 namespace panda::ecmascript::kungfu {
51 using JSFunction = panda::ecmascript::JSFunction;
52 using PropertyBox = panda::ecmascript::PropertyBox;
NextVariableId()53 inline int StubBuilder::NextVariableId()
54 {
55 return env_->NextVariableId();
56 }
57
ReadSp()58 inline GateRef StubBuilder::ReadSp()
59 {
60 return env_->GetBuilder()->ReadSp();
61 }
62
CheckStackOverflow(GateRef glue)63 inline GateRef StubBuilder::CheckStackOverflow(GateRef glue)
64 {
65 GateRef allowCrossThreadExecution = LoadPrimitive(VariableType::BOOL(), glue,
66 IntPtr(JSThread::GlueData::GetAllowCrossThreadExecutionOffset(env_->IsArch32Bit())));
67 GateRef sp = ReadSp();
68 GateRef stackLimit = LoadPrimitive(VariableType::INT64(), glue,
69 IntPtr(JSThread::GlueData::GetStackLimitOffset(env_->IsArch32Bit())));
70 return LogicAndBuilder(env_)
71 .And(BoolNot(allowCrossThreadExecution))
72 .And(Int64UnsignedLessThanOrEqual(sp, stackLimit))
73 .Done();
74 }
75
Int8(int8_t value)76 inline GateRef StubBuilder::Int8(int8_t value)
77 {
78 return env_->GetBuilder()->Int8(value);
79 }
80
Int16(int16_t value)81 inline GateRef StubBuilder::Int16(int16_t value)
82 {
83 return env_->GetBuilder()->Int16(value);
84 }
85
Int32(int32_t value)86 inline GateRef StubBuilder::Int32(int32_t value)
87 {
88 return env_->GetBuilder()->Int32(value);
89 }
90
Int64(int64_t value)91 inline GateRef StubBuilder::Int64(int64_t value)
92 {
93 return env_->GetBuilder()->Int64(value);
94 }
95
TaggedInt(int32_t value)96 inline GateRef StubBuilder::TaggedInt(int32_t value)
97 {
98 JSTaggedType value64 = static_cast<JSTaggedType>(value) | JSTaggedValue::TAG_INT;
99 return env_->GetBuilder()->Int64(value64);
100 }
101
StringPtr(std::string_view str)102 inline GateRef StubBuilder::StringPtr(std::string_view str)
103 {
104 return env_->GetBuilder()->StringPtr(str);
105 }
106
IntPtr(int64_t value)107 inline GateRef StubBuilder::IntPtr(int64_t value)
108 {
109 return env_->Is32Bit() ? Int32(value) : Int64(value);
110 }
111
IntPtrSize()112 inline GateRef StubBuilder::IntPtrSize()
113 {
114 return env_->Is32Bit() ? Int32(sizeof(uint32_t)) : Int64(sizeof(uint64_t));
115 }
116
True()117 inline GateRef StubBuilder::True()
118 {
119 return TruncInt32ToInt1(Int32(1));
120 }
121
False()122 inline GateRef StubBuilder::False()
123 {
124 return TruncInt32ToInt1(Int32(0));
125 }
126
Boolean(bool value)127 inline GateRef StubBuilder::Boolean(bool value)
128 {
129 return env_->GetBuilder()->Boolean(value);
130 }
131
Double(double value)132 inline GateRef StubBuilder::Double(double value)
133 {
134 return env_->GetBuilder()->Double(value);
135 }
136
Undefined()137 inline GateRef StubBuilder::Undefined()
138 {
139 return env_->GetBuilder()->UndefineConstant();
140 }
141
Hole()142 inline GateRef StubBuilder::Hole()
143 {
144 return env_->GetBuilder()->HoleConstant();
145 }
146
SpecialHole()147 inline GateRef StubBuilder::SpecialHole()
148 {
149 return env_->GetBuilder()->SpecialHoleConstant();
150 }
151
Null()152 inline GateRef StubBuilder::Null()
153 {
154 return env_->GetBuilder()->NullConstant();
155 }
156
NullPtr()157 inline GateRef StubBuilder::NullPtr()
158 {
159 return env_->GetBuilder()->NullPtrConstant();
160 }
161
Exception()162 inline GateRef StubBuilder::Exception()
163 {
164 return env_->GetBuilder()->ExceptionConstant();
165 }
166
RelocatableData(uint64_t value)167 inline GateRef StubBuilder::RelocatableData(uint64_t value)
168 {
169 return env_->GetBuilder()->RelocatableData(value);
170 }
171
172 // parameter
Argument(size_t index)173 inline GateRef StubBuilder::Argument(size_t index)
174 {
175 return env_->GetArgument(index);
176 }
177
Int1Argument(size_t index)178 inline GateRef StubBuilder::Int1Argument(size_t index)
179 {
180 return Argument(index);
181 }
182
Int32Argument(size_t index)183 inline GateRef StubBuilder::Int32Argument(size_t index)
184 {
185 return Argument(index);
186 }
187
Int64Argument(size_t index)188 inline GateRef StubBuilder::Int64Argument(size_t index)
189 {
190 return Argument(index);
191 }
192
TaggedArgument(size_t index)193 inline GateRef StubBuilder::TaggedArgument(size_t index)
194 {
195 return Argument(index);
196 }
197
TaggedPointerArgument(size_t index)198 inline GateRef StubBuilder::TaggedPointerArgument(size_t index)
199 {
200 return Argument(index);
201 }
202
PtrArgument(size_t index)203 inline GateRef StubBuilder::PtrArgument(size_t index)
204 {
205 return Argument(index);
206 }
207
Float32Argument(size_t index)208 inline GateRef StubBuilder::Float32Argument(size_t index)
209 {
210 return Argument(index);
211 }
212
Float64Argument(size_t index)213 inline GateRef StubBuilder::Float64Argument(size_t index)
214 {
215 return Argument(index);
216 }
217
Alloca(int size)218 inline GateRef StubBuilder::Alloca(int size)
219 {
220 return env_->GetBuilder()->Alloca(size);
221 }
222
Return(GateRef value)223 inline GateRef StubBuilder::Return(GateRef value)
224 {
225 auto control = env_->GetCurrentLabel()->GetControl();
226 auto depend = env_->GetCurrentLabel()->GetDepend();
227 return env_->GetBuilder()->Return(control, depend, value);
228 }
229
Return()230 inline GateRef StubBuilder::Return()
231 {
232 auto control = env_->GetCurrentLabel()->GetControl();
233 auto depend = env_->GetCurrentLabel()->GetDepend();
234 return env_->GetBuilder()->ReturnVoid(control, depend);
235 }
236
Bind(Label * label)237 inline void StubBuilder::Bind(Label *label)
238 {
239 env_->GetBuilder()->Bind(label);
240 }
241
CallRuntime(GateRef glue,int index,const std::vector<GateRef> & args)242 inline GateRef StubBuilder::CallRuntime(GateRef glue, int index, const std::vector<GateRef>& args)
243 {
244 SavePcIfNeeded(glue);
245 const std::string name = RuntimeStubCSigns::GetRTName(index);
246 GateRef result = env_->GetBuilder()->CallRuntime(glue, index, Gate::InvalidGateRef, args,
247 glue, name.c_str());
248 return result;
249 }
250
CallRuntime(GateRef glue,int index,GateRef argc,GateRef argv)251 inline GateRef StubBuilder::CallRuntime(GateRef glue, int index, GateRef argc, GateRef argv)
252 {
253 SavePcIfNeeded(glue);
254 const std::string name = RuntimeStubCSigns::GetRTName(index);
255 GateRef result = env_->GetBuilder()->CallRuntimeVarargs(glue, index, argc, argv, name.c_str());
256 return result;
257 }
258
CallRuntimeWithGlobalEnv(GateRef glue,GateRef globalEnv,int index,const std::vector<GateRef> & args)259 inline GateRef StubBuilder::CallRuntimeWithGlobalEnv(GateRef glue, GateRef globalEnv,
260 int index, const std::vector<GateRef>& args)
261 {
262 SavePcIfNeeded(glue);
263 SetGlueGlobalEnv(glue, globalEnv);
264 const std::string name = RuntimeStubCSigns::GetRTName(index);
265 GateRef result = env_->GetBuilder()->CallRuntime(glue, index, Gate::InvalidGateRef, args,
266 glue, name.c_str());
267 return result;
268 }
269
CallRuntimeWithGlobalEnv(GateRef glue,GateRef globalEnv,int index,GateRef argc,GateRef argv)270 inline GateRef StubBuilder::CallRuntimeWithGlobalEnv(GateRef glue, GateRef globalEnv,
271 int index, GateRef argc, GateRef argv)
272 {
273 SavePcIfNeeded(glue);
274 SetGlueGlobalEnv(glue, globalEnv);
275 const std::string name = RuntimeStubCSigns::GetRTName(index);
276 GateRef result = env_->GetBuilder()->CallRuntimeVarargs(glue, index, argc, argv, name.c_str());
277 return result;
278 }
279
280 // To reduce overhead, we provide an additional interface for
281 // bytecode that directly CallRuntime and requires globalEnv,
282 // which is essentially the same as CallRuntimeWithGlobalEnv.
CallRuntimeWithCurrentEnv(GateRef glue,GateRef currentEnv,int index,const std::vector<GateRef> & args)283 inline GateRef StubBuilder::CallRuntimeWithCurrentEnv(GateRef glue, GateRef currentEnv,
284 int index, const std::vector<GateRef>& args)
285 {
286 SavePcIfNeeded(glue);
287 SetGlueGlobalEnvFromCurrentEnv(glue, currentEnv);
288 const std::string name = RuntimeStubCSigns::GetRTName(index);
289 GateRef result = env_->GetBuilder()->CallRuntime(glue, index, Gate::InvalidGateRef, args,
290 glue, name.c_str());
291 return result;
292 }
293
CallNGCRuntime(GateRef glue,int index,const std::vector<GateRef> & args,GateRef hir)294 inline GateRef StubBuilder::CallNGCRuntime(GateRef glue, int index,
295 const std::vector<GateRef>& args, GateRef hir)
296 {
297 const std::string name = RuntimeStubCSigns::GetRTName(index);
298 GateRef result;
299 if (env_->GetCircuit()->IsOptimizedOrFastJit()) {
300 result = env_->GetBuilder()->CallNGCRuntime(glue, index, Gate::InvalidGateRef, args,
301 hir, name.c_str());
302 } else {
303 result = env_->GetBuilder()->CallNGCRuntime(glue, index, Gate::InvalidGateRef, args,
304 Circuit::NullGate(), name.c_str());
305 }
306 return result;
307 }
308
FastCallOptimized(GateRef glue,GateRef code,const std::vector<GateRef> & args,GateRef hir)309 inline GateRef StubBuilder::FastCallOptimized(GateRef glue, GateRef code, const std::vector<GateRef>& args, GateRef hir)
310 {
311 GateRef result;
312 if (env_->GetCircuit()->IsOptimizedOrFastJit()) {
313 result = env_->GetBuilder()->FastCallOptimized(glue, code, Gate::InvalidGateRef, args, hir);
314 } else {
315 result = env_->GetBuilder()->FastCallOptimized(glue, code, Gate::InvalidGateRef, args, Circuit::NullGate());
316 }
317 return result;
318 }
319
CallOptimized(GateRef glue,GateRef code,const std::vector<GateRef> & args,GateRef hir)320 inline GateRef StubBuilder::CallOptimized(GateRef glue, GateRef code, const std::vector<GateRef>& args, GateRef hir)
321 {
322 GateRef result;
323 if (env_->GetCircuit()->IsOptimizedOrFastJit()) {
324 result = env_->GetBuilder()->CallOptimized(glue, code, Gate::InvalidGateRef, args, hir);
325 } else {
326 result = env_->GetBuilder()->CallOptimized(glue, code, Gate::InvalidGateRef, args, Circuit::NullGate());
327 }
328 return result;
329 }
330
GetAotCodeAddr(GateRef jsFunc)331 inline GateRef StubBuilder::GetAotCodeAddr(GateRef jsFunc)
332 {
333 return env_->GetBuilder()->GetCodeAddr(jsFunc);
334 }
335
GetBaselineCodeAddr(GateRef baselineCode)336 inline GateRef StubBuilder::GetBaselineCodeAddr(GateRef baselineCode)
337 {
338 return env_->GetBuilder()->GetBaselineCodeAddr(baselineCode);
339 }
340
CallStub(GateRef glue,int index,const std::initializer_list<GateRef> & args)341 inline GateRef StubBuilder::CallStub(GateRef glue, int index, const std::initializer_list<GateRef>& args)
342 {
343 SavePcIfNeeded(glue);
344 const std::string name = CommonStubCSigns::GetName(index);
345 GateRef result = env_->GetBuilder()->CallStub(glue, Circuit::NullGate(), index, args, name.c_str());
346 return result;
347 }
348
CallCommonStub(GateRef glue,int index,const std::initializer_list<GateRef> & args,GateRef hir)349 inline GateRef StubBuilder::CallCommonStub(GateRef glue, int index, const std::initializer_list<GateRef>& args,
350 GateRef hir)
351 {
352 SavePcIfNeeded(glue);
353 const std::string name = CommonStubCSigns::GetName(index);
354 GateRef result = env_->GetBuilder()->CallCommonStub(glue, hir, index, args, name.c_str());
355 return result;
356 }
357
CallBuiltinRuntime(GateRef glue,const std::initializer_list<GateRef> & args,bool isNew)358 inline GateRef StubBuilder::CallBuiltinRuntime(GateRef glue, const std::initializer_list<GateRef>& args, bool isNew)
359 {
360 return env_->GetBuilder()->CallBuiltinRuntime(glue, Gate::InvalidGateRef, args, isNew);
361 }
362
CallBuiltinRuntimeWithNewTarget(GateRef glue,const std::initializer_list<GateRef> & args)363 inline GateRef StubBuilder::CallBuiltinRuntimeWithNewTarget(GateRef glue, const std::initializer_list<GateRef>& args)
364 {
365 return env_->GetBuilder()->CallBuiltinRuntimeWithNewTarget(glue, Gate::InvalidGateRef, args);
366 }
367
DebugPrint(GateRef glue,std::initializer_list<GateRef> args)368 inline void StubBuilder::DebugPrint(GateRef glue, std::initializer_list<GateRef> args)
369 {
370 CallNGCRuntime(glue, RTSTUB_ID(DebugPrint), args);
371 }
372
FatalPrint(GateRef glue,std::initializer_list<GateRef> args)373 inline void StubBuilder::FatalPrint(GateRef glue, std::initializer_list<GateRef> args)
374 {
375 CallNGCRuntime(glue, RTSTUB_ID(FatalPrint), args);
376 }
377
SavePcIfNeeded(GateRef glue)378 void StubBuilder::SavePcIfNeeded(GateRef glue)
379 {
380 if (env_->IsAsmInterp()) {
381 GateRef sp = Argument(static_cast<size_t>(InterpreterHandlerInputs::SP));
382 GateRef pc = Argument(static_cast<size_t>(InterpreterHandlerInputs::PC));
383 GateRef frame = PtrSub(sp,
384 IntPtr(AsmInterpretedFrame::GetSize(GetEnvironment()->IsArch32Bit())));
385 Store(VariableType::INT64(), glue, frame,
386 IntPtr(AsmInterpretedFrame::GetPcOffset(GetEnvironment()->IsArch32Bit())), pc);
387 }
388 }
389
SaveJumpSizeIfNeeded(GateRef glue,GateRef jumpSize)390 void StubBuilder::SaveJumpSizeIfNeeded(GateRef glue, GateRef jumpSize)
391 {
392 if (env_->IsAsmInterp() || env_->IsBaselineBuiltin()) {
393 GateRef sp = Argument(static_cast<size_t>(InterpreterHandlerInputs::SP));
394 GateRef frame = PtrSub(sp,
395 IntPtr(AsmInterpretedFrame::GetSize(GetEnvironment()->IsArch32Bit())));
396 Store(VariableType::INT64(), glue, frame,
397 IntPtr(AsmInterpretedFrame::GetCallSizeOffset(GetEnvironment()->IsArch32Bit())), jumpSize);
398 }
399 }
400
SetHotnessCounter(GateRef glue,GateRef method,GateRef value)401 void StubBuilder::SetHotnessCounter(GateRef glue, GateRef method, GateRef value)
402 {
403 auto env = GetEnvironment();
404 GateRef newValue = env->GetBuilder()->TruncInt64ToInt16(value);
405 Store(VariableType::INT16(), glue, method, IntPtr(Method::LITERAL_INFO_OFFSET), newValue);
406 }
407
SaveHotnessCounterIfNeeded(GateRef glue,GateRef sp,GateRef hotnessCounter,JSCallMode mode)408 void StubBuilder::SaveHotnessCounterIfNeeded(GateRef glue, GateRef sp, GateRef hotnessCounter, JSCallMode mode)
409 {
410 if ((env_->IsAsmInterp() || env_->IsBaselineBuiltin())
411 && kungfu::AssemblerModule::IsJumpToCallCommonEntry(mode)) {
412 ASSERT(hotnessCounter != Circuit::NullGate());
413 GateRef frame = PtrSub(sp, IntPtr(AsmInterpretedFrame::GetSize(env_->IsArch32Bit())));
414 GateRef function = LoadPrimitive(VariableType::JS_POINTER(), frame,
415 IntPtr(AsmInterpretedFrame::GetFunctionOffset(env_->IsArch32Bit())));
416 GateRef method = Load(VariableType::JS_ANY(), glue, function, IntPtr(JSFunctionBase::METHOD_OFFSET));
417 SetHotnessCounter(glue, method, hotnessCounter);
418 }
419 }
420
421 // memory
Load(VariableType type,GateRef glue,GateRef base,GateRef offset,MemoryAttribute mAttr)422 inline GateRef StubBuilder::Load(VariableType type, GateRef glue, GateRef base, GateRef offset,
423 [[maybe_unused]] MemoryAttribute mAttr)
424 {
425 if (type == VariableType::NATIVE_POINTER()) {
426 type = env_->IsArch64Bit() ? VariableType::INT64() : VariableType::INT32();
427 }
428 if (type == VariableType::JS_ANY() || type == VariableType::JS_POINTER()) {
429 return env_->GetBuilder()->Load(type, glue, base, offset);
430 }
431 return LoadPrimitive(type, base, offset);
432 }
433
LoadZeroOffset(VariableType type,GateRef glue,GateRef base,MemoryAttribute mAttr)434 inline GateRef StubBuilder::LoadZeroOffset(VariableType type, GateRef glue, GateRef base,
435 MemoryAttribute mAttr)
436 {
437 return Load(type, glue, base, IntPtr(0), mAttr);
438 }
439
LoadPrimitive(VariableType type,GateRef base,GateRef offset)440 inline GateRef StubBuilder::LoadPrimitive(VariableType type, GateRef base, GateRef offset)
441 {
442 if (type == VariableType::NATIVE_POINTER()) {
443 type = env_->IsArch64Bit() ? VariableType::INT64() : VariableType::INT32();
444 }
445 return env_->GetBuilder()->LoadWithoutBarrier(type, base, offset);
446 }
447
LoadZeroOffsetPrimitive(VariableType type,GateRef base)448 inline GateRef StubBuilder::LoadZeroOffsetPrimitive(VariableType type, GateRef base)
449 {
450 return LoadPrimitive(type, base, IntPtr(0));
451 }
452
453 // arithmetic
Int16Add(GateRef x,GateRef y)454 inline GateRef StubBuilder::Int16Add(GateRef x, GateRef y)
455 {
456 return env_->GetBuilder()->Int16Add(x, y);
457 }
458
Int32Add(GateRef x,GateRef y)459 inline GateRef StubBuilder::Int32Add(GateRef x, GateRef y)
460 {
461 return env_->GetBuilder()->Int32Add(x, y);
462 }
463
Int64Add(GateRef x,GateRef y)464 inline GateRef StubBuilder::Int64Add(GateRef x, GateRef y)
465 {
466 return env_->GetBuilder()->Int64Add(x, y);
467 }
468
DoubleAdd(GateRef x,GateRef y)469 inline GateRef StubBuilder::DoubleAdd(GateRef x, GateRef y)
470 {
471 return env_->GetBuilder()->DoubleAdd(x, y);
472 }
473
PtrMul(GateRef x,GateRef y)474 inline GateRef StubBuilder::PtrMul(GateRef x, GateRef y)
475 {
476 return env_->GetBuilder()->PtrMul(x, y);
477 }
478
PtrAdd(GateRef x,GateRef y)479 inline GateRef StubBuilder::PtrAdd(GateRef x, GateRef y)
480 {
481 return env_->GetBuilder()->PtrAdd(x, y);
482 }
483
PtrSub(GateRef x,GateRef y)484 inline GateRef StubBuilder::PtrSub(GateRef x, GateRef y)
485 {
486 return env_->GetBuilder()->PtrSub(x, y);
487 }
488
IntPtrAnd(GateRef x,GateRef y)489 inline GateRef StubBuilder::IntPtrAnd(GateRef x, GateRef y)
490 {
491 return env_->Is32Bit() ? Int32And(x, y) : Int64And(x, y);
492 }
493
IntPtrEqual(GateRef x,GateRef y)494 inline GateRef StubBuilder::IntPtrEqual(GateRef x, GateRef y)
495 {
496 return env_->GetBuilder()->IntPtrEqual(x, y);
497 }
498
Int16Sub(GateRef x,GateRef y)499 inline GateRef StubBuilder::Int16Sub(GateRef x, GateRef y)
500 {
501 return env_->GetBuilder()->Int16Sub(x, y);
502 }
503
Int32Sub(GateRef x,GateRef y)504 inline GateRef StubBuilder::Int32Sub(GateRef x, GateRef y)
505 {
506 return env_->GetBuilder()->Int32Sub(x, y);
507 }
508
Int64Sub(GateRef x,GateRef y)509 inline GateRef StubBuilder::Int64Sub(GateRef x, GateRef y)
510 {
511 return env_->GetBuilder()->Int64Sub(x, y);
512 }
513
DoubleSub(GateRef x,GateRef y)514 inline GateRef StubBuilder::DoubleSub(GateRef x, GateRef y)
515 {
516 return env_->GetBuilder()->DoubleSub(x, y);
517 }
518
Int32Mul(GateRef x,GateRef y)519 inline GateRef StubBuilder::Int32Mul(GateRef x, GateRef y)
520 {
521 return env_->GetBuilder()->Int32Mul(x, y);
522 }
523
Int64Mul(GateRef x,GateRef y)524 inline GateRef StubBuilder::Int64Mul(GateRef x, GateRef y)
525 {
526 return env_->GetBuilder()->Int64Mul(x, y);
527 }
528
DoubleMul(GateRef x,GateRef y)529 inline GateRef StubBuilder::DoubleMul(GateRef x, GateRef y)
530 {
531 return env_->GetBuilder()->DoubleMul(x, y);
532 }
533
DoubleDiv(GateRef x,GateRef y)534 inline GateRef StubBuilder::DoubleDiv(GateRef x, GateRef y)
535 {
536 return env_->GetBuilder()->DoubleDiv(x, y);
537 }
538
Int32Div(GateRef x,GateRef y)539 inline GateRef StubBuilder::Int32Div(GateRef x, GateRef y)
540 {
541 return env_->GetBuilder()->Int32Div(x, y);
542 }
543
Int64Div(GateRef x,GateRef y)544 inline GateRef StubBuilder::Int64Div(GateRef x, GateRef y)
545 {
546 return env_->GetBuilder()->Int64Div(x, y);
547 }
548
IntPtrDiv(GateRef x,GateRef y)549 inline GateRef StubBuilder::IntPtrDiv(GateRef x, GateRef y)
550 {
551 return env_->GetBuilder()->IntPtrDiv(x, y);
552 }
553
IntPtrMod(GateRef x,GateRef y)554 inline GateRef StubBuilder::IntPtrMod(GateRef x, GateRef y)
555 {
556 return env_->GetBuilder()->IntPtrMod(x, y);
557 }
558
Int32Min(GateRef x,GateRef y)559 inline GateRef StubBuilder::Int32Min(GateRef x, GateRef y)
560 {
561 return env_->GetBuilder()->Int32Min(x, y);
562 }
563
Int32Max(GateRef x,GateRef y)564 inline GateRef StubBuilder::Int32Max(GateRef x, GateRef y)
565 {
566 return env_->GetBuilder()->Int32Max(x, y);
567 }
568
Int32Mod(GateRef x,GateRef y)569 inline GateRef StubBuilder::Int32Mod(GateRef x, GateRef y)
570 {
571 return env_->GetBuilder()->Int32Mod(x, y);
572 }
573
DoubleMod(GateRef x,GateRef y)574 inline GateRef StubBuilder::DoubleMod(GateRef x, GateRef y)
575 {
576 return env_->GetBuilder()->DoubleMod(x, y);
577 }
578
579 // bit operation
580
Int16Or(GateRef x,GateRef y)581 inline GateRef StubBuilder::Int16Or(GateRef x, GateRef y)
582 {
583 return env_->GetBuilder()->Int16Or(x, y);
584 }
585
Int16And(GateRef x,GateRef y)586 inline GateRef StubBuilder::Int16And(GateRef x, GateRef y)
587 {
588 return env_->GetBuilder()->Int16And(x, y);
589 }
590
Int32Or(GateRef x,GateRef y)591 inline GateRef StubBuilder::Int32Or(GateRef x, GateRef y)
592 {
593 return env_->GetBuilder()->Int32Or(x, y);
594 }
595
Int8And(GateRef x,GateRef y)596 inline GateRef StubBuilder::Int8And(GateRef x, GateRef y)
597 {
598 return env_->GetBuilder()->Int8And(x, y);
599 }
600
Int8Xor(GateRef x,GateRef y)601 inline GateRef StubBuilder::Int8Xor(GateRef x, GateRef y)
602 {
603 return env_->GetBuilder()->Int8Xor(x, y);
604 }
605
Int32And(GateRef x,GateRef y)606 inline GateRef StubBuilder::Int32And(GateRef x, GateRef y)
607 {
608 return env_->GetBuilder()->Int32And(x, y);
609 }
610
BitAnd(GateRef x,GateRef y)611 inline GateRef StubBuilder::BitAnd(GateRef x, GateRef y)
612 {
613 return env_->GetBuilder()->BitAnd(x, y);
614 }
615
BitOr(GateRef x,GateRef y)616 inline GateRef StubBuilder::BitOr(GateRef x, GateRef y)
617 {
618 return env_->GetBuilder()->BitOr(x, y);
619 }
620
Int32Not(GateRef x)621 inline GateRef StubBuilder::Int32Not(GateRef x)
622 {
623 return env_->GetBuilder()->Int32Not(x);
624 }
625
IntPtrNot(GateRef x)626 inline GateRef StubBuilder::IntPtrNot(GateRef x)
627 {
628 return env_->Is32Bit() ? Int32Not(x) : Int64Not(x);
629 }
630
BoolNot(GateRef x)631 inline GateRef StubBuilder::BoolNot(GateRef x)
632 {
633 return env_->GetBuilder()->BoolNot(x);
634 }
635
Int64Or(GateRef x,GateRef y)636 inline GateRef StubBuilder::Int64Or(GateRef x, GateRef y)
637 {
638 return env_->GetBuilder()->Int64Or(x, y);
639 }
640
Int64FetchOr(GateRef x,GateRef y,MemoryAttribute mAttr)641 inline GateRef StubBuilder::Int64FetchOr(GateRef x, GateRef y, MemoryAttribute mAttr)
642 {
643 return env_->GetBuilder()->FetchOr(x, y, mAttr);
644 }
645
IntPtrOr(GateRef x,GateRef y)646 inline GateRef StubBuilder::IntPtrOr(GateRef x, GateRef y)
647 {
648 return env_->GetBuilder()->IntPtrOr(x, y);
649 }
650
Int64And(GateRef x,GateRef y)651 inline GateRef StubBuilder::Int64And(GateRef x, GateRef y)
652 {
653 return env_->GetBuilder()->Int64And(x, y);
654 }
655
Int16LSL(GateRef x,GateRef y)656 inline GateRef StubBuilder::Int16LSL(GateRef x, GateRef y)
657 {
658 return env_->GetBuilder()->Int16LSL(x, y);
659 }
660
Int64Xor(GateRef x,GateRef y)661 inline GateRef StubBuilder::Int64Xor(GateRef x, GateRef y)
662 {
663 return env_->GetBuilder()->Int64Xor(x, y);
664 }
665
Int32Xor(GateRef x,GateRef y)666 inline GateRef StubBuilder::Int32Xor(GateRef x, GateRef y)
667 {
668 return env_->GetBuilder()->Int32Xor(x, y);
669 }
670
Int8LSR(GateRef x,GateRef y)671 inline GateRef StubBuilder::Int8LSR(GateRef x, GateRef y)
672 {
673 return env_->GetBuilder()->Int8LSR(x, y);
674 }
675
Int16LSR(GateRef x,GateRef y)676 inline GateRef StubBuilder::Int16LSR(GateRef x, GateRef y)
677 {
678 return env_->GetBuilder()->Int16LSR(x, y);
679 }
680
Int64Not(GateRef x)681 inline GateRef StubBuilder::Int64Not(GateRef x)
682 {
683 return env_->GetBuilder()->Int64Not(x);
684 }
685
Int32LSL(GateRef x,GateRef y)686 inline GateRef StubBuilder::Int32LSL(GateRef x, GateRef y)
687 {
688 return env_->GetBuilder()->Int32LSL(x, y);
689 }
690
Int64LSL(GateRef x,GateRef y)691 inline GateRef StubBuilder::Int64LSL(GateRef x, GateRef y)
692 {
693 return env_->GetBuilder()->Int64LSL(x, y);
694 }
695
IntPtrLSL(GateRef x,GateRef y)696 inline GateRef StubBuilder::IntPtrLSL(GateRef x, GateRef y)
697 {
698 return env_->GetBuilder()->IntPtrLSL(x, y);
699 }
700
Int32ASR(GateRef x,GateRef y)701 inline GateRef StubBuilder::Int32ASR(GateRef x, GateRef y)
702 {
703 return env_->GetBuilder()->Int32ASR(x, y);
704 }
705
Int32LSR(GateRef x,GateRef y)706 inline GateRef StubBuilder::Int32LSR(GateRef x, GateRef y)
707 {
708 return env_->GetBuilder()->Int32LSR(x, y);
709 }
710
Int64LSR(GateRef x,GateRef y)711 inline GateRef StubBuilder::Int64LSR(GateRef x, GateRef y)
712 {
713 return env_->GetBuilder()->Int64LSR(x, y);
714 }
715
IntPtrLSR(GateRef x,GateRef y)716 inline GateRef StubBuilder::IntPtrLSR(GateRef x, GateRef y)
717 {
718 return env_->GetBuilder()->IntPtrLSR(x, y);
719 }
720
721 template<OpCode Op, MachineType Type>
BinaryOp(GateRef x,GateRef y)722 inline GateRef StubBuilder::BinaryOp(GateRef x, GateRef y)
723 {
724 return env_->GetBuilder()->BinaryOp<Op, Type>(x, y);
725 }
726
727 template<OpCode Op, MachineType Type>
BinaryOpWithOverflow(GateRef x,GateRef y)728 inline GateRef StubBuilder::BinaryOpWithOverflow(GateRef x, GateRef y)
729 {
730 return env_->GetBuilder()->BinaryOpWithOverflow<Op, Type>(x, y);
731 }
732
TaggedIsInt(GateRef x)733 inline GateRef StubBuilder::TaggedIsInt(GateRef x)
734 {
735 return env_->GetBuilder()->TaggedIsInt(x);
736 }
737
TaggedIsDouble(GateRef x)738 inline GateRef StubBuilder::TaggedIsDouble(GateRef x)
739 {
740 return env_->GetBuilder()->TaggedIsDouble(x);
741 }
742
TaggedIsObject(GateRef x)743 inline GateRef StubBuilder::TaggedIsObject(GateRef x)
744 {
745 return env_->GetBuilder()->TaggedIsObject(x);
746 }
747
TaggedIsString(GateRef glue,GateRef obj)748 inline GateRef StubBuilder::TaggedIsString(GateRef glue, GateRef obj)
749 {
750 return env_->GetBuilder()->TaggedIsString(glue, obj);
751 }
752
TaggedIsStringIterator(GateRef glue,GateRef obj)753 inline GateRef StubBuilder::TaggedIsStringIterator(GateRef glue, GateRef obj)
754 {
755 return env_->GetBuilder()->TaggedIsStringIterator(glue, obj);
756 }
757
TaggedIsSharedObj(GateRef glue,GateRef obj)758 inline GateRef StubBuilder::TaggedIsSharedObj(GateRef glue, GateRef obj)
759 {
760 return env_->GetBuilder()->TaggedIsSharedObj(glue, obj);
761 }
762
TaggedIsStringOrSymbol(GateRef glue,GateRef obj)763 inline GateRef StubBuilder::TaggedIsStringOrSymbol(GateRef glue, GateRef obj)
764 {
765 return env_->GetBuilder()->TaggedIsStringOrSymbol(glue, obj);
766 }
767
TaggedIsSymbol(GateRef glue,GateRef obj)768 inline GateRef StubBuilder::TaggedIsSymbol(GateRef glue, GateRef obj)
769 {
770 return env_->GetBuilder()->TaggedIsSymbol(glue, obj);
771 }
772
TaggedIsArrayBuffer(GateRef glue,GateRef obj)773 inline GateRef StubBuilder::TaggedIsArrayBuffer(GateRef glue, GateRef obj)
774 {
775 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
776 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_ARRAY_BUFFER)));
777 }
778
TaggedIsArrayIterator(GateRef glue,GateRef obj)779 inline GateRef StubBuilder::TaggedIsArrayIterator(GateRef glue, GateRef obj)
780 {
781 return env_->GetBuilder()->TaggedIsArrayIterator(glue, obj);
782 }
783
BothAreString(GateRef glue,GateRef x,GateRef y)784 inline GateRef StubBuilder::BothAreString(GateRef glue, GateRef x, GateRef y)
785 {
786 return env_->GetBuilder()->BothAreString(glue, x, y);
787 }
788
TaggedIsNumber(GateRef x)789 inline GateRef StubBuilder::TaggedIsNumber(GateRef x)
790 {
791 return BoolNot(TaggedIsObject(x));
792 }
793
TaggedIsNumeric(GateRef glue,GateRef x)794 inline GateRef StubBuilder::TaggedIsNumeric(GateRef glue, GateRef x)
795 {
796 return env_->GetBuilder()->TaggedIsNumeric(glue, x);
797 }
798
TaggedIsHole(GateRef x)799 inline GateRef StubBuilder::TaggedIsHole(GateRef x)
800 {
801 return env_->GetBuilder()->TaggedIsHole(x);
802 }
803
TaggedIsNotHole(GateRef x)804 inline GateRef StubBuilder::TaggedIsNotHole(GateRef x)
805 {
806 return env_->GetBuilder()->TaggedIsNotHole(x);
807 }
808
ValueIsSpecialHole(GateRef x)809 inline GateRef StubBuilder::ValueIsSpecialHole(GateRef x)
810 {
811 return env_->GetBuilder()->IsSpecialHole(x);
812 }
813
ElementsKindIsInt(GateRef kind)814 inline GateRef StubBuilder::ElementsKindIsInt(GateRef kind)
815 {
816 return env_->GetBuilder()->ElementsKindIsInt(kind);
817 }
818
ElementsKindIsIntOrHoleInt(GateRef kind)819 inline GateRef StubBuilder::ElementsKindIsIntOrHoleInt(GateRef kind)
820 {
821 return env_->GetBuilder()->ElementsKindIsIntOrHoleInt(kind);
822 }
823
ElementsKindIsNumber(GateRef kind)824 inline GateRef StubBuilder::ElementsKindIsNumber(GateRef kind)
825 {
826 return env_->GetBuilder()->ElementsKindIsNumber(kind);
827 }
828
ElementsKindIsNumOrHoleNum(GateRef kind)829 inline GateRef StubBuilder::ElementsKindIsNumOrHoleNum(GateRef kind)
830 {
831 return env_->GetBuilder()->ElementsKindIsNumOrHoleNum(kind);
832 }
833
ElementsKindIsString(GateRef kind)834 inline GateRef StubBuilder::ElementsKindIsString(GateRef kind)
835 {
836 return env_->GetBuilder()->ElementsKindIsString(kind);
837 }
838
ElementsKindIsStringOrHoleString(GateRef kind)839 inline GateRef StubBuilder::ElementsKindIsStringOrHoleString(GateRef kind)
840 {
841 return env_->GetBuilder()->ElementsKindIsStringOrHoleString(kind);
842 }
843
ElementsKindIsHeapKind(GateRef kind)844 inline GateRef StubBuilder::ElementsKindIsHeapKind(GateRef kind)
845 {
846 return env_->GetBuilder()->ElementsKindIsHeapKind(kind);
847 }
848
ElementsKindHasHole(GateRef kind)849 inline GateRef StubBuilder::ElementsKindHasHole(GateRef kind)
850 {
851 return env_->GetBuilder()->ElementsKindHasHole(kind);
852 }
853
TaggedIsUndefined(GateRef x)854 inline GateRef StubBuilder::TaggedIsUndefined(GateRef x)
855 {
856 return env_->GetBuilder()->TaggedIsUndefined(x);
857 }
858
TaggedIsException(GateRef x)859 inline GateRef StubBuilder::TaggedIsException(GateRef x)
860 {
861 return env_->GetBuilder()->TaggedIsException(x);
862 }
863
TaggedIsSpecial(GateRef x)864 inline GateRef StubBuilder::TaggedIsSpecial(GateRef x)
865 {
866 return env_->GetBuilder()->TaggedIsSpecial(x);
867 }
868
TaggedIsRegularObject(GateRef glue,GateRef x)869 inline GateRef StubBuilder::TaggedIsRegularObject(GateRef glue, GateRef x)
870 {
871 GateRef objectType = GetObjectType(LoadHClass(glue, x));
872 return BitAnd(Int32LessThan(objectType, Int32(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST))),
873 Int32GreaterThan(objectType, Int32(static_cast<int32_t>(JSType::STRING_LAST))));
874 }
875
TaggedIsHeapObject(GateRef x)876 inline GateRef StubBuilder::TaggedIsHeapObject(GateRef x)
877 {
878 return env_->GetBuilder()->TaggedIsHeapObject(x);
879 }
880
TaggedIsGeneratorObject(GateRef glue,GateRef x)881 inline GateRef StubBuilder::TaggedIsGeneratorObject(GateRef glue, GateRef x)
882 {
883 return env_->GetBuilder()->TaggedIsGeneratorObject(glue, x);
884 }
885
TaggedIsJSProxy(GateRef glue,GateRef x)886 inline GateRef StubBuilder::TaggedIsJSProxy(GateRef glue, GateRef x)
887 {
888 return env_->GetBuilder()->TaggedIsJSProxy(glue, x);
889 }
890
TaggedIsJSArray(GateRef glue,GateRef x)891 inline GateRef StubBuilder::TaggedIsJSArray(GateRef glue, GateRef x)
892 {
893 return env_->GetBuilder()->TaggedIsJSArray(glue, x);
894 }
895
IsTaggedArray(GateRef glue,GateRef x)896 inline GateRef StubBuilder::IsTaggedArray(GateRef glue, GateRef x)
897 {
898 return env_->GetBuilder()->IsTaggedArray(glue, x);
899 }
900
TaggedIsAsyncGeneratorObject(GateRef glue,GateRef x)901 inline GateRef StubBuilder::TaggedIsAsyncGeneratorObject(GateRef glue, GateRef x)
902 {
903 return env_->GetBuilder()->TaggedIsAsyncGeneratorObject(glue, x);
904 }
905
TaggedIsJSGlobalObject(GateRef glue,GateRef x)906 inline GateRef StubBuilder::TaggedIsJSGlobalObject(GateRef glue, GateRef x)
907 {
908 return env_->GetBuilder()->TaggedIsJSGlobalObject(glue, x);
909 }
910
TaggedIsWeak(GateRef x)911 inline GateRef StubBuilder::TaggedIsWeak(GateRef x)
912 {
913 return env_->GetBuilder()->TaggedIsWeak(x);
914 }
915
TaggedIsPrototypeHandler(GateRef glue,GateRef x)916 inline GateRef StubBuilder::TaggedIsPrototypeHandler(GateRef glue, GateRef x)
917 {
918 return env_->GetBuilder()->TaggedIsPrototypeHandler(glue, x);
919 }
920
TaggedIsStoreAOTHandler(GateRef glue,GateRef x)921 inline GateRef StubBuilder::TaggedIsStoreAOTHandler(GateRef glue, GateRef x)
922 {
923 return env_->GetBuilder()->TaggedIsStoreAOTHandler(glue, x);
924 }
925
TaggedIsTransWithProtoHandler(GateRef glue,GateRef x)926 inline GateRef StubBuilder::TaggedIsTransWithProtoHandler(GateRef glue, GateRef x)
927 {
928 return env_->GetBuilder()->TaggedIsTransWithProtoHandler(glue, x);
929 }
930
TaggedIsTransitionHandler(GateRef glue,GateRef x)931 inline GateRef StubBuilder::TaggedIsTransitionHandler(GateRef glue, GateRef x)
932 {
933 return env_->GetBuilder()->TaggedIsTransitionHandler(glue, x);
934 }
935
GetNextPositionForHash(GateRef last,GateRef count,GateRef size)936 inline GateRef StubBuilder::GetNextPositionForHash(GateRef last, GateRef count, GateRef size)
937 {
938 auto nextOffset = Int32LSR(Int32Mul(count, Int32Add(count, Int32(1))),
939 Int32(1));
940 return Int32And(Int32Add(last, nextOffset), Int32Sub(size, Int32(1)));
941 }
942
DoubleIsNAN(GateRef x)943 inline GateRef StubBuilder::DoubleIsNAN(GateRef x)
944 {
945 return env_->GetBuilder()->DoubleIsNAN(x);
946 }
947
DoubleIsINF(GateRef x)948 inline GateRef StubBuilder::DoubleIsINF(GateRef x)
949 {
950 return env_->GetBuilder()->DoubleIsINF(x);
951 }
952
DoubleIsNanOrInf(GateRef x)953 inline GateRef StubBuilder::DoubleIsNanOrInf(GateRef x)
954 {
955 return env_->GetBuilder()->DoubleIsNanOrInf(x);
956 }
957
DoubleAbs(GateRef x)958 inline GateRef StubBuilder::DoubleAbs(GateRef x)
959 {
960 return env_->GetBuilder()->FAbs(x);
961 }
962
DoubleIsInteger(GateRef x)963 inline GateRef StubBuilder::DoubleIsInteger(GateRef x)
964 {
965 GateRef notInteger = LogicOrBuilder(env_).Or(DoubleIsNAN(x)).Or(DoubleIsINF(x))
966 .Or(BoolNot(DoubleEqual(x, DoubleTrunc(x)))).Done();
967 return BoolNot(notInteger);
968 }
969
DoubleIsWithinInt32(GateRef x)970 inline GateRef StubBuilder::DoubleIsWithinInt32(GateRef x)
971 {
972 return env_->GetBuilder()->DoubleIsWithinInt32(x);
973 }
974
DoubleTrunc(GateRef x)975 inline GateRef StubBuilder::DoubleTrunc(GateRef x)
976 {
977 if (env_->IsAArch64()) {
978 return env_->GetBuilder()->DoubleTrunc(x);
979 }
980
981 Label entry(env_);
982 env_->SubCfgEntry(&entry);
983
984 DEFVARIABLE(result, VariableType::FLOAT64(), x);
985 Label exit(env_);
986
987 constexpr int64_t DOUBLE_FRACTION_BITS = 52;
988 constexpr int64_t DOUBLE_EXP_MASK = 0x7ff;
989 constexpr int64_t DOUBLE_EXP_OFFSET = 0x3ff;
990 GateRef bits = CastDoubleToInt64(x);
991 GateRef exp = Int64Sub(Int64And(Int64LSR(bits, Int64(DOUBLE_FRACTION_BITS)), Int64(DOUBLE_EXP_MASK)),
992 Int64(DOUBLE_EXP_OFFSET));
993
994 Label trunc(env_);
995 BRANCH(Int64GreaterThanOrEqual(exp, Int64(DOUBLE_FRACTION_BITS)), &exit, &trunc);
996 Bind(&trunc);
997 {
998 Label zero(env_);
999 Label nonZero(env_);
1000 BRANCH(Int64LessThan(exp, Int64(0)), &zero, &nonZero);
1001 Bind(&zero);
1002 {
1003 constexpr int64_t DOUBLE_SIGN_SHIFT = 63;
1004 constexpr int64_t mask = static_cast<int64_t>(1) << DOUBLE_SIGN_SHIFT;
1005 result = CastInt64ToFloat64(Int64And(bits, Int64(mask)));
1006 Jump(&exit);
1007 }
1008 Bind(&nonZero);
1009 {
1010 constexpr int64_t DOUBLE_NON_FRACTION_BITS = 12;
1011 constexpr int64_t NEG_ONE = -1;
1012 GateRef mask = Int64LSR(Int64(NEG_ONE), Int64Add(exp, Int64(DOUBLE_NON_FRACTION_BITS)));
1013 result = CastInt64ToFloat64(Int64And(bits, Int64Not(mask)));
1014 Jump(&exit);
1015 }
1016 }
1017
1018 Bind(&exit);
1019 auto ret = *result;
1020 env_->SubCfgExit();
1021 return ret;
1022 }
1023
TaggedIsNull(GateRef x)1024 inline GateRef StubBuilder::TaggedIsNull(GateRef x)
1025 {
1026 return env_->GetBuilder()->TaggedIsNull(x);
1027 }
1028
TaggedIsNotNull(GateRef x)1029 inline GateRef StubBuilder::TaggedIsNotNull(GateRef x)
1030 {
1031 return env_->GetBuilder()->TaggedIsNotNull(x);
1032 }
1033
TaggedIsUndefinedOrNull(GateRef x)1034 inline GateRef StubBuilder::TaggedIsUndefinedOrNull(GateRef x)
1035 {
1036 return env_->GetBuilder()->TaggedIsUndefinedOrNull(x);
1037 }
1038
TaggedIsUndefinedOrNullOrHole(GateRef x)1039 inline GateRef StubBuilder::TaggedIsUndefinedOrNullOrHole(GateRef x)
1040 {
1041 return env_->GetBuilder()->TaggedIsUndefinedOrNullOrHole(x);
1042 }
1043
TaggedIsTrue(GateRef x)1044 inline GateRef StubBuilder::TaggedIsTrue(GateRef x)
1045 {
1046 return env_->GetBuilder()->TaggedIsTrue(x);
1047 }
1048
TaggedIsFalse(GateRef x)1049 inline GateRef StubBuilder::TaggedIsFalse(GateRef x)
1050 {
1051 return env_->GetBuilder()->TaggedIsFalse(x);
1052 }
1053
TaggedIsBoolean(GateRef x)1054 inline GateRef StubBuilder::TaggedIsBoolean(GateRef x)
1055 {
1056 return env_->GetBuilder()->TaggedIsBoolean(x);
1057 }
1058
TaggedIsNativePointer(GateRef glue,GateRef x)1059 inline GateRef StubBuilder::TaggedIsNativePointer(GateRef glue, GateRef x)
1060 {
1061 return env_->GetBuilder()->TaggedIsNativePointer(glue, x);
1062 }
1063
TaggedGetInt(GateRef x)1064 inline GateRef StubBuilder::TaggedGetInt(GateRef x)
1065 {
1066 return env_->GetBuilder()->TaggedGetInt(x);
1067 }
1068
Int8ToTaggedInt(GateRef x)1069 inline GateRef StubBuilder::Int8ToTaggedInt(GateRef x)
1070 {
1071 GateRef val = SExtInt8ToInt64(x);
1072 return env_->GetBuilder()->ToTaggedInt(val);
1073 }
1074
Int16ToTaggedInt(GateRef x)1075 inline GateRef StubBuilder::Int16ToTaggedInt(GateRef x)
1076 {
1077 GateRef val = SExtInt16ToInt64(x);
1078 return env_->GetBuilder()->ToTaggedInt(val);
1079 }
1080
IntToTaggedPtr(GateRef x)1081 inline GateRef StubBuilder::IntToTaggedPtr(GateRef x)
1082 {
1083 GateRef val = SExtInt32ToInt64(x);
1084 return env_->GetBuilder()->ToTaggedIntPtr(val);
1085 }
1086
IntToTaggedInt(GateRef x)1087 inline GateRef StubBuilder::IntToTaggedInt(GateRef x)
1088 {
1089 GateRef val = SExtInt32ToInt64(x);
1090 return env_->GetBuilder()->ToTaggedInt(val);
1091 }
1092
Int64ToTaggedInt(GateRef x)1093 inline GateRef StubBuilder::Int64ToTaggedInt(GateRef x)
1094 {
1095 return env_->GetBuilder()->ToTaggedInt(x);
1096 }
1097
Int64ToTaggedIntPtr(GateRef x)1098 inline GateRef StubBuilder::Int64ToTaggedIntPtr(GateRef x)
1099 {
1100 return env_->GetBuilder()->ToTaggedIntPtr(x);
1101 }
1102
DoubleToTaggedDouble(GateRef x)1103 inline GateRef StubBuilder::DoubleToTaggedDouble(GateRef x)
1104 {
1105 return env_->GetBuilder()->DoubleToTaggedDouble(x);
1106 }
1107
DoubleToTaggedDoublePtr(GateRef x)1108 inline GateRef StubBuilder::DoubleToTaggedDoublePtr(GateRef x)
1109 {
1110 return env_->GetBuilder()->DoubleToTaggedDoublePtr(x);
1111 }
1112
BooleanToTaggedBooleanPtr(GateRef x)1113 inline GateRef StubBuilder::BooleanToTaggedBooleanPtr(GateRef x)
1114 {
1115 return env_->GetBuilder()->BooleanToTaggedBooleanPtr(x);
1116 }
1117
TaggedPtrToTaggedDoublePtr(GateRef x)1118 inline GateRef StubBuilder::TaggedPtrToTaggedDoublePtr(GateRef x)
1119 {
1120 return DoubleToTaggedDoublePtr(CastInt64ToFloat64(ChangeTaggedPointerToInt64(x)));
1121 }
1122
TaggedPtrToTaggedIntPtr(GateRef x)1123 inline GateRef StubBuilder::TaggedPtrToTaggedIntPtr(GateRef x)
1124 {
1125 return IntToTaggedPtr(TruncInt64ToInt32(ChangeTaggedPointerToInt64(x)));
1126 }
1127
CastDoubleToInt64(GateRef x)1128 inline GateRef StubBuilder::CastDoubleToInt64(GateRef x)
1129 {
1130 return env_->GetBuilder()->CastDoubleToInt64(x);
1131 }
1132
CastFloat32ToInt32(GateRef x)1133 inline GateRef StubBuilder::CastFloat32ToInt32(GateRef x)
1134 {
1135 return env_->GetBuilder()->CastFloat32ToInt32(x);
1136 }
1137
TaggedTrue()1138 inline GateRef StubBuilder::TaggedTrue()
1139 {
1140 return env_->GetBuilder()->TaggedTrue();
1141 }
1142
TaggedFalse()1143 inline GateRef StubBuilder::TaggedFalse()
1144 {
1145 return env_->GetBuilder()->TaggedFalse();
1146 }
1147
TaggedUndefined()1148 inline GateRef StubBuilder::TaggedUndefined()
1149 {
1150 return env_->GetBuilder()->UndefineConstant();
1151 }
1152
1153 // compare operation
Int8Equal(GateRef x,GateRef y)1154 inline GateRef StubBuilder::Int8Equal(GateRef x, GateRef y)
1155 {
1156 return env_->GetBuilder()->Int8Equal(x, y);
1157 }
1158
Int8GreaterThanOrEqual(GateRef x,GateRef y)1159 inline GateRef StubBuilder::Int8GreaterThanOrEqual(GateRef x, GateRef y)
1160 {
1161 return env_->GetBuilder()->Int8GreaterThanOrEqual(x, y);
1162 }
1163
Equal(GateRef x,GateRef y)1164 inline GateRef StubBuilder::Equal(GateRef x, GateRef y)
1165 {
1166 return env_->GetBuilder()->Equal(x, y);
1167 }
1168
NotEqual(GateRef x,GateRef y)1169 inline GateRef StubBuilder::NotEqual(GateRef x, GateRef y)
1170 {
1171 return env_->GetBuilder()->NotEqual(x, y);
1172 }
1173
Int32Equal(GateRef x,GateRef y)1174 inline GateRef StubBuilder::Int32Equal(GateRef x, GateRef y)
1175 {
1176 return env_->GetBuilder()->Int32Equal(x, y);
1177 }
1178
Int32NotEqual(GateRef x,GateRef y)1179 inline GateRef StubBuilder::Int32NotEqual(GateRef x, GateRef y)
1180 {
1181 return env_->GetBuilder()->Int32NotEqual(x, y);
1182 }
1183
Int64Equal(GateRef x,GateRef y)1184 inline GateRef StubBuilder::Int64Equal(GateRef x, GateRef y)
1185 {
1186 return env_->GetBuilder()->Int64Equal(x, y);
1187 }
1188
DoubleEqual(GateRef x,GateRef y)1189 inline GateRef StubBuilder::DoubleEqual(GateRef x, GateRef y)
1190 {
1191 return env_->GetBuilder()->DoubleEqual(x, y);
1192 }
1193
DoubleNotEqual(GateRef x,GateRef y)1194 inline GateRef StubBuilder::DoubleNotEqual(GateRef x, GateRef y)
1195 {
1196 return env_->GetBuilder()->DoubleNotEqual(x, y);
1197 }
1198
DoubleLessThan(GateRef x,GateRef y)1199 inline GateRef StubBuilder::DoubleLessThan(GateRef x, GateRef y)
1200 {
1201 return env_->GetBuilder()->DoubleLessThan(x, y);
1202 }
1203
DoubleLessThanOrEqual(GateRef x,GateRef y)1204 inline GateRef StubBuilder::DoubleLessThanOrEqual(GateRef x, GateRef y)
1205 {
1206 return env_->GetBuilder()->DoubleLessThanOrEqual(x, y);
1207 }
1208
DoubleGreaterThan(GateRef x,GateRef y)1209 inline GateRef StubBuilder::DoubleGreaterThan(GateRef x, GateRef y)
1210 {
1211 return env_->GetBuilder()->DoubleGreaterThan(x, y);
1212 }
1213
DoubleGreaterThanOrEqual(GateRef x,GateRef y)1214 inline GateRef StubBuilder::DoubleGreaterThanOrEqual(GateRef x, GateRef y)
1215 {
1216 return env_->GetBuilder()->DoubleGreaterThanOrEqual(x, y);
1217 }
1218
Int64NotEqual(GateRef x,GateRef y)1219 inline GateRef StubBuilder::Int64NotEqual(GateRef x, GateRef y)
1220 {
1221 return env_->GetBuilder()->Int64NotEqual(x, y);
1222 }
1223
Int32GreaterThan(GateRef x,GateRef y)1224 inline GateRef StubBuilder::Int32GreaterThan(GateRef x, GateRef y)
1225 {
1226 return env_->GetBuilder()->Int32GreaterThan(x, y);
1227 }
1228
Int32LessThan(GateRef x,GateRef y)1229 inline GateRef StubBuilder::Int32LessThan(GateRef x, GateRef y)
1230 {
1231 return env_->GetBuilder()->Int32LessThan(x, y);
1232 }
1233
Int32GreaterThanOrEqual(GateRef x,GateRef y)1234 inline GateRef StubBuilder::Int32GreaterThanOrEqual(GateRef x, GateRef y)
1235 {
1236 return env_->GetBuilder()->Int32GreaterThanOrEqual(x, y);
1237 }
1238
Int32LessThanOrEqual(GateRef x,GateRef y)1239 inline GateRef StubBuilder::Int32LessThanOrEqual(GateRef x, GateRef y)
1240 {
1241 return env_->GetBuilder()->Int32LessThanOrEqual(x, y);
1242 }
1243
Int32UnsignedGreaterThan(GateRef x,GateRef y)1244 inline GateRef StubBuilder::Int32UnsignedGreaterThan(GateRef x, GateRef y)
1245 {
1246 return env_->GetBuilder()->Int32UnsignedGreaterThan(x, y);
1247 }
1248
Int32UnsignedLessThan(GateRef x,GateRef y)1249 inline GateRef StubBuilder::Int32UnsignedLessThan(GateRef x, GateRef y)
1250 {
1251 return env_->GetBuilder()->Int32UnsignedLessThan(x, y);
1252 }
1253
Int32UnsignedGreaterThanOrEqual(GateRef x,GateRef y)1254 inline GateRef StubBuilder::Int32UnsignedGreaterThanOrEqual(GateRef x, GateRef y)
1255 {
1256 return env_->GetBuilder()->Int32UnsignedGreaterThanOrEqual(x, y);
1257 }
1258
Int32UnsignedLessThanOrEqual(GateRef x,GateRef y)1259 inline GateRef StubBuilder::Int32UnsignedLessThanOrEqual(GateRef x, GateRef y)
1260 {
1261 return env_->GetBuilder()->Int32UnsignedLessThanOrEqual(x, y);
1262 }
1263
Int64GreaterThan(GateRef x,GateRef y)1264 inline GateRef StubBuilder::Int64GreaterThan(GateRef x, GateRef y)
1265 {
1266 return env_->GetBuilder()->Int64GreaterThan(x, y);
1267 }
1268
Int64LessThan(GateRef x,GateRef y)1269 inline GateRef StubBuilder::Int64LessThan(GateRef x, GateRef y)
1270 {
1271 return env_->GetBuilder()->Int64LessThan(x, y);
1272 }
1273
Int64LessThanOrEqual(GateRef x,GateRef y)1274 inline GateRef StubBuilder::Int64LessThanOrEqual(GateRef x, GateRef y)
1275 {
1276 return env_->GetBuilder()->Int64LessThanOrEqual(x, y);
1277 }
1278
Int64GreaterThanOrEqual(GateRef x,GateRef y)1279 inline GateRef StubBuilder::Int64GreaterThanOrEqual(GateRef x, GateRef y)
1280 {
1281 return env_->GetBuilder()->Int64GreaterThanOrEqual(x, y);
1282 }
1283
Int64UnsignedLessThanOrEqual(GateRef x,GateRef y)1284 inline GateRef StubBuilder::Int64UnsignedLessThanOrEqual(GateRef x, GateRef y)
1285 {
1286 return env_->GetBuilder()->Int64UnsignedLessThanOrEqual(x, y);
1287 }
1288
Int64UnsignedGreaterThan(GateRef x,GateRef y)1289 inline GateRef StubBuilder::Int64UnsignedGreaterThan(GateRef x, GateRef y)
1290 {
1291 return env_->GetBuilder()->Int64UnsignedGreaterThan(x, y);
1292 }
1293
Int64UnsignedGreaterThanOrEqual(GateRef x,GateRef y)1294 inline GateRef StubBuilder::Int64UnsignedGreaterThanOrEqual(GateRef x, GateRef y)
1295 {
1296 return env_->GetBuilder()->Int64UnsignedGreaterThanOrEqual(x, y);
1297 }
1298
IntPtrLessThan(GateRef x,GateRef y)1299 inline GateRef StubBuilder::IntPtrLessThan(GateRef x, GateRef y)
1300 {
1301 return env_->GetBuilder()->IntPtrLessThan(x, y);
1302 }
1303
IntPtrLessThanOrEqual(GateRef x,GateRef y)1304 inline GateRef StubBuilder::IntPtrLessThanOrEqual(GateRef x, GateRef y)
1305 {
1306 return env_->GetBuilder()->IntPtrLessThanOrEqual(x, y);
1307 }
1308
IntPtrGreaterThan(GateRef x,GateRef y)1309 inline GateRef StubBuilder::IntPtrGreaterThan(GateRef x, GateRef y)
1310 {
1311 return env_->GetBuilder()->IntPtrGreaterThan(x, y);
1312 }
1313
IntPtrGreaterThanOrEqual(GateRef x,GateRef y)1314 inline GateRef StubBuilder::IntPtrGreaterThanOrEqual(GateRef x, GateRef y)
1315 {
1316 return env_->GetBuilder()->IntPtrGreaterThanOrEqual(x, y);
1317 }
1318
1319 // cast operation
TruncInt16ToInt8(GateRef val)1320 inline GateRef StubBuilder::TruncInt16ToInt8(GateRef val)
1321 {
1322 return env_->GetBuilder()->TruncInt16ToInt8(val);
1323 }
1324
TruncInt32ToInt16(GateRef val)1325 inline GateRef StubBuilder::TruncInt32ToInt16(GateRef val)
1326 {
1327 return env_->GetBuilder()->TruncInt32ToInt16(val);
1328 }
1329
TruncInt32ToInt8(GateRef val)1330 inline GateRef StubBuilder::TruncInt32ToInt8(GateRef val)
1331 {
1332 return env_->GetBuilder()->TruncInt32ToInt8(val);
1333 }
1334
TruncFloatToInt64(GateRef val)1335 inline GateRef StubBuilder::TruncFloatToInt64(GateRef val)
1336 {
1337 return env_->GetBuilder()->TruncFloatToInt64(val);
1338 }
1339
CanNotConvertNotValidObject(GateRef glue,GateRef obj)1340 inline void StubBuilder::CanNotConvertNotValidObject([[maybe_unused]] GateRef glue, [[maybe_unused]] GateRef obj)
1341 {
1342 ASM_ASSERT(GET_MESSAGE_STRING_ID(CanNotConvertNotValidObject), IsEcmaObject(glue, obj));
1343 }
1344
IsNotValidObject(GateRef flag)1345 inline void StubBuilder::IsNotValidObject([[maybe_unused]] GateRef flag)
1346 {
1347 ASM_ASSERT(GET_MESSAGE_STRING_ID(CanNotConvertNotValidObject), flag);
1348 }
1349
IsNotPropertyKey(GateRef flag)1350 inline void StubBuilder::IsNotPropertyKey([[maybe_unused]] GateRef flag)
1351 {
1352 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsNotPropertyKey), flag);
1353 }
1354
ChangeInt64ToIntPtr(GateRef val)1355 inline GateRef StubBuilder::ChangeInt64ToIntPtr(GateRef val)
1356 {
1357 if (env_->IsArch32Bit()) {
1358 return TruncInt64ToInt32(val);
1359 }
1360 return val;
1361 }
1362
ZExtInt32ToPtr(GateRef val)1363 inline GateRef StubBuilder::ZExtInt32ToPtr(GateRef val)
1364 {
1365 if (env_->IsArch32Bit()) {
1366 return val;
1367 }
1368 return ZExtInt32ToInt64(val);
1369 }
1370
ChangeIntPtrToInt32(GateRef val)1371 inline GateRef StubBuilder::ChangeIntPtrToInt32(GateRef val)
1372 {
1373 if (env_->IsArch32Bit()) {
1374 return val;
1375 }
1376 return TruncInt64ToInt32(val);
1377 }
1378
GetSetterFromAccessor(GateRef glue,GateRef accessor)1379 inline GateRef StubBuilder::GetSetterFromAccessor(GateRef glue, GateRef accessor)
1380 {
1381 GateRef setterOffset = IntPtr(AccessorData::SETTER_OFFSET);
1382 return Load(VariableType::JS_ANY(), glue, accessor, setterOffset);
1383 }
1384
GetElementsArray(GateRef glue,GateRef object)1385 inline GateRef StubBuilder::GetElementsArray(GateRef glue, GateRef object)
1386 {
1387 return env_->GetBuilder()->GetElementsArray(glue, object);
1388 }
1389
SetElementsArray(VariableType type,GateRef glue,GateRef object,GateRef elementsArray,MemoryAttribute mAttr)1390 inline void StubBuilder::SetElementsArray(VariableType type, GateRef glue, GateRef object, GateRef elementsArray,
1391 MemoryAttribute mAttr)
1392 {
1393 GateRef elementsOffset = IntPtr(JSObject::ELEMENTS_OFFSET);
1394 Store(type, glue, object, elementsOffset, elementsArray, mAttr);
1395 }
1396
GetPropertiesArray(GateRef glue,GateRef object)1397 inline GateRef StubBuilder::GetPropertiesArray(GateRef glue, GateRef object)
1398 {
1399 GateRef propertiesOffset = IntPtr(JSObject::PROPERTIES_OFFSET);
1400 return Load(VariableType::JS_POINTER(), glue, object, propertiesOffset);
1401 }
1402
1403 // SetProperties in js_object.h
SetPropertiesArray(VariableType type,GateRef glue,GateRef object,GateRef propsArray,MemoryAttribute mAttr)1404 inline void StubBuilder::SetPropertiesArray(VariableType type, GateRef glue, GateRef object, GateRef propsArray,
1405 MemoryAttribute mAttr)
1406 {
1407 GateRef propertiesOffset = IntPtr(JSObject::PROPERTIES_OFFSET);
1408 Store(type, glue, object, propertiesOffset, propsArray, mAttr);
1409 }
1410
GetLengthOfTaggedArray(GateRef array)1411 inline GateRef StubBuilder::GetLengthOfTaggedArray(GateRef array)
1412 {
1413 return LoadPrimitive(VariableType::INT32(), array, IntPtr(TaggedArray::LENGTH_OFFSET));
1414 }
1415
GetLengthOfJSTypedArray(GateRef array)1416 inline GateRef StubBuilder::GetLengthOfJSTypedArray(GateRef array)
1417 {
1418 return LoadPrimitive(VariableType::INT32(), array, IntPtr(JSTypedArray::ARRAY_LENGTH_OFFSET));
1419 }
1420
GetExtraLengthOfTaggedArray(GateRef array)1421 inline GateRef StubBuilder::GetExtraLengthOfTaggedArray(GateRef array)
1422 {
1423 return LoadPrimitive(VariableType::INT32(), array, IntPtr(TaggedArray::EXTRA_LENGTH_OFFSET));
1424 }
1425
SetExtraLengthOfTaggedArray(GateRef glue,GateRef array,GateRef len)1426 inline void StubBuilder::SetExtraLengthOfTaggedArray(GateRef glue, GateRef array, GateRef len)
1427 {
1428 return Store(VariableType::INT32(), glue, array, IntPtr(TaggedArray::EXTRA_LENGTH_OFFSET),
1429 len, MemoryAttribute::NoBarrier());
1430 }
1431
IsJSHClass(GateRef glue,GateRef obj)1432 inline GateRef StubBuilder::IsJSHClass(GateRef glue, GateRef obj)
1433 {
1434 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsJSHClass), TaggedIsHeapObject(obj));
1435 GateRef res = env_->GetBuilder()->IsJSHClass(glue, obj);
1436 return res;
1437 }
1438
1439 // object operation
1440
LoadHclassImpl(GateRef glue,GateRef object,int line)1441 inline GateRef StubBuilder::LoadHclassImpl(GateRef glue, GateRef object, int line)
1442 {
1443 ASM_ASSERT_WITH_LINE(GET_MESSAGE_STRING_ID(LoadHClass), TaggedIsHeapObject(object), line);
1444 GateRef res = env_->GetBuilder()->LoadHClass(glue, object);
1445 return res;
1446 }
1447
StoreHClass(GateRef glue,GateRef object,GateRef hClass,MemoryAttribute mAttr)1448 inline void StubBuilder::StoreHClass(GateRef glue, GateRef object, GateRef hClass, MemoryAttribute mAttr)
1449 {
1450 return env_->GetBuilder()->StoreHClass(glue, object, hClass, mAttr);
1451 }
1452
TransitionHClass(GateRef glue,GateRef object,GateRef hClass,MemoryAttribute mAttr)1453 inline void StubBuilder::TransitionHClass(GateRef glue, GateRef object, GateRef hClass, MemoryAttribute mAttr)
1454 {
1455 return env_->GetBuilder()->TransitionHClass(glue, object, hClass, mAttr);
1456 }
1457
StoreBuiltinHClass(GateRef glue,GateRef object,GateRef hClass)1458 inline void StubBuilder::StoreBuiltinHClass(GateRef glue, GateRef object, GateRef hClass)
1459 {
1460 return env_->GetBuilder()->StoreHClass(glue, object, hClass, MemoryAttribute::NoBarrier());
1461 }
1462
StorePrototype(GateRef glue,GateRef hclass,GateRef prototype)1463 inline void StubBuilder::StorePrototype(GateRef glue, GateRef hclass, GateRef prototype)
1464 {
1465 return env_->GetBuilder()->StorePrototype(glue, hclass, prototype);
1466 }
1467
GetObjectType(GateRef hClass)1468 inline GateRef StubBuilder::GetObjectType(GateRef hClass)
1469 {
1470 return env_->GetBuilder()->GetObjectType(hClass);
1471 }
1472
IsDictionaryMode(GateRef glue,GateRef object)1473 inline GateRef StubBuilder::IsDictionaryMode(GateRef glue, GateRef object)
1474 {
1475 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsDictionaryMode), TaggedIsHeapObject(object));
1476 GateRef res = env_->GetBuilder()->IsDictionaryMode(glue, object);
1477 return res;
1478 }
1479
IsDictionaryModeByHClass(GateRef hClass)1480 inline GateRef StubBuilder::IsDictionaryModeByHClass(GateRef hClass)
1481 {
1482 return env_->GetBuilder()->IsDictionaryModeByHClass(hClass);
1483 }
1484
IsDictionaryElement(GateRef hClass)1485 inline GateRef StubBuilder::IsDictionaryElement(GateRef hClass)
1486 {
1487 return env_->GetBuilder()->IsDictionaryElement(hClass);
1488 }
1489
IsJSArrayPrototypeModified(GateRef hClass)1490 inline GateRef StubBuilder::IsJSArrayPrototypeModified(GateRef hClass)
1491 {
1492 return env_->GetBuilder()->IsJSArrayPrototypeModified(hClass);
1493 }
1494
IsClassConstructorFromBitField(GateRef bitfield)1495 inline GateRef StubBuilder::IsClassConstructorFromBitField(GateRef bitfield)
1496 {
1497 // decode
1498 return env_->GetBuilder()->IsClassConstructorWithBitField(bitfield);
1499 }
1500
IsClassConstructor(GateRef glue,GateRef object)1501 inline GateRef StubBuilder::IsClassConstructor(GateRef glue, GateRef object)
1502 {
1503 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsClassConstructor), TaggedIsHeapObject(object));
1504 GateRef res = env_->GetBuilder()->IsClassConstructor(glue, object);
1505 return res;
1506 }
1507
IsClassPrototype(GateRef glue,GateRef object)1508 inline GateRef StubBuilder::IsClassPrototype(GateRef glue, GateRef object)
1509 {
1510 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsClassPrototype), TaggedIsHeapObject(object));
1511 GateRef res = env_->GetBuilder()->IsClassPrototype(glue, object);
1512 return res;
1513 }
1514
IsExtensible(GateRef glue,GateRef object)1515 inline GateRef StubBuilder::IsExtensible(GateRef glue, GateRef object)
1516 {
1517 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsExtensible), TaggedIsHeapObject(object));
1518 GateRef res = env_->GetBuilder()->IsExtensible(glue, object);
1519 return res;
1520 }
1521
IsSendableFunctionModule(GateRef glue,GateRef module)1522 inline GateRef StubBuilder::IsSendableFunctionModule([[maybe_unused]] GateRef glue, GateRef module)
1523 {
1524 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsSendableFunctionModule), IsSourceTextModule(glue, module));
1525 GateRef bitfieldOffset = Int32(SourceTextModule::BIT_FIELD_OFFSET);
1526 GateRef bitfield = LoadPrimitive(VariableType::INT32(), module, bitfieldOffset);
1527 return Equal(Int32And(Int32LSR(bitfield,
1528 Int32(SourceTextModule::SharedTypeBits::START_BIT)),
1529 Int32((1LU << SourceTextModule::SharedTypeBits::SIZE) - 1)),
1530 Int32(static_cast<int32_t>(SharedTypes::SENDABLE_FUNCTION_MODULE)));
1531 }
1532
GetFunctionLexicalEnv(GateRef glue,GateRef function)1533 inline GateRef StubBuilder::GetFunctionLexicalEnv(GateRef glue, GateRef function)
1534 {
1535 return env_->GetBuilder()->GetFunctionLexicalEnv(glue, function);
1536 }
1537
TaggedObjectIsEcmaObject(GateRef glue,GateRef obj)1538 inline GateRef StubBuilder::TaggedObjectIsEcmaObject(GateRef glue, GateRef obj)
1539 {
1540 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsEcmaObject), TaggedIsHeapObject(obj));
1541 GateRef res = env_->GetBuilder()->TaggedObjectIsEcmaObject(glue, obj);
1542 return res;
1543 }
1544
IsEcmaObject(GateRef glue,GateRef obj)1545 inline GateRef StubBuilder::IsEcmaObject(GateRef glue, GateRef obj)
1546 {
1547 return env_->GetBuilder()->IsEcmaObject(glue, obj);
1548 }
1549
IsJSObject(GateRef glue,GateRef obj)1550 inline GateRef StubBuilder::IsJSObject(GateRef glue, GateRef obj)
1551 {
1552 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsJSObject), TaggedIsHeapObject(obj));
1553 GateRef res = env_->GetBuilder()->IsJSObject(glue, obj);
1554 return res;
1555 }
1556
IsJSFunctionBase(GateRef glue,GateRef obj)1557 inline GateRef StubBuilder::IsJSFunctionBase(GateRef glue, GateRef obj)
1558 {
1559 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1560 GateRef greater = Int32GreaterThanOrEqual(objectType,
1561 Int32(static_cast<int32_t>(JSType::JS_FUNCTION_BASE)));
1562 GateRef less = Int32LessThanOrEqual(objectType,
1563 Int32(static_cast<int32_t>(JSType::JS_BOUND_FUNCTION)));
1564 return BitAnd(greater, less);
1565 }
1566
IsConstructor(GateRef glue,GateRef object)1567 inline GateRef StubBuilder::IsConstructor(GateRef glue, GateRef object)
1568 {
1569 GateRef hClass = LoadHClass(glue, object);
1570 GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
1571 GateRef bitfield = LoadPrimitive(VariableType::INT32(), hClass, bitfieldOffset);
1572 // decode
1573 return Int32NotEqual(
1574 Int32And(Int32LSR(bitfield, Int32(JSHClass::ConstructorBit::START_BIT)),
1575 Int32((1LU << JSHClass::ConstructorBit::SIZE) - 1)),
1576 Int32(0));
1577 }
1578
IsBase(GateRef glue,GateRef func)1579 inline GateRef StubBuilder::IsBase(GateRef glue, GateRef func)
1580 {
1581 return env_->GetBuilder()->IsBase(glue, func);
1582 }
1583
IsDerived(GateRef glue,GateRef func)1584 inline GateRef StubBuilder::IsDerived(GateRef glue, GateRef func)
1585 {
1586 return env_->GetBuilder()->IsDerived(glue, func);
1587 }
1588
IsSymbol(GateRef glue,GateRef obj)1589 inline GateRef StubBuilder::IsSymbol(GateRef glue, GateRef obj)
1590 {
1591 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1592 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::SYMBOL)));
1593 }
1594
IsDataView(GateRef glue,GateRef obj)1595 inline GateRef StubBuilder::IsDataView(GateRef glue, GateRef obj)
1596 {
1597 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1598 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_DATA_VIEW)));
1599 }
1600
IsString(GateRef glue,GateRef obj)1601 inline GateRef StubBuilder::IsString(GateRef glue, GateRef obj)
1602 {
1603 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsJSObject), TaggedIsHeapObject(obj));
1604 GateRef res = env_->GetBuilder()->TaggedObjectIsString(glue, obj);
1605 return res;
1606 }
1607
IsLineString(GateRef glue,GateRef obj)1608 inline GateRef StubBuilder::IsLineString(GateRef glue, GateRef obj)
1609 {
1610 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1611 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::LINE_STRING)));
1612 }
1613
IsSlicedString(GateRef glue,GateRef obj)1614 inline GateRef StubBuilder::IsSlicedString(GateRef glue, GateRef obj)
1615 {
1616 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1617 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::SLICED_STRING)));
1618 }
1619
IsTreeString(GateRef glue,GateRef obj)1620 inline GateRef StubBuilder::IsTreeString(GateRef glue, GateRef obj)
1621 {
1622 return env_->GetBuilder()->IsTreeString(glue, obj);
1623 }
1624
TreeStringIsFlat(GateRef glue,GateRef string)1625 inline GateRef StubBuilder::TreeStringIsFlat(GateRef glue, GateRef string)
1626 {
1627 return env_->GetBuilder()->TreeStringIsFlat(glue, string);
1628 }
1629
TaggedObjectIsBigInt(GateRef glue,GateRef obj)1630 inline GateRef StubBuilder::TaggedObjectIsBigInt(GateRef glue, GateRef obj)
1631 {
1632 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1633 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::BIGINT)));
1634 }
1635
IsJsProxy(GateRef glue,GateRef obj)1636 inline GateRef StubBuilder::IsJsProxy(GateRef glue, GateRef obj)
1637 {
1638 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1639 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_PROXY)));
1640 }
1641
IsJSShared(GateRef glue,GateRef obj)1642 inline GateRef StubBuilder::IsJSShared(GateRef glue, GateRef obj)
1643 {
1644 return TaggedIsSharedObj(glue, obj);
1645 }
1646
IsProfileTypeInfoCell0(GateRef glue,GateRef obj)1647 inline GateRef StubBuilder::IsProfileTypeInfoCell0(GateRef glue, GateRef obj)
1648 {
1649 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1650 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::PROFILE_TYPE_INFO_CELL_0)));
1651 }
1652
IsJSGlobalObject(GateRef glue,GateRef obj)1653 inline GateRef StubBuilder::IsJSGlobalObject(GateRef glue, GateRef obj)
1654 {
1655 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1656 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_GLOBAL_OBJECT)));
1657 }
1658
IsGlobalEnv(GateRef glue,GateRef obj)1659 inline GateRef StubBuilder::IsGlobalEnv(GateRef glue, GateRef obj)
1660 {
1661 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1662 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::GLOBAL_ENV)));
1663 }
1664
IsLexicalEnv(GateRef glue,GateRef obj)1665 inline GateRef StubBuilder::IsLexicalEnv(GateRef glue, GateRef obj)
1666 {
1667 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1668 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::LEXICAL_ENV)));
1669 }
1670
IsSFunctionEnv(GateRef glue,GateRef obj)1671 inline GateRef StubBuilder::IsSFunctionEnv(GateRef glue, GateRef obj)
1672 {
1673 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1674 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::SFUNCTION_ENV)));
1675 }
1676
IsNativeModuleFailureInfo(GateRef glue,GateRef obj)1677 inline GateRef StubBuilder::IsNativeModuleFailureInfo(GateRef glue, GateRef obj)
1678 {
1679 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1680 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::NATIVE_MODULE_FAILURE_INFO)));
1681 }
1682
TaggedIsNativeModuleFailureInfo(GateRef glue,GateRef x)1683 inline GateRef StubBuilder::TaggedIsNativeModuleFailureInfo(GateRef glue, GateRef x)
1684 {
1685 return LogicAndBuilder(env_)
1686 .And(TaggedIsHeapObject(x))
1687 .And(IsNativeModuleFailureInfo(glue, x))
1688 .Done();
1689 }
1690
IsNativePointer(GateRef glue,GateRef obj)1691 inline GateRef StubBuilder::IsNativePointer(GateRef glue, GateRef obj)
1692 {
1693 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1694 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_NATIVE_POINTER)));
1695 }
1696
IsModuleNamespace(GateRef glue,GateRef obj)1697 inline GateRef StubBuilder::IsModuleNamespace(GateRef glue, GateRef obj)
1698 {
1699 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1700 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_MODULE_NAMESPACE)));
1701 }
1702
IsSourceTextModule(GateRef glue,GateRef obj)1703 inline GateRef StubBuilder::IsSourceTextModule(GateRef glue, GateRef obj)
1704 {
1705 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1706 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::SOURCE_TEXT_MODULE_RECORD)));
1707 }
1708
IsSpecialContainer(GateRef glue,GateRef obj)1709 inline GateRef StubBuilder::IsSpecialContainer(GateRef glue, GateRef obj)
1710 {
1711 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1712 return BitAnd(
1713 Int32GreaterThanOrEqual(objectType, Int32(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST))),
1714 Int32LessThanOrEqual(objectType, Int32(static_cast<int32_t>(JSType::JS_API_QUEUE))));
1715 }
1716
IsJSPrimitiveRef(GateRef glue,GateRef obj)1717 inline GateRef StubBuilder::IsJSPrimitiveRef(GateRef glue, GateRef obj)
1718 {
1719 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1720 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_PRIMITIVE_REF)));
1721 }
1722
IsJsArray(GateRef glue,GateRef obj)1723 inline GateRef StubBuilder::IsJsArray(GateRef glue, GateRef obj)
1724 {
1725 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1726 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_ARRAY)));
1727 }
1728
IsJsSArray(GateRef glue,GateRef obj)1729 inline GateRef StubBuilder::IsJsSArray(GateRef glue, GateRef obj)
1730 {
1731 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1732 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_SHARED_ARRAY)));
1733 }
1734
IsByteArray(GateRef glue,GateRef obj)1735 inline GateRef StubBuilder::IsByteArray(GateRef glue, GateRef obj)
1736 {
1737 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1738 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::BYTE_ARRAY)));
1739 }
1740
IsJSAPIVector(GateRef glue,GateRef obj)1741 inline GateRef StubBuilder::IsJSAPIVector(GateRef glue, GateRef obj)
1742 {
1743 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1744 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_VECTOR)));
1745 }
1746
IsJSAPIStack(GateRef glue,GateRef obj)1747 inline GateRef StubBuilder::IsJSAPIStack(GateRef glue, GateRef obj)
1748 {
1749 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1750 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_STACK)));
1751 }
1752
IsJSAPIPlainArray(GateRef glue,GateRef obj)1753 inline GateRef StubBuilder::IsJSAPIPlainArray(GateRef glue, GateRef obj)
1754 {
1755 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1756 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_PLAIN_ARRAY)));
1757 }
1758
IsJSAPIQueue(GateRef glue,GateRef obj)1759 inline GateRef StubBuilder::IsJSAPIQueue(GateRef glue, GateRef obj)
1760 {
1761 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1762 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_QUEUE)));
1763 }
1764
IsJSAPIDeque(GateRef glue,GateRef obj)1765 inline GateRef StubBuilder::IsJSAPIDeque(GateRef glue, GateRef obj)
1766 {
1767 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1768 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_DEQUE)));
1769 }
1770
IsJSAPILightWeightMap(GateRef glue,GateRef obj)1771 inline GateRef StubBuilder::IsJSAPILightWeightMap(GateRef glue, GateRef obj)
1772 {
1773 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1774 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LIGHT_WEIGHT_MAP)));
1775 }
1776
IsJSAPILightWeightSet(GateRef glue,GateRef obj)1777 inline GateRef StubBuilder::IsJSAPILightWeightSet(GateRef glue, GateRef obj)
1778 {
1779 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1780 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LIGHT_WEIGHT_SET)));
1781 }
1782
IsLinkedNode(GateRef glue,GateRef obj)1783 inline GateRef StubBuilder::IsLinkedNode(GateRef glue, GateRef obj)
1784 {
1785 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1786 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::LINKED_NODE)));
1787 }
1788
IsJSAPIHashMap(GateRef glue,GateRef obj)1789 inline GateRef StubBuilder::IsJSAPIHashMap(GateRef glue, GateRef obj)
1790 {
1791 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1792 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_HASH_MAP)));
1793 }
1794
IsJSAPIHashSet(GateRef glue,GateRef obj)1795 inline GateRef StubBuilder::IsJSAPIHashSet(GateRef glue, GateRef obj)
1796 {
1797 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1798 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_HASH_SET)));
1799 }
1800
IsJSAPILinkedList(GateRef glue,GateRef obj)1801 inline GateRef StubBuilder::IsJSAPILinkedList(GateRef glue, GateRef obj)
1802 {
1803 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1804 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LINKED_LIST)));
1805 }
1806
IsJSAPIList(GateRef glue,GateRef obj)1807 inline GateRef StubBuilder::IsJSAPIList(GateRef glue, GateRef obj)
1808 {
1809 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1810 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LIST)));
1811 }
1812
IsJSAPIArrayList(GateRef glue,GateRef obj)1813 inline GateRef StubBuilder::IsJSAPIArrayList(GateRef glue, GateRef obj)
1814 {
1815 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1816 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST)));
1817 }
1818
IsJSCollator(GateRef glue,GateRef obj)1819 inline GateRef StubBuilder::IsJSCollator(GateRef glue, GateRef obj)
1820 {
1821 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1822 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_COLLATOR)));
1823 }
1824
IsJSObjectType(GateRef glue,GateRef obj,JSType jsType)1825 inline GateRef StubBuilder::IsJSObjectType(GateRef glue, GateRef obj, JSType jsType)
1826 {
1827 return LogicAndBuilder(env_)
1828 .And(TaggedIsHeapObject(obj))
1829 .And(Int32Equal(GetObjectType(LoadHClass(glue, obj)), Int32(static_cast<int32_t>(jsType))))
1830 .Done();
1831 }
1832
IsJSRegExp(GateRef glue,GateRef obj)1833 inline GateRef StubBuilder::IsJSRegExp(GateRef glue, GateRef obj)
1834 {
1835 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1836 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_REG_EXP)));
1837 }
1838
GetTarget(GateRef glue,GateRef proxyObj)1839 inline GateRef StubBuilder::GetTarget(GateRef glue, GateRef proxyObj)
1840 {
1841 GateRef offset = IntPtr(JSProxy::TARGET_OFFSET);
1842 return Load(VariableType::JS_ANY(), glue, proxyObj, offset);
1843 }
1844
IsJsCOWArray(GateRef glue,GateRef obj)1845 inline GateRef StubBuilder::IsJsCOWArray(GateRef glue, GateRef obj)
1846 {
1847 // Elements of JSArray are shared and properties are not yet.
1848 GateRef elements = GetElementsArray(glue, obj);
1849 GateRef objectType = GetObjectType(LoadHClass(glue, elements));
1850 return env_->GetBuilder()->IsCOWArray(objectType);
1851 }
1852
IsCOWArray(GateRef glue,GateRef obj)1853 inline GateRef StubBuilder::IsCOWArray(GateRef glue, GateRef obj)
1854 {
1855 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
1856 return env_->GetBuilder()->IsCOWArray(objectType);
1857 }
1858
IsMutantTaggedArray(GateRef glue,GateRef elements)1859 inline GateRef StubBuilder::IsMutantTaggedArray(GateRef glue, GateRef elements)
1860 {
1861 GateRef objectType = GetObjectType(LoadHClass(glue, elements));
1862 return env_->GetBuilder()->IsMutantTaggedArray(objectType);
1863 }
1864
IsWritable(GateRef attr)1865 inline GateRef StubBuilder::IsWritable(GateRef attr)
1866 {
1867 return Int32NotEqual(
1868 Int32And(
1869 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::WritableField::START_BIT))),
1870 Int32((1LLU << PropertyAttributes::WritableField::SIZE) - 1)),
1871 Int32(0));
1872 }
1873
SetWritableFieldInPropAttr(GateRef attr,GateRef value)1874 inline GateRef StubBuilder::SetWritableFieldInPropAttr(GateRef attr, GateRef value)
1875 {
1876 GateRef mask = Int64LSL(Int64((1LU << PropertyAttributes::WritableField::SIZE) - 1),
1877 Int64(PropertyAttributes::WritableField::START_BIT));
1878 GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
1879 Int64LSL(ZExtInt32ToInt64(value), Int64(PropertyAttributes::WritableField::START_BIT)));
1880 return newVal;
1881 }
1882
IsDefaultAttribute(GateRef attr)1883 inline GateRef StubBuilder::IsDefaultAttribute(GateRef attr)
1884 {
1885 return Int32NotEqual(
1886 Int32And(
1887 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::DefaultAttributesField::START_BIT))),
1888 Int32((1LLU << PropertyAttributes::DefaultAttributesField::SIZE) - 1)),
1889 Int32(0));
1890 }
1891
IsConfigable(GateRef attr)1892 inline GateRef StubBuilder::IsConfigable(GateRef attr)
1893 {
1894 return Int32NotEqual(
1895 Int32And(
1896 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::ConfigurableField::START_BIT))),
1897 Int32((1LLU << PropertyAttributes::ConfigurableField::SIZE) - 1)),
1898 Int32(0));
1899 }
1900
SetConfigurableFieldInPropAttr(GateRef attr,GateRef value)1901 inline GateRef StubBuilder::SetConfigurableFieldInPropAttr(GateRef attr, GateRef value)
1902 {
1903 GateRef mask = Int64LSL(Int64((1LU << PropertyAttributes::ConfigurableField::SIZE) - 1),
1904 Int64(PropertyAttributes::ConfigurableField::START_BIT));
1905 GateRef newVal =
1906 Int64Or(Int64And(attr, Int64Not(mask)),
1907 Int64LSL(ZExtInt32ToInt64(value), Int64(PropertyAttributes::ConfigurableField::START_BIT)));
1908 return newVal;
1909 }
1910
IsAccessor(GateRef attr)1911 inline GateRef StubBuilder::IsAccessor(GateRef attr)
1912 {
1913 return Int32NotEqual(
1914 Int32And(
1915 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::IsAccessorField::START_BIT))),
1916 Int32((1LLU << PropertyAttributes::IsAccessorField::SIZE) - 1)),
1917 Int32(0));
1918 }
1919
IsEnumerable(GateRef attr)1920 inline GateRef StubBuilder::IsEnumerable(GateRef attr)
1921 {
1922 return Int32NotEqual(
1923 Int32And(
1924 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::EnumerableField::START_BIT))),
1925 Int32((1LLU << PropertyAttributes::EnumerableField::SIZE) - 1)),
1926 Int32(0));
1927 }
1928
SetEnumerableFiledInPropAttr(GateRef attr,GateRef value)1929 inline GateRef StubBuilder::SetEnumerableFiledInPropAttr(GateRef attr, GateRef value)
1930 {
1931 GateRef mask = Int64LSL(Int64((1LU << PropertyAttributes::EnumerableField::SIZE) - 1),
1932 Int64(PropertyAttributes::EnumerableField::START_BIT));
1933 GateRef newVal =
1934 Int64Or(Int64And(attr, Int64Not(mask)),
1935 Int64LSL(ZExtInt32ToInt64(value), Int64(PropertyAttributes::EnumerableField::START_BIT)));
1936 return newVal;
1937 }
1938
IsInlinedProperty(GateRef attr)1939 inline GateRef StubBuilder::IsInlinedProperty(GateRef attr)
1940 {
1941 return Int32NotEqual(
1942 Int32And(
1943 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::IsInlinedPropsField::START_BIT))),
1944 Int32((1LLU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1)),
1945 Int32(0));
1946 }
1947
GetPrototypeHandlerProtoCell(GateRef glue,GateRef object)1948 inline GateRef StubBuilder::GetPrototypeHandlerProtoCell(GateRef glue, GateRef object)
1949 {
1950 GateRef protoCellOffset = IntPtr(PrototypeHandler::PROTO_CELL_OFFSET);
1951 return Load(VariableType::JS_POINTER(), glue, object, protoCellOffset);
1952 }
1953
GetTransWithProtoHandlerProtoCell(GateRef glue,GateRef object)1954 inline GateRef StubBuilder::GetTransWithProtoHandlerProtoCell(GateRef glue, GateRef object)
1955 {
1956 GateRef protoCellOffset = IntPtr(TransWithProtoHandler::PROTO_CELL_OFFSET);
1957 return Load(VariableType::JS_POINTER(), glue, object, protoCellOffset);
1958 }
1959
GetStoreAOTHandlerProtoCell(GateRef glue,GateRef object)1960 inline GateRef StubBuilder::GetStoreAOTHandlerProtoCell(GateRef glue, GateRef object)
1961 {
1962 GateRef protoCellOffset = IntPtr(StoreAOTHandler::PROTO_CELL_OFFSET);
1963 return Load(VariableType::JS_POINTER(), glue, object, protoCellOffset);
1964 }
1965
GetPrototypeHandlerHolder(GateRef glue,GateRef object)1966 inline GateRef StubBuilder::GetPrototypeHandlerHolder(GateRef glue, GateRef object)
1967 {
1968 GateRef holderOffset = IntPtr(PrototypeHandler::HOLDER_OFFSET);
1969 return Load(VariableType::JS_ANY(), glue, object, holderOffset);
1970 }
1971
GetPrototypeHandlerHandlerInfo(GateRef glue,GateRef object)1972 inline GateRef StubBuilder::GetPrototypeHandlerHandlerInfo(GateRef glue, GateRef object)
1973 {
1974 GateRef handlerInfoOffset = IntPtr(PrototypeHandler::HANDLER_INFO_OFFSET);
1975 return Load(VariableType::JS_ANY(), glue, object, handlerInfoOffset);
1976 }
1977
SetPrototypeHandlerHandlerInfo(GateRef glue,GateRef obj,GateRef value)1978 inline void StubBuilder::SetPrototypeHandlerHandlerInfo(GateRef glue, GateRef obj, GateRef value)
1979 {
1980 GateRef handlerInfoOffset = IntPtr(PrototypeHandler::HANDLER_INFO_OFFSET);
1981 Store(VariableType::JS_ANY(), glue, obj, handlerInfoOffset, value);
1982 }
1983
GetStoreAOTHandlerHolder(GateRef glue,GateRef object)1984 inline GateRef StubBuilder::GetStoreAOTHandlerHolder(GateRef glue, GateRef object)
1985 {
1986 GateRef holderOffset = IntPtr(StoreAOTHandler::HOLDER_OFFSET);
1987 return Load(VariableType::JS_ANY(), glue, object, holderOffset);
1988 }
1989
GetStoreAOTHandlerHandlerInfo(GateRef glue,GateRef object)1990 inline GateRef StubBuilder::GetStoreAOTHandlerHandlerInfo(GateRef glue, GateRef object)
1991 {
1992 GateRef handlerInfoOffset = IntPtr(StoreAOTHandler::HANDLER_INFO_OFFSET);
1993 return Load(VariableType::JS_ANY(), glue, object, handlerInfoOffset);
1994 }
1995
GetHasChanged(GateRef object)1996 inline GateRef StubBuilder::GetHasChanged(GateRef object)
1997 {
1998 return env_->GetBuilder()->GetHasChanged(object);
1999 }
2000
GetNotFoundHasChanged(GateRef object)2001 inline GateRef StubBuilder::GetNotFoundHasChanged(GateRef object)
2002 {
2003 return env_->GetBuilder()->GetNotFoundHasChanged(object);
2004 }
2005
HclassIsPrototypeHandler(GateRef hClass)2006 inline GateRef StubBuilder::HclassIsPrototypeHandler(GateRef hClass)
2007 {
2008 return Int32Equal(GetObjectType(hClass),
2009 Int32(static_cast<int32_t>(JSType::PROTOTYPE_HANDLER)));
2010 }
2011
HclassIsTransitionHandler(GateRef hClass)2012 inline GateRef StubBuilder::HclassIsTransitionHandler(GateRef hClass)
2013 {
2014 return Int32Equal(GetObjectType(hClass),
2015 Int32(static_cast<int32_t>(JSType::TRANSITION_HANDLER)));
2016 }
2017
HclassIsPropertyBox(GateRef hClass)2018 inline GateRef StubBuilder::HclassIsPropertyBox(GateRef hClass)
2019 {
2020 return Int32Equal(GetObjectType(hClass),
2021 Int32(static_cast<int32_t>(JSType::PROPERTY_BOX)));
2022 }
2023
TaggedIsProtoChangeMarker(GateRef glue,GateRef obj)2024 inline GateRef StubBuilder::TaggedIsProtoChangeMarker(GateRef glue, GateRef obj)
2025 {
2026 return env_->GetBuilder()->TaggedIsProtoChangeMarker(glue, obj);
2027 }
2028
GetEmptyArray(GateRef glue)2029 inline GateRef StubBuilder::GetEmptyArray(GateRef glue)
2030 {
2031 return env_->GetBuilder()->GetEmptyArray(glue);
2032 }
2033
GetCacheKindFromForInIterator(GateRef iter)2034 inline GateRef StubBuilder::GetCacheKindFromForInIterator(GateRef iter)
2035 {
2036 return env_->GetBuilder()->GetCacheKindFromForInIterator(iter);
2037 }
2038
GetLengthFromForInIterator(GateRef iter)2039 inline GateRef StubBuilder::GetLengthFromForInIterator(GateRef iter)
2040 {
2041 return env_->GetBuilder()->GetLengthFromForInIterator(iter);
2042 }
2043
GetIndexFromForInIterator(GateRef iter)2044 inline GateRef StubBuilder::GetIndexFromForInIterator(GateRef iter)
2045 {
2046 return env_->GetBuilder()->GetIndexFromForInIterator(iter);
2047 }
2048
GetKeysFromForInIterator(GateRef glue,GateRef iter)2049 inline GateRef StubBuilder::GetKeysFromForInIterator(GateRef glue, GateRef iter)
2050 {
2051 return env_->GetBuilder()->GetKeysFromForInIterator(glue, iter);
2052 }
2053
GetObjectFromForInIterator(GateRef glue,GateRef iter)2054 inline GateRef StubBuilder::GetObjectFromForInIterator(GateRef glue, GateRef iter)
2055 {
2056 return env_->GetBuilder()->GetObjectFromForInIterator(glue, iter);
2057 }
2058
GetCachedHClassFromForInIterator(GateRef glue,GateRef iter)2059 inline GateRef StubBuilder::GetCachedHClassFromForInIterator(GateRef glue, GateRef iter)
2060 {
2061 return env_->GetBuilder()->GetCachedHClassFromForInIterator(glue, iter);
2062 }
2063
SetLengthOfForInIterator(GateRef glue,GateRef iter,GateRef length)2064 inline void StubBuilder::SetLengthOfForInIterator(GateRef glue, GateRef iter, GateRef length)
2065 {
2066 env_->GetBuilder()->SetLengthOfForInIterator(glue, iter, length);
2067 }
2068
SetIndexOfForInIterator(GateRef glue,GateRef iter,GateRef index)2069 inline void StubBuilder::SetIndexOfForInIterator(GateRef glue, GateRef iter, GateRef index)
2070 {
2071 env_->GetBuilder()->SetIndexOfForInIterator(glue, iter, index);
2072 }
2073
SetCacheKindForInIterator(GateRef glue,GateRef iter,GateRef cacheKind)2074 inline void StubBuilder::SetCacheKindForInIterator(GateRef glue, GateRef iter, GateRef cacheKind)
2075 {
2076 env_->GetBuilder()->SetCacheKindForInIterator(glue, iter, cacheKind);
2077 }
2078
SetKeysOfForInIterator(GateRef glue,GateRef iter,GateRef keys)2079 inline void StubBuilder::SetKeysOfForInIterator(GateRef glue, GateRef iter, GateRef keys)
2080 {
2081 env_->GetBuilder()->SetKeysOfForInIterator(glue, iter, keys);
2082 }
2083
SetObjectOfForInIterator(GateRef glue,GateRef iter,GateRef object)2084 inline void StubBuilder::SetObjectOfForInIterator(GateRef glue, GateRef iter, GateRef object)
2085 {
2086 env_->GetBuilder()->SetObjectOfForInIterator(glue, iter, object);
2087 }
2088
SetCachedHClassOfForInIterator(GateRef glue,GateRef iter,GateRef hclass)2089 inline void StubBuilder::SetCachedHClassOfForInIterator(GateRef glue, GateRef iter, GateRef hclass)
2090 {
2091 env_->GetBuilder()->SetCachedHClassOfForInIterator(glue, iter, hclass);
2092 }
2093
IncreaseIteratorIndex(GateRef glue,GateRef iter,GateRef index)2094 inline void StubBuilder::IncreaseIteratorIndex(GateRef glue, GateRef iter, GateRef index)
2095 {
2096 env_->GetBuilder()->IncreaseIteratorIndex(glue, iter, index);
2097 }
2098
IncreaseArrayIteratorIndex(GateRef glue,GateRef iter,GateRef index)2099 inline void StubBuilder::IncreaseArrayIteratorIndex(GateRef glue, GateRef iter, GateRef index)
2100 {
2101 env_->GetBuilder()->IncreaseArrayIteratorIndex(glue, iter, index);
2102 }
2103
SetNextIndexOfArrayIterator(GateRef glue,GateRef iter,GateRef nextIndex)2104 inline void StubBuilder::SetNextIndexOfArrayIterator(GateRef glue, GateRef iter, GateRef nextIndex)
2105 {
2106 env_->GetBuilder()->SetNextIndexOfArrayIterator(glue, iter, nextIndex);
2107 }
2108
SetIteratedArrayOfArrayIterator(GateRef glue,GateRef iter,GateRef iteratedArray)2109 inline void StubBuilder::SetIteratedArrayOfArrayIterator(GateRef glue, GateRef iter, GateRef iteratedArray)
2110 {
2111 env_->GetBuilder()->SetIteratedArrayOfArrayIterator(glue, iter, iteratedArray);
2112 }
2113
SetBitFieldOfArrayIterator(GateRef glue,GateRef iter,GateRef kind)2114 inline void StubBuilder::SetBitFieldOfArrayIterator(GateRef glue, GateRef iter, GateRef kind)
2115 {
2116 env_->GetBuilder()->SetBitFieldOfArrayIterator(glue, iter, kind);
2117 }
2118
GetArrayIterationKind(GateRef iter)2119 inline GateRef StubBuilder::GetArrayIterationKind(GateRef iter)
2120 {
2121 return env_->GetBuilder()->GetArrayIterationKind(iter);
2122 }
2123
IsField(GateRef attr)2124 inline GateRef StubBuilder::IsField(GateRef attr)
2125 {
2126 return Int32Equal(
2127 Int32And(
2128 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::KindBit::START_BIT))),
2129 Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
2130 Int32(HandlerBase::HandlerKind::FIELD));
2131 }
2132
IsNonSharedStoreField(GateRef attr)2133 inline GateRef StubBuilder::IsNonSharedStoreField(GateRef attr)
2134 {
2135 return Int32Equal(
2136 Int32And(
2137 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::SWholeKindBit::START_BIT))),
2138 Int32((1LLU << HandlerBase::SWholeKindBit::SIZE) - 1)),
2139 Int32(HandlerBase::StoreHandlerKind::S_FIELD));
2140 }
2141
IsStoreShared(GateRef attr)2142 inline GateRef StubBuilder::IsStoreShared(GateRef attr)
2143 {
2144 return Int32NotEqual(
2145 Int32And(
2146 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::SSharedBit::START_BIT))),
2147 Int32((1LLU << HandlerBase::SSharedBit::SIZE) - 1)),
2148 Int32(0));
2149 }
2150
IsElement(GateRef attr)2151 inline GateRef StubBuilder::IsElement(GateRef attr)
2152 {
2153 return Int32Equal(
2154 Int32And(
2155 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::KindBit::START_BIT))),
2156 Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
2157 Int32(HandlerBase::HandlerKind::ELEMENT));
2158 }
2159
IsStringElement(GateRef attr)2160 inline GateRef StubBuilder::IsStringElement(GateRef attr)
2161 {
2162 return Int32Equal(
2163 Int32And(
2164 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::KindBit::START_BIT))),
2165 Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
2166 Int32(HandlerBase::HandlerKind::STRING));
2167 }
2168
IsNumberHandler(GateRef attr)2169 inline GateRef StubBuilder::IsNumberHandler(GateRef attr)
2170 {
2171 return Int32Equal(
2172 Int32And(
2173 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::KindBit::START_BIT))),
2174 Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
2175 Int32(HandlerBase::HandlerKind::NUMBER));
2176 }
2177
IsBooleanHandler(GateRef attr)2178 inline GateRef StubBuilder::IsBooleanHandler(GateRef attr)
2179 {
2180 return Int32Equal(
2181 Int32And(
2182 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::KindBit::START_BIT))),
2183 Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
2184 Int32(HandlerBase::HandlerKind::BOOLEAN));
2185 }
2186
IsStringLength(GateRef attr)2187 inline GateRef StubBuilder::IsStringLength(GateRef attr)
2188 {
2189 return Int32Equal(
2190 Int32And(
2191 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::KindBit::START_BIT))),
2192 Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
2193 Int32(HandlerBase::HandlerKind::STRING_LENGTH));
2194 }
2195
IsTypedArrayElement(GateRef attr)2196 inline GateRef StubBuilder::IsTypedArrayElement(GateRef attr)
2197 {
2198 return Int32Equal(
2199 Int32And(
2200 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::KindBit::START_BIT))),
2201 Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
2202 Int32(HandlerBase::HandlerKind::TYPED_ARRAY));
2203 }
2204
IsNonExist(GateRef attr)2205 inline GateRef StubBuilder::IsNonExist(GateRef attr)
2206 {
2207 return Int32Equal(
2208 Int32And(
2209 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::KindBit::START_BIT))),
2210 Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
2211 Int32(HandlerBase::HandlerKind::NON_EXIST));
2212 }
2213
HandlerBaseIsAccessor(GateRef attr)2214 inline GateRef StubBuilder::HandlerBaseIsAccessor(GateRef attr)
2215 {
2216 return Int32NotEqual(
2217 Int32And(
2218 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::AccessorBit::START_BIT))),
2219 Int32((1LLU << HandlerBase::AccessorBit::SIZE) - 1)),
2220 Int32(0));
2221 }
2222
HandlerBaseIsJSArray(GateRef attr)2223 inline GateRef StubBuilder::HandlerBaseIsJSArray(GateRef attr)
2224 {
2225 return Int32NotEqual(
2226 Int32And(
2227 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::IsJSArrayBit::START_BIT))),
2228 Int32((1LLU << HandlerBase::IsJSArrayBit::SIZE) - 1)),
2229 Int32(0));
2230 }
2231
HandlerBaseIsInlinedProperty(GateRef attr)2232 inline GateRef StubBuilder::HandlerBaseIsInlinedProperty(GateRef attr)
2233 {
2234 return Int32NotEqual(
2235 Int32And(
2236 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::InlinedPropsBit::START_BIT))),
2237 Int32((1LLU << HandlerBase::InlinedPropsBit::SIZE) - 1)),
2238 Int32(0));
2239 }
2240
HandlerBaseGetOffset(GateRef attr)2241 inline GateRef StubBuilder::HandlerBaseGetOffset(GateRef attr)
2242 {
2243 return Int32And(
2244 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::OffsetBit::START_BIT))),
2245 Int32((1LLU << HandlerBase::OffsetBit::SIZE) - 1));
2246 }
2247
2248
HandlerBaseGetAttrIndex(GateRef attr)2249 inline GateRef StubBuilder::HandlerBaseGetAttrIndex(GateRef attr)
2250 {
2251 return Int32And(
2252 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::AttrIndexBit::START_BIT))),
2253 Int32((1LLU << HandlerBase::AttrIndexBit::SIZE) - 1));
2254 }
2255
HandlerBaseGetRep(GateRef attr)2256 inline GateRef StubBuilder::HandlerBaseGetRep(GateRef attr)
2257 {
2258 return Int32And(
2259 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::RepresentationBit::START_BIT))),
2260 Int32((1LLU << HandlerBase::RepresentationBit::SIZE) - 1));
2261 }
2262
IsInvalidPropertyBox(GateRef glue,GateRef obj)2263 inline GateRef StubBuilder::IsInvalidPropertyBox(GateRef glue, GateRef obj)
2264 {
2265 GateRef valueOffset = IntPtr(PropertyBox::VALUE_OFFSET);
2266 GateRef value = Load(VariableType::JS_ANY(), glue, obj, valueOffset);
2267 return TaggedIsHole(value);
2268 }
2269
IsAccessorPropertyBox(GateRef glue,GateRef obj)2270 inline GateRef StubBuilder::IsAccessorPropertyBox(GateRef glue, GateRef obj)
2271 {
2272 GateRef valueOffset = IntPtr(PropertyBox::VALUE_OFFSET);
2273 GateRef value = Load(VariableType::JS_ANY(), glue, obj, valueOffset);
2274 return TaggedIsAccessor(glue, value);
2275 }
2276
GetValueFromPropertyBox(GateRef glue,GateRef obj)2277 inline GateRef StubBuilder::GetValueFromPropertyBox(GateRef glue, GateRef obj)
2278 {
2279 GateRef valueOffset = IntPtr(PropertyBox::VALUE_OFFSET);
2280 return Load(VariableType::JS_ANY(), glue, obj, valueOffset);
2281 }
2282
SetValueToPropertyBox(GateRef glue,GateRef obj,GateRef value)2283 inline void StubBuilder::SetValueToPropertyBox(GateRef glue, GateRef obj, GateRef value)
2284 {
2285 GateRef valueOffset = IntPtr(PropertyBox::VALUE_OFFSET);
2286 Store(VariableType::JS_ANY(), glue, obj, valueOffset, value);
2287 }
2288
GetTransitionHClass(GateRef glue,GateRef obj)2289 inline GateRef StubBuilder::GetTransitionHClass(GateRef glue, GateRef obj)
2290 {
2291 GateRef transitionHClassOffset = IntPtr(TransitionHandler::TRANSITION_HCLASS_OFFSET);
2292 return Load(VariableType::JS_POINTER(), glue, obj, transitionHClassOffset);
2293 }
2294
GetTransitionHandlerInfo(GateRef glue,GateRef obj)2295 inline GateRef StubBuilder::GetTransitionHandlerInfo(GateRef glue, GateRef obj)
2296 {
2297 GateRef handlerInfoOffset = IntPtr(TransitionHandler::HANDLER_INFO_OFFSET);
2298 return Load(VariableType::JS_ANY(), glue, obj, handlerInfoOffset);
2299 }
2300
GetTransWithProtoHClass(GateRef glue,GateRef obj)2301 inline GateRef StubBuilder::GetTransWithProtoHClass(GateRef glue, GateRef obj)
2302 {
2303 GateRef transitionHClassOffset = IntPtr(TransWithProtoHandler::TRANSITION_HCLASS_OFFSET);
2304 return Load(VariableType::JS_POINTER(), glue, obj, transitionHClassOffset);
2305 }
2306
GetTransWithProtoHandlerInfo(GateRef glue,GateRef obj)2307 inline GateRef StubBuilder::GetTransWithProtoHandlerInfo(GateRef glue, GateRef obj)
2308 {
2309 GateRef handlerInfoOffset = IntPtr(TransWithProtoHandler::HANDLER_INFO_OFFSET);
2310 return Load(VariableType::JS_ANY(), glue, obj, handlerInfoOffset);
2311 }
2312
PropAttrGetOffset(GateRef attr)2313 inline GateRef StubBuilder::PropAttrGetOffset(GateRef attr)
2314 {
2315 return Int32And(
2316 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::OffsetField::START_BIT))),
2317 Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1));
2318 }
2319
GetSortedIndex(GateRef attr)2320 inline GateRef StubBuilder::GetSortedIndex(GateRef attr)
2321 {
2322 return TruncInt64ToInt32(Int64And(
2323 Int64LSR(attr, Int64(PropertyAttributes::SortedIndexField::START_BIT)),
2324 Int64((1LLU << PropertyAttributes::SortedIndexField::SIZE) - 1)));
2325 }
2326
2327 // SetDictionaryOrder func in property_attribute.h
SetDictionaryOrderFieldInPropAttr(GateRef attr,GateRef value)2328 inline GateRef StubBuilder::SetDictionaryOrderFieldInPropAttr(GateRef attr, GateRef value)
2329 {
2330 GateRef mask = Int64LSL(
2331 Int64((1LLU << PropertyAttributes::DictionaryOrderField::SIZE) - 1),
2332 Int64(PropertyAttributes::DictionaryOrderField::START_BIT));
2333 GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
2334 Int64LSL(value, Int64(PropertyAttributes::DictionaryOrderField::START_BIT)));
2335 return newVal;
2336 }
2337
GetPrototypeFromHClass(GateRef glue,GateRef hClass)2338 inline GateRef StubBuilder::GetPrototypeFromHClass(GateRef glue, GateRef hClass)
2339 {
2340 return env_->GetBuilder()->GetPrototypeFromHClass(glue, hClass);
2341 }
2342
GetEnumCacheFromHClass(GateRef glue,GateRef hClass)2343 inline GateRef StubBuilder::GetEnumCacheFromHClass(GateRef glue, GateRef hClass)
2344 {
2345 return env_->GetBuilder()->GetEnumCacheFromHClass(glue, hClass);
2346 }
2347
GetProtoChangeMarkerFromHClass(GateRef glue,GateRef hClass)2348 inline GateRef StubBuilder::GetProtoChangeMarkerFromHClass(GateRef glue, GateRef hClass)
2349 {
2350 return env_->GetBuilder()->GetProtoChangeMarkerFromHClass(glue, hClass);
2351 }
2352
GetLayoutFromHClass(GateRef glue,GateRef hClass)2353 inline GateRef StubBuilder::GetLayoutFromHClass(GateRef glue, GateRef hClass)
2354 {
2355 env_->GetBuilder()->CheckHClassFieldInvalidAccess(glue, hClass);
2356 GateRef attrOffset = IntPtr(JSHClass::LAYOUT_OFFSET);
2357 return Load(VariableType::JS_POINTER(), glue, hClass, attrOffset);
2358 }
2359
GetBitFieldFromHClass(GateRef hClass)2360 inline GateRef StubBuilder::GetBitFieldFromHClass(GateRef hClass)
2361 {
2362 GateRef offset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
2363 return LoadPrimitive(VariableType::INT32(), hClass, offset);
2364 }
2365
GetLengthFromString(GateRef value)2366 inline GateRef StubBuilder::GetLengthFromString(GateRef value)
2367 {
2368 return env_->GetBuilder()->GetLengthFromString(value);
2369 }
2370
GetFirstFromTreeString(GateRef glue,GateRef string)2371 inline GateRef StubBuilder::GetFirstFromTreeString(GateRef glue, GateRef string)
2372 {
2373 return env_->GetBuilder()->GetFirstFromTreeString(glue, string);
2374 }
2375
GetSecondFromTreeString(GateRef glue,GateRef string)2376 inline GateRef StubBuilder::GetSecondFromTreeString(GateRef glue, GateRef string)
2377 {
2378 return env_->GetBuilder()->GetSecondFromTreeString(glue, string);
2379 }
2380
GetIsAllTaggedPropFromHClass(GateRef hclass)2381 inline GateRef StubBuilder::GetIsAllTaggedPropFromHClass(GateRef hclass)
2382 {
2383 GateRef bitfield = LoadPrimitive(VariableType::INT32(), hclass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
2384 return Int32And(Int32LSR(bitfield,
2385 Int32(JSHClass::IsAllTaggedPropBit::START_BIT)),
2386 Int32((1LLU << JSHClass::IsAllTaggedPropBit::SIZE) - 1));
2387 }
2388
SetIsStableToBitField(GateRef bitfield,GateRef isStable)2389 inline GateRef StubBuilder::SetIsStableToBitField(GateRef bitfield, GateRef isStable)
2390 {
2391 GateRef mask = Int32LSL(
2392 Int32((1LU << JSHClass::IsStableBit::SIZE) - 1),
2393 Int32(JSHClass::IsStableBit::START_BIT));
2394 return Int32Or(Int32And(bitfield, Int32Not(mask)),
2395 Int32LSL(isStable, Int32(JSHClass::IsStableBit::START_BIT)));
2396 }
2397
SetBitFieldToHClass(GateRef glue,GateRef hClass,GateRef bitfield)2398 inline void StubBuilder::SetBitFieldToHClass(GateRef glue, GateRef hClass, GateRef bitfield)
2399 {
2400 GateRef offset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
2401 Store(VariableType::INT32(), glue, hClass, offset, bitfield);
2402 }
2403
SetIsAllTaggedProp(GateRef glue,GateRef hclass,GateRef hasRep)2404 inline void StubBuilder::SetIsAllTaggedProp(GateRef glue, GateRef hclass, GateRef hasRep)
2405 {
2406 GateRef bitfield1 = LoadPrimitive(VariableType::INT32(), hclass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
2407 GateRef mask = Int32LSL(
2408 Int32((1LU << JSHClass::IsAllTaggedPropBit::SIZE) - 1),
2409 Int32(JSHClass::IsAllTaggedPropBit::START_BIT));
2410 GateRef newVal = Int32Or(Int32And(bitfield1, Int32Not(mask)),
2411 Int32LSL(hasRep, Int32(JSHClass::IsAllTaggedPropBit::START_BIT)));
2412 Store(VariableType::INT32(), glue, hclass, IntPtr(JSHClass::BIT_FIELD1_OFFSET), newVal);
2413 }
2414
SetPrototypeToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef proto)2415 inline void StubBuilder::SetPrototypeToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef proto)
2416 {
2417 env_->GetBuilder()->CheckHClassFieldInvalidAccess(glue, hClass);
2418 GateRef offset = IntPtr(JSHClass::PROTOTYPE_OFFSET);
2419 Store(type, glue, hClass, offset, proto);
2420 }
2421
SetProtoChangeDetailsToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef protoChange)2422 inline void StubBuilder::SetProtoChangeDetailsToHClass(VariableType type,
2423 GateRef glue, GateRef hClass, GateRef protoChange)
2424 {
2425 env_->GetBuilder()->CheckHClassFieldInvalidAccess(glue, hClass);
2426 GateRef offset = IntPtr(JSHClass::PROTO_CHANGE_DETAILS_OFFSET);
2427 Store(type, glue, hClass, offset, protoChange);
2428 }
2429
GetProtoChangeDetails(GateRef glue,GateRef hClass)2430 inline GateRef StubBuilder::GetProtoChangeDetails(GateRef glue, GateRef hClass)
2431 {
2432 env_->GetBuilder()->CheckHClassFieldInvalidAccess(glue, hClass);
2433 GateRef offset = IntPtr(JSHClass::PROTO_CHANGE_DETAILS_OFFSET);
2434 return Load(VariableType::JS_ANY(), glue, hClass, offset);
2435 }
2436
SetLayoutToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef attr,MemoryAttribute mAttr)2437 inline void StubBuilder::SetLayoutToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef attr,
2438 MemoryAttribute mAttr)
2439 {
2440 env_->GetBuilder()->CheckHClassFieldInvalidAccess(glue, hClass);
2441 GateRef offset = IntPtr(JSHClass::LAYOUT_OFFSET);
2442 Store(type, glue, hClass, offset, attr, mAttr);
2443 }
2444
SetEnumCacheToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef key)2445 inline void StubBuilder::SetEnumCacheToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef key)
2446 {
2447 env_->GetBuilder()->CheckHClassFieldInvalidAccess(glue, hClass);
2448 GateRef offset = IntPtr(JSHClass::ENUM_CACHE_OFFSET);
2449 Store(type, glue, hClass, offset, key);
2450 }
2451
SetDependentInfosToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef value)2452 inline void StubBuilder::SetDependentInfosToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef value)
2453 {
2454 env_->GetBuilder()->CheckHClassFieldInvalidAccess(glue, hClass);
2455 GateRef offset = IntPtr(JSHClass::DEPENDENT_INFOS_OFFSET);
2456 Store(type, glue, hClass, offset, value);
2457 }
2458
SetTransitionsToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef transition)2459 inline void StubBuilder::SetTransitionsToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef transition)
2460 {
2461 env_->GetBuilder()->CheckHClassFieldInvalidAccess(glue, hClass);
2462 GateRef offset = IntPtr(JSHClass::TRANSTIONS_OFFSET);
2463 Store(type, glue, hClass, offset, transition);
2464 }
2465
GetTransitionsFromHClass(GateRef glue,GateRef hClass)2466 inline GateRef StubBuilder::GetTransitionsFromHClass(GateRef glue, GateRef hClass)
2467 {
2468 env_->GetBuilder()->CheckHClassFieldInvalidAccess(glue, hClass);
2469 GateRef offset = IntPtr(JSHClass::TRANSTIONS_OFFSET);
2470 return Load(VariableType::JS_POINTER(), glue, hClass, offset);
2471 }
2472
SetParentToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef parent)2473 inline void StubBuilder::SetParentToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef parent)
2474 {
2475 env_->GetBuilder()->CheckHClassFieldInvalidAccess(glue, hClass);
2476 GateRef offset = IntPtr(JSHClass::PARENT_OFFSET);
2477 Store(type, glue, hClass, offset, parent);
2478 }
2479
SetIsPrototypeToHClass(GateRef glue,GateRef hClass,GateRef value)2480 inline void StubBuilder::SetIsPrototypeToHClass(GateRef glue, GateRef hClass, GateRef value)
2481 {
2482 GateRef oldValue = ZExtInt1ToInt32(value);
2483 GateRef bitfield = GetBitFieldFromHClass(hClass);
2484 GateRef mask = Int32LSL(
2485 Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1),
2486 Int32(JSHClass::IsPrototypeBit::START_BIT));
2487 GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
2488 Int32LSL(oldValue, Int32(JSHClass::IsPrototypeBit::START_BIT)));
2489 SetBitFieldToHClass(glue, hClass, newVal);
2490 }
2491
SetIsAOT(GateRef glue,GateRef hClass,GateRef value)2492 inline void StubBuilder::SetIsAOT(GateRef glue, GateRef hClass, GateRef value)
2493 {
2494 GateRef oldValue = ZExtInt1ToInt32(value);
2495 GateRef bitfield = GetBitFieldFromHClass(hClass);
2496 GateRef mask = Int32LSL(
2497 Int32((1LU << JSHClass::IsAOTBit::SIZE) - 1),
2498 Int32(JSHClass::IsAOTBit::START_BIT));
2499 GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
2500 Int32LSL(oldValue, Int32(JSHClass::IsAOTBit::START_BIT)));
2501 SetBitFieldToHClass(glue, hClass, newVal);
2502 }
2503
IsPrototypeHClass(GateRef hClass)2504 inline GateRef StubBuilder::IsPrototypeHClass(GateRef hClass)
2505 {
2506 GateRef bitfield = GetBitFieldFromHClass(hClass);
2507 return TruncInt32ToInt1(Int32And(Int32LSR(bitfield,
2508 Int32(JSHClass::IsPrototypeBit::START_BIT)),
2509 Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1)));
2510 }
2511
SetPropertyInlinedProps(GateRef glue,GateRef obj,GateRef hClass,GateRef value,GateRef attrOffset,VariableType type,MemoryAttribute mAttr)2512 inline void StubBuilder::SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass, GateRef value,
2513 GateRef attrOffset, VariableType type, MemoryAttribute mAttr)
2514 {
2515 ASM_ASSERT_WITH_GLUE(GET_MESSAGE_STRING_ID(IsNotDictionaryMode), BoolNot(IsDictionaryModeByHClass(hClass)), glue);
2516 GateRef bitfield = LoadPrimitive(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
2517 GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield,
2518 Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
2519 Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
2520 GateRef propOffset = Int32Mul(
2521 Int32Add(inlinedPropsStart, attrOffset), Int32(JSTaggedValue::TaggedTypeSize()));
2522
2523 // NOTE: need to translate MarkingBarrier
2524 Store(type, glue, obj, ZExtInt32ToPtr(propOffset), value, mAttr);
2525 EXITENTRY();
2526 }
2527
GetPropertyInlinedProps(GateRef glue,GateRef obj,GateRef hClass,GateRef index)2528 inline GateRef StubBuilder::GetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass,
2529 GateRef index)
2530 {
2531 GateRef inlinedPropsStart = GetInlinedPropsStartFromHClass(hClass);
2532 GateRef propOffset = Int32Mul(
2533 Int32Add(inlinedPropsStart, index), Int32(JSTaggedValue::TaggedTypeSize()));
2534 return Load(VariableType::JS_ANY(), glue, obj, ZExtInt32ToInt64(propOffset));
2535 }
2536
GetInlinedPropOffsetFromHClass(GateRef hclass,GateRef index)2537 inline GateRef StubBuilder::GetInlinedPropOffsetFromHClass(GateRef hclass, GateRef index)
2538 {
2539 GateRef inlinedPropsStart = GetInlinedPropsStartFromHClass(hclass);
2540 GateRef propOffset = Int32Mul(
2541 Int32Add(inlinedPropsStart, index), Int32(JSTaggedValue::TaggedTypeSize()));
2542 return ZExtInt32ToInt64(propOffset);
2543 }
2544
IsObjSizeTrackingInProgress(GateRef hclass)2545 inline GateRef StubBuilder::IsObjSizeTrackingInProgress(GateRef hclass)
2546 {
2547 GateRef count = GetConstructionCounter(hclass);
2548 return Int32NotEqual(count, Int32(0));
2549 }
2550
GetConstructionCounter(GateRef hclass)2551 inline GateRef StubBuilder::GetConstructionCounter(GateRef hclass)
2552 {
2553 GateRef bitfield = LoadPrimitive(VariableType::INT32(), hclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
2554 return Int32And(Int32LSR(bitfield,
2555 Int32(JSHClass::ConstructionCounterBits::START_BIT)),
2556 Int32((1LU << JSHClass::ConstructionCounterBits::SIZE) - 1));
2557 }
2558
SetConstructionCounter(GateRef glue,GateRef hclass,GateRef count)2559 inline void StubBuilder::SetConstructionCounter(GateRef glue, GateRef hclass, GateRef count)
2560 {
2561 GateRef bitfield = LoadPrimitive(VariableType::INT32(), hclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
2562 GateRef encodeValue = Int32LSL(count, Int32(JSHClass::ConstructionCounterBits::START_BIT));
2563 GateRef mask =
2564 Int32(((1LU << JSHClass::ConstructionCounterBits::SIZE) - 1) << JSHClass::ConstructionCounterBits::START_BIT);
2565 bitfield = Int32Or(Int32And(bitfield, Int32Not(mask)), encodeValue);
2566 Store(VariableType::INT32(), glue, hclass, IntPtr(JSHClass::BIT_FIELD_OFFSET), bitfield);
2567 }
2568
IncNumberOfProps(GateRef glue,GateRef hClass)2569 inline void StubBuilder::IncNumberOfProps(GateRef glue, GateRef hClass)
2570 {
2571 GateRef propNums = GetNumberOfPropsFromHClass(hClass);
2572 SetNumberOfPropsToHClass(glue, hClass, Int32Add(propNums, Int32(1)));
2573 }
2574
GetNumberOfPropsFromHClass(GateRef hClass)2575 inline GateRef StubBuilder::GetNumberOfPropsFromHClass(GateRef hClass)
2576 {
2577 GateRef bitfield = LoadPrimitive(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
2578 return Int32And(Int32LSR(bitfield,
2579 Int32(JSHClass::NumberOfPropsBits::START_BIT)),
2580 Int32((1LLU << JSHClass::NumberOfPropsBits::SIZE) - 1));
2581 }
2582
HasDeleteProperty(GateRef hClass)2583 inline GateRef StubBuilder::HasDeleteProperty(GateRef hClass)
2584 {
2585 return env_->GetBuilder()->HasDeleteProperty(hClass);
2586 }
2587
IsAOTHClass(GateRef hClass)2588 inline GateRef StubBuilder::IsAOTHClass(GateRef hClass)
2589 {
2590 GateRef bitfield = LoadPrimitive(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
2591 return Int32NotEqual(Int32And(Int32LSR(bitfield,
2592 Int32(JSHClass::IsAOTBit::START_BIT)),
2593 Int32((1LU << JSHClass::IsAOTBit::SIZE) - 1)),
2594 Int32(0));
2595 }
2596
SetNumberOfPropsToHClass(GateRef glue,GateRef hClass,GateRef value)2597 inline void StubBuilder::SetNumberOfPropsToHClass(GateRef glue, GateRef hClass, GateRef value)
2598 {
2599 GateRef bitfield1 = LoadPrimitive(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
2600 GateRef oldWithMask = Int32And(bitfield1,
2601 Int32(~static_cast<uint32_t>(JSHClass::NumberOfPropsBits::Mask())));
2602 GateRef newValue = Int32LSR(value, Int32(JSHClass::NumberOfPropsBits::START_BIT));
2603 Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET),
2604 Int32Or(oldWithMask, newValue));
2605 }
2606
GetInlinedPropertiesFromHClass(GateRef hClass)2607 inline GateRef StubBuilder::GetInlinedPropertiesFromHClass(GateRef hClass)
2608 {
2609 GateRef bitfield = LoadPrimitive(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
2610 GateRef objectSizeInWords = Int32And(Int32LSR(bitfield,
2611 Int32(JSHClass::ObjectSizeInWordsBits::START_BIT)),
2612 Int32((1LU << JSHClass::ObjectSizeInWordsBits::SIZE) - 1));
2613 GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield,
2614 Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
2615 Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
2616 return Int32Sub(objectSizeInWords, inlinedPropsStart);
2617 }
2618
SetElementsKindToTrackInfo(GateRef glue,GateRef trackInfo,GateRef elementsKind)2619 inline void StubBuilder::SetElementsKindToTrackInfo(GateRef glue, GateRef trackInfo, GateRef elementsKind)
2620 {
2621 GateRef bitfield = LoadPrimitive(VariableType::INT32(), trackInfo, IntPtr(TrackInfo::BIT_FIELD_OFFSET));
2622 GateRef oldWithMask = Int32And(bitfield,
2623 Int32(~static_cast<uint32_t>(TrackInfo::ElementsKindBits::Mask())));
2624 GateRef newValue = Int32LSR(elementsKind, Int32(TrackInfo::ElementsKindBits::START_BIT));
2625 GateRef newBitfield = Int32Or(oldWithMask, newValue);
2626 Store(VariableType::INT32(), glue, trackInfo, IntPtr(TrackInfo::BIT_FIELD_OFFSET), newBitfield);
2627 }
2628
SetSpaceFlagToTrackInfo(GateRef glue,GateRef trackInfo,GateRef spaceFlag)2629 inline void StubBuilder::SetSpaceFlagToTrackInfo(GateRef glue, GateRef trackInfo, GateRef spaceFlag)
2630 {
2631 GateRef bitfield = LoadPrimitive(VariableType::INT32(), trackInfo, IntPtr(TrackInfo::BIT_FIELD_OFFSET));
2632 GateRef oldWithMask = Int32And(bitfield,
2633 Int32(~static_cast<uint32_t>(TrackInfo::SpaceFlagBits::Mask())));
2634 GateRef newValue = Int32LSL(spaceFlag, Int32(TrackInfo::SpaceFlagBits::START_BIT));
2635 GateRef newBitfield = Int32Or(oldWithMask, newValue);
2636 Store(VariableType::INT32(), glue, trackInfo, IntPtr(TrackInfo::BIT_FIELD_OFFSET), newBitfield);
2637 }
2638
GetElementsKindFromHClass(GateRef hClass)2639 inline GateRef StubBuilder::GetElementsKindFromHClass(GateRef hClass)
2640 {
2641 return env_->GetBuilder()->GetElementsKindByHClass(hClass);
2642 }
2643
GetObjectSizeFromHClass(GateRef hClass)2644 inline GateRef StubBuilder::GetObjectSizeFromHClass(GateRef hClass)
2645 {
2646 return env_->GetBuilder()->GetObjectSizeFromHClass(hClass);
2647 }
2648
GetInlinedPropsStartFromHClass(GateRef hClass)2649 inline GateRef StubBuilder::GetInlinedPropsStartFromHClass(GateRef hClass)
2650 {
2651 GateRef bitfield = LoadPrimitive(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
2652 return Int32And(Int32LSR(bitfield,
2653 Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
2654 Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
2655 }
2656
SetValueToTaggedArrayWithAttr(GateRef glue,GateRef array,GateRef index,GateRef key,GateRef val,GateRef attr)2657 inline void StubBuilder::SetValueToTaggedArrayWithAttr(
2658 GateRef glue, GateRef array, GateRef index, GateRef key, GateRef val, GateRef attr)
2659 {
2660 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
2661 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
2662 SetValueWithAttr(glue, array, dataOffset, key, val, attr);
2663 }
2664
SetValueToTaggedArrayWithRep(GateRef glue,GateRef array,GateRef index,GateRef val,GateRef rep,Label * repChange)2665 inline void StubBuilder::SetValueToTaggedArrayWithRep(
2666 GateRef glue, GateRef array, GateRef index, GateRef val, GateRef rep, Label *repChange)
2667 {
2668 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
2669 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
2670 SetValueWithRep(glue, array, dataOffset, val, rep, repChange);
2671 }
2672
SetValueToTaggedArray(VariableType valType,GateRef glue,GateRef array,GateRef index,GateRef val,MemoryAttribute mAttr)2673 inline void StubBuilder::SetValueToTaggedArray(VariableType valType, GateRef glue, GateRef array,
2674 GateRef index, GateRef val, MemoryAttribute mAttr)
2675 {
2676 // NOTE: need to translate MarkingBarrier
2677 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
2678 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
2679 Store(valType, glue, array, dataOffset, val, mAttr);
2680 }
2681
GetValueFromTaggedArray(GateRef glue,GateRef array,GateRef index)2682 inline GateRef StubBuilder::GetValueFromTaggedArray(GateRef glue, GateRef array, GateRef index)
2683 {
2684 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
2685 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
2686 return Load(VariableType::JS_ANY(), glue, array, dataOffset);
2687 }
2688
GetDataPtrInTaggedArray(GateRef array)2689 inline GateRef StubBuilder::GetDataPtrInTaggedArray(GateRef array)
2690 {
2691 return PtrAdd(array, IntPtr(TaggedArray::DATA_OFFSET));
2692 }
2693
GetDataPtrInTaggedArray(GateRef array,GateRef index)2694 inline GateRef StubBuilder::GetDataPtrInTaggedArray(GateRef array, GateRef index)
2695 {
2696 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
2697 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
2698 return PtrAdd(array, dataOffset);
2699 }
2700
GetUnsharedConstpoolIndex(GateRef glue,GateRef constpool)2701 inline GateRef StubBuilder::GetUnsharedConstpoolIndex(GateRef glue, GateRef constpool)
2702 {
2703 GateRef constPoolSize = GetLengthOfTaggedArray(constpool);
2704 GateRef unshareIdx = Int32Sub(constPoolSize, Int32(ConstantPool::UNSHARED_CONSTPOOL_INDEX));
2705 return GetValueFromTaggedArray(glue, constpool, unshareIdx);
2706 }
2707
GetUnsharedConstpoolFromGlue(GateRef glue,GateRef constpool)2708 inline GateRef StubBuilder::GetUnsharedConstpoolFromGlue(GateRef glue, GateRef constpool)
2709 {
2710 return env_->GetBuilder()->GetUnsharedConstpoolFromGlue(glue, constpool);
2711 }
2712
GetUnsharedConstpool(GateRef glue,GateRef arrayAddr,GateRef index)2713 inline GateRef StubBuilder::GetUnsharedConstpool(GateRef glue, GateRef arrayAddr, GateRef index)
2714 {
2715 GateRef dataOffset =
2716 PtrAdd(arrayAddr, PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), ZExtInt32ToPtr(TaggedGetInt(index))));
2717 return LoadZeroOffset(VariableType::JS_ANY(), glue, dataOffset);
2718 }
2719
GetValueFromMutantTaggedArray(GateRef elements,GateRef index)2720 inline GateRef StubBuilder::GetValueFromMutantTaggedArray(GateRef elements, GateRef index)
2721 {
2722 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(sizeof(int64_t)));
2723 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
2724 return LoadPrimitive(VariableType::INT64(), elements, dataOffset);
2725 }
2726
IsSpecialIndexedObj(GateRef jsType)2727 inline GateRef StubBuilder::IsSpecialIndexedObj(GateRef jsType)
2728 {
2729 return BitOr(Int32GreaterThan(jsType, Int32(static_cast<int32_t>(JSType::JS_ARRAY))),
2730 BitAnd(Int32GreaterThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::STRING_FIRST))),
2731 Int32LessThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::STRING_LAST)))));
2732 }
2733
SharedObjectStoreBarrierWithTypeCheck(bool isDicMode,Variable * result,GateRef glue,GateRef attr,GateRef value,Variable * newValue,Label * executeSharedSetProp,Label * exit)2734 inline void StubBuilder::SharedObjectStoreBarrierWithTypeCheck(bool isDicMode, Variable *result, GateRef glue,
2735 GateRef attr, GateRef value, Variable *newValue, Label *executeSharedSetProp, Label *exit)
2736 {
2737 auto *env = GetEnvironment();
2738 Label barrier(env);
2739 Label typeMismatch(env);
2740 GateRef fieldType = isDicMode ? GetDictSharedFieldTypeInPropAttr(attr) : GetSharedFieldTypeInPropAttr(attr);
2741 SharedObjectStoreBarrierWithTypeCheck(result, glue, fieldType, value, newValue, executeSharedSetProp, exit);
2742 }
2743
SharedObjectStoreBarrierWithTypeCheck(bool isDicMode,Variable * result,GateRef glue,GateRef attr,GateRef value,Variable * newValue,Label * executeSharedSetProp,Label * exit,GateRef SCheckModelIsCHECK)2744 inline void StubBuilder::SharedObjectStoreBarrierWithTypeCheck(bool isDicMode, Variable *result, GateRef glue,
2745 GateRef attr, GateRef value, Variable *newValue, Label *executeSharedSetProp, Label *exit,
2746 GateRef SCheckModelIsCHECK)
2747 {
2748 auto *env = GetEnvironment();
2749 Label checkFieldTypeAndStoreBarrier(env);
2750 Label storeBarrierOnly(env);
2751 BRANCH(SCheckModelIsCHECK, &checkFieldTypeAndStoreBarrier, &storeBarrierOnly);
2752 Bind(&checkFieldTypeAndStoreBarrier);
2753 {
2754 SharedObjectStoreBarrierWithTypeCheck(isDicMode, result, glue, attr, value, newValue,
2755 executeSharedSetProp, exit);
2756 }
2757 Bind(&storeBarrierOnly);
2758 {
2759 SharedObjectStoreBarrier(glue, value, newValue, executeSharedSetProp);
2760 }
2761 }
2762
SharedObjectStoreBarrierWithTypeCheck(Variable * result,GateRef glue,GateRef fieldType,GateRef value,Variable * newValue,Label * executeSharedSetProp,Label * exit)2763 inline void StubBuilder::SharedObjectStoreBarrierWithTypeCheck(Variable *result, GateRef glue, GateRef fieldType,
2764 GateRef value, Variable *newValue, Label *executeSharedSetProp, Label *exit)
2765 {
2766 auto *env = GetEnvironment();
2767 Label barrier(env);
2768 Label typeMismatch(env);
2769 MatchFieldType(glue, fieldType, value, &barrier, &typeMismatch);
2770 Bind(&typeMismatch);
2771 {
2772 GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetTypeMismatchedSharedProperty));
2773 CallRuntime(glue, RTSTUB_ID(ThrowTypeError), {IntToTaggedInt(taggedId)});
2774 *result = Exception();
2775 Jump(exit);
2776 }
2777 Bind(&barrier);
2778 {
2779 SharedObjectStoreBarrier(glue, value, newValue, executeSharedSetProp);
2780 }
2781 }
2782
SharedObjectStoreBarrier(GateRef glue,GateRef value,Variable * newValue,Label * exit)2783 inline void StubBuilder::SharedObjectStoreBarrier(GateRef glue, GateRef value, Variable *newValue, Label *exit)
2784 {
2785 auto *env = GetEnvironment();
2786 Label checkIsTreeString(env);
2787 BRANCH(TaggedIsHeapObject(value), &checkIsTreeString, exit);
2788 Bind(&checkIsTreeString);
2789 {
2790 Label needFlatten(env);
2791 BRANCH(IsTreeString(glue, value), &needFlatten, exit);
2792 Bind(&needFlatten);
2793 {
2794 *newValue = CallRuntime(glue, RTSTUB_ID(SlowSharedObjectStoreBarrier), { value });
2795 Jump(exit);
2796 }
2797 }
2798 }
2799
GetFieldTypeFromHandler(GateRef attr)2800 inline GateRef StubBuilder::GetFieldTypeFromHandler(GateRef attr)
2801 {
2802 return Int32And(
2803 TruncInt64ToInt32(Int64LSR(attr, Int64(HandlerBase::SFieldTypeBit::START_BIT))),
2804 Int32((1LLU << HandlerBase::SFieldTypeBit::SIZE) - 1));
2805 }
2806
ClearSharedStoreKind(GateRef handlerInfo)2807 inline GateRef StubBuilder::ClearSharedStoreKind(GateRef handlerInfo)
2808 {
2809 return Int64And(handlerInfo, Int64Not(Int64(HandlerBase::SSharedBit::Mask())));
2810 }
2811
UpdateSOutOfBoundsForHandler(GateRef handlerInfo)2812 inline GateRef StubBuilder::UpdateSOutOfBoundsForHandler(GateRef handlerInfo)
2813 {
2814 return Int64Or(handlerInfo, Int64(HandlerBase::SOutOfBoundsBit::Mask()));
2815 }
2816
IsArrayListOrVector(GateRef jsType)2817 inline GateRef StubBuilder::IsArrayListOrVector(GateRef jsType)
2818 {
2819 // arraylist and vector has fast pass now
2820 return BitOr(Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST))),
2821 Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_API_VECTOR))));
2822 }
2823
IsSharedArray(GateRef jsType)2824 inline GateRef StubBuilder::IsSharedArray(GateRef jsType)
2825 {
2826 return Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_SHARED_ARRAY)));
2827 }
2828
IsFastTypeArray(GateRef jsType)2829 inline GateRef StubBuilder::IsFastTypeArray(GateRef jsType)
2830 {
2831 return BitAnd(
2832 Int32GreaterThan(jsType, Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_FIRST))),
2833 Int32LessThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::JS_FLOAT64_ARRAY))));
2834 }
2835
IsJSProxy(GateRef jsType)2836 inline GateRef StubBuilder::IsJSProxy(GateRef jsType)
2837 {
2838 return Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_PROXY)));
2839 }
2840
IsAccessorInternal(GateRef glue,GateRef value)2841 inline GateRef StubBuilder::IsAccessorInternal(GateRef glue, GateRef value)
2842 {
2843 return Int32Equal(GetObjectType(LoadHClass(glue, value)),
2844 Int32(static_cast<int32_t>(JSType::INTERNAL_ACCESSOR)));
2845 }
2846
GetPropAttrFromLayoutInfo(GateRef glue,GateRef layout,GateRef entry)2847 inline GateRef StubBuilder::GetPropAttrFromLayoutInfo(GateRef glue, GateRef layout, GateRef entry)
2848 {
2849 GateRef index = Int32Add(Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2)),
2850 Int32(LayoutInfo::ATTR_INDEX_OFFSET));
2851 return GetInt64OfTInt(GetValueFromTaggedArray(glue, layout, index));
2852 }
2853
GetIhcFromAOTLiteralInfo(GateRef glue,GateRef info)2854 inline GateRef StubBuilder::GetIhcFromAOTLiteralInfo(GateRef glue, GateRef info)
2855 {
2856 auto len = GetLengthOfTaggedArray(info);
2857 GateRef aotIhcIndex = Int32Sub(len, Int32(AOTLiteralInfo::AOT_IHC_INDEX));
2858 GateRef ihcOffset = Int32Mul(aotIhcIndex, Int32(JSTaggedValue::TaggedTypeSize()));
2859 GateRef dataOffset = PtrAdd(ihcOffset, IntPtr(TaggedArray::DATA_OFFSET));
2860 return Load(VariableType::JS_ANY(), glue, info, dataOffset);
2861 }
2862
UpdateFieldType(GateRef glue,GateRef hclass,GateRef attr)2863 inline void StubBuilder::UpdateFieldType(GateRef glue, GateRef hclass, GateRef attr)
2864 {
2865 CallNGCRuntime(glue, RTSTUB_ID(UpdateFieldType), { glue, hclass, attr });
2866 }
2867
GetPropertyMetaDataFromAttr(GateRef attr)2868 inline GateRef StubBuilder::GetPropertyMetaDataFromAttr(GateRef attr)
2869 {
2870 return Int32And(
2871 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::PropertyMetaDataField::START_BIT))),
2872 Int32((1LLU << PropertyAttributes::PropertyMetaDataField::SIZE) - 1));
2873 }
2874
TranslateToRep(GateRef value)2875 inline GateRef StubBuilder::TranslateToRep(GateRef value)
2876 {
2877 auto env = GetEnvironment();
2878 Label entryPass(env);
2879 env->SubCfgEntry(&entryPass);
2880 Label intLabel(env);
2881 Label nonIntLabel(env);
2882 Label doubleLabel(env);
2883 Label exit(env);
2884 DEFVARIABLE(result, VariableType::INT32(), Int32(static_cast<int32_t>(Representation::TAGGED)));
2885 Branch(TaggedIsInt(value), &intLabel, &nonIntLabel);
2886 Bind(&intLabel);
2887 {
2888 result = Int32(static_cast<int32_t>(Representation::INT));
2889 Jump(&exit);
2890 }
2891 Bind(&nonIntLabel);
2892 {
2893 Branch(TaggedIsDouble(value), &doubleLabel, &exit);
2894 }
2895 Bind(&doubleLabel);
2896 {
2897 result = Int32(static_cast<int32_t>(Representation::DOUBLE));
2898 Jump(&exit);
2899 }
2900 Bind(&exit);
2901 auto ret = *result;
2902 env->SubCfgExit();
2903 return ret;
2904 }
2905
GetKeyFromLayoutInfo(GateRef glue,GateRef layout,GateRef entry)2906 inline GateRef StubBuilder::GetKeyFromLayoutInfo(GateRef glue, GateRef layout, GateRef entry)
2907 {
2908 GateRef index = Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2));
2909 return GetValueFromTaggedArray(glue, layout, index);
2910 }
2911
GetPropertiesAddrFromLayoutInfo(GateRef layout)2912 inline GateRef StubBuilder::GetPropertiesAddrFromLayoutInfo(GateRef layout)
2913 {
2914 return PtrAdd(layout, IntPtr(TaggedArray::DATA_OFFSET));
2915 }
2916
IsInternalString(GateRef string)2917 inline GateRef StubBuilder::IsInternalString(GateRef string)
2918 {
2919 return env_->GetBuilder()->IsInternString(string);
2920 }
2921
GetInt64OfTInt(GateRef x)2922 inline GateRef StubBuilder::GetInt64OfTInt(GateRef x)
2923 {
2924 return env_->GetBuilder()->GetInt64OfTInt(x);
2925 }
2926
GetInt32OfTInt(GateRef x)2927 inline GateRef StubBuilder::GetInt32OfTInt(GateRef x)
2928 {
2929 return TruncInt64ToInt32(GetInt64OfTInt(x));
2930 }
2931
TaggedCastToIntPtr(GateRef x)2932 inline GateRef StubBuilder::TaggedCastToIntPtr(GateRef x)
2933 {
2934 return env_->Is32Bit() ? TruncInt64ToInt32(GetInt64OfTInt(x)) : GetInt64OfTInt(x);
2935 }
2936
GetDoubleOfTInt(GateRef x)2937 inline GateRef StubBuilder::GetDoubleOfTInt(GateRef x)
2938 {
2939 return ChangeInt32ToFloat64(GetInt32OfTInt(x));
2940 }
2941
GetDoubleOfTDouble(GateRef x)2942 inline GateRef StubBuilder::GetDoubleOfTDouble(GateRef x)
2943 {
2944 return env_->GetBuilder()->GetDoubleOfTDouble(x);
2945 }
2946
GetInt32OfTNumber(GateRef x)2947 inline GateRef StubBuilder::GetInt32OfTNumber(GateRef x)
2948 {
2949 return env_->GetBuilder()->GetInt32OfTNumber(x);
2950 }
2951
GetDoubleOfTNumber(GateRef x)2952 inline GateRef StubBuilder::GetDoubleOfTNumber(GateRef x)
2953 {
2954 return env_->GetBuilder()->GetDoubleOfTNumber(x);
2955 }
2956
LoadObjectFromWeakRef(GateRef x)2957 inline GateRef StubBuilder::LoadObjectFromWeakRef(GateRef x)
2958 {
2959 return env_->GetBuilder()->LoadObjectFromWeakRef(x);
2960 }
2961
ExtFloat32ToDouble(GateRef x)2962 inline GateRef StubBuilder::ExtFloat32ToDouble(GateRef x)
2963 {
2964 return env_->GetBuilder()->ExtFloat32ToDouble(x);
2965 }
2966
ChangeInt32ToFloat32(GateRef x)2967 inline GateRef StubBuilder::ChangeInt32ToFloat32(GateRef x)
2968 {
2969 return env_->GetBuilder()->ChangeInt32ToFloat32(x);
2970 }
2971
ChangeInt32ToFloat64(GateRef x)2972 inline GateRef StubBuilder::ChangeInt32ToFloat64(GateRef x)
2973 {
2974 return env_->GetBuilder()->ChangeInt32ToFloat64(x);
2975 }
2976
ChangeUInt32ToFloat64(GateRef x)2977 inline GateRef StubBuilder::ChangeUInt32ToFloat64(GateRef x)
2978 {
2979 return env_->GetBuilder()->ChangeUInt32ToFloat64(x);
2980 }
2981
ChangeFloat64ToInt32(GateRef x)2982 inline GateRef StubBuilder::ChangeFloat64ToInt32(GateRef x)
2983 {
2984 return env_->GetBuilder()->ChangeFloat64ToInt32(x);
2985 }
2986
TruncDoubleToFloat32(GateRef x)2987 inline GateRef StubBuilder::TruncDoubleToFloat32(GateRef x)
2988 {
2989 return env_->GetBuilder()->TruncDoubleToFloat32(x);
2990 }
2991
ChangeTaggedPointerToInt64(GateRef x)2992 inline GateRef StubBuilder::ChangeTaggedPointerToInt64(GateRef x)
2993 {
2994 return env_->GetBuilder()->ChangeTaggedPointerToInt64(x);
2995 }
2996
Int64ToTaggedPtr(GateRef x)2997 inline GateRef StubBuilder::Int64ToTaggedPtr(GateRef x)
2998 {
2999 return env_->GetBuilder()->Int64ToTaggedPtr(x);
3000 }
3001
CastInt32ToFloat32(GateRef x)3002 inline GateRef StubBuilder::CastInt32ToFloat32(GateRef x)
3003 {
3004 return env_->GetBuilder()->CastInt32ToFloat32(x);
3005 }
3006
CastInt64ToFloat64(GateRef x)3007 inline GateRef StubBuilder::CastInt64ToFloat64(GateRef x)
3008 {
3009 return env_->GetBuilder()->CastInt64ToFloat64(x);
3010 }
3011
SExtInt32ToInt64(GateRef x)3012 inline GateRef StubBuilder::SExtInt32ToInt64(GateRef x)
3013 {
3014 return env_->GetBuilder()->SExtInt32ToInt64(x);
3015 }
3016
SExtInt16ToInt64(GateRef x)3017 inline GateRef StubBuilder::SExtInt16ToInt64(GateRef x)
3018 {
3019 return env_->GetBuilder()->SExtInt16ToInt64(x);
3020 }
3021
SExtInt8ToInt64(GateRef x)3022 inline GateRef StubBuilder::SExtInt8ToInt64(GateRef x)
3023 {
3024 return env_->GetBuilder()->SExtInt8ToInt64(x);
3025 }
3026
SExtInt8ToInt32(GateRef x)3027 inline GateRef StubBuilder::SExtInt8ToInt32(GateRef x)
3028 {
3029 return env_->GetBuilder()->SExtInt8ToInt32(x);
3030 }
3031
SExtInt16ToInt32(GateRef x)3032 inline GateRef StubBuilder::SExtInt16ToInt32(GateRef x)
3033 {
3034 return env_->GetBuilder()->SExtInt16ToInt32(x);
3035 }
3036
SExtInt1ToInt64(GateRef x)3037 inline GateRef StubBuilder::SExtInt1ToInt64(GateRef x)
3038 {
3039 return env_->GetBuilder()->SExtInt1ToInt64(x);
3040 }
3041
SExtInt1ToInt32(GateRef x)3042 inline GateRef StubBuilder::SExtInt1ToInt32(GateRef x)
3043 {
3044 return env_->GetBuilder()->SExtInt1ToInt32(x);
3045 }
3046
ZExtInt8ToInt16(GateRef x)3047 inline GateRef StubBuilder::ZExtInt8ToInt16(GateRef x)
3048 {
3049 return env_->GetBuilder()->ZExtInt8ToInt16(x);
3050 }
3051
ZExtInt32ToInt64(GateRef x)3052 inline GateRef StubBuilder::ZExtInt32ToInt64(GateRef x)
3053 {
3054 return env_->GetBuilder()->ZExtInt32ToInt64(x);
3055 }
3056
ZExtInt1ToInt64(GateRef x)3057 inline GateRef StubBuilder::ZExtInt1ToInt64(GateRef x)
3058 {
3059 return env_->GetBuilder()->ZExtInt1ToInt64(x);
3060 }
3061
ZExtInt1ToInt32(GateRef x)3062 inline GateRef StubBuilder::ZExtInt1ToInt32(GateRef x)
3063 {
3064 return env_->GetBuilder()->ZExtInt1ToInt32(x);
3065 }
3066
ZExtInt8ToInt32(GateRef x)3067 inline GateRef StubBuilder::ZExtInt8ToInt32(GateRef x)
3068 {
3069 return env_->GetBuilder()->ZExtInt8ToInt32(x);
3070 }
3071
ZExtInt8ToInt64(GateRef x)3072 inline GateRef StubBuilder::ZExtInt8ToInt64(GateRef x)
3073 {
3074 return env_->GetBuilder()->ZExtInt8ToInt64(x);
3075 }
3076
ZExtInt8ToPtr(GateRef x)3077 inline GateRef StubBuilder::ZExtInt8ToPtr(GateRef x)
3078 {
3079 return env_->GetBuilder()->ZExtInt8ToPtr(x);
3080 }
3081
ZExtInt16ToPtr(GateRef x)3082 inline GateRef StubBuilder::ZExtInt16ToPtr(GateRef x)
3083 {
3084 return env_->GetBuilder()->ZExtInt16ToPtr(x);
3085 }
3086
SExtInt32ToPtr(GateRef x)3087 inline GateRef StubBuilder::SExtInt32ToPtr(GateRef x)
3088 {
3089 return env_->GetBuilder()->SExtInt32ToPtr(x);
3090 }
3091
ZExtInt16ToInt32(GateRef x)3092 inline GateRef StubBuilder::ZExtInt16ToInt32(GateRef x)
3093 {
3094 return env_->GetBuilder()->ZExtInt16ToInt32(x);
3095 }
3096
ZExtInt16ToInt64(GateRef x)3097 inline GateRef StubBuilder::ZExtInt16ToInt64(GateRef x)
3098 {
3099 return env_->GetBuilder()->ZExtInt16ToInt64(x);
3100 }
3101
TruncInt64ToInt32(GateRef x)3102 inline GateRef StubBuilder::TruncInt64ToInt32(GateRef x)
3103 {
3104 return env_->GetBuilder()->TruncInt64ToInt32(x);
3105 }
3106
TruncInt64ToInt16(GateRef x)3107 inline GateRef StubBuilder::TruncInt64ToInt16(GateRef x)
3108 {
3109 return env_->GetBuilder()->TruncInt64ToInt16(x);
3110 }
3111
TruncPtrToInt32(GateRef x)3112 inline GateRef StubBuilder::TruncPtrToInt32(GateRef x)
3113 {
3114 if (env_->Is32Bit()) {
3115 return x;
3116 }
3117 return TruncInt64ToInt32(x);
3118 }
3119
TruncInt64ToInt1(GateRef x)3120 inline GateRef StubBuilder::TruncInt64ToInt1(GateRef x)
3121 {
3122 return env_->GetBuilder()->TruncInt64ToInt1(x);
3123 }
3124
TruncInt32ToInt1(GateRef x)3125 inline GateRef StubBuilder::TruncInt32ToInt1(GateRef x)
3126 {
3127 return env_->GetBuilder()->TruncInt32ToInt1(x);
3128 }
3129
GetObjectFromConstPool(GateRef glue,GateRef constpool,GateRef index)3130 inline GateRef StubBuilder::GetObjectFromConstPool(GateRef glue, GateRef constpool, GateRef index)
3131 {
3132 return GetValueFromTaggedArray(glue, constpool, index);
3133 }
3134
GetGlobalConstantAddr(GateRef index)3135 inline GateRef StubBuilder::GetGlobalConstantAddr(GateRef index)
3136 {
3137 return Int64Mul(Int64(sizeof(JSTaggedValue)), index);
3138 }
3139
GetGlobalConstantOffset(ConstantIndex index)3140 inline GateRef StubBuilder::GetGlobalConstantOffset(ConstantIndex index)
3141 {
3142 if (env_->Is32Bit()) {
3143 return Int32Mul(Int32(sizeof(JSTaggedValue)), Int32(static_cast<int>(index)));
3144 } else {
3145 return Int64Mul(Int64(sizeof(JSTaggedValue)), Int64(static_cast<int>(index)));
3146 }
3147 }
3148
IsCallableFromBitField(GateRef bitfield)3149 inline GateRef StubBuilder::IsCallableFromBitField(GateRef bitfield)
3150 {
3151 return env_->GetBuilder()->IsCallableFromBitField(bitfield);
3152 }
3153
IsCallable(GateRef glue,GateRef obj)3154 inline GateRef StubBuilder::IsCallable(GateRef glue, GateRef obj)
3155 {
3156 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsCallable), TaggedIsHeapObject(obj));
3157 GateRef res = env_->GetBuilder()->IsCallable(glue, obj);
3158 return res;
3159 }
3160
TaggedIsCallable(GateRef glue,GateRef obj)3161 inline GateRef StubBuilder::TaggedIsCallable(GateRef glue, GateRef obj)
3162 {
3163 return LogicAndBuilder(env_)
3164 .And(TaggedIsHeapObject(obj))
3165 .And(env_->GetBuilder()->IsCallable(glue, obj))
3166 .Done();
3167 }
3168
3169 // GetOffset func in property_attribute.h
GetOffsetFieldInPropAttr(GateRef attr)3170 inline GateRef StubBuilder::GetOffsetFieldInPropAttr(GateRef attr)
3171 {
3172 return Int32And(
3173 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::OffsetField::START_BIT))),
3174 Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1));
3175 }
3176
3177 // SetOffset func in property_attribute.h
SetOffsetFieldInPropAttr(GateRef attr,GateRef value)3178 inline GateRef StubBuilder::SetOffsetFieldInPropAttr(GateRef attr, GateRef value)
3179 {
3180 GateRef mask = Int64LSL(
3181 Int64((1LLU << PropertyAttributes::OffsetField::SIZE) - 1),
3182 Int64(PropertyAttributes::OffsetField::START_BIT));
3183 GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
3184 Int64LSL(ZExtInt32ToInt64(value), Int64(PropertyAttributes::OffsetField::START_BIT)));
3185 return newVal;
3186 }
3187
3188 // SetIsInlinedProps func in property_attribute.h
SetIsInlinePropsFieldInPropAttr(GateRef attr,GateRef value)3189 inline GateRef StubBuilder::SetIsInlinePropsFieldInPropAttr(GateRef attr, GateRef value)
3190 {
3191 GateRef mask = Int64LSL(
3192 Int64((1LU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1),
3193 Int64(PropertyAttributes::IsInlinedPropsField::START_BIT));
3194 GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
3195 Int64LSL(ZExtInt32ToInt64(value), Int64(PropertyAttributes::IsInlinedPropsField::START_BIT)));
3196 return newVal;
3197 }
3198
3199
SetTrackTypeInPropAttr(GateRef attr,GateRef type)3200 inline GateRef StubBuilder::SetTrackTypeInPropAttr(GateRef attr, GateRef type)
3201 {
3202 GateRef mask = Int64LSL(
3203 Int64((1LU << PropertyAttributes::TrackTypeField::SIZE) - 1),
3204 Int64(PropertyAttributes::TrackTypeField::START_BIT));
3205 GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
3206 Int64LSL(ZExtInt32ToInt64(type), Int64(PropertyAttributes::TrackTypeField::START_BIT)));
3207 return newVal;
3208 }
3209
GetSharedFieldTypeInPropAttr(GateRef attr)3210 inline GateRef StubBuilder::GetSharedFieldTypeInPropAttr(GateRef attr)
3211 {
3212 return Int32And(
3213 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::SharedFieldTypeField::START_BIT))),
3214 Int32((1LLU << PropertyAttributes::SharedFieldTypeField::SIZE) - 1));
3215 }
3216
GetTrackTypeInPropAttr(GateRef attr)3217 inline GateRef StubBuilder::GetTrackTypeInPropAttr(GateRef attr)
3218 {
3219 return Int32And(
3220 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::TrackTypeField::START_BIT))),
3221 Int32((1LLU << PropertyAttributes::TrackTypeField::SIZE) - 1));
3222 }
3223
GetDictSharedFieldTypeInPropAttr(GateRef attr)3224 inline GateRef StubBuilder::GetDictSharedFieldTypeInPropAttr(GateRef attr)
3225 {
3226 return Int32And(
3227 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::DictSharedFieldTypeField::START_BIT))),
3228 Int32((1LLU << PropertyAttributes::DictSharedFieldTypeField::SIZE) - 1));
3229 }
3230
GetRepInPropAttr(GateRef attr)3231 inline GateRef StubBuilder::GetRepInPropAttr(GateRef attr)
3232 {
3233 return Int32And(
3234 TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::RepresentationField::START_BIT))),
3235 Int32((1LLU << PropertyAttributes::RepresentationField::SIZE) - 1));
3236 }
3237
IsIntRepInPropAttr(GateRef rep)3238 inline GateRef StubBuilder::IsIntRepInPropAttr(GateRef rep)
3239 {
3240 return Int32Equal(rep, Int32(static_cast<int32_t>(Representation::INT)));
3241 }
3242
IsDoubleRepInPropAttr(GateRef rep)3243 inline GateRef StubBuilder::IsDoubleRepInPropAttr(GateRef rep)
3244 {
3245 return Int32Equal(rep, Int32(static_cast<int32_t>(Representation::DOUBLE)));
3246 }
3247
IsTaggedRepInPropAttr(GateRef attr)3248 inline GateRef StubBuilder::IsTaggedRepInPropAttr(GateRef attr)
3249 {
3250 GateRef rep = GetRepInPropAttr(attr);
3251 return BitAnd(BoolNot(IsDoubleRepInPropAttr(rep)), BoolNot(IsIntRepInPropAttr(rep)));
3252 }
3253
SetTaggedRepInPropAttr(GateRef attr)3254 inline GateRef StubBuilder::SetTaggedRepInPropAttr(GateRef attr)
3255 {
3256 GateRef mask = Int64LSL(
3257 Int64((1LU << PropertyAttributes::RepresentationField::SIZE) - 1),
3258 Int64(PropertyAttributes::RepresentationField::START_BIT));
3259 GateRef targetType = Int32(static_cast<uint32_t>(Representation::TAGGED));
3260 GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
3261 Int64LSL(ZExtInt32ToInt64(targetType), Int64(PropertyAttributes::RepresentationField::START_BIT)));
3262 return newVal;
3263 }
3264
3265 template<class T>
SetHClassBit(GateRef glue,GateRef hClass,GateRef value)3266 void StubBuilder::SetHClassBit(GateRef glue, GateRef hClass, GateRef value)
3267 {
3268 GateRef bitfield = LoadPrimitive(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
3269 GateRef mask = Int32LSL(
3270 Int32((1LU << T::SIZE) - 1),
3271 Int32(T::START_BIT));
3272 GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
3273 Int32LSL(value, Int32(T::START_BIT)));
3274 Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET), newVal);
3275 }
3276
IntPtrEuqal(GateRef x,GateRef y)3277 inline GateRef StubBuilder::IntPtrEuqal(GateRef x, GateRef y)
3278 {
3279 return env_->Is32Bit() ? Int32Equal(x, y) : Int64Equal(x, y);
3280 }
3281
IntPtrNotEqual(GateRef x,GateRef y)3282 inline GateRef StubBuilder::IntPtrNotEqual(GateRef x, GateRef y)
3283 {
3284 return env_->Is32Bit() ? Int32NotEqual(x, y) : Int64NotEqual(x, y);
3285 }
3286
GetBitMask(GateRef bitoffset)3287 inline GateRef StubBuilder::GetBitMask(GateRef bitoffset)
3288 {
3289 // BIT_PER_WORD_MASK
3290 GateRef bitPerWordMask = Int32(GCBitset::BIT_PER_WORD_MASK);
3291 // IndexInWord(bitOffset) = bitOffset & BIT_PER_WORD_MASK
3292 GateRef indexInWord = Int32And(bitoffset, bitPerWordMask);
3293 // Mask(indeInWord) = 1 << index
3294 return Int32LSL(Int32(1), indexInWord);
3295 }
3296
ObjectAddressToRange(GateRef x)3297 inline GateRef StubBuilder::ObjectAddressToRange(GateRef x)
3298 {
3299 // This function may cause GateRef x is not an object. GC may not mark this x object.
3300 return IntPtrAnd(TaggedCastToIntPtr(x), IntPtr(~panda::ecmascript::DEFAULT_REGION_MASK));
3301 }
3302
RegionInSpace(GateRef region,RegionSpaceFlag space)3303 inline GateRef StubBuilder::RegionInSpace(GateRef region, RegionSpaceFlag space)
3304 {
3305 auto offset = Region::PackedData::GetFlagsOffset(env_->Is32Bit());
3306 GateRef x = LoadPrimitive(VariableType::NATIVE_POINTER(), PtrAdd(IntPtr(offset), region),
3307 IntPtr(0));
3308 if (env_->Is32Bit()) {
3309 return Int32Equal(Int32And(x,
3310 Int32(RegionSpaceFlag::VALID_SPACE_MASK)), Int32(space));
3311 } else {
3312 return Int64Equal(Int64And(x,
3313 Int64(RegionSpaceFlag::VALID_SPACE_MASK)), Int64(space));
3314 }
3315 }
3316
InYoungGeneration(GateRef region)3317 inline GateRef StubBuilder::InYoungGeneration(GateRef region)
3318 {
3319 return RegionInSpace(region, RegionSpaceFlag::IN_YOUNG_SPACE);
3320 }
3321
RegionInSpace(GateRef region,RegionSpaceFlag spaceBegin,RegionSpaceFlag spaceEnd)3322 inline GateRef StubBuilder::RegionInSpace(GateRef region, RegionSpaceFlag spaceBegin, RegionSpaceFlag spaceEnd)
3323 {
3324 auto offset = Region::PackedData::GetFlagsOffset(env_->Is32Bit());
3325 GateRef x = LoadPrimitive(VariableType::NATIVE_POINTER(), PtrAdd(IntPtr(offset), region),
3326 IntPtr(0));
3327 if (env_->Is32Bit()) {
3328 GateRef spaceType = Int32And(x, Int32(RegionSpaceFlag::VALID_SPACE_MASK));
3329 GateRef greater = Int32GreaterThanOrEqual(spaceType, Int32(spaceBegin));
3330 GateRef less = Int32LessThanOrEqual(spaceType, Int32(spaceEnd));
3331 return BitAnd(greater, less);
3332 } else {
3333 GateRef spaceType = Int64And(x, Int64(RegionSpaceFlag::VALID_SPACE_MASK));
3334 GateRef greater = Int64GreaterThanOrEqual(spaceType, Int64(spaceBegin));
3335 GateRef less = Int64LessThanOrEqual(spaceType, Int64(spaceEnd));
3336 return BitAnd(greater, less);
3337 }
3338 }
3339
InGeneralOldGeneration(GateRef region)3340 inline GateRef StubBuilder::InGeneralOldGeneration(GateRef region)
3341 {
3342 return RegionInSpace(region, RegionSpaceFlag::GENERAL_OLD_BEGIN, RegionSpaceFlag::GENERAL_OLD_END);
3343 }
3344
InSharedHeap(GateRef region)3345 inline GateRef StubBuilder::InSharedHeap(GateRef region)
3346 {
3347 auto offset = Region::PackedData::GetFlagsOffset(env_->Is32Bit());
3348 GateRef x = LoadPrimitive(VariableType::NATIVE_POINTER(), PtrAdd(IntPtr(offset), region),
3349 IntPtr(0));
3350 if (env_->Is32Bit()) {
3351 GateRef spaceType = Int32And(x, Int32(RegionSpaceFlag::VALID_SPACE_MASK));
3352 GateRef greater = Int32GreaterThanOrEqual(spaceType, Int32(RegionSpaceFlag::SHARED_SPACE_BEGIN));
3353 GateRef less = Int32LessThanOrEqual(spaceType, Int32(RegionSpaceFlag::SHARED_SPACE_END));
3354 return BitAnd(greater, less);
3355 } else {
3356 GateRef spaceType = Int64And(x, Int64(RegionSpaceFlag::VALID_SPACE_MASK));
3357 GateRef greater = Int64GreaterThanOrEqual(spaceType, Int64(RegionSpaceFlag::SHARED_SPACE_BEGIN));
3358 GateRef less = Int64LessThanOrEqual(spaceType, Int64(RegionSpaceFlag::SHARED_SPACE_END));
3359 return BitAnd(greater, less);
3360 }
3361 }
3362
InSharedSweepableSpace(GateRef region)3363 inline GateRef StubBuilder::InSharedSweepableSpace(GateRef region)
3364 {
3365 auto offset = Region::PackedData::GetFlagsOffset(env_->Is32Bit());
3366 GateRef x = LoadPrimitive(VariableType::NATIVE_POINTER(), PtrAdd(IntPtr(offset), region),
3367 IntPtr(0));
3368 if (env_->Is32Bit()) {
3369 GateRef spaceType = Int32And(x, Int32(RegionSpaceFlag::VALID_SPACE_MASK));
3370 GateRef greater = Int32GreaterThanOrEqual(spaceType, Int32(RegionSpaceFlag::SHARED_SWEEPABLE_SPACE_BEGIN));
3371 GateRef less = Int32LessThanOrEqual(spaceType, Int32(RegionSpaceFlag::SHARED_SWEEPABLE_SPACE_END));
3372 return BitAnd(greater, less);
3373 } else {
3374 GateRef spaceType = Int64And(x, Int64(RegionSpaceFlag::VALID_SPACE_MASK));
3375 GateRef greater = Int64GreaterThanOrEqual(spaceType, Int64(RegionSpaceFlag::SHARED_SWEEPABLE_SPACE_BEGIN));
3376 GateRef less = Int64LessThanOrEqual(spaceType, Int64(RegionSpaceFlag::SHARED_SWEEPABLE_SPACE_END));
3377 return BitAnd(greater, less);
3378 }
3379 }
3380
GetParentEnv(GateRef glue,GateRef object)3381 inline GateRef StubBuilder::GetParentEnv(GateRef glue, GateRef object)
3382 {
3383 return env_->GetBuilder()->GetParentEnv(glue, object);
3384 }
3385
GetSendableParentEnv(GateRef glue,GateRef object)3386 inline GateRef StubBuilder::GetSendableParentEnv(GateRef glue, GateRef object)
3387 {
3388 return env_->GetBuilder()->GetSendableParentEnv(glue, object);
3389 }
3390
GetPropertiesFromLexicalEnv(GateRef glue,GateRef object,GateRef index)3391 inline GateRef StubBuilder::GetPropertiesFromLexicalEnv(GateRef glue, GateRef object, GateRef index)
3392 {
3393 return env_->GetBuilder()->GetPropertiesFromLexicalEnv(glue, object, index);
3394 }
3395
GetPropertiesFromSendableEnv(GateRef glue,GateRef object,GateRef index)3396 inline GateRef StubBuilder::GetPropertiesFromSendableEnv(GateRef glue, GateRef object, GateRef index)
3397 {
3398 return env_->GetBuilder()->GetPropertiesFromSendableEnv(glue, object, index);
3399 }
3400
GetKeyFromLexivalEnv(GateRef glue,GateRef lexicalEnv,GateRef levelIndex,GateRef slotIndex)3401 inline GateRef StubBuilder::GetKeyFromLexivalEnv(GateRef glue, GateRef lexicalEnv, GateRef levelIndex,
3402 GateRef slotIndex)
3403 {
3404 return env_->GetBuilder()->GetKeyFromLexivalEnv(glue, lexicalEnv, levelIndex, slotIndex);
3405 }
3406
SetPropertiesToSendableEnv(GateRef glue,GateRef object,GateRef index,GateRef value)3407 inline void StubBuilder::SetPropertiesToSendableEnv(GateRef glue, GateRef object, GateRef index, GateRef value)
3408 {
3409 GateRef valueIndex = Int32Add(index, Int32(SendableEnv::SENDABLE_RESERVED_ENV_LENGTH));
3410 SetValueToTaggedArray(VariableType::JS_ANY(), glue, object, valueIndex, value);
3411 }
3412
GetSendableEnvFromModule(GateRef glue,GateRef module)3413 inline GateRef StubBuilder::GetSendableEnvFromModule(GateRef glue, GateRef module)
3414 {
3415 return env_->GetBuilder()->GetSendableEnvFromModule(glue, module);
3416 }
3417
SetSendableEnvToModule(GateRef glue,GateRef module,GateRef value,MemoryAttribute mAttr)3418 inline void StubBuilder::SetSendableEnvToModule(GateRef glue, GateRef module, GateRef value, MemoryAttribute mAttr)
3419 {
3420 GateRef offset = IntPtr(SourceTextModule::SENDABLE_ENV_OFFSET);
3421 mAttr.SetShare(MemoryAttribute::SHARED);
3422 Store(VariableType::JS_POINTER(), glue, module, offset, value, mAttr);
3423 }
3424
GetHomeObjectFromJSFunction(GateRef glue,GateRef object)3425 inline GateRef StubBuilder::GetHomeObjectFromJSFunction(GateRef glue, GateRef object)
3426 {
3427 GateRef offset = IntPtr(JSFunction::HOME_OBJECT_OFFSET);
3428 return Load(VariableType::JS_ANY(), glue, object, offset);
3429 }
3430
GetMethodFromJSFunctionOrProxy(GateRef glue,GateRef object)3431 inline GateRef StubBuilder::GetMethodFromJSFunctionOrProxy(GateRef glue, GateRef object)
3432 {
3433 auto env = GetEnvironment();
3434 Label subentry(env);
3435 env->SubCfgEntry(&subentry);
3436
3437 GateRef methodOffset;
3438 Label funcIsJSFunctionBase(env);
3439 Label funcIsJSProxy(env);
3440 Label getMethod(env);
3441 BRANCH(IsJSFunctionBase(glue, object), &funcIsJSFunctionBase, &funcIsJSProxy);
3442 Bind(&funcIsJSFunctionBase);
3443 {
3444 methodOffset = IntPtr(JSFunctionBase::METHOD_OFFSET);
3445 Jump(&getMethod);
3446 }
3447 Bind(&funcIsJSProxy);
3448 {
3449 methodOffset = IntPtr(JSProxy::METHOD_OFFSET);
3450 Jump(&getMethod);
3451 }
3452 Bind(&getMethod);
3453 GateRef method = Load(VariableType::JS_ANY(), glue, object, methodOffset);
3454 env->SubCfgExit();
3455 return method;
3456 }
3457
GetCallFieldFromMethod(GateRef method)3458 inline GateRef StubBuilder::GetCallFieldFromMethod(GateRef method)
3459 {
3460 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
3461 return LoadPrimitive(VariableType::INT64(), method, callFieldOffset);
3462 }
3463
SetLexicalEnvToFunction(GateRef glue,GateRef object,GateRef lexicalEnv,MemoryAttribute mAttr)3464 inline void StubBuilder::SetLexicalEnvToFunction(GateRef glue, GateRef object, GateRef lexicalEnv,
3465 MemoryAttribute mAttr)
3466 {
3467 GateRef offset = IntPtr(JSFunction::LEXICAL_ENV_OFFSET);
3468 Store(VariableType::JS_ANY(), glue, object, offset, lexicalEnv, mAttr);
3469 }
3470
SetProtoOrHClassToFunction(GateRef glue,GateRef function,GateRef value,MemoryAttribute mAttr)3471 inline void StubBuilder::SetProtoOrHClassToFunction(GateRef glue, GateRef function, GateRef value,
3472 MemoryAttribute mAttr)
3473 {
3474 GateRef offset = IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET);
3475 Store(VariableType::JS_ANY(), glue, function, offset, value, mAttr);
3476 }
3477
GetProtoOrHClass(GateRef glue,GateRef function)3478 inline GateRef StubBuilder::GetProtoOrHClass(GateRef glue, GateRef function)
3479 {
3480 GateRef offset = IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET);
3481 return Load(VariableType::JS_ANY(), glue, function, offset);
3482 }
3483
SetTypedArrayName(GateRef glue,GateRef typedArray,GateRef name,MemoryAttribute mAttr)3484 inline void StubBuilder::SetTypedArrayName(GateRef glue, GateRef typedArray, GateRef name,
3485 MemoryAttribute mAttr)
3486 {
3487 GateRef offset = IntPtr(JSTypedArray::TYPED_ARRAY_NAME_OFFSET);
3488 Store(VariableType::JS_ANY(), glue, typedArray, offset, name, mAttr);
3489 }
3490
SetContentType(GateRef glue,GateRef typedArray,GateRef type)3491 inline void StubBuilder::SetContentType(GateRef glue, GateRef typedArray, GateRef type)
3492 {
3493 GateRef offset = IntPtr(JSTypedArray::CONTENT_TYPE_OFFSET);
3494 Store(VariableType::INT8(), glue, typedArray, offset, type, MemoryAttribute::NoBarrier());
3495 }
3496
SetViewedArrayBufferOrByteArray(GateRef glue,GateRef typedArray,GateRef data,MemoryAttribute mAttr)3497 inline void StubBuilder::SetViewedArrayBufferOrByteArray(GateRef glue, GateRef typedArray, GateRef data,
3498 MemoryAttribute mAttr)
3499 {
3500 GateRef offset = IntPtr(JSTypedArray::VIEWED_ARRAY_BUFFER_OFFSET);
3501 Store(VariableType::JS_ANY(), glue, typedArray, offset, data, mAttr);
3502 }
3503
GetViewedArrayBufferOrByteArray(GateRef glue,GateRef typedArray)3504 inline GateRef StubBuilder::GetViewedArrayBufferOrByteArray(GateRef glue, GateRef typedArray)
3505 {
3506 GateRef offset = IntPtr(JSTypedArray::VIEWED_ARRAY_BUFFER_OFFSET);
3507 return Load(VariableType::JS_ANY(), glue, typedArray, offset);
3508 }
3509
SetByteLength(GateRef glue,GateRef typedArray,GateRef byteLength)3510 inline void StubBuilder::SetByteLength(GateRef glue, GateRef typedArray, GateRef byteLength)
3511 {
3512 GateRef offset = IntPtr(JSTypedArray::BYTE_LENGTH_OFFSET);
3513 Store(VariableType::INT8(), glue, typedArray, offset, byteLength, MemoryAttribute::NoBarrier());
3514 }
3515
SetByteOffset(GateRef glue,GateRef typedArray,GateRef byteOffset)3516 inline void StubBuilder::SetByteOffset(GateRef glue, GateRef typedArray, GateRef byteOffset)
3517 {
3518 GateRef offset = IntPtr(JSTypedArray::BYTE_OFFSET_OFFSET);
3519 Store(VariableType::INT8(), glue, typedArray, offset, byteOffset, MemoryAttribute::NoBarrier());
3520 }
3521
SetTypedArrayLength(GateRef glue,GateRef typedArray,GateRef arrayLength)3522 inline void StubBuilder::SetTypedArrayLength(GateRef glue, GateRef typedArray, GateRef arrayLength)
3523 {
3524 GateRef offset = IntPtr(JSTypedArray::ARRAY_LENGTH_OFFSET);
3525 Store(VariableType::INT8(), glue, typedArray, offset, arrayLength, MemoryAttribute::NoBarrier());
3526 }
3527
SetHomeObjectToFunction(GateRef glue,GateRef function,GateRef value,MemoryAttribute mAttr)3528 inline void StubBuilder::SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value,
3529 MemoryAttribute mAttr)
3530 {
3531 GateRef offset = IntPtr(JSFunction::HOME_OBJECT_OFFSET);
3532 Store(VariableType::JS_ANY(), glue, function, offset, value, mAttr);
3533 }
3534
SetModuleToFunction(GateRef glue,GateRef function,GateRef value,MemoryAttribute mAttr)3535 inline void StubBuilder::SetModuleToFunction(GateRef glue, GateRef function, GateRef value,
3536 MemoryAttribute mAttr)
3537 {
3538 GateRef offset = IntPtr(JSFunction::ECMA_MODULE_OFFSET);
3539 Store(VariableType::JS_POINTER(), glue, function, offset, value, mAttr);
3540 }
3541
SetWorkNodePointerToFunction(GateRef glue,GateRef function,GateRef value,MemoryAttribute mAttr)3542 inline void StubBuilder::SetWorkNodePointerToFunction(GateRef glue, GateRef function, GateRef value,
3543 MemoryAttribute mAttr)
3544 {
3545 GateRef offset = IntPtr(JSFunction::WORK_NODE_POINTER_OFFSET);
3546 Store(VariableType::NATIVE_POINTER(), glue, function, offset, value, mAttr);
3547 }
3548
SetMethodToFunction(GateRef glue,GateRef function,GateRef value,MemoryAttribute mAttr)3549 inline void StubBuilder::SetMethodToFunction(GateRef glue, GateRef function, GateRef value,
3550 MemoryAttribute mAttr)
3551 {
3552 GateRef offset = IntPtr(JSFunctionBase::METHOD_OFFSET);
3553 Store(VariableType::JS_ANY(), glue, function, offset, value, mAttr);
3554 }
3555
SetCodeEntryToFunctionFromMethod(GateRef glue,GateRef function,GateRef method)3556 inline void StubBuilder::SetCodeEntryToFunctionFromMethod(GateRef glue, GateRef function, GateRef method)
3557 {
3558 GateRef codeEntryOffset = IntPtr(Method::CODEENTRY_LITERAL_OFFSET);
3559 GateRef codeEntry = LoadPrimitive(VariableType::NATIVE_POINTER(), method, codeEntryOffset);
3560 GateRef funcOffset = IntPtr(JSFunctionBase::CODE_ENTRY_OFFSET);
3561 Store(VariableType::NATIVE_POINTER(), glue, function, funcOffset, codeEntry);
3562 }
3563
SetCodeEntryToFunctionFromFuncEntry(GateRef glue,GateRef function,GateRef codeEntry)3564 inline void StubBuilder::SetCodeEntryToFunctionFromFuncEntry(GateRef glue, GateRef function, GateRef codeEntry)
3565 {
3566 GateRef funcOffset = IntPtr(JSFunctionBase::CODE_ENTRY_OFFSET);
3567 Store(VariableType::NATIVE_POINTER(), glue, function, funcOffset, codeEntry);
3568 }
3569
SetNativePointerToFunctionFromMethod(GateRef glue,GateRef function,GateRef method)3570 inline void StubBuilder::SetNativePointerToFunctionFromMethod(GateRef glue, GateRef function, GateRef method)
3571 {
3572 GateRef nativePointerOffset = IntPtr(Method::NATIVE_POINTER_OR_BYTECODE_ARRAY_OFFSET);
3573 GateRef nativePointer = LoadPrimitive(VariableType::NATIVE_POINTER(), method, nativePointerOffset);
3574 GateRef funcOffset = IntPtr(JSFunctionBase::CODE_ENTRY_OFFSET);
3575 Store(VariableType::NATIVE_POINTER(), glue, function, funcOffset, nativePointer);
3576 }
3577
SetLengthToFunction(GateRef glue,GateRef function,GateRef value)3578 inline void StubBuilder::SetLengthToFunction(GateRef glue, GateRef function, GateRef value)
3579 {
3580 GateRef offset = IntPtr(JSFunctionBase::LENGTH_OFFSET);
3581 Store(VariableType::INT32(), glue, function, offset, value, MemoryAttribute::NoBarrier());
3582 }
3583
GetLengthFromFunction(GateRef function)3584 inline GateRef StubBuilder::GetLengthFromFunction(GateRef function)
3585 {
3586 return LoadPrimitive(VariableType::JS_NOT_POINTER(), function, IntPtr(JSFunctionBase::LENGTH_OFFSET));
3587 }
3588
SetRawProfileTypeInfoToFunction(GateRef glue,GateRef function,GateRef value,MemoryAttribute mAttr)3589 inline void StubBuilder::SetRawProfileTypeInfoToFunction(GateRef glue, GateRef function, GateRef value,
3590 MemoryAttribute mAttr)
3591 {
3592 GateRef offset = IntPtr(JSFunction::RAW_PROFILE_TYPE_INFO_OFFSET);
3593 Store(VariableType::JS_ANY(), glue, function, offset, value, mAttr);
3594 }
3595
SetValueToProfileTypeInfoCell(GateRef glue,GateRef profileTypeInfoCell,GateRef value)3596 inline void StubBuilder::SetValueToProfileTypeInfoCell(GateRef glue, GateRef profileTypeInfoCell, GateRef value)
3597 {
3598 GateRef offset = IntPtr(ProfileTypeInfoCell::VALUE_OFFSET);
3599 Store(VariableType::JS_POINTER(), glue, profileTypeInfoCell, offset, value);
3600 }
3601
UpdateProfileTypeInfoCellType(GateRef glue,GateRef profileTypeInfoCell)3602 inline void StubBuilder::UpdateProfileTypeInfoCellType(GateRef glue, GateRef profileTypeInfoCell)
3603 {
3604 auto env = GetEnvironment();
3605 Label subEntry(env);
3606 env->SubCfgEntry(&subEntry);
3607
3608 // ProfileTypeInfoCell0 -> Cell1 -> CellN
3609 Label isProfileTypeInfoCell0(env);
3610 Label notProfileTypeInfoCell0(env);
3611 Label isProfileTypeInfoCell1(env);
3612 Label endProfileTypeInfoCellType(env);
3613 GateRef objectType = GetObjectType(LoadHClass(glue, profileTypeInfoCell));
3614 BRANCH(Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::PROFILE_TYPE_INFO_CELL_0))),
3615 &isProfileTypeInfoCell0, ¬ProfileTypeInfoCell0);
3616 Bind(&isProfileTypeInfoCell0);
3617 {
3618 auto profileTypeInfoCell1Class = GetGlobalConstantValue(VariableType::JS_POINTER(), glue,
3619 ConstantIndex::PROFILE_TYPE_INFO_CELL_1_CLASS_INDEX);
3620 TransitionHClass(glue, profileTypeInfoCell, profileTypeInfoCell1Class, MemoryAttribute::NoBarrier());
3621 Jump(&endProfileTypeInfoCellType);
3622 }
3623 Bind(¬ProfileTypeInfoCell0);
3624 BRANCH(Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::PROFILE_TYPE_INFO_CELL_1))),
3625 &isProfileTypeInfoCell1, &endProfileTypeInfoCellType);
3626 Bind(&isProfileTypeInfoCell1);
3627 {
3628 auto profileTypeInfoCellNClass = GetGlobalConstantValue(VariableType::JS_POINTER(), glue,
3629 ConstantIndex::PROFILE_TYPE_INFO_CELL_N_CLASS_INDEX);
3630 TransitionHClass(glue, profileTypeInfoCell, profileTypeInfoCellNClass, MemoryAttribute::NoBarrier());
3631 Jump(&endProfileTypeInfoCellType);
3632 }
3633 Bind(&endProfileTypeInfoCellType);
3634 env->SubCfgExit();
3635 }
3636
SetJSObjectTaggedField(GateRef glue,GateRef object,size_t offset,GateRef value)3637 inline void StubBuilder::SetJSObjectTaggedField(GateRef glue, GateRef object, size_t offset, GateRef value)
3638 {
3639 Store(VariableType::JS_ANY(), glue, object, IntPtr(offset), value);
3640 }
3641
SetCompiledCodeFlagToFunction(GateRef glue,GateRef function,GateRef value)3642 inline void StubBuilder::SetCompiledCodeFlagToFunction(GateRef glue, GateRef function, GateRef value)
3643 {
3644 GateRef bitFieldOffset = IntPtr(JSFunctionBase::BIT_FIELD_OFFSET);
3645 GateRef oldVal = LoadPrimitive(VariableType::INT32(), function, bitFieldOffset);
3646
3647 GateRef mask = Int32(JSFunctionBase::COMPILED_CODE_FASTCALL_BITS << JSFunctionBase::IsCompiledCodeBit::START_BIT);
3648 GateRef newVal = Int32Or(Int32And(oldVal, Int32Not(mask)), value);
3649 Store(VariableType::INT32(), glue, function, bitFieldOffset, newVal, MemoryAttribute::NoBarrier());
3650 }
3651
SetCompiledFuncEntry(GateRef glue,GateRef jsFunc,GateRef codeEntry,GateRef isFastCall)3652 inline void StubBuilder::SetCompiledFuncEntry(GateRef glue, GateRef jsFunc, GateRef codeEntry, GateRef isFastCall)
3653 {
3654 SetCodeEntryToFunctionFromFuncEntry(glue, jsFunc, codeEntry);
3655 GateRef compiledCodeFastCallBits = Int32Add(Int32(1),
3656 Int32LSL(isFastCall, Int32(JSFunctionBase::IsFastCallBit::START_BIT)));
3657 SetCompiledCodeFlagToFunction(glue, jsFunc, compiledCodeFastCallBits);
3658 }
3659
GetIsFastCall(GateRef machineCode)3660 inline GateRef StubBuilder::GetIsFastCall(GateRef machineCode)
3661 {
3662 GateRef bitfield = LoadPrimitive(VariableType::INT32(), machineCode, IntPtr(MachineCode::BIT_FIELD_OFFSET));
3663 return Int32And(Int32LSR(bitfield, Int32(MachineCode::IsFastCallBits::START_BIT)),
3664 Int32((1LU << MachineCode::IsFastCallBits::SIZE) - 1));
3665 }
3666
SetTaskConcurrentFuncFlagToFunction(GateRef glue,GateRef function,GateRef value)3667 inline void StubBuilder::SetTaskConcurrentFuncFlagToFunction(GateRef glue, GateRef function, GateRef value)
3668 {
3669 GateRef bitFieldOffset = IntPtr(JSFunctionBase::BIT_FIELD_OFFSET);
3670 GateRef oldVal = LoadPrimitive(VariableType::INT32(), function, bitFieldOffset);
3671 GateRef mask = Int32LSL(
3672 Int32((1LU << JSFunctionBase::TaskConcurrentFuncFlagBit::SIZE) - 1),
3673 Int32(JSFunctionBase::TaskConcurrentFuncFlagBit::START_BIT));
3674 GateRef newVal = Int32Or(Int32And(oldVal, Int32Not(mask)),
3675 Int32LSL(ZExtInt1ToInt32(value), Int32(JSFunctionBase::TaskConcurrentFuncFlagBit::START_BIT)));
3676 Store(VariableType::INT32(), glue, function, bitFieldOffset, newVal);
3677 }
3678
SetBitFieldToFunction(GateRef glue,GateRef function,GateRef value,MemoryAttribute mAttr)3679 inline void StubBuilder::SetBitFieldToFunction(GateRef glue, GateRef function, GateRef value, MemoryAttribute mAttr)
3680 {
3681 GateRef bitFieldOffset = IntPtr(JSFunctionBase::BIT_FIELD_OFFSET);
3682 Store(VariableType::INT32(), glue, function, bitFieldOffset, value, mAttr);
3683 }
3684
SetMachineCodeToFunction(GateRef glue,GateRef function,GateRef value,MemoryAttribute mAttr)3685 inline void StubBuilder::SetMachineCodeToFunction(GateRef glue, GateRef function, GateRef value, MemoryAttribute mAttr)
3686 {
3687 GateRef offset = IntPtr(JSFunction::MACHINECODE_OFFSET);
3688 Store(VariableType::JS_ANY(), glue, function, offset, value, mAttr);
3689 }
3690
GetGlobalEnv(GateRef glue)3691 inline GateRef StubBuilder::GetGlobalEnv(GateRef glue)
3692 {
3693 return env_->GetBuilder()->GetGlobalEnv(glue);
3694 }
3695
SetGlueGlobalEnv(GateRef glue,GateRef globalEnv)3696 inline void StubBuilder::SetGlueGlobalEnv(GateRef glue, GateRef globalEnv)
3697 {
3698 GateRef globalEnvOffset = IntPtr(JSThread::GlueData::GetCurrentEnvOffset(env_->IsArch32Bit()));
3699 StoreWithoutBarrier(VariableType::JS_POINTER(), glue, globalEnvOffset, globalEnv);
3700 }
3701
SetGlueGlobalEnvFromCurrentEnv(GateRef glue,GateRef currentEnv)3702 inline void StubBuilder::SetGlueGlobalEnvFromCurrentEnv(GateRef glue, GateRef currentEnv)
3703 {
3704 auto env0 = GetEnvironment();
3705 {
3706 ASM_ASSERT(GET_MESSAGE_STRING_ID(CurrentEnvIsInvalid),
3707 LogicAndBuilder(env0).And(TaggedIsHeapObject(currentEnv))
3708 .And(LogicOrBuilder(env0).Or(IsGlobalEnv(glue, currentEnv))
3709 .Or(IsLexicalEnv(glue, currentEnv))
3710 .Or(IsSFunctionEnv(glue, currentEnv)).Done())
3711 .Done());
3712 }
3713 Label entry(env0);
3714 env0->SubCfgEntry(&entry);
3715 Label setGlue(env0);
3716 Label exit(env0);
3717 GateRef globalEnv = GetValueFromTaggedArray(glue, currentEnv, Int32(BaseEnv::GLOBAL_ENV_INDEX));
3718 BRANCH_UNLIKELY(TaggedIsHole(globalEnv), &exit, &setGlue);
3719 Bind(&setGlue);
3720 {
3721 GateRef globalEnvOffset = IntPtr(JSThread::GlueData::GetCurrentEnvOffset(env0->IsArch32Bit()));
3722 StoreWithoutBarrier(VariableType::JS_POINTER(), glue, globalEnvOffset, globalEnv);
3723 Jump(&exit);
3724 }
3725 Bind(&exit);
3726 env0->SubCfgExit();
3727 }
3728
GetGlobalObject(GateRef glue,GateRef globalEnv)3729 inline GateRef StubBuilder::GetGlobalObject(GateRef glue, GateRef globalEnv)
3730 {
3731 return env_->GetBuilder()->GetGlobalObject(glue, globalEnv);
3732 }
3733
GetMethodFromFunction(GateRef glue,GateRef function)3734 inline GateRef StubBuilder::GetMethodFromFunction(GateRef glue, GateRef function)
3735 {
3736 return env_->GetBuilder()->GetMethodFromFunction(glue, function);
3737 }
3738
GetModuleFromFunction(GateRef glue,GateRef function)3739 inline GateRef StubBuilder::GetModuleFromFunction(GateRef glue, GateRef function)
3740 {
3741 return env_->GetBuilder()->GetModuleFromFunction(glue, function);
3742 }
3743
GetHomeObjectFromFunction(GateRef glue,GateRef function)3744 inline GateRef StubBuilder::GetHomeObjectFromFunction(GateRef glue, GateRef function)
3745 {
3746 return env_->GetBuilder()->GetHomeObjectFromFunction(glue, function);
3747 }
3748
GetEntryIndexOfGlobalDictionary(GateRef entry)3749 inline GateRef StubBuilder::GetEntryIndexOfGlobalDictionary(GateRef entry)
3750 {
3751 return Int32Add(Int32(OrderTaggedHashTable<GlobalDictionary>::TABLE_HEADER_SIZE),
3752 Int32Mul(entry, Int32(GlobalDictionary::ENTRY_SIZE)));
3753 }
3754
GetBoxFromGlobalDictionary(GateRef glue,GateRef object,GateRef entry)3755 inline GateRef StubBuilder::GetBoxFromGlobalDictionary(GateRef glue, GateRef object, GateRef entry)
3756 {
3757 GateRef index = GetEntryIndexOfGlobalDictionary(entry);
3758 GateRef offset = PtrAdd(ZExtInt32ToPtr(index),
3759 IntPtr(GlobalDictionary::ENTRY_VALUE_INDEX));
3760 return GetValueFromTaggedArray(glue, object, offset);
3761 }
3762
GetValueFromGlobalDictionary(GateRef glue,GateRef object,GateRef entry)3763 inline GateRef StubBuilder::GetValueFromGlobalDictionary(GateRef glue, GateRef object, GateRef entry)
3764 {
3765 GateRef box = GetBoxFromGlobalDictionary(glue, object, entry);
3766 return Load(VariableType::JS_ANY(), glue, box, IntPtr(PropertyBox::VALUE_OFFSET));
3767 }
3768
GetPropertiesFromJSObject(GateRef glue,GateRef object)3769 inline GateRef StubBuilder::GetPropertiesFromJSObject(GateRef glue, GateRef object)
3770 {
3771 GateRef offset = IntPtr(JSObject::PROPERTIES_OFFSET);
3772 return Load(VariableType::JS_ANY(), glue, object, offset);
3773 }
3774
IsJSFunction(GateRef glue,GateRef obj)3775 inline GateRef StubBuilder::IsJSFunction(GateRef glue, GateRef obj)
3776 {
3777 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
3778 GateRef greater = Int32GreaterThanOrEqual(objectType,
3779 Int32(static_cast<int32_t>(JSType::JS_FUNCTION_FIRST)));
3780 GateRef less = Int32LessThanOrEqual(objectType,
3781 Int32(static_cast<int32_t>(JSType::JS_FUNCTION_LAST)));
3782 return BitAnd(greater, less);
3783 }
3784
IsBoundFunction(GateRef glue,GateRef obj)3785 inline GateRef StubBuilder::IsBoundFunction(GateRef glue, GateRef obj)
3786 {
3787 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
3788 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_BOUND_FUNCTION)));
3789 }
3790
IsJSOrBoundFunction(GateRef glue,GateRef obj)3791 inline GateRef StubBuilder::IsJSOrBoundFunction(GateRef glue, GateRef obj)
3792 {
3793 GateRef objectType = GetObjectType(LoadHClass(glue, obj));
3794 GateRef greater = Int32GreaterThanOrEqual(objectType,
3795 Int32(static_cast<int32_t>(JSType::JS_FUNCTION_FIRST)));
3796 GateRef less = Int32LessThanOrEqual(objectType,
3797 Int32(static_cast<int32_t>(JSType::JS_BOUND_FUNCTION)));
3798 return BitAnd(greater, less);
3799 }
3800
IsAOTLiteralInfo(GateRef glue,GateRef info)3801 inline GateRef StubBuilder::IsAOTLiteralInfo(GateRef glue, GateRef info)
3802 {
3803 return env_->GetBuilder()->IsAOTLiteralInfo(glue, info);
3804 }
3805
IsAotWithCallField(GateRef method)3806 inline GateRef StubBuilder::IsAotWithCallField(GateRef method)
3807 {
3808 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
3809 GateRef callfield = LoadPrimitive(VariableType::INT64(), method, callFieldOffset);
3810 return Int64NotEqual(
3811 Int64And(
3812 Int64LSR(callfield, Int64(Method::IsAotCodeBit::START_BIT)),
3813 Int64((1LU << Method::IsAotCodeBit::SIZE) - 1)),
3814 Int64(0));
3815 }
3816
IsFastCall(GateRef method)3817 inline GateRef StubBuilder::IsFastCall(GateRef method)
3818 {
3819 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
3820 GateRef callfield = LoadPrimitive(VariableType::INT64(), method, callFieldOffset);
3821 return Int64NotEqual(
3822 Int64And(
3823 Int64LSR(callfield, Int64(Method::IsFastCallBit::START_BIT)),
3824 Int64((1LU << Method::IsFastCallBit::SIZE) - 1)),
3825 Int64(0));
3826 }
3827
HasPrototype(GateRef kind)3828 inline GateRef StubBuilder::HasPrototype(GateRef kind)
3829 {
3830 return LogicAndBuilder(env_)
3831 .And(Int32NotEqual(kind, Int32(static_cast<int32_t>(FunctionKind::BUILTIN_PROXY_CONSTRUCTOR))))
3832 .And(Int32GreaterThanOrEqual(kind, Int32(static_cast<int32_t>(FunctionKind::BASE_CONSTRUCTOR))))
3833 .And(Int32LessThanOrEqual(kind, Int32(static_cast<int32_t>(FunctionKind::ASYNC_GENERATOR_FUNCTION))))
3834 .Done();
3835 }
3836
HasAccessor(GateRef kind)3837 inline GateRef StubBuilder::HasAccessor(GateRef kind)
3838 {
3839 GateRef greater = Int32GreaterThanOrEqual(kind,
3840 Int32(static_cast<int32_t>(FunctionKind::NORMAL_FUNCTION)));
3841 GateRef less = Int32LessThanOrEqual(kind,
3842 Int32(static_cast<int32_t>(FunctionKind::ASYNC_FUNCTION)));
3843 return BitAnd(greater, less);
3844 }
3845
IsClassConstructorKind(GateRef kind)3846 inline GateRef StubBuilder::IsClassConstructorKind(GateRef kind)
3847 {
3848 GateRef left = Int32Equal(kind, Int32(static_cast<int32_t>(FunctionKind::CLASS_CONSTRUCTOR)));
3849 GateRef right = Int32Equal(kind, Int32(static_cast<int32_t>(FunctionKind::DERIVED_CONSTRUCTOR)));
3850 return BitOr(left, right);
3851 }
3852
IsGeneratorKind(GateRef kind)3853 inline GateRef StubBuilder::IsGeneratorKind(GateRef kind)
3854 {
3855 GateRef left = Int32Equal(kind, Int32(static_cast<int32_t>(FunctionKind::ASYNC_GENERATOR_FUNCTION)));
3856 GateRef right = Int32Equal(kind, Int32(static_cast<int32_t>(FunctionKind::GENERATOR_FUNCTION)));
3857 return BitOr(left, right);
3858 }
3859
IsBaseKind(GateRef kind)3860 inline GateRef StubBuilder::IsBaseKind(GateRef kind)
3861 {
3862 GateRef left = Int32Equal(kind, Int32(static_cast<int32_t>(FunctionKind::BASE_CONSTRUCTOR)));
3863 GateRef right = Int32Equal(kind, Int32(static_cast<int32_t>(FunctionKind::NONE_FUNCTION)));
3864 GateRef val = BitOr(left, right);
3865 return BitOr(val, IsGeneratorKind(kind));
3866 }
3867
IsBaseConstructorKind(GateRef kind)3868 inline GateRef StubBuilder::IsBaseConstructorKind(GateRef kind)
3869 {
3870 return Int32Equal(kind, Int32(static_cast<int32_t>(FunctionKind::BASE_CONSTRUCTOR)));
3871 }
3872
IsSendableFunction(GateRef method)3873 inline GateRef StubBuilder::IsSendableFunction(GateRef method)
3874 {
3875 GateRef fieldOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
3876 GateRef literalField = LoadPrimitive(VariableType::INT64(), method, fieldOffset);
3877 return Int64NotEqual(
3878 Int64And(
3879 Int64LSR(literalField, Int64(Method::IsSharedBit::START_BIT)),
3880 Int64((1LU << Method::IsSharedBit::SIZE) - 1)),
3881 Int64(0));
3882 }
3883
IsNativeMethod(GateRef method)3884 inline GateRef StubBuilder::IsNativeMethod(GateRef method)
3885 {
3886 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
3887 GateRef callfield = LoadPrimitive(VariableType::INT64(), method, callFieldOffset);
3888 return Int64NotEqual(
3889 Int64And(
3890 Int64LSR(callfield, Int64(MethodLiteral::IsNativeBit::START_BIT)),
3891 Int64((1LU << MethodLiteral::IsNativeBit::SIZE) - 1)),
3892 Int64(0));
3893 }
3894
JudgeAotAndFastCall(GateRef jsFunc,CircuitBuilder::JudgeMethodType type)3895 inline GateRef StubBuilder::JudgeAotAndFastCall(GateRef jsFunc, CircuitBuilder::JudgeMethodType type)
3896 {
3897 return env_->GetBuilder()->JudgeAotAndFastCall(jsFunc, type);
3898 }
3899
GetExpectedNumOfArgs(GateRef method)3900 inline GateRef StubBuilder::GetExpectedNumOfArgs(GateRef method)
3901 {
3902 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
3903 GateRef callfield = LoadPrimitive(VariableType::INT64(), method, callFieldOffset);
3904 return TruncInt64ToInt32(Int64And(
3905 Int64LSR(callfield, Int64(MethodLiteral::NumArgsBits::START_BIT)),
3906 Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1)));
3907 }
3908
GetMethodFromJSProxy(GateRef glue,GateRef proxy)3909 inline GateRef StubBuilder::GetMethodFromJSProxy(GateRef glue, GateRef proxy)
3910 {
3911 GateRef offset = IntPtr(JSProxy::METHOD_OFFSET);
3912 return Load(VariableType::JS_ANY(), glue, proxy, offset);
3913 }
3914
GetHandlerFromJSProxy(GateRef glue,GateRef proxy)3915 inline GateRef StubBuilder::GetHandlerFromJSProxy(GateRef glue, GateRef proxy)
3916 {
3917 GateRef offset = IntPtr(JSProxy::HANDLER_OFFSET);
3918 return Load(VariableType::JS_ANY(), glue, proxy, offset);
3919 }
3920
GetTargetFromJSProxy(GateRef glue,GateRef proxy)3921 inline GateRef StubBuilder::GetTargetFromJSProxy(GateRef glue, GateRef proxy)
3922 {
3923 GateRef offset = IntPtr(JSProxy::TARGET_OFFSET);
3924 return Load(VariableType::JS_ANY(), glue, proxy, offset);
3925 }
3926
ComputeTaggedArraySize(GateRef length)3927 inline GateRef StubBuilder::ComputeTaggedArraySize(GateRef length)
3928 {
3929 return PtrAdd(IntPtr(TaggedArray::DATA_OFFSET),
3930 PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), length));
3931 }
3932
GetGlobalConstantValue(VariableType type,GateRef glue,ConstantIndex index)3933 inline GateRef StubBuilder::GetGlobalConstantValue(VariableType type, GateRef glue, ConstantIndex index)
3934 {
3935 return env_->GetBuilder()->GetGlobalConstantValue(type, glue, index);
3936 }
3937
GetGlobalConstantValue(VariableType type,GateRef glue,GateRef index)3938 inline GateRef StubBuilder::GetGlobalConstantValue(VariableType type, GateRef glue, GateRef index)
3939 {
3940 GateRef gConstAddr = LoadPrimitive(VariableType::JS_ANY(), glue,
3941 IntPtr(JSThread::GlueData::GetGlobalConstOffset(env_->Is32Bit())));
3942 auto constantIndex = PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), index);
3943 return LoadPrimitive(type, gConstAddr, constantIndex);
3944 }
3945
GetSingleCharTable(GateRef glue)3946 inline GateRef StubBuilder::GetSingleCharTable(GateRef glue)
3947 {
3948 return GetGlobalConstantValue(
3949 VariableType::JS_POINTER(), glue, ConstantIndex::SINGLE_CHAR_TABLE_INDEX);
3950 }
3951
IsEnableMutantArray(GateRef glue)3952 inline GateRef StubBuilder::IsEnableMutantArray(GateRef glue)
3953 {
3954 GateRef offset = IntPtr(JSThread::GlueData::GetIsEnableMutantArrayOffset(env_->Is32Bit()));
3955 return LoadPrimitive(VariableType::BOOL(), glue, offset);
3956 }
3957
IsEnableElementsKind(GateRef glue)3958 inline GateRef StubBuilder::IsEnableElementsKind(GateRef glue)
3959 {
3960 GateRef offset = IntPtr(JSThread::GlueData::GetIsEnableElementsKindOffset(env_->Is32Bit()));
3961 return LoadPrimitive(VariableType::BOOL(), glue, offset);
3962 }
3963
TaggedIsEnumCache(GateRef glue,GateRef obj)3964 inline GateRef StubBuilder::TaggedIsEnumCache(GateRef glue, GateRef obj)
3965 {
3966 return env_->GetBuilder()->TaggedIsEnumCache(glue, obj);
3967 }
3968
GetGlobalEnvValue(VariableType type,GateRef glue,GateRef env,size_t index)3969 inline GateRef StubBuilder::GetGlobalEnvValue(VariableType type, [[maybe_unused]] GateRef glue, GateRef env,
3970 size_t index)
3971 {
3972 auto valueIndex = IntPtr(GlobalEnv::HEADER_SIZE + JSTaggedValue::TaggedTypeSize() * index);
3973 // ReadBarrier is not needed for loading global env fields, because all the fields are GC roots
3974 return LoadPrimitive(type, env, valueIndex);
3975 }
3976
HasPendingException(GateRef glue)3977 inline GateRef StubBuilder::HasPendingException(GateRef glue)
3978 {
3979 GateRef exceptionOffset = IntPtr(JSThread::GlueData::GetExceptionOffset(env_->IsArch32Bit()));
3980 GateRef exception = LoadPrimitive(VariableType::JS_ANY(), glue, exceptionOffset);
3981 return TaggedIsNotHole(exception);
3982 }
3983
DispatchBuiltins(GateRef glue,GateRef builtinsId,const std::vector<GateRef> & args,GateRef hir)3984 inline GateRef StubBuilder::DispatchBuiltins(GateRef glue, GateRef builtinsId, const std::vector<GateRef>& args,
3985 GateRef hir)
3986 {
3987 GateRef target = PtrMul(ZExtInt32ToPtr(builtinsId), IntPtrSize());
3988 return env_->GetBuilder()->CallBuiltin(glue, target, args, hir);
3989 }
3990
DispatchBuiltinsWithArgv(GateRef glue,GateRef builtinsId,const std::vector<GateRef> & args)3991 inline GateRef StubBuilder::DispatchBuiltinsWithArgv(GateRef glue, GateRef builtinsId, const std::vector<GateRef>& args)
3992 {
3993 GateRef target = PtrMul(ZExtInt32ToPtr(builtinsId), IntPtrSize());
3994 return env_->GetBuilder()->CallBuiltinWithArgv(glue, target, args);
3995 }
3996
GetBuiltinId(GateRef method)3997 inline GateRef StubBuilder::GetBuiltinId(GateRef method)
3998 {
3999 GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
4000 GateRef extraLiteralInfo = LoadPrimitive(VariableType::INT64(), method, extraLiteralInfoOffset);
4001 return TruncInt64ToInt32(Int64And(
4002 Int64LSR(extraLiteralInfo, Int64(MethodLiteral::BuiltinIdBits::START_BIT)),
4003 Int64((1LU << MethodLiteral::BuiltinIdBits::SIZE) - 1)));
4004 }
4005
ComputeSizeUtf8(GateRef length)4006 inline GateRef StubBuilder::ComputeSizeUtf8(GateRef length)
4007 {
4008 return PtrAdd(IntPtr(LineString::DATA_OFFSET), length);
4009 }
4010
ComputeSizeUtf16(GateRef length)4011 inline GateRef StubBuilder::ComputeSizeUtf16(GateRef length)
4012 {
4013 return PtrAdd(IntPtr(LineString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t))));
4014 }
4015
AlignUp(GateRef x,GateRef alignment)4016 inline GateRef StubBuilder::AlignUp(GateRef x, GateRef alignment)
4017 {
4018 GateRef x1 = PtrAdd(x, PtrSub(alignment, IntPtr(1)));
4019 return IntPtrAnd(x1, IntPtrNot(PtrSub(alignment, IntPtr(1))));
4020 }
4021
AlignDown(GateRef x,GateRef alignment)4022 inline GateRef StubBuilder::AlignDown(GateRef x, GateRef alignment)
4023 {
4024 return IntPtrAnd(x, IntPtrNot(PtrSub(alignment, IntPtr(1))));
4025 }
4026
InitStringLengthAndFlags(GateRef glue,GateRef str,GateRef length,bool compressed)4027 inline void StubBuilder::InitStringLengthAndFlags(GateRef glue, GateRef str, GateRef length, bool compressed)
4028 {
4029 GateRef len = Int32LSL(length, Int32(BaseString::LengthBits::START_BIT));
4030 GateRef mixLength;
4031 if (compressed) {
4032 mixLength = Int32Or(len, Int32(BaseString::STRING_COMPRESSED));
4033 } else {
4034 mixLength = Int32Or(len, Int32(BaseString::STRING_UNCOMPRESSED));
4035 }
4036 Store(VariableType::INT32(), glue, str, IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET), mixLength);
4037 }
4038
InitStringLengthAndFlags(GateRef glue,GateRef str,GateRef length,GateRef isCompressed)4039 inline void StubBuilder::InitStringLengthAndFlags(GateRef glue, GateRef str, GateRef length, GateRef isCompressed)
4040 {
4041 GateRef len = Int32LSL(length, Int32(BaseString::LengthBits::START_BIT));
4042 GateRef mixLength = Int32Or(len, ZExtInt1ToInt32(BoolNot(isCompressed))); // encode bool to CompressedStatus
4043 Store(VariableType::INT32(), glue, str, IntPtr(BaseString::LENGTH_AND_FLAGS_OFFSET), mixLength);
4044 }
4045
SetMixHashcode(GateRef glue,GateRef str,GateRef mixHashcode)4046 inline void StubBuilder::SetMixHashcode(GateRef glue, GateRef str, GateRef mixHashcode)
4047 {
4048 env_->GetBuilder()->SetMixHashcode(glue, str, mixHashcode);
4049 }
4050
TryGetHashcodeFromString(GateRef string)4051 inline GateRef StubBuilder::TryGetHashcodeFromString(GateRef string)
4052 {
4053 return env_->GetBuilder()->TryGetHashcodeFromString(string);
4054 }
4055
SetElementsKindToJSHClass(GateRef glue,GateRef jsHclass,GateRef elementsKind)4056 inline void StubBuilder::SetElementsKindToJSHClass(GateRef glue, GateRef jsHclass, GateRef elementsKind)
4057 {
4058 GateRef bitfield = LoadPrimitive(VariableType::INT32(), jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
4059 GateRef encodeValue = Int32LSL(elementsKind, Int32(JSHClass::ElementsKindBits::START_BIT));
4060 GateRef mask = Int32(((1LU << JSHClass::ElementsKindBits::SIZE) - 1) << JSHClass::ElementsKindBits::START_BIT);
4061 bitfield = Int32Or(Int32And(bitfield, Int32Not(mask)), encodeValue);
4062 Store(VariableType::INT32(), glue, jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET), bitfield);
4063 }
4064
SetExtensibleToBitfield(GateRef glue,GateRef obj,bool isExtensible)4065 inline void StubBuilder::SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible)
4066 {
4067 GateRef jsHclass = LoadHClass(glue, obj);
4068 GateRef bitfield = LoadPrimitive(VariableType::INT32(), jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
4069 GateRef boolVal = Boolean(isExtensible);
4070 GateRef boolToInt32 = ZExtInt1ToInt32(boolVal);
4071 GateRef encodeValue = Int32LSL(boolToInt32, Int32(JSHClass::ExtensibleBit::START_BIT));
4072 GateRef mask = Int32(((1LU << JSHClass::ExtensibleBit::SIZE) - 1) << JSHClass::ExtensibleBit::START_BIT);
4073 bitfield = Int32Or(Int32And(bitfield, Int32Not(mask)), encodeValue);
4074 Store(VariableType::INT32(), glue, jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET), bitfield,
4075 MemoryAttribute::NoBarrier());
4076 }
4077
SetCallableToBitfield(GateRef glue,GateRef obj,bool isCallable)4078 inline void StubBuilder::SetCallableToBitfield(GateRef glue, GateRef obj, bool isCallable)
4079 {
4080 GateRef jsHclass = LoadHClass(glue, obj);
4081 GateRef bitfield = LoadPrimitive(VariableType::INT32(), jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
4082 GateRef boolVal = Boolean(isCallable);
4083 GateRef boolToInt32 = ZExtInt1ToInt32(boolVal);
4084 GateRef encodeValue = Int32LSL(boolToInt32, Int32(JSHClass::CallableBit::START_BIT));
4085 GateRef mask = Int32(((1LU << JSHClass::CallableBit::SIZE) - 1) << JSHClass::CallableBit::START_BIT);
4086 bitfield = Int32Or(Int32And(bitfield, Int32Not(mask)), encodeValue);
4087 Store(VariableType::INT32(), glue, jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET), bitfield,
4088 MemoryAttribute::NoBarrier());
4089 }
4090
Comment(GateRef glue,const std::string & str)4091 inline void StubBuilder::Comment(GateRef glue, const std::string &str)
4092 {
4093 CallNGCRuntime(glue, RTSTUB_ID(Comment), { StringPtr(str) });
4094 }
4095
IsStableElements(GateRef hClass)4096 inline GateRef StubBuilder::IsStableElements(GateRef hClass)
4097 {
4098 return env_->GetBuilder()->IsStableElements(hClass);
4099 }
4100
HasConstructorByHClass(GateRef hClass)4101 inline GateRef StubBuilder::HasConstructorByHClass(GateRef hClass)
4102 {
4103 return env_->GetBuilder()->HasConstructorByHClass(hClass);
4104 }
4105
HasConstructor(GateRef glue,GateRef object)4106 inline GateRef StubBuilder::HasConstructor(GateRef glue, GateRef object)
4107 {
4108 // only array and typedArray use this bitfield
4109 return env_->GetBuilder()->HasConstructor(glue, object);
4110 }
4111
IsStableArguments(GateRef hClass)4112 inline GateRef StubBuilder::IsStableArguments(GateRef hClass)
4113 {
4114 return env_->GetBuilder()->IsStableArguments(hClass);
4115 }
4116
IsStableArray(GateRef hClass)4117 inline GateRef StubBuilder::IsStableArray(GateRef hClass)
4118 {
4119 return env_->GetBuilder()->IsStableArray(hClass);
4120 }
4121
IsTypedArray(GateRef glue,GateRef obj)4122 inline GateRef StubBuilder::IsTypedArray(GateRef glue, GateRef obj)
4123 {
4124 return env_->GetBuilder()->IsTypedArray(glue, obj);
4125 }
4126
IsSharedTypedArray(GateRef glue,GateRef obj)4127 inline GateRef StubBuilder::IsSharedTypedArray(GateRef glue, GateRef obj)
4128 {
4129 return env_->GetBuilder()->IsSharedTypedArray(glue, obj);
4130 }
4131
GetProfileTypeInfo(GateRef glue,GateRef jsFunc)4132 inline GateRef StubBuilder::GetProfileTypeInfo(GateRef glue, GateRef jsFunc)
4133 {
4134 GateRef raw = Load(VariableType::JS_POINTER(), glue, jsFunc, IntPtr(JSFunction::RAW_PROFILE_TYPE_INFO_OFFSET));
4135 return Load(VariableType::JS_POINTER(), glue, raw, IntPtr(ProfileTypeInfoCell::VALUE_OFFSET));
4136 }
4137
CheckDetectorName(GateRef glue,GateRef key,Label * fallthrough,Label * slow)4138 inline void StubBuilder::CheckDetectorName(GateRef glue, GateRef key, Label *fallthrough, Label *slow)
4139 {
4140 GateRef globalEnv = GetCurrentGlobalEnv();
4141 GateRef keyAddr = ChangeTaggedPointerToInt64(key);
4142 GateRef firstDetectorName = GetGlobalEnvValue(
4143 VariableType::INT64(), glue, globalEnv, GlobalEnv::FIRST_DETECTOR_SYMBOL_INDEX);
4144 GateRef lastDetectorName = GetGlobalEnvValue(
4145 VariableType::INT64(), glue, globalEnv, GlobalEnv::LAST_DETECTOR_SYMBOL_INDEX);
4146 GateRef isDetectorName = BitAnd(Int64UnsignedLessThanOrEqual(firstDetectorName, keyAddr),
4147 Int64UnsignedLessThanOrEqual(keyAddr, lastDetectorName));
4148 Label checkCommonDetector(env_);
4149 BRANCH(isDetectorName, slow, &checkCommonDetector);
4150 Bind(&checkCommonDetector);
4151 auto gFlagsStr = GetGlobalConstantValue(
4152 VariableType::JS_POINTER(), glue, ConstantIndex::FLAGS_INDEX);
4153 GateRef isFlagsStr = Equal(key, gFlagsStr);
4154 BRANCH(isFlagsStr, slow, fallthrough);
4155 }
4156
LoadPfHeaderFromConstPool(GateRef glue,GateRef jsFunc)4157 inline GateRef StubBuilder::LoadPfHeaderFromConstPool(GateRef glue, GateRef jsFunc)
4158 {
4159 GateRef method = Load(VariableType::JS_ANY(), glue, jsFunc, IntPtr(JSFunctionBase::METHOD_OFFSET));
4160 GateRef constPool = Load(VariableType::JS_ANY(), glue, method, IntPtr(Method::CONSTANT_POOL_OFFSET));
4161 auto length = GetLengthOfTaggedArray(constPool);
4162 auto index = Int32Sub(length, Int32(ConstantPool::JS_PANDA_FILE_INDEX));
4163 auto jsPandaFile = GetValueFromTaggedArray(glue, constPool, index);
4164 auto jsPfAddr = ChangeInt64ToIntPtr(ChangeTaggedPointerToInt64(jsPandaFile));
4165 auto pfAddr = LoadPrimitive(VariableType::NATIVE_POINTER(), jsPfAddr, Int32(JSPandaFile::PF_OFFSET));
4166 auto pfHeader = LoadPrimitive(VariableType::NATIVE_POINTER(), pfAddr, Int32(0));
4167 return pfHeader;
4168 }
4169
LoadHCIndexInfosFromConstPool(GateRef glue,GateRef jsFunc)4170 inline GateRef StubBuilder::LoadHCIndexInfosFromConstPool(GateRef glue, GateRef jsFunc)
4171 {
4172 GateRef method = Load(VariableType::JS_ANY(), glue, jsFunc, IntPtr(JSFunctionBase::METHOD_OFFSET));
4173 GateRef constPool = Load(VariableType::JS_ANY(), glue, method, IntPtr(Method::CONSTANT_POOL_OFFSET));
4174 auto length = GetLengthOfTaggedArray(constPool);
4175 auto index = Int32Sub(length, Int32(ConstantPool::CONSTANT_INDEX_INFO_INDEX));
4176 return GetValueFromTaggedArray(glue, constPool, index);
4177 }
4178
LoadHCIndexFromConstPool(GateRef glue,GateRef cachedArray,GateRef cachedLength,GateRef traceId,Label * miss)4179 inline GateRef StubBuilder::LoadHCIndexFromConstPool(
4180 GateRef glue, GateRef cachedArray, GateRef cachedLength, GateRef traceId, Label *miss)
4181 {
4182 auto env = GetEnvironment();
4183 Label subEntry(env);
4184 env->SubCfgEntry(&subEntry);
4185
4186 DEFVARIABLE(bcOffset, VariableType::INT32(), Int32(0));
4187 DEFVARIABLE(elementIndex, VariableType::INT32(),
4188 Int32(static_cast<int32_t>(GlobalEnvField::ELEMENT_HOLE_TAGGED_HCLASS_INDEX)));
4189 DEFVARIABLE(i, VariableType::INT32(), Int32(0));
4190
4191 Label loopHead(env);
4192 Label loopEnd(env);
4193 Label afterLoop(env);
4194 Label matchSuccess(env);
4195 Label afterUpdate(env);
4196 BRANCH(Int32LessThan(*i, cachedLength), &loopHead, miss);
4197 LoopBegin(&loopHead);
4198 bcOffset = GetInt32OfTInt(GetValueFromTaggedArray(glue, cachedArray, *i));
4199 BRANCH(Int32Equal(*bcOffset, traceId), &matchSuccess, &afterUpdate);
4200 Bind(&matchSuccess);
4201 elementIndex = GetInt32OfTInt(GetValueFromTaggedArray(glue, cachedArray, Int32Add(*i, Int32(1))));
4202 Jump(&afterLoop);
4203 Bind(&afterUpdate);
4204 i = Int32Add(*i, Int32(2)); // 2 : skip traceId and elementIndex
4205 BRANCH(Int32LessThan(*i, cachedLength), &loopEnd, miss);
4206 Bind(&loopEnd);
4207 LoopEnd(&loopHead);
4208 Bind(&afterLoop);
4209 auto ret = *elementIndex;
4210
4211 env->SubCfgExit();
4212 return ret;
4213 }
4214
RemoveTaggedWeakTag(GateRef weak)4215 inline GateRef StubBuilder::RemoveTaggedWeakTag(GateRef weak)
4216 {
4217 return Int64ToTaggedPtr(IntPtrAnd(ChangeTaggedPointerToInt64(weak), IntPtr(~JSTaggedValue::TAG_WEAK)));
4218 }
4219
GetAttrIndex(GateRef index)4220 inline GateRef StubBuilder::GetAttrIndex(GateRef index)
4221 {
4222 return Int32Add(Int32LSL(index, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2)), Int32(LayoutInfo::ATTR_INDEX_OFFSET));
4223 }
4224
GetKeyIndex(GateRef index)4225 inline GateRef StubBuilder::GetKeyIndex(GateRef index)
4226 {
4227 return Int32LSL(index, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2));
4228 }
4229
GetAttr(GateRef glue,GateRef layoutInfo,GateRef index)4230 inline GateRef StubBuilder::GetAttr(GateRef glue, GateRef layoutInfo, GateRef index)
4231 {
4232 GateRef fixedIdx = GetAttrIndex(index);
4233 return GetInt64OfTInt(GetValueFromTaggedArray(glue, layoutInfo, fixedIdx));
4234 }
4235
GetKey(GateRef glue,GateRef layoutInfo,GateRef index)4236 inline GateRef StubBuilder::GetKey(GateRef glue, GateRef layoutInfo, GateRef index)
4237 {
4238 GateRef fixedIdx = GetKeyIndex(index);
4239 return GetValueFromTaggedArray(glue, layoutInfo, fixedIdx);
4240 }
4241
IsMarkerCellValid(GateRef cell)4242 inline GateRef StubBuilder::IsMarkerCellValid(GateRef cell)
4243 {
4244 return env_->GetBuilder()->IsMarkerCellValid(cell);
4245 }
4246
GetAccessorHasChanged(GateRef obj)4247 inline GateRef StubBuilder::GetAccessorHasChanged(GateRef obj)
4248 {
4249 return env_->GetBuilder()->GetAccessorHasChanged(obj);
4250 }
4251
ComputeTaggedTypedArraySize(GateRef elementSize,GateRef length)4252 inline GateRef StubBuilder::ComputeTaggedTypedArraySize(GateRef elementSize, GateRef length)
4253 {
4254 return PtrAdd(IntPtr(ByteArray::DATA_OFFSET), PtrMul(elementSize, length));
4255 }
4256
GetAccGetter(GateRef glue,GateRef accesstor)4257 inline GateRef StubBuilder::GetAccGetter(GateRef glue, GateRef accesstor)
4258 {
4259 return Load(VariableType::JS_ANY(), glue, accesstor, IntPtr(AccessorData::GETTER_OFFSET));
4260 }
4261
GetAccSetter(GateRef glue,GateRef accesstor)4262 inline GateRef StubBuilder::GetAccSetter(GateRef glue, GateRef accesstor)
4263 {
4264 return Load(VariableType::JS_ANY(), glue, accesstor, IntPtr(AccessorData::SETTER_OFFSET));
4265 }
4266
GetViewedArrayBuffer(GateRef glue,GateRef dataView)4267 inline GateRef StubBuilder::GetViewedArrayBuffer(GateRef glue, GateRef dataView)
4268 {
4269 return Load(VariableType::JS_ANY(), glue, dataView,
4270 IntPtr(JSDataView::VIEW_ARRAY_BUFFER_OFFSET));
4271 }
4272
GetByteOffset(GateRef dataView)4273 inline GateRef StubBuilder::GetByteOffset(GateRef dataView)
4274 {
4275 return LoadPrimitive(VariableType::INT32(), dataView,
4276 IntPtr(JSDataView::BYTE_OFFSET_OFFSET));
4277 }
4278
GetByteLength(GateRef dataView)4279 inline GateRef StubBuilder::GetByteLength(GateRef dataView)
4280 {
4281 return LoadPrimitive(VariableType::INT32(), dataView,
4282 IntPtr(JSDataView::BYTE_LENGTH_OFFSET));
4283 }
4284
GetArrayBufferData(GateRef glue,GateRef buffer)4285 inline GateRef StubBuilder::GetArrayBufferData(GateRef glue, GateRef buffer)
4286 {
4287 GateRef offset = IntPtr(JSArrayBuffer::DATA_OFFSET);
4288 return Load(VariableType::JS_ANY(), glue, buffer, offset);
4289 }
4290
GetArrayBufferByteLength(GateRef buffer)4291 inline GateRef StubBuilder::GetArrayBufferByteLength(GateRef buffer)
4292 {
4293 GateRef offset = IntPtr(JSArrayBuffer::BYTE_LENGTH_OFFSET);
4294 return LoadPrimitive(VariableType::INT32(), buffer, offset);
4295 }
4296
SetArrayBufferByteLength(GateRef glue,GateRef buffer,GateRef length)4297 inline void StubBuilder::SetArrayBufferByteLength(GateRef glue, GateRef buffer, GateRef length)
4298 {
4299 GateRef offset = IntPtr(JSArrayBuffer::BYTE_LENGTH_OFFSET);
4300 Store(VariableType::INT32(), glue, buffer, offset, length);
4301 }
4302
GetPropertiesCache(GateRef glue)4303 inline GateRef StubBuilder::GetPropertiesCache(GateRef glue)
4304 {
4305 GateRef propertiesCacheOffset = IntPtr(JSThread::GlueData::GetPropertiesCacheOffset(env_->Is32Bit()));
4306 return LoadPrimitive(VariableType::NATIVE_POINTER(), glue, propertiesCacheOffset);
4307 }
4308
GetMegaICCache(GateRef glue,MegaICCache::MegaICKind kind)4309 inline GateRef StubBuilder::GetMegaICCache(GateRef glue, MegaICCache::MegaICKind kind)
4310 {
4311 GateRef megaICCache_Offset;
4312 if (kind == MegaICCache::Load) {
4313 megaICCache_Offset = IntPtr(JSThread::GlueData::GetLoadMegaICCacheOffset(env_->Is32Bit()));
4314 } else {
4315 megaICCache_Offset = IntPtr(JSThread::GlueData::GetStoreMegaICCacheOffset(env_->Is32Bit()));
4316 }
4317 return LoadPrimitive(VariableType::NATIVE_POINTER(), glue, megaICCache_Offset);
4318 }
4319
GetModuleLogger(GateRef glue)4320 inline GateRef StubBuilder::GetModuleLogger(GateRef glue)
4321 {
4322 GateRef moduleLoggerOffset = IntPtr(JSThread::GlueData::GetModuleLoggerOffset(env_->Is32Bit()));
4323 return LoadPrimitive(VariableType::NATIVE_POINTER(), glue, moduleLoggerOffset);
4324 }
4325
GetStageOfHotReload(GateRef glue)4326 inline GateRef StubBuilder::GetStageOfHotReload(GateRef glue)
4327 {
4328 GateRef stageOfColdReloadOffset = IntPtr(JSThread::GlueData::GetStageOfHotReloadOffset(env_->Is32Bit()));
4329 return LoadPrimitive(VariableType::INT32(), glue, stageOfColdReloadOffset);
4330 }
4331
GetModuleManager(GateRef glue)4332 inline GateRef StubBuilder::GetModuleManager(GateRef glue)
4333 {
4334 GateRef globalEnv = GetCurrentGlobalEnv();
4335 GateRef pointer = GetGlobalEnvValue(VariableType::JS_ANY(), glue, globalEnv,
4336 GlobalEnv::MODULE_MANAGER_NATIVE_POINTER_INDEX);
4337 GateRef offset = IntPtr(JSNativePointer::POINTER_OFFSET);
4338 GateRef moduleManager = Load(VariableType::NATIVE_POINTER(), glue, pointer, offset);
4339 return moduleManager;
4340 }
4341
IncMegaProbeCount(GateRef glue)4342 inline void StubBuilder::IncMegaProbeCount([[maybe_unused]]GateRef glue)
4343 {
4344 #if ECMASCRIPT_ENABLE_MEGA_PROFILER
4345 GateRef megaProbeCountOffset = IntPtr(JSThread::GlueData::GetMegaProbesCountOffset(env_->Is32Bit()));
4346 GateRef before = LoadPrimitive(VariableType::INT64(), glue, megaProbeCountOffset);
4347 Store(VariableType::INT64(), glue, glue, megaProbeCountOffset, Int64Add(before, Int64(1)));
4348 #endif
4349 }
IncMegaHitCount(GateRef glue)4350 inline void StubBuilder::IncMegaHitCount([[maybe_unused]]GateRef glue)
4351 {
4352 #if ECMASCRIPT_ENABLE_MEGA_PROFILER
4353 GateRef megaHitCountOffset = IntPtr(JSThread::GlueData::GetMegaHitCountOffset(env_->Is32Bit()));
4354 GateRef before = LoadPrimitive(VariableType::INT64(), glue, megaHitCountOffset);
4355 Store(VariableType::INT64(), glue, glue, megaHitCountOffset, Int64Add(before, Int64(1)));
4356 #endif
4357 }
4358
GetSortedKey(GateRef glue,GateRef layoutInfo,GateRef index)4359 inline GateRef StubBuilder::GetSortedKey(GateRef glue, GateRef layoutInfo, GateRef index)
4360 {
4361 GateRef fixedIdx = GetSortedIndex(glue, layoutInfo, index);
4362 return GetKey(glue, layoutInfo, fixedIdx);
4363 }
4364
GetSortedIndex(GateRef glue,GateRef layoutInfo,GateRef index)4365 inline GateRef StubBuilder::GetSortedIndex(GateRef glue, GateRef layoutInfo, GateRef index)
4366 {
4367 return GetSortedIndex(GetAttr(glue, layoutInfo, index));
4368 }
4369
SetToPropertiesCache(GateRef glue,GateRef cache,GateRef cls,GateRef key,GateRef result,GateRef hir)4370 inline void StubBuilder::SetToPropertiesCache(GateRef glue, GateRef cache, GateRef cls, GateRef key, GateRef result,
4371 GateRef hir)
4372 {
4373 GateRef hash = HashFromHclassAndKey(glue, cls, key, hir);
4374 GateRef prop =
4375 PtrAdd(cache, PtrMul(ZExtInt32ToPtr(hash), IntPtr(PropertiesCache::PropertyKey::GetPropertyKeySize())));
4376 StoreWithoutBarrier(VariableType::JS_POINTER(), prop, IntPtr(PropertiesCache::PropertyKey::GetHclassOffset()), cls);
4377 StoreWithoutBarrier(VariableType::JS_ANY(), prop, IntPtr(PropertiesCache::PropertyKey::GetKeyOffset()), key);
4378 StoreWithoutBarrier(VariableType::INT32(), prop, IntPtr(PropertiesCache::PropertyKey::GetResultsOffset()), result);
4379 }
4380
NeedSkipReadBarrier(GateRef glue)4381 inline GateRef StubBuilder::NeedSkipReadBarrier(GateRef glue)
4382 {
4383 return env_->GetBuilder()->NeedSkipReadBarrier(glue);
4384 }
4385
StoreWithoutBarrier(VariableType type,GateRef base,GateRef offset,GateRef value)4386 inline void StubBuilder::StoreWithoutBarrier(VariableType type, GateRef base, GateRef offset, GateRef value)
4387 {
4388 GateRef addr = PtrAdd(base, offset);
4389 env_->GetBuilder()->StoreWithoutBarrier(type, addr, value);
4390 }
4391
HashFromHclassAndKey(GateRef glue,GateRef cls,GateRef key,GateRef hir)4392 inline GateRef StubBuilder::HashFromHclassAndKey(GateRef glue, GateRef cls, GateRef key, GateRef hir)
4393 {
4394 GateRef clsHash = Int32LSR(ChangeIntPtrToInt32(TaggedCastToIntPtr(cls)), Int32(3)); // skip 8bytes
4395 GateRef keyHash = GetKeyHashCode(glue, key, hir);
4396 return Int32And(Int32Xor(clsHash, keyHash), Int32(PropertiesCache::CACHE_LENGTH_MASK));
4397 }
GetLastLeaveFrame(GateRef glue)4398 inline GateRef StubBuilder::GetLastLeaveFrame(GateRef glue)
4399 {
4400 bool isArch32 = GetEnvironment()->Is32Bit();
4401 GateRef spOffset = IntPtr(JSThread::GlueData::GetLeaveFrameOffset(isArch32));
4402 return LoadPrimitive(VariableType::NATIVE_POINTER(), glue, spOffset);
4403 }
4404
4405 // HashFromHclassAndStringKey only supports String and does not support Symbol. Additionally, it is necessary to ensure
4406 // that the hash value of the String exists.
HashFromHclassAndStringKey(GateRef glue,GateRef cls,GateRef key)4407 inline GateRef StubBuilder::HashFromHclassAndStringKey([[maybe_unused]] GateRef glue, GateRef cls, GateRef key)
4408 {
4409 GateRef hclassRef = TaggedCastToIntPtr(cls);
4410 GateRef clsHash = ChangeIntPtrToInt32(Int64Xor(
4411 hclassRef,
4412 Int64LSR(hclassRef,
4413 Int64(MegaICCache::PRIMARY_LENGTH_BIT)))); // skip 8bytes
4414 GateRef keyHash = Load(VariableType::INT32(), glue, key,
4415 IntPtr(BaseString::MIX_HASHCODE_OFFSET));
4416 GateRef temp = Int32Add(clsHash, keyHash);
4417 return Int32And(temp, Int32(MegaICCache::PRIMARY_LENGTH_MASK));
4418 }
4419
HashSecondaryFromHclassAndStringKey(GateRef glue,GateRef cls,GateRef key)4420 inline GateRef StubBuilder::HashSecondaryFromHclassAndStringKey([[maybe_unused]] GateRef glue, GateRef cls, GateRef key)
4421 {
4422 GateRef clsHash =
4423 ChangeIntPtrToInt32(Int64LSR(TaggedCastToIntPtr(cls), Int64(MegaICCache::HCLASS_SHIFT))); // skip 8bytes
4424 GateRef keyHash = TruncInt64ToInt32(ChangeTaggedPointerToInt64(key));
4425 GateRef addHash = Int32Add(clsHash, keyHash);
4426 GateRef tempHash = Int32Add(addHash, Int32LSR(addHash, Int32(MegaICCache::SECONDARY_LENGTH_BIT)));
4427 return Int32And(tempHash, Int32(MegaICCache::SECONDARY_LENGTH_MASK));
4428 }
4429
OrdinaryNewJSObjectCreate(GateRef glue,GateRef proto)4430 inline GateRef StubBuilder::OrdinaryNewJSObjectCreate(GateRef glue, GateRef proto)
4431 {
4432 return env_->GetBuilder()->OrdinaryNewJSObjectCreate(glue, proto);
4433 }
4434
NewJSPrimitiveRef(GateRef glue,GateRef globalEnv,size_t index,GateRef obj)4435 inline GateRef StubBuilder::NewJSPrimitiveRef(GateRef glue, GateRef globalEnv, size_t index, GateRef obj)
4436 {
4437 return env_->GetBuilder()->NewJSPrimitiveRef(glue, globalEnv, index, obj);
4438 }
4439
ToObject(GateRef glue,GateRef globalEnv,GateRef obj)4440 inline GateRef StubBuilder::ToObject(GateRef glue, GateRef globalEnv, GateRef obj)
4441 {
4442 return env_->GetBuilder()->ToObject(glue, globalEnv, obj);
4443 }
4444
GetPrototype(GateRef glue,GateRef object)4445 inline GateRef StubBuilder::GetPrototype(GateRef glue, GateRef object)
4446 {
4447 return env_->GetBuilder()->GetPrototype(glue, object);
4448 }
4449
GetLengthOfJSArray(GateRef array)4450 inline GateRef StubBuilder::GetLengthOfJSArray(GateRef array)
4451 {
4452 return env_->GetBuilder()->GetLengthOfJSArray(array);
4453 }
4454
ResolvedModuleMustBeSourceTextModule(GateRef glue,GateRef resolvedModule)4455 inline void StubBuilder::ResolvedModuleMustBeSourceTextModule([[maybe_unused]] GateRef glue,
4456 [[maybe_unused]] GateRef resolvedModule)
4457 {
4458 ASM_ASSERT(GET_MESSAGE_STRING_ID(CurrentModuleNotSourceTextModule), IsSourceTextModule(glue, resolvedModule));
4459 }
4460
ModuleEnvMustBeDefined(GateRef curEnv)4461 inline void StubBuilder::ModuleEnvMustBeDefined([[maybe_unused]] GateRef curEnv)
4462 {
4463 ASM_ASSERT(GET_MESSAGE_STRING_ID(ModuleEnvMustBeDefined), BoolNot(TaggedIsUndefined(curEnv)));
4464 }
4465
CheckIsResolvedIndexBinding(GateRef glue,GateRef resolution)4466 inline void StubBuilder::CheckIsResolvedIndexBinding([[maybe_unused]] GateRef glue, [[maybe_unused]] GateRef resolution)
4467 {
4468 ASM_ASSERT(GET_MESSAGE_STRING_ID(CheckIsResolvedIndexBinding), IsResolvedIndexBinding(glue, resolution));
4469 }
4470
RecordNameMustBeString(GateRef glue,GateRef recordName)4471 inline void StubBuilder::RecordNameMustBeString([[maybe_unused]] GateRef glue, [[maybe_unused]] GateRef recordName)
4472 {
4473 ASM_ASSERT(GET_MESSAGE_STRING_ID(RecordNameMustBeString), TaggedIsString(glue, recordName));
4474 }
4475
GetNameDictionary(GateRef glue,GateRef module)4476 inline GateRef StubBuilder::GetNameDictionary(GateRef glue, GateRef module)
4477 {
4478 GateRef nameDictionaryOffset = IntPtr(SourceTextModule::NAME_DICTIONARY_OFFSET);
4479 return Load(VariableType::JS_ANY(), glue, module, nameDictionaryOffset);
4480 }
4481
GetCurrentModuleEnv(GateRef glue,GateRef curModule)4482 inline GateRef StubBuilder::GetCurrentModuleEnv(GateRef glue, GateRef curModule)
4483 {
4484 GateRef sourceTextModuleOffset = IntPtr(SourceTextModule::SOURCE_TEXT_MODULE_OFFSET);
4485 return Load(VariableType::JS_ANY(), glue, curModule, sourceTextModuleOffset);
4486 }
4487
GetBitFieldFromSourceTextModule(GateRef curModule)4488 inline GateRef StubBuilder::GetBitFieldFromSourceTextModule(GateRef curModule)
4489 {
4490 GateRef bitFieldOffset = IntPtr(SourceTextModule::BIT_FIELD_OFFSET);
4491 return LoadPrimitive(VariableType::INT32(), curModule, bitFieldOffset);
4492 }
4493
GetRequestedModules(GateRef glue,GateRef module)4494 inline GateRef StubBuilder::GetRequestedModules(GateRef glue, GateRef module)
4495 {
4496 GateRef requestedModulesOffset = IntPtr(SourceTextModule::REQUESTED_MODULES_OFFSET);
4497 return Load(VariableType::JS_ANY(), glue, module, requestedModulesOffset);
4498 }
4499
GetNamespaceFromSourceTextModule(GateRef glue,GateRef module)4500 inline GateRef StubBuilder::GetNamespaceFromSourceTextModule(GateRef glue, GateRef module)
4501 {
4502 GateRef namespaceOffset = IntPtr(SourceTextModule::NAMESPACE_OFFSET);
4503 GateRef moduleNamespace = Load(VariableType::JS_ANY(), glue, module, namespaceOffset);
4504 return RemoveTaggedWeakTag(moduleNamespace);
4505 }
4506
GetResolveModuleFromResolvedIndexBinding(GateRef glue,GateRef resolvedBinding)4507 inline GateRef StubBuilder::GetResolveModuleFromResolvedIndexBinding(GateRef glue, GateRef resolvedBinding)
4508 {
4509 GateRef moduleOffset = IntPtr(ResolvedIndexBinding::MODULE_OFFSET);
4510 return Load(VariableType::JS_ANY(), glue, resolvedBinding, moduleOffset);
4511 }
4512
GetResolveModuleFromResolvedBinding(GateRef glue,GateRef resolvedBinding)4513 inline GateRef StubBuilder::GetResolveModuleFromResolvedBinding(GateRef glue, GateRef resolvedBinding)
4514 {
4515 GateRef moduleOffset = IntPtr(ResolvedBinding::MODULE_OFFSET);
4516 return Load(VariableType::JS_ANY(), glue, resolvedBinding, moduleOffset);
4517 }
4518
GetIdxOfResolvedIndexBinding(GateRef resolvedBinding)4519 inline GateRef StubBuilder::GetIdxOfResolvedIndexBinding(GateRef resolvedBinding)
4520 {
4521 GateRef indexOffset = IntPtr(ResolvedIndexBinding::INDEX_OFFSET);
4522 return LoadPrimitive(VariableType::INT32(), resolvedBinding, indexOffset);
4523 }
4524
SetIsUpdatedFromResolvedBindingOfResolvedIndexBinding(GateRef glue,GateRef resolvedBinding,GateRef value)4525 inline void StubBuilder::SetIsUpdatedFromResolvedBindingOfResolvedIndexBinding(GateRef glue,
4526 GateRef resolvedBinding, GateRef value)
4527 {
4528 GateRef bitFieldOffset = IntPtr(ResolvedIndexBinding::BIT_FIELD_OFFSET);
4529 GateRef oldVal = LoadPrimitive(VariableType::INT32(), resolvedBinding, bitFieldOffset);
4530 GateRef mask = Int32LSL(
4531 Int32((1LU << ResolvedIndexBinding::IsUpdatedFromResolvedBindingBits::SIZE) - 1),
4532 Int32(ResolvedIndexBinding::IsUpdatedFromResolvedBindingBits::START_BIT));
4533 GateRef newVal = Int32Or(Int32And(oldVal, Int32Not(mask)), Int32LSL(ZExtInt1ToInt32(value),
4534 Int32(ResolvedIndexBinding::IsUpdatedFromResolvedBindingBits::START_BIT)));
4535 Store(VariableType::INT32(), glue, resolvedBinding, bitFieldOffset, newVal);
4536 }
4537
GetIdxOfResolvedRecordIndexBinding(GateRef resolvedBinding)4538 inline GateRef StubBuilder::GetIdxOfResolvedRecordIndexBinding(GateRef resolvedBinding)
4539 {
4540 GateRef indexOffset = IntPtr(ResolvedRecordIndexBinding::INDEX_OFFSET);
4541 return LoadPrimitive(VariableType::INT32(), resolvedBinding, indexOffset);
4542 }
4543
GetModuleRecord(GateRef glue,GateRef resolvedBinding)4544 inline GateRef StubBuilder::GetModuleRecord(GateRef glue, GateRef resolvedBinding)
4545 {
4546 GateRef moduleRecordIdxOffset = IntPtr(ResolvedRecordIndexBinding::MODULE_RECORD_INDEX_OFFSET);
4547 return Load(VariableType::JS_ANY(), glue, resolvedBinding, moduleRecordIdxOffset);
4548 }
4549
GetBindingName(GateRef glue,GateRef resolvedBinding)4550 inline GateRef StubBuilder::GetBindingName(GateRef glue, GateRef resolvedBinding)
4551 {
4552 GateRef bindingNameOffset = IntPtr(ResolvedRecordBinding::BINDING_NAME_OFFSET);
4553 return Load(VariableType::JS_ANY(), glue, resolvedBinding, bindingNameOffset);
4554 }
4555
IsResolvedIndexBinding(GateRef glue,GateRef resolvedBinding)4556 inline GateRef StubBuilder::IsResolvedIndexBinding(GateRef glue, GateRef resolvedBinding)
4557 {
4558 GateRef objectType = GetObjectType(LoadHClass(glue, resolvedBinding));
4559 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::RESOLVEDINDEXBINDING_RECORD)));
4560 }
4561
IsResolvedBinding(GateRef glue,GateRef resolvedBinding)4562 inline GateRef StubBuilder::IsResolvedBinding(GateRef glue, GateRef resolvedBinding)
4563 {
4564 GateRef objectType = GetObjectType(LoadHClass(glue, resolvedBinding));
4565 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::RESOLVEDBINDING_RECORD)));
4566 }
4567
IsResolvedRecordIndexBinding(GateRef glue,GateRef resolvedBinding)4568 inline GateRef StubBuilder::IsResolvedRecordIndexBinding(GateRef glue, GateRef resolvedBinding)
4569 {
4570 GateRef objectType = GetObjectType(LoadHClass(glue, resolvedBinding));
4571 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::RESOLVEDRECORDINDEXBINDING_RECORD)));
4572 }
4573
IsResolvedRecordBinding(GateRef glue,GateRef resolvedBinding)4574 inline GateRef StubBuilder::IsResolvedRecordBinding(GateRef glue, GateRef resolvedBinding)
4575 {
4576 GateRef objectType = GetObjectType(LoadHClass(glue, resolvedBinding));
4577 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::RESOLVEDRECORDBINDING_RECORD)));
4578 }
4579
IsLdEndExecPatchMain(GateRef glue)4580 inline GateRef StubBuilder::IsLdEndExecPatchMain(GateRef glue)
4581 {
4582 return Int32Equal(GetStageOfHotReload(glue),
4583 Int32(static_cast<int>(StageOfHotReload::LOAD_END_EXECUTE_PATCHMAIN)));
4584 }
4585
GetModuleType(GateRef module)4586 inline GateRef StubBuilder::GetModuleType(GateRef module)
4587 {
4588 GateRef bitfield = GetBitFieldFromSourceTextModule(module);
4589 return Int32And(Int32LSR(bitfield, Int32(SourceTextModule::STATUS_BITS)),
4590 Int32((1LU << SourceTextModule::MODULE_TYPE_BITS) - 1));
4591 }
4592
IsNativeModule(GateRef module)4593 inline GateRef StubBuilder::IsNativeModule(GateRef module)
4594 {
4595 GateRef moduleType = GetModuleType(module);
4596 return LogicOrBuilder(env_)
4597 .Or(Int32Equal(moduleType, Int32(static_cast<int>(ModuleTypes::OHOS_MODULE))))
4598 .Or(Int32Equal(moduleType, Int32(static_cast<int>(ModuleTypes::APP_MODULE))))
4599 .Or(Int32Equal(moduleType, Int32(static_cast<int>(ModuleTypes::NATIVE_MODULE))))
4600 .Or(Int32Equal(moduleType, Int32(static_cast<int>(ModuleTypes::INTERNAL_MODULE))))
4601 .Done();
4602 }
4603
IsCjsModule(GateRef module)4604 inline GateRef StubBuilder::IsCjsModule(GateRef module)
4605 {
4606 GateRef moduleType = GetModuleType(module);
4607 return Int32Equal(moduleType, Int32(static_cast<int>(ModuleTypes::CJS_MODULE)));
4608 }
4609
GetSharedType(GateRef module)4610 inline GateRef StubBuilder::GetSharedType(GateRef module)
4611 {
4612 GateRef bitfield = GetBitFieldFromSourceTextModule(module);
4613 return Int32And(Int32LSR(bitfield, Int32(SourceTextModule::SHARED_TYPES_SHIFT)),
4614 Int32((1LU << SourceTextModule::IS_SHARED_TYPE_BITS) - 1));
4615 }
4616
IsSharedModule(GateRef module)4617 inline GateRef StubBuilder::IsSharedModule(GateRef module)
4618 {
4619 GateRef sharedType = GetSharedType(module);
4620 return Int32Equal(sharedType, Int32(static_cast<int>(SharedTypes::SHARED_MODULE)));
4621 }
4622
GetCjsModuleFunction(GateRef glue)4623 inline GateRef StubBuilder::GetCjsModuleFunction(GateRef glue)
4624 {
4625 GateRef globalEnv = GetCurrentGlobalEnv();
4626 return GetGlobalEnvValue(VariableType::JS_ANY(), glue, globalEnv, GlobalEnv::CJS_MODULE_FUNCTION_INDEX);
4627 }
4628
GetArrayElementsGuardians(GateRef env)4629 inline GateRef StubBuilder::GetArrayElementsGuardians(GateRef env)
4630 {
4631 GateRef offset = IntPtr(GlobalEnv::BIT_FIELD_OFFSET);
4632 GateRef bitfield = LoadPrimitive(VariableType::INT32(), env, offset);
4633 return TruncInt32ToInt1(Int32And(Int32LSR(bitfield,
4634 Int32(GlobalEnv::ArrayPrototypeChangedGuardiansBits::START_BIT)),
4635 Int32((1LU << GlobalEnv::ArrayPrototypeChangedGuardiansBits::SIZE) - 1)));
4636 }
4637
SetArrayElementsGuardians(GateRef glue,GateRef env,GateRef value)4638 inline void StubBuilder::SetArrayElementsGuardians(GateRef glue, GateRef env, GateRef value)
4639 {
4640 GateRef oldValue = ZExtInt1ToInt32(value);
4641 GateRef offset = IntPtr(GlobalEnv::BIT_FIELD_OFFSET);
4642 GateRef bitfield = LoadPrimitive(VariableType::INT32(), env, offset);
4643 GateRef mask = Int32LSL(
4644 Int32((1LU <<GlobalEnv::ArrayPrototypeChangedGuardiansBits::SIZE) - 1),
4645 Int32(GlobalEnv::ArrayPrototypeChangedGuardiansBits::START_BIT));
4646 GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
4647 Int32LSL(oldValue, Int32(GlobalEnv::ArrayPrototypeChangedGuardiansBits::START_BIT)));
4648 Store(VariableType::INT32(), glue, env, offset, newVal);
4649 }
4650
GetTypedArraySpeciesProtectDetector(GateRef env)4651 inline GateRef StubBuilder::GetTypedArraySpeciesProtectDetector(GateRef env)
4652 {
4653 return env_->GetBuilder()->GetTypedArraySpeciesProtectDetector(env);
4654 }
4655
GetArrayIteratorDetector(GateRef env)4656 inline GateRef StubBuilder::GetArrayIteratorDetector(GateRef env)
4657 {
4658 return env_->GetBuilder()->GetArrayIteratorDetector(env);
4659 }
4660
GetMapIteratorDetector(GateRef env)4661 inline GateRef StubBuilder::GetMapIteratorDetector(GateRef env)
4662 {
4663 return env_->GetBuilder()->GetMapIteratorDetector(env);
4664 }
4665
GetSetIteratorDetector(GateRef env)4666 inline GateRef StubBuilder::GetSetIteratorDetector(GateRef env)
4667 {
4668 return env_->GetBuilder()->GetSetIteratorDetector(env);
4669 }
4670 } // namespace panda::ecmascript::kungfu
4671 #endif // ECMASCRIPT_COMPILER_STUB_INL_H
4672