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