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