• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &notProfileTypeInfoCell0);
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(&notProfileTypeInfoCell0);
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