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