• 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/stub_builder.h"
20 
21 #include "ecmascript/accessor_data.h"
22 #include "ecmascript/base/number_helper.h"
23 #include "ecmascript/compiler/assembler_module.h"
24 #include "ecmascript/compiler/bc_call_signature.h"
25 #include "ecmascript/global_dictionary.h"
26 #include "ecmascript/global_env.h"
27 #include "ecmascript/global_env_constants.h"
28 #include "ecmascript/ic/ic_handler.h"
29 #include "ecmascript/ic/proto_change_details.h"
30 #include "ecmascript/js_array.h"
31 #include "ecmascript/js_function.h"
32 #include "ecmascript/js_generator_object.h"
33 #include "ecmascript/js_object.h"
34 #include "ecmascript/js_tagged_value.h"
35 #include "ecmascript/layout_info.h"
36 #include "ecmascript/message_string.h"
37 #include "ecmascript/mem/slots.h"
38 #include "ecmascript/mem/visitor.h"
39 
40 namespace panda::ecmascript::kungfu {
41 using JSFunction = panda::ecmascript::JSFunction;
42 using PropertyBox = panda::ecmascript::PropertyBox;
43 
Int8(int8_t value)44 inline GateRef StubBuilder::Int8(int8_t value)
45 {
46     return env_->GetBuilder()->Int8(value);
47 }
48 
Int16(int16_t value)49 inline GateRef StubBuilder::Int16(int16_t value)
50 {
51     return env_->GetBuilder()->Int16(value);
52 }
53 
Int32(int32_t value)54 inline GateRef StubBuilder::Int32(int32_t value)
55 {
56     return env_->GetBuilder()->Int32(value);
57 };
58 
Int64(int64_t value)59 inline GateRef StubBuilder::Int64(int64_t value)
60 {
61     return env_->GetBuilder()->Int64(value);
62 }
63 
IntPtr(int64_t value)64 inline GateRef StubBuilder::IntPtr(int64_t value)
65 {
66     return env_->Is32Bit() ? Int32(value) : Int64(value);
67 };
68 
IntPtrSize()69 inline GateRef StubBuilder::IntPtrSize()
70 {
71     return env_->Is32Bit() ? Int32(sizeof(uint32_t)) : Int64(sizeof(uint64_t));
72 }
73 
True()74 inline GateRef StubBuilder::True()
75 {
76     return TruncInt32ToInt1(Int32(1));
77 }
78 
False()79 inline GateRef StubBuilder::False()
80 {
81     return TruncInt32ToInt1(Int32(0));
82 }
83 
Boolean(bool value)84 inline GateRef StubBuilder::Boolean(bool value)
85 {
86     return env_->GetBuilder()->Boolean(value);
87 }
88 
Double(double value)89 inline GateRef StubBuilder::Double(double value)
90 {
91     return env_->GetBuilder()->Double(value);
92 }
93 
Undefined()94 inline GateRef StubBuilder::Undefined()
95 {
96     return env_->GetBuilder()->UndefineConstant();
97 }
98 
Hole()99 inline GateRef StubBuilder::Hole()
100 {
101     return env_->GetBuilder()->HoleConstant();
102 }
103 
Null()104 inline GateRef StubBuilder::Null()
105 {
106     return env_->GetBuilder()->NullConstant();
107 }
108 
Exception()109 inline GateRef StubBuilder::Exception()
110 {
111     return env_->GetBuilder()->ExceptionConstant();
112 }
113 
RelocatableData(uint64_t value)114 inline GateRef StubBuilder::RelocatableData(uint64_t value)
115 {
116     return env_->GetBuilder()->RelocatableData(value);
117 }
118 
119 // parameter
Argument(size_t index)120 inline GateRef StubBuilder::Argument(size_t index)
121 {
122     return env_->GetArgument(index);
123 }
124 
Int1Argument(size_t index)125 inline GateRef StubBuilder::Int1Argument(size_t index)
126 {
127     return Argument(index);
128 }
129 
Int32Argument(size_t index)130 inline GateRef StubBuilder::Int32Argument(size_t index)
131 {
132     return Argument(index);
133 }
134 
Int64Argument(size_t index)135 inline GateRef StubBuilder::Int64Argument(size_t index)
136 {
137     return Argument(index);
138 }
139 
TaggedArgument(size_t index)140 inline GateRef StubBuilder::TaggedArgument(size_t index)
141 {
142     return Argument(index);
143 }
144 
TaggedPointerArgument(size_t index)145 inline GateRef StubBuilder::TaggedPointerArgument(size_t index)
146 {
147     return Argument(index);
148 }
149 
PtrArgument(size_t index)150 inline GateRef StubBuilder::PtrArgument(size_t index)
151 {
152     return Argument(index);
153 }
154 
Float32Argument(size_t index)155 inline GateRef StubBuilder::Float32Argument(size_t index)
156 {
157     return Argument(index);
158 }
159 
Float64Argument(size_t index)160 inline GateRef StubBuilder::Float64Argument(size_t index)
161 {
162     return Argument(index);
163 }
164 
Alloca(int size)165 inline GateRef StubBuilder::Alloca(int size)
166 {
167     return env_->GetBuilder()->Alloca(size);
168 }
169 
Return(GateRef value)170 inline GateRef StubBuilder::Return(GateRef value)
171 {
172     auto control = env_->GetCurrentLabel()->GetControl();
173     auto depend = env_->GetCurrentLabel()->GetDepend();
174     return env_->GetBuilder()->Return(control, depend, value);
175 }
176 
Return()177 inline GateRef StubBuilder::Return()
178 {
179     auto control = env_->GetCurrentLabel()->GetControl();
180     auto depend = env_->GetCurrentLabel()->GetDepend();
181     return env_->GetBuilder()->ReturnVoid(control, depend);
182 }
183 
Bind(Label * label)184 inline void StubBuilder::Bind(Label *label)
185 {
186     env_->GetBuilder()->Bind(label);
187 }
188 
CallRuntime(GateRef glue,int index,const std::initializer_list<GateRef> & args)189 inline GateRef StubBuilder::CallRuntime(GateRef glue, int index, const std::initializer_list<GateRef>& args)
190 {
191     SavePcIfNeeded(glue);
192     GateRef result = env_->GetBuilder()->CallRuntime(glue, index, Gate::InvalidGateRef, args);
193     return result;
194 }
195 
CallRuntime(GateRef glue,int index,GateRef argc,GateRef argv)196 inline GateRef StubBuilder::CallRuntime(GateRef glue, int index, GateRef argc, GateRef argv)
197 {
198     SavePcIfNeeded(glue);
199     GateRef result = env_->GetBuilder()->CallRuntimeVarargs(glue, index, argc, argv);
200     return result;
201 }
202 
CallNGCRuntime(GateRef glue,int index,const std::initializer_list<GateRef> & args)203 inline GateRef StubBuilder::CallNGCRuntime(GateRef glue, int index, const std::initializer_list<GateRef>& args)
204 {
205     GateRef result = env_->GetBuilder()->CallNGCRuntime(glue, index, Gate::InvalidGateRef, args);
206     return result;
207 }
208 
CallStub(GateRef glue,int index,const std::initializer_list<GateRef> & args)209 inline GateRef StubBuilder::CallStub(GateRef glue, int index, const std::initializer_list<GateRef>& args)
210 {
211     SavePcIfNeeded(glue);
212     GateRef result = env_->GetBuilder()->CallStub(glue, index, args);
213     return result;
214 }
215 
CallBuiltinRuntime(GateRef glue,const std::initializer_list<GateRef> & args,bool isNew)216 inline GateRef StubBuilder::CallBuiltinRuntime(GateRef glue, const std::initializer_list<GateRef>& args, bool isNew)
217 {
218     GateRef result = env_->GetBuilder()->CallBuiltinRuntime(glue, Gate::InvalidGateRef, args, isNew);
219     return result;
220 }
221 
DebugPrint(GateRef glue,std::initializer_list<GateRef> args)222 inline void StubBuilder::DebugPrint(GateRef glue, std::initializer_list<GateRef> args)
223 {
224     CallNGCRuntime(glue, RTSTUB_ID(DebugPrint), args);
225 }
226 
FatalPrint(GateRef glue,std::initializer_list<GateRef> args)227 inline void StubBuilder::FatalPrint(GateRef glue, std::initializer_list<GateRef> args)
228 {
229     CallNGCRuntime(glue, RTSTUB_ID(FatalPrint), args);
230 }
231 
SavePcIfNeeded(GateRef glue)232 void StubBuilder::SavePcIfNeeded(GateRef glue)
233 {
234     if (env_->IsAsmInterp()) {
235         GateRef sp = Argument(static_cast<size_t>(InterpreterHandlerInputs::SP));
236         GateRef pc = Argument(static_cast<size_t>(InterpreterHandlerInputs::PC));
237         GateRef frame = PtrSub(sp,
238             IntPtr(AsmInterpretedFrame::GetSize(GetEnvironment()->IsArch32Bit())));
239         Store(VariableType::INT64(), glue, frame,
240             IntPtr(AsmInterpretedFrame::GetPcOffset(GetEnvironment()->IsArch32Bit())), pc);
241     }
242 }
243 
SaveJumpSizeIfNeeded(GateRef glue,GateRef jumpSize)244 void StubBuilder::SaveJumpSizeIfNeeded(GateRef glue, GateRef jumpSize)
245 {
246     if (env_->IsAsmInterp()) {
247         GateRef sp = Argument(static_cast<size_t>(InterpreterHandlerInputs::SP));
248         GateRef frame = PtrSub(sp,
249             IntPtr(AsmInterpretedFrame::GetSize(GetEnvironment()->IsArch32Bit())));
250         Store(VariableType::INT64(), glue, frame,
251             IntPtr(AsmInterpretedFrame::GetCallSizeOffset(GetEnvironment()->IsArch32Bit())), jumpSize);
252     }
253 }
254 
SetHotnessCounter(GateRef glue,GateRef method,GateRef value)255 void StubBuilder::SetHotnessCounter(GateRef glue, GateRef method, GateRef value)
256 {
257     auto env = GetEnvironment();
258     GateRef newValue = env->GetBuilder()->TruncInt64ToInt16(value);
259     Store(VariableType::INT16(), glue, method, IntPtr(Method::LITERAL_INFO_OFFSET), newValue);
260 }
261 
SaveHotnessCounterIfNeeded(GateRef glue,GateRef sp,GateRef hotnessCounter,JSCallMode mode)262 void StubBuilder::SaveHotnessCounterIfNeeded(GateRef glue, GateRef sp, GateRef hotnessCounter, JSCallMode mode)
263 {
264     if (env_->IsAsmInterp() && kungfu::AssemblerModule::IsJumpToCallCommonEntry(mode)) {
265         ASSERT(hotnessCounter != Circuit::NullGate());
266         GateRef frame = PtrSub(sp, IntPtr(AsmInterpretedFrame::GetSize(env_->IsArch32Bit())));
267         GateRef function = Load(VariableType::JS_POINTER(), frame,
268             IntPtr(AsmInterpretedFrame::GetFunctionOffset(env_->IsArch32Bit())));
269         GateRef method = Load(VariableType::JS_ANY(), function, IntPtr(JSFunctionBase::METHOD_OFFSET));
270         SetHotnessCounter(glue, method, hotnessCounter);
271     }
272 }
273 
274 // memory
Load(VariableType type,GateRef base,GateRef offset)275 inline GateRef StubBuilder::Load(VariableType type, GateRef base, GateRef offset)
276 {
277     if (type == VariableType::NATIVE_POINTER()) {
278         type = env_->IsArch64Bit() ? VariableType::INT64() : VariableType::INT32();
279     }
280     return env_->GetBuilder()->Load(type, base, offset);
281 }
282 
Load(VariableType type,GateRef base)283 inline GateRef StubBuilder::Load(VariableType type, GateRef base)
284 {
285     return Load(type, base, IntPtr(0));
286 }
287 
288 // arithmetic
Int16Add(GateRef x,GateRef y)289 inline GateRef StubBuilder::Int16Add(GateRef x, GateRef y)
290 {
291     return env_->GetBuilder()->Int16Add(x, y);
292 }
293 
Int32Add(GateRef x,GateRef y)294 inline GateRef StubBuilder::Int32Add(GateRef x, GateRef y)
295 {
296     return env_->GetBuilder()->Int32Add(x, y);
297 }
298 
Int64Add(GateRef x,GateRef y)299 inline GateRef StubBuilder::Int64Add(GateRef x, GateRef y)
300 {
301     return env_->GetBuilder()->Int64Add(x, y);
302 }
303 
DoubleAdd(GateRef x,GateRef y)304 inline GateRef StubBuilder::DoubleAdd(GateRef x, GateRef y)
305 {
306     return env_->GetBuilder()->DoubleAdd(x, y);
307 }
308 
PtrMul(GateRef x,GateRef y)309 inline GateRef StubBuilder::PtrMul(GateRef x, GateRef y)
310 {
311     return env_->GetBuilder()->PtrMul(x, y);
312 }
313 
PtrAdd(GateRef x,GateRef y)314 inline GateRef StubBuilder::PtrAdd(GateRef x, GateRef y)
315 {
316     return env_->GetBuilder()->PtrAdd(x, y);
317 }
318 
PtrSub(GateRef x,GateRef y)319 inline GateRef StubBuilder::PtrSub(GateRef x, GateRef y)
320 {
321     return env_->GetBuilder()->PtrSub(x, y);
322 }
323 
IntPtrAnd(GateRef x,GateRef y)324 inline GateRef StubBuilder::IntPtrAnd(GateRef x, GateRef y)
325 {
326     return env_->Is32Bit() ? Int32And(x, y) : Int64And(x, y);
327 }
328 
IntPtrEqual(GateRef x,GateRef y)329 inline GateRef StubBuilder::IntPtrEqual(GateRef x, GateRef y)
330 {
331     if (env_->Is32Bit()) {
332         return Int32Equal(x, y);
333     }
334     return Int64Equal(x, y);
335 }
336 
Int16Sub(GateRef x,GateRef y)337 inline GateRef StubBuilder::Int16Sub(GateRef x, GateRef y)
338 {
339     return env_->GetBuilder()->Int16Sub(x, y);
340 }
341 
Int32Sub(GateRef x,GateRef y)342 inline GateRef StubBuilder::Int32Sub(GateRef x, GateRef y)
343 {
344     return env_->GetBuilder()->Int32Sub(x, y);
345 }
346 
Int64Sub(GateRef x,GateRef y)347 inline GateRef StubBuilder::Int64Sub(GateRef x, GateRef y)
348 {
349     return env_->GetBuilder()->Int64Sub(x, y);
350 }
351 
DoubleSub(GateRef x,GateRef y)352 inline GateRef StubBuilder::DoubleSub(GateRef x, GateRef y)
353 {
354     return env_->GetBuilder()->DoubleSub(x, y);
355 }
356 
Int32Mul(GateRef x,GateRef y)357 inline GateRef StubBuilder::Int32Mul(GateRef x, GateRef y)
358 {
359     return env_->GetBuilder()->Int32Mul(x, y);
360 }
361 
Int64Mul(GateRef x,GateRef y)362 inline GateRef StubBuilder::Int64Mul(GateRef x, GateRef y)
363 {
364     return env_->GetBuilder()->Int64Mul(x, y);
365 }
366 
DoubleMul(GateRef x,GateRef y)367 inline GateRef StubBuilder::DoubleMul(GateRef x, GateRef y)
368 {
369     return env_->GetBuilder()->DoubleMul(x, y);
370 }
371 
DoubleDiv(GateRef x,GateRef y)372 inline GateRef StubBuilder::DoubleDiv(GateRef x, GateRef y)
373 {
374     return env_->GetBuilder()->DoubleDiv(x, y);
375 }
376 
Int32Div(GateRef x,GateRef y)377 inline GateRef StubBuilder::Int32Div(GateRef x, GateRef y)
378 {
379     return env_->GetBuilder()->Int32Div(x, y);
380 }
381 
Int64Div(GateRef x,GateRef y)382 inline GateRef StubBuilder::Int64Div(GateRef x, GateRef y)
383 {
384     return env_->GetBuilder()->Int64Div(x, y);
385 }
386 
IntPtrDiv(GateRef x,GateRef y)387 inline GateRef StubBuilder::IntPtrDiv(GateRef x, GateRef y)
388 {
389     return env_->GetBuilder()->IntPtrDiv(x, y);
390 }
391 
Int32Mod(GateRef x,GateRef y)392 inline GateRef StubBuilder::Int32Mod(GateRef x, GateRef y)
393 {
394     return env_->GetBuilder()->Int32Mod(x, y);
395 }
396 
DoubleMod(GateRef x,GateRef y)397 inline GateRef StubBuilder::DoubleMod(GateRef x, GateRef y)
398 {
399     return env_->GetBuilder()->DoubleMod(x, y);
400 }
401 
402 // bit operation
Int32Or(GateRef x,GateRef y)403 inline GateRef StubBuilder::Int32Or(GateRef x, GateRef y)
404 {
405     return env_->GetBuilder()->Int32Or(x, y);
406 }
407 
Int8And(GateRef x,GateRef y)408 inline GateRef StubBuilder::Int8And(GateRef x, GateRef y)
409 {
410     return env_->GetBuilder()->Int8And(x, y);
411 }
412 
Int32And(GateRef x,GateRef y)413 inline GateRef StubBuilder::Int32And(GateRef x, GateRef y)
414 {
415     return env_->GetBuilder()->Int32And(x, y);
416 }
417 
BoolAnd(GateRef x,GateRef y)418 inline GateRef StubBuilder::BoolAnd(GateRef x, GateRef y)
419 {
420     return env_->GetBuilder()->BoolAnd(x, y);
421 }
422 
BoolOr(GateRef x,GateRef y)423 inline GateRef StubBuilder::BoolOr(GateRef x, GateRef y)
424 {
425     return env_->GetBuilder()->BoolOr(x, y);
426 }
427 
Int32Not(GateRef x)428 inline GateRef StubBuilder::Int32Not(GateRef x)
429 {
430     return env_->GetBuilder()->Int32Not(x);
431 }
432 
IntPtrNot(GateRef x)433 inline GateRef StubBuilder::IntPtrNot(GateRef x)
434 {
435     return env_->Is32Bit() ? Int32Not(x) : Int64Not(x);
436 }
437 
BoolNot(GateRef x)438 inline GateRef StubBuilder::BoolNot(GateRef x)
439 {
440     return env_->GetBuilder()->BoolNot(x);
441 }
442 
Int64Or(GateRef x,GateRef y)443 inline GateRef StubBuilder::Int64Or(GateRef x, GateRef y)
444 {
445     return env_->GetBuilder()->Int64Or(x, y);
446 }
447 
IntPtrOr(GateRef x,GateRef y)448 inline GateRef StubBuilder::IntPtrOr(GateRef x, GateRef y)
449 {
450     return env_->GetBuilder()->IntPtrOr(x, y);
451 }
452 
Int64And(GateRef x,GateRef y)453 inline GateRef StubBuilder::Int64And(GateRef x, GateRef y)
454 {
455     return env_->GetBuilder()->Int64And(x, y);
456 }
457 
Int16LSL(GateRef x,GateRef y)458 inline GateRef StubBuilder::Int16LSL(GateRef x, GateRef y)
459 {
460     return env_->GetBuilder()->Int16LSL(x, y);
461 }
462 
Int64Xor(GateRef x,GateRef y)463 inline GateRef StubBuilder::Int64Xor(GateRef x, GateRef y)
464 {
465     return env_->GetBuilder()->Int64Xor(x, y);
466 }
467 
Int32Xor(GateRef x,GateRef y)468 inline GateRef StubBuilder::Int32Xor(GateRef x, GateRef y)
469 {
470     return env_->GetBuilder()->Int32Xor(x, y);
471 }
472 
Int8LSR(GateRef x,GateRef y)473 inline GateRef StubBuilder::Int8LSR(GateRef x, GateRef y)
474 {
475     return env_->GetBuilder()->Int8LSR(x, y);
476 }
477 
Int64Not(GateRef x)478 inline GateRef StubBuilder::Int64Not(GateRef x)
479 {
480     return env_->GetBuilder()->Int64Not(x);
481 }
482 
Int32LSL(GateRef x,GateRef y)483 inline GateRef StubBuilder::Int32LSL(GateRef x, GateRef y)
484 {
485     return env_->GetBuilder()->Int32LSL(x, y);
486 }
487 
Int64LSL(GateRef x,GateRef y)488 inline GateRef StubBuilder::Int64LSL(GateRef x, GateRef y)
489 {
490     return env_->GetBuilder()->Int64LSL(x, y);
491 }
492 
IntPtrLSL(GateRef x,GateRef y)493 inline GateRef StubBuilder::IntPtrLSL(GateRef x, GateRef y)
494 {
495     return env_->GetBuilder()->IntPtrLSL(x, y);
496 }
497 
Int32ASR(GateRef x,GateRef y)498 inline GateRef StubBuilder::Int32ASR(GateRef x, GateRef y)
499 {
500     return env_->GetBuilder()->Int32ASR(x, y);
501 }
502 
Int32LSR(GateRef x,GateRef y)503 inline GateRef StubBuilder::Int32LSR(GateRef x, GateRef y)
504 {
505     return env_->GetBuilder()->Int32LSR(x, y);
506 }
507 
Int64LSR(GateRef x,GateRef y)508 inline GateRef StubBuilder::Int64LSR(GateRef x, GateRef y)
509 {
510     return env_->GetBuilder()->Int64LSR(x, y);
511 }
512 
IntPtrLSR(GateRef x,GateRef y)513 inline GateRef StubBuilder::IntPtrLSR(GateRef x, GateRef y)
514 {
515     return env_->GetBuilder()->IntPtrLSR(x, y);
516 }
517 
518 template<OpCode Op, MachineType Type>
BinaryOp(GateRef x,GateRef y)519 inline GateRef StubBuilder::BinaryOp(GateRef x, GateRef y)
520 {
521     return env_->GetBuilder()->BinaryOp<Op, Type>(x, y);
522 }
523 
TaggedIsInt(GateRef x)524 inline GateRef StubBuilder::TaggedIsInt(GateRef x)
525 {
526     return env_->GetBuilder()->TaggedIsInt(x);
527 }
528 
TaggedIsDouble(GateRef x)529 inline GateRef StubBuilder::TaggedIsDouble(GateRef x)
530 {
531     return BoolAnd(TaggedIsNumber(x), BoolNot(TaggedIsInt(x)));
532 }
533 
TaggedIsObject(GateRef x)534 inline GateRef StubBuilder::TaggedIsObject(GateRef x)
535 {
536     return env_->GetBuilder()->TaggedIsObject(x);
537 }
538 
TaggedIsString(GateRef obj)539 inline GateRef StubBuilder::TaggedIsString(GateRef obj)
540 {
541     return env_->GetBuilder()->TaggedIsString(obj);
542 }
543 
TaggedIsStringOrSymbol(GateRef obj)544 inline GateRef StubBuilder::TaggedIsStringOrSymbol(GateRef obj)
545 {
546     return env_->GetBuilder()->TaggedIsStringOrSymbol(obj);
547 }
548 
BothAreString(GateRef x,GateRef y)549 inline GateRef StubBuilder::BothAreString(GateRef x, GateRef y)
550 {
551     auto allHeapObject = BoolAnd(TaggedIsHeapObject(x), TaggedIsHeapObject(y));
552     auto allString = env_->GetBuilder()->TaggedObjectBothAreString(x, y);
553     return env_->GetBuilder()->LogicAnd(allHeapObject, allString);
554 }
555 
TaggedIsNumber(GateRef x)556 inline GateRef StubBuilder::TaggedIsNumber(GateRef x)
557 {
558     return BoolNot(TaggedIsObject(x));
559 }
560 
TaggedIsNumeric(GateRef x)561 inline GateRef StubBuilder::TaggedIsNumeric(GateRef x)
562 {
563     return BoolOr(TaggedIsNumber(x), TaggedIsBigInt(x));
564 }
565 
TaggedIsHole(GateRef x)566 inline GateRef StubBuilder::TaggedIsHole(GateRef x)
567 {
568     return env_->GetBuilder()->TaggedIsHole(x);
569 }
570 
TaggedIsNotHole(GateRef x)571 inline GateRef StubBuilder::TaggedIsNotHole(GateRef x)
572 {
573     return env_->GetBuilder()->TaggedIsNotHole(x);
574 }
575 
TaggedIsUndefined(GateRef x)576 inline GateRef StubBuilder::TaggedIsUndefined(GateRef x)
577 {
578     return env_->GetBuilder()->TaggedIsUndefined(x);
579 }
580 
TaggedIsException(GateRef x)581 inline GateRef StubBuilder::TaggedIsException(GateRef x)
582 {
583     return env_->GetBuilder()->TaggedIsException(x);
584 }
585 
TaggedIsSpecial(GateRef x)586 inline GateRef StubBuilder::TaggedIsSpecial(GateRef x)
587 {
588     return env_->GetBuilder()->TaggedIsSpecial(x);
589 }
590 
TaggedIsHeapObject(GateRef x)591 inline GateRef StubBuilder::TaggedIsHeapObject(GateRef x)
592 {
593     return env_->GetBuilder()->TaggedIsHeapObject(x);
594 }
595 
TaggedIsGeneratorObject(GateRef x)596 inline GateRef StubBuilder::TaggedIsGeneratorObject(GateRef x)
597 {
598     return env_->GetBuilder()->TaggedIsGeneratorObject(x);
599 }
600 
TaggedIsAsyncGeneratorObject(GateRef x)601 inline GateRef StubBuilder::TaggedIsAsyncGeneratorObject(GateRef x)
602 {
603     return env_->GetBuilder()->TaggedIsAsyncGeneratorObject(x);
604 }
605 
606 
TaggedIsWeak(GateRef x)607 inline GateRef StubBuilder::TaggedIsWeak(GateRef x)
608 {
609     return env_->GetBuilder()->TaggedIsWeak(x);
610 }
611 
TaggedIsPrototypeHandler(GateRef x)612 inline GateRef StubBuilder::TaggedIsPrototypeHandler(GateRef x)
613 {
614     return env_->GetBuilder()->TaggedIsPrototypeHandler(x);
615 }
616 
TaggedIsStoreTSHandler(GateRef x)617 inline GateRef StubBuilder::TaggedIsStoreTSHandler(GateRef x)
618 {
619     return env_->GetBuilder()->TaggedIsStoreTSHandler(x);
620 }
621 
TaggedIsTransWithProtoHandler(GateRef x)622 inline GateRef StubBuilder::TaggedIsTransWithProtoHandler(GateRef x)
623 {
624     return env_->GetBuilder()->TaggedIsTransWithProtoHandler(x);
625 }
626 
TaggedIsTransitionHandler(GateRef x)627 inline GateRef StubBuilder::TaggedIsTransitionHandler(GateRef x)
628 {
629     return env_->GetBuilder()->TaggedIsTransitionHandler(x);
630 }
631 
GetNextPositionForHash(GateRef last,GateRef count,GateRef size)632 inline GateRef StubBuilder::GetNextPositionForHash(GateRef last, GateRef count, GateRef size)
633 {
634     auto nextOffset = Int32LSR(Int32Mul(count, Int32Add(count, Int32(1))),
635                                Int32(1));
636     return Int32And(Int32Add(last, nextOffset), Int32Sub(size, Int32(1)));
637 }
638 
DoubleIsNAN(GateRef x)639 inline GateRef StubBuilder::DoubleIsNAN(GateRef x)
640 {
641     return env_->GetBuilder()->DoubleIsNAN(x);
642 }
643 
DoubleIsINF(GateRef x)644 inline GateRef StubBuilder::DoubleIsINF(GateRef x)
645 {
646     return env_->GetBuilder()->DoubleIsINF(x);
647 }
648 
TaggedIsNull(GateRef x)649 inline GateRef StubBuilder::TaggedIsNull(GateRef x)
650 {
651     return env_->GetBuilder()->TaggedIsNull(x);
652 }
653 
TaggedIsUndefinedOrNull(GateRef x)654 inline GateRef StubBuilder::TaggedIsUndefinedOrNull(GateRef x)
655 {
656     return env_->GetBuilder()->TaggedIsUndefinedOrNull(x);
657 }
658 
TaggedIsTrue(GateRef x)659 inline GateRef StubBuilder::TaggedIsTrue(GateRef x)
660 {
661     return env_->GetBuilder()->TaggedIsTrue(x);
662 }
663 
TaggedIsFalse(GateRef x)664 inline GateRef StubBuilder::TaggedIsFalse(GateRef x)
665 {
666     return env_->GetBuilder()->TaggedIsFalse(x);
667 }
668 
TaggedIsBoolean(GateRef x)669 inline GateRef StubBuilder::TaggedIsBoolean(GateRef x)
670 {
671     return env_->GetBuilder()->TaggedIsBoolean(x);
672 }
673 
TaggedGetInt(GateRef x)674 inline GateRef StubBuilder::TaggedGetInt(GateRef x)
675 {
676     return env_->GetBuilder()->TaggedGetInt(x);
677 }
678 
Int8ToTaggedInt(GateRef x)679 inline GateRef StubBuilder::Int8ToTaggedInt(GateRef x)
680 {
681     GateRef val = SExtInt8ToInt64(x);
682     return env_->GetBuilder()->ToTaggedInt(val);
683 }
684 
Int16ToTaggedInt(GateRef x)685 inline GateRef StubBuilder::Int16ToTaggedInt(GateRef x)
686 {
687     GateRef val = SExtInt16ToInt64(x);
688     return env_->GetBuilder()->ToTaggedInt(val);
689 }
690 
IntToTaggedPtr(GateRef x)691 inline GateRef StubBuilder::IntToTaggedPtr(GateRef x)
692 {
693     GateRef val = SExtInt32ToInt64(x);
694     return env_->GetBuilder()->ToTaggedIntPtr(val);
695 }
696 
IntToTaggedInt(GateRef x)697 inline GateRef StubBuilder::IntToTaggedInt(GateRef x)
698 {
699     GateRef val = SExtInt32ToInt64(x);
700     return env_->GetBuilder()->ToTaggedInt(val);
701 }
702 
Int64ToTaggedInt(GateRef x)703 inline GateRef StubBuilder::Int64ToTaggedInt(GateRef x)
704 {
705     return env_->GetBuilder()->ToTaggedInt(x);
706 }
707 
DoubleToTaggedDoublePtr(GateRef x)708 inline GateRef StubBuilder::DoubleToTaggedDoublePtr(GateRef x)
709 {
710     return env_->GetBuilder()->DoubleToTaggedDoublePtr(x);
711 }
712 
CastDoubleToInt64(GateRef x)713 inline GateRef StubBuilder::CastDoubleToInt64(GateRef x)
714 {
715     return env_->GetBuilder()->CastDoubleToInt64(x);
716 }
717 
TaggedTrue()718 inline GateRef StubBuilder::TaggedTrue()
719 {
720     return env_->GetBuilder()->TaggedTrue();
721 }
722 
TaggedFalse()723 inline GateRef StubBuilder::TaggedFalse()
724 {
725     return env_->GetBuilder()->TaggedFalse();
726 }
727 
728 // compare operation
Int8Equal(GateRef x,GateRef y)729 inline GateRef StubBuilder::Int8Equal(GateRef x, GateRef y)
730 {
731     return env_->GetBuilder()->Int8Equal(x, y);
732 }
733 
Equal(GateRef x,GateRef y)734 inline GateRef StubBuilder::Equal(GateRef x, GateRef y)
735 {
736     return env_->GetBuilder()->Equal(x, y);
737 }
738 
Int32Equal(GateRef x,GateRef y)739 inline GateRef StubBuilder::Int32Equal(GateRef x, GateRef y)
740 {
741     return env_->GetBuilder()->Int32Equal(x, y);
742 }
743 
Int32NotEqual(GateRef x,GateRef y)744 inline GateRef StubBuilder::Int32NotEqual(GateRef x, GateRef y)
745 {
746     return env_->GetBuilder()->Int32NotEqual(x, y);
747 }
748 
Int64Equal(GateRef x,GateRef y)749 inline GateRef StubBuilder::Int64Equal(GateRef x, GateRef y)
750 {
751     return env_->GetBuilder()->Int64Equal(x, y);
752 }
753 
DoubleEqual(GateRef x,GateRef y)754 inline GateRef StubBuilder::DoubleEqual(GateRef x, GateRef y)
755 {
756     return env_->GetBuilder()->DoubleEqual(x, y);
757 }
758 
DoubleNotEqual(GateRef x,GateRef y)759 inline GateRef StubBuilder::DoubleNotEqual(GateRef x, GateRef y)
760 {
761     return env_->GetBuilder()->DoubleNotEqual(x, y);
762 }
763 
DoubleLessThan(GateRef x,GateRef y)764 inline GateRef StubBuilder::DoubleLessThan(GateRef x, GateRef y)
765 {
766     return env_->GetBuilder()->DoubleLessThan(x, y);
767 }
768 
DoubleLessThanOrEqual(GateRef x,GateRef y)769 inline GateRef StubBuilder::DoubleLessThanOrEqual(GateRef x, GateRef y)
770 {
771     return env_->GetBuilder()->DoubleLessThanOrEqual(x, y);
772 }
773 
DoubleGreaterThan(GateRef x,GateRef y)774 inline GateRef StubBuilder::DoubleGreaterThan(GateRef x, GateRef y)
775 {
776     return env_->GetBuilder()->DoubleGreaterThan(x, y);
777 }
778 
DoubleGreaterThanOrEqual(GateRef x,GateRef y)779 inline GateRef StubBuilder::DoubleGreaterThanOrEqual(GateRef x, GateRef y)
780 {
781     return env_->GetBuilder()->DoubleGreaterThanOrEqual(x, y);
782 }
783 
Int64NotEqual(GateRef x,GateRef y)784 inline GateRef StubBuilder::Int64NotEqual(GateRef x, GateRef y)
785 {
786     return env_->GetBuilder()->Int64NotEqual(x, y);
787 }
788 
Int32GreaterThan(GateRef x,GateRef y)789 inline GateRef StubBuilder::Int32GreaterThan(GateRef x, GateRef y)
790 {
791     return env_->GetBuilder()->Int32GreaterThan(x, y);
792 }
793 
Int32LessThan(GateRef x,GateRef y)794 inline GateRef StubBuilder::Int32LessThan(GateRef x, GateRef y)
795 {
796     return env_->GetBuilder()->Int32LessThan(x, y);
797 }
798 
Int32GreaterThanOrEqual(GateRef x,GateRef y)799 inline GateRef StubBuilder::Int32GreaterThanOrEqual(GateRef x, GateRef y)
800 {
801     return env_->GetBuilder()->Int32GreaterThanOrEqual(x, y);
802 }
803 
Int32LessThanOrEqual(GateRef x,GateRef y)804 inline GateRef StubBuilder::Int32LessThanOrEqual(GateRef x, GateRef y)
805 {
806     return env_->GetBuilder()->Int32LessThanOrEqual(x, y);
807 }
808 
Int32UnsignedGreaterThan(GateRef x,GateRef y)809 inline GateRef StubBuilder::Int32UnsignedGreaterThan(GateRef x, GateRef y)
810 {
811     return env_->GetBuilder()->Int32UnsignedGreaterThan(x, y);
812 }
813 
Int32UnsignedLessThan(GateRef x,GateRef y)814 inline GateRef StubBuilder::Int32UnsignedLessThan(GateRef x, GateRef y)
815 {
816     return env_->GetBuilder()->Int32UnsignedLessThan(x, y);
817 }
818 
Int32UnsignedGreaterThanOrEqual(GateRef x,GateRef y)819 inline GateRef StubBuilder::Int32UnsignedGreaterThanOrEqual(GateRef x, GateRef y)
820 {
821     return env_->GetBuilder()->Int32UnsignedGreaterThanOrEqual(x, y);
822 }
823 
Int64GreaterThan(GateRef x,GateRef y)824 inline GateRef StubBuilder::Int64GreaterThan(GateRef x, GateRef y)
825 {
826     return env_->GetBuilder()->Int64GreaterThan(x, y);
827 }
828 
Int64LessThan(GateRef x,GateRef y)829 inline GateRef StubBuilder::Int64LessThan(GateRef x, GateRef y)
830 {
831     return env_->GetBuilder()->Int64LessThan(x, y);
832 }
833 
Int64LessThanOrEqual(GateRef x,GateRef y)834 inline GateRef StubBuilder::Int64LessThanOrEqual(GateRef x, GateRef y)
835 {
836     return env_->GetBuilder()->Int64LessThanOrEqual(x, y);
837 }
838 
Int64GreaterThanOrEqual(GateRef x,GateRef y)839 inline GateRef StubBuilder::Int64GreaterThanOrEqual(GateRef x, GateRef y)
840 {
841     return env_->GetBuilder()->Int64GreaterThanOrEqual(x, y);
842 }
843 
Int64UnsignedLessThanOrEqual(GateRef x,GateRef y)844 inline GateRef StubBuilder::Int64UnsignedLessThanOrEqual(GateRef x, GateRef y)
845 {
846     return env_->GetBuilder()->Int64UnsignedLessThanOrEqual(x, y);
847 }
848 
IntPtrGreaterThan(GateRef x,GateRef y)849 inline GateRef StubBuilder::IntPtrGreaterThan(GateRef x, GateRef y)
850 {
851     return env_->GetBuilder()->IntPtrGreaterThan(x, y);
852 }
853 
854 // cast operation
TruncInt16ToInt8(GateRef val)855 inline GateRef StubBuilder::TruncInt16ToInt8(GateRef val)
856 {
857     return env_->GetBuilder()->TruncInt16ToInt8(val);
858 }
859 
ChangeInt64ToIntPtr(GateRef val)860 inline GateRef StubBuilder::ChangeInt64ToIntPtr(GateRef val)
861 {
862     if (env_->IsArch32Bit()) {
863         return TruncInt64ToInt32(val);
864     }
865     return val;
866 }
867 
ZExtInt32ToPtr(GateRef val)868 inline GateRef StubBuilder::ZExtInt32ToPtr(GateRef val)
869 {
870     if (env_->IsArch32Bit()) {
871         return val;
872     }
873     return ZExtInt32ToInt64(val);
874 }
875 
ChangeIntPtrToInt32(GateRef val)876 inline GateRef StubBuilder::ChangeIntPtrToInt32(GateRef val)
877 {
878     if (env_->IsArch32Bit()) {
879         return val;
880     }
881     return TruncInt64ToInt32(val);
882 }
883 
GetSetterFromAccessor(GateRef accessor)884 inline GateRef StubBuilder::GetSetterFromAccessor(GateRef accessor)
885 {
886     GateRef setterOffset = IntPtr(AccessorData::SETTER_OFFSET);
887     return Load(VariableType::JS_ANY(), accessor, setterOffset);
888 }
889 
GetElementsArray(GateRef object)890 inline GateRef StubBuilder::GetElementsArray(GateRef object)
891 {
892     GateRef elementsOffset = IntPtr(JSObject::ELEMENTS_OFFSET);
893     return Load(VariableType::JS_POINTER(), object, elementsOffset);
894 }
895 
SetElementsArray(VariableType type,GateRef glue,GateRef object,GateRef elementsArray)896 inline void StubBuilder::SetElementsArray(VariableType type, GateRef glue, GateRef object, GateRef elementsArray)
897 {
898     GateRef elementsOffset = IntPtr(JSObject::ELEMENTS_OFFSET);
899     Store(type, glue, object, elementsOffset, elementsArray);
900 }
901 
GetPropertiesArray(GateRef object)902 inline GateRef StubBuilder::GetPropertiesArray(GateRef object)
903 {
904     GateRef propertiesOffset = IntPtr(JSObject::PROPERTIES_OFFSET);
905     return Load(VariableType::JS_POINTER(), object, propertiesOffset);
906 }
907 
908 // SetProperties in js_object.h
SetPropertiesArray(VariableType type,GateRef glue,GateRef object,GateRef propsArray)909 inline void StubBuilder::SetPropertiesArray(VariableType type, GateRef glue, GateRef object, GateRef propsArray)
910 {
911     GateRef propertiesOffset = IntPtr(JSObject::PROPERTIES_OFFSET);
912     Store(type, glue, object, propertiesOffset, propsArray);
913 }
914 
SetHash(GateRef glue,GateRef object,GateRef hash)915 inline void StubBuilder::SetHash(GateRef glue, GateRef object, GateRef hash)
916 {
917     GateRef hashOffset = IntPtr(ECMAObject::HASH_OFFSET);
918     Store(VariableType::INT64(), glue, object, hashOffset, hash);
919 }
920 
GetLengthOfTaggedArray(GateRef array)921 inline GateRef StubBuilder::GetLengthOfTaggedArray(GateRef array)
922 {
923     return Load(VariableType::INT32(), array, IntPtr(TaggedArray::LENGTH_OFFSET));
924 }
925 
IsJSHClass(GateRef obj)926 inline GateRef StubBuilder::IsJSHClass(GateRef obj)
927 {
928     ASM_ASSERT(GET_MESSAGE_STRING_ID(IsJSHClass), TaggedIsHeapObject(obj));
929     GateRef res = env_->GetBuilder()->IsJSHClass(obj);
930     EXITENTRY();
931     return res;
932 }
933 
934 // object operation
LoadHClass(GateRef object)935 inline GateRef StubBuilder::LoadHClass(GateRef object)
936 {
937     ASM_ASSERT(GET_MESSAGE_STRING_ID(LoadHClass), TaggedIsHeapObject(object));
938     GateRef res = env_->GetBuilder()->LoadHClass(object);
939     EXITENTRY();
940     return res;
941 }
942 
StoreHClass(GateRef glue,GateRef object,GateRef hClass)943 inline void StubBuilder::StoreHClass(GateRef glue, GateRef object, GateRef hClass)
944 {
945     return env_->GetBuilder()->StoreHClass(glue, object, hClass);
946 }
947 
GetObjectType(GateRef hClass)948 inline GateRef StubBuilder::GetObjectType(GateRef hClass)
949 {
950     return env_->GetBuilder()->GetObjectType(hClass);
951 }
952 
IsDictionaryMode(GateRef object)953 inline GateRef StubBuilder::IsDictionaryMode(GateRef object)
954 {
955     ASM_ASSERT(GET_MESSAGE_STRING_ID(IsDictionaryMode), TaggedIsHeapObject(object));
956     GateRef res = env_->GetBuilder()->IsDictionaryMode(object);
957     EXITENTRY();
958     return res;
959 }
960 
IsDictionaryModeByHClass(GateRef hClass)961 inline GateRef StubBuilder::IsDictionaryModeByHClass(GateRef hClass)
962 {
963     return env_->GetBuilder()->IsDictionaryModeByHClass(hClass);
964 }
965 
IsDictionaryElement(GateRef hClass)966 inline GateRef StubBuilder::IsDictionaryElement(GateRef hClass)
967 {
968     return env_->GetBuilder()->IsDictionaryElement(hClass);
969 }
970 
IsClassConstructorFromBitField(GateRef bitfield)971 inline GateRef StubBuilder::IsClassConstructorFromBitField(GateRef bitfield)
972 {
973     // decode
974     return Int32NotEqual(
975         Int32And(Int32LSR(bitfield, Int32(JSHClass::ClassConstructorBit::START_BIT)),
976                  Int32((1LU << JSHClass::ClassConstructorBit::SIZE) - 1)),
977         Int32(0));
978 }
979 
IsClassConstructor(GateRef object)980 inline GateRef StubBuilder::IsClassConstructor(GateRef object)
981 {
982     ASM_ASSERT(GET_MESSAGE_STRING_ID(IsClassConstructor), TaggedIsHeapObject(object));
983     GateRef res = env_->GetBuilder()->IsClassConstructor(object);
984     EXITENTRY();
985     return res;
986 }
987 
IsClassPrototype(GateRef object)988 inline GateRef StubBuilder::IsClassPrototype(GateRef object)
989 {
990     ASM_ASSERT(GET_MESSAGE_STRING_ID(IsClassPrototype), TaggedIsHeapObject(object));
991     GateRef res = env_->GetBuilder()->IsClassPrototype(object);
992     EXITENTRY();
993     return res;
994 }
995 
IsExtensible(GateRef object)996 inline GateRef StubBuilder::IsExtensible(GateRef object)
997 {
998     ASM_ASSERT(GET_MESSAGE_STRING_ID(IsExtensible), TaggedIsHeapObject(object));
999     GateRef res = env_->GetBuilder()->IsExtensible(object);
1000     EXITENTRY();
1001     return res;
1002 }
1003 
TaggedObjectIsEcmaObject(GateRef obj)1004 inline GateRef StubBuilder::TaggedObjectIsEcmaObject(GateRef obj)
1005 {
1006     ASM_ASSERT(GET_MESSAGE_STRING_ID(IsEcmaObject), TaggedIsHeapObject(obj));
1007     GateRef res = env_->GetBuilder()->TaggedObjectIsEcmaObject(obj);
1008     EXITENTRY();
1009     return res;
1010 }
1011 
IsEcmaObject(GateRef obj)1012 inline GateRef StubBuilder::IsEcmaObject(GateRef obj)
1013 {
1014     auto isEcmaObject = TaggedObjectIsEcmaObject(obj);
1015     return env_->GetBuilder()->LogicAnd(TaggedIsHeapObject(obj), isEcmaObject);
1016 }
1017 
IsJSObject(GateRef obj)1018 inline GateRef StubBuilder::IsJSObject(GateRef obj)
1019 {
1020     ASM_ASSERT(GET_MESSAGE_STRING_ID(IsJSObject), TaggedIsHeapObject(obj));
1021     GateRef res = env_->GetBuilder()->IsJSObject(obj);
1022     EXITENTRY();
1023     return res;
1024 }
1025 
IsJSFunctionBase(GateRef obj)1026 inline GateRef StubBuilder::IsJSFunctionBase(GateRef obj)
1027 {
1028     GateRef objectType = GetObjectType(LoadHClass(obj));
1029     GateRef greater = Int32GreaterThanOrEqual(objectType,
1030         Int32(static_cast<int32_t>(JSType::JS_FUNCTION_BASE)));
1031     GateRef less = Int32LessThanOrEqual(objectType,
1032         Int32(static_cast<int32_t>(JSType::JS_BOUND_FUNCTION)));
1033     return BoolAnd(greater, less);
1034 }
1035 
IsConstructor(GateRef object)1036 inline GateRef StubBuilder::IsConstructor(GateRef object)
1037 {
1038     GateRef hClass = LoadHClass(object);
1039     GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
1040     GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
1041     // decode
1042     return Int32NotEqual(
1043         Int32And(Int32LSR(bitfield, Int32(JSHClass::ConstructorBit::START_BIT)),
1044                  Int32((1LU << JSHClass::ConstructorBit::SIZE) - 1)),
1045         Int32(0));
1046 }
1047 
IsBase(GateRef func)1048 inline GateRef StubBuilder::IsBase(GateRef func)
1049 {
1050     return env_->GetBuilder()->IsBase(func);
1051 }
1052 
IsSymbol(GateRef obj)1053 inline GateRef StubBuilder::IsSymbol(GateRef obj)
1054 {
1055     GateRef objectType = GetObjectType(LoadHClass(obj));
1056     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::SYMBOL)));
1057 }
1058 
IsString(GateRef obj)1059 inline GateRef StubBuilder::IsString(GateRef obj)
1060 {
1061     GateRef objectType = GetObjectType(LoadHClass(obj));
1062     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::STRING)));
1063 }
1064 
TaggedObjectIsBigInt(GateRef obj)1065 inline GateRef StubBuilder::TaggedObjectIsBigInt(GateRef obj)
1066 {
1067     GateRef objectType = GetObjectType(LoadHClass(obj));
1068     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::BIGINT)));
1069 }
1070 
IsJsProxy(GateRef obj)1071 inline GateRef StubBuilder::IsJsProxy(GateRef obj)
1072 {
1073     GateRef objectType = GetObjectType(LoadHClass(obj));
1074     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_PROXY)));
1075 }
1076 
IsJsArray(GateRef obj)1077 inline GateRef StubBuilder::IsJsArray(GateRef obj)
1078 {
1079     GateRef objectType = GetObjectType(LoadHClass(obj));
1080     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_ARRAY)));
1081 }
1082 
IsJSAPIVector(GateRef obj)1083 inline GateRef StubBuilder::IsJSAPIVector(GateRef obj)
1084 {
1085     GateRef objectType = GetObjectType(LoadHClass(obj));
1086     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_VECTOR)));
1087 }
1088 
IsJSAPIStack(GateRef obj)1089 inline GateRef StubBuilder::IsJSAPIStack(GateRef obj)
1090 {
1091     GateRef objectType = GetObjectType(LoadHClass(obj));
1092     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_STACK)));
1093 }
1094 
IsJSAPIPlainArray(GateRef obj)1095 inline GateRef StubBuilder::IsJSAPIPlainArray(GateRef obj)
1096 {
1097     GateRef objectType = GetObjectType(LoadHClass(obj));
1098     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_PLAIN_ARRAY)));
1099 }
1100 
IsJSAPIQueue(GateRef obj)1101 inline GateRef StubBuilder::IsJSAPIQueue(GateRef obj)
1102 {
1103     GateRef objectType = GetObjectType(LoadHClass(obj));
1104     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_QUEUE)));
1105 }
1106 
IsJSAPIDeque(GateRef obj)1107 inline GateRef StubBuilder::IsJSAPIDeque(GateRef obj)
1108 {
1109     GateRef objectType = GetObjectType(LoadHClass(obj));
1110     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_DEQUE)));
1111 }
1112 
IsJSAPILightWeightMap(GateRef obj)1113 inline GateRef StubBuilder::IsJSAPILightWeightMap(GateRef obj)
1114 {
1115     GateRef objectType = GetObjectType(LoadHClass(obj));
1116     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LIGHT_WEIGHT_MAP)));
1117 }
1118 
IsJSAPILightWeightSet(GateRef obj)1119 inline GateRef StubBuilder::IsJSAPILightWeightSet(GateRef obj)
1120 {
1121     GateRef objectType = GetObjectType(LoadHClass(obj));
1122     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LIGHT_WEIGHT_SET)));
1123 }
1124 
IsLinkedNode(GateRef obj)1125 inline GateRef StubBuilder::IsLinkedNode(GateRef obj)
1126 {
1127     GateRef objectType = GetObjectType(LoadHClass(obj));
1128     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::LINKED_NODE)));
1129 }
1130 
IsJSAPIHashMap(GateRef obj)1131 inline GateRef StubBuilder::IsJSAPIHashMap(GateRef obj)
1132 {
1133     GateRef objectType = GetObjectType(LoadHClass(obj));
1134     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_HASH_MAP)));
1135 }
1136 
IsJSAPIHashSet(GateRef obj)1137 inline GateRef StubBuilder::IsJSAPIHashSet(GateRef obj)
1138 {
1139     GateRef objectType = GetObjectType(LoadHClass(obj));
1140     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_HASH_SET)));
1141 }
1142 
IsJSAPILinkedList(GateRef obj)1143 inline GateRef StubBuilder::IsJSAPILinkedList(GateRef obj)
1144 {
1145     GateRef objectType = GetObjectType(LoadHClass(obj));
1146     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LINKED_LIST)));
1147 }
1148 
IsJSAPIList(GateRef obj)1149 inline GateRef StubBuilder::IsJSAPIList(GateRef obj)
1150 {
1151     GateRef objectType = GetObjectType(LoadHClass(obj));
1152     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LIST)));
1153 }
1154 
IsJSAPIArrayList(GateRef obj)1155 inline GateRef StubBuilder::IsJSAPIArrayList(GateRef obj)
1156 {
1157     GateRef objectType = GetObjectType(LoadHClass(obj));
1158     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST)));
1159 }
1160 
GetTarget(GateRef proxyObj)1161 inline GateRef StubBuilder::GetTarget(GateRef proxyObj)
1162 {
1163     GateRef offset = IntPtr(JSProxy::TARGET_OFFSET);
1164     return Load(VariableType::JS_ANY(), proxyObj, offset);
1165 }
1166 
IsJsCOWArray(GateRef obj)1167 inline GateRef StubBuilder::IsJsCOWArray(GateRef obj)
1168 {
1169     // Elements of JSArray are shared and properties are not yet.
1170     GateRef elements = GetElementsArray(obj);
1171     return IsCOWArray(elements);
1172 }
1173 
IsCOWArray(GateRef obj)1174 inline GateRef StubBuilder::IsCOWArray(GateRef obj)
1175 {
1176     GateRef objectType = GetObjectType(LoadHClass(obj));
1177     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::COW_TAGGED_ARRAY)));
1178 }
1179 
IsWritable(GateRef attr)1180 inline GateRef StubBuilder::IsWritable(GateRef attr)
1181 {
1182     return Int32NotEqual(
1183         Int32And(
1184             Int32LSR(attr, Int32(PropertyAttributes::WritableField::START_BIT)),
1185             Int32((1LLU << PropertyAttributes::WritableField::SIZE) - 1)),
1186         Int32(0));
1187 }
1188 
IsAccessor(GateRef attr)1189 inline GateRef StubBuilder::IsAccessor(GateRef attr)
1190 {
1191     return Int32NotEqual(
1192         Int32And(Int32LSR(attr,
1193             Int32(PropertyAttributes::IsAccessorField::START_BIT)),
1194             Int32((1LLU << PropertyAttributes::IsAccessorField::SIZE) - 1)),
1195         Int32(0));
1196 }
1197 
IsInlinedProperty(GateRef attr)1198 inline GateRef StubBuilder::IsInlinedProperty(GateRef attr)
1199 {
1200     return Int32NotEqual(
1201         Int32And(Int32LSR(attr,
1202             Int32(PropertyAttributes::IsInlinedPropsField::START_BIT)),
1203             Int32((1LLU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1)),
1204         Int32(0));
1205 }
1206 
GetProtoCell(GateRef object)1207 inline GateRef StubBuilder::GetProtoCell(GateRef object)
1208 {
1209     GateRef protoCellOffset = IntPtr(PrototypeHandler::PROTO_CELL_OFFSET);
1210     return Load(VariableType::JS_POINTER(), object, protoCellOffset);
1211 }
1212 
GetPrototypeHandlerHolder(GateRef object)1213 inline GateRef StubBuilder::GetPrototypeHandlerHolder(GateRef object)
1214 {
1215     GateRef holderOffset = IntPtr(PrototypeHandler::HOLDER_OFFSET);
1216     return Load(VariableType::JS_ANY(), object, holderOffset);
1217 }
1218 
GetPrototypeHandlerHandlerInfo(GateRef object)1219 inline GateRef StubBuilder::GetPrototypeHandlerHandlerInfo(GateRef object)
1220 {
1221     GateRef handlerInfoOffset = IntPtr(PrototypeHandler::HANDLER_INFO_OFFSET);
1222     return Load(VariableType::JS_ANY(), object, handlerInfoOffset);
1223 }
1224 
GetStoreTSHandlerHolder(GateRef object)1225 inline GateRef StubBuilder::GetStoreTSHandlerHolder(GateRef object)
1226 {
1227     GateRef holderOffset = IntPtr(StoreTSHandler::HOLDER_OFFSET);
1228     return Load(VariableType::JS_ANY(), object, holderOffset);
1229 }
1230 
GetStoreTSHandlerHandlerInfo(GateRef object)1231 inline GateRef StubBuilder::GetStoreTSHandlerHandlerInfo(GateRef object)
1232 {
1233     GateRef handlerInfoOffset = IntPtr(StoreTSHandler::HANDLER_INFO_OFFSET);
1234     return Load(VariableType::JS_ANY(), object, handlerInfoOffset);
1235 }
1236 
GetHasChanged(GateRef object)1237 inline GateRef StubBuilder::GetHasChanged(GateRef object)
1238 {
1239     GateRef bitfieldOffset = IntPtr(ProtoChangeMarker::BIT_FIELD_OFFSET);
1240     GateRef bitfield = Load(VariableType::INT32(), object, bitfieldOffset);
1241     GateRef mask = Int32(1LLU << (ProtoChangeMarker::HAS_CHANGED_BITS - 1));
1242     return Int32NotEqual(Int32And(bitfield, mask), Int32(0));
1243 }
1244 
HclassIsPrototypeHandler(GateRef hClass)1245 inline GateRef StubBuilder::HclassIsPrototypeHandler(GateRef hClass)
1246 {
1247     return Int32Equal(GetObjectType(hClass),
1248         Int32(static_cast<int32_t>(JSType::PROTOTYPE_HANDLER)));
1249 }
1250 
HclassIsTransitionHandler(GateRef hClass)1251 inline GateRef StubBuilder::HclassIsTransitionHandler(GateRef hClass)
1252 {
1253     return Int32Equal(GetObjectType(hClass),
1254         Int32(static_cast<int32_t>(JSType::TRANSITION_HANDLER)));
1255 }
1256 
HclassIsPropertyBox(GateRef hClass)1257 inline GateRef StubBuilder::HclassIsPropertyBox(GateRef hClass)
1258 {
1259     return Int32Equal(GetObjectType(hClass),
1260         Int32(static_cast<int32_t>(JSType::PROPERTY_BOX)));
1261 }
1262 
IsField(GateRef attr)1263 inline GateRef StubBuilder::IsField(GateRef attr)
1264 {
1265     return Int32Equal(
1266         Int32And(
1267             Int32LSR(attr, Int32(HandlerBase::KindBit::START_BIT)),
1268             Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
1269         Int32(HandlerBase::HandlerKind::FIELD));
1270 }
1271 
IsNonExist(GateRef attr)1272 inline GateRef StubBuilder::IsNonExist(GateRef attr)
1273 {
1274     return Int32Equal(
1275         Int32And(
1276             Int32LSR(attr, Int32(HandlerBase::KindBit::START_BIT)),
1277             Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
1278         Int32(HandlerBase::HandlerKind::NON_EXIST));
1279 }
1280 
HandlerBaseIsAccessor(GateRef attr)1281 inline GateRef StubBuilder::HandlerBaseIsAccessor(GateRef attr)
1282 {
1283     return Int32NotEqual(
1284         Int32And(Int32LSR(attr,
1285             Int32(HandlerBase::AccessorBit::START_BIT)),
1286             Int32((1LLU << HandlerBase::AccessorBit::SIZE) - 1)),
1287         Int32(0));
1288 }
1289 
HandlerBaseIsJSArray(GateRef attr)1290 inline GateRef StubBuilder::HandlerBaseIsJSArray(GateRef attr)
1291 {
1292     return Int32NotEqual(
1293         Int32And(Int32LSR(attr,
1294             Int32(HandlerBase::IsJSArrayBit::START_BIT)),
1295             Int32((1LLU << HandlerBase::IsJSArrayBit::SIZE) - 1)),
1296         Int32(0));
1297 }
1298 
HandlerBaseIsInlinedProperty(GateRef attr)1299 inline GateRef StubBuilder::HandlerBaseIsInlinedProperty(GateRef attr)
1300 {
1301     return Int32NotEqual(
1302         Int32And(Int32LSR(attr,
1303             Int32(HandlerBase::InlinedPropsBit::START_BIT)),
1304             Int32((1LLU << HandlerBase::InlinedPropsBit::SIZE) - 1)),
1305         Int32(0));
1306 }
1307 
HandlerBaseGetOffset(GateRef attr)1308 inline GateRef StubBuilder::HandlerBaseGetOffset(GateRef attr)
1309 {
1310     return Int32And(Int32LSR(attr,
1311         Int32(HandlerBase::OffsetBit::START_BIT)),
1312         Int32((1LLU << HandlerBase::OffsetBit::SIZE) - 1));
1313 }
1314 
IsInternalAccessor(GateRef attr)1315 inline GateRef StubBuilder::IsInternalAccessor(GateRef attr)
1316 {
1317     return Int32NotEqual(
1318         Int32And(Int32LSR(attr,
1319             Int32(HandlerBase::InternalAccessorBit::START_BIT)),
1320             Int32((1LLU << HandlerBase::InternalAccessorBit::SIZE) - 1)),
1321         Int32(0));
1322 }
1323 
IsInvalidPropertyBox(GateRef obj)1324 inline GateRef StubBuilder::IsInvalidPropertyBox(GateRef obj)
1325 {
1326     GateRef valueOffset = IntPtr(PropertyBox::VALUE_OFFSET);
1327     GateRef value = Load(VariableType::JS_ANY(), obj, valueOffset);
1328     return TaggedIsHole(value);
1329 }
1330 
GetValueFromPropertyBox(GateRef obj)1331 inline GateRef StubBuilder::GetValueFromPropertyBox(GateRef obj)
1332 {
1333     GateRef valueOffset = IntPtr(PropertyBox::VALUE_OFFSET);
1334     return Load(VariableType::JS_ANY(), obj, valueOffset);
1335 }
1336 
SetValueToPropertyBox(GateRef glue,GateRef obj,GateRef value)1337 inline void StubBuilder::SetValueToPropertyBox(GateRef glue, GateRef obj, GateRef value)
1338 {
1339     GateRef valueOffset = IntPtr(PropertyBox::VALUE_OFFSET);
1340     Store(VariableType::JS_ANY(), glue, obj, valueOffset, value);
1341 }
1342 
GetTransitionHClass(GateRef obj)1343 inline GateRef StubBuilder::GetTransitionHClass(GateRef obj)
1344 {
1345     GateRef transitionHClassOffset = IntPtr(TransitionHandler::TRANSITION_HCLASS_OFFSET);
1346     return Load(VariableType::JS_POINTER(), obj, transitionHClassOffset);
1347 }
1348 
GetTransitionHandlerInfo(GateRef obj)1349 inline GateRef StubBuilder::GetTransitionHandlerInfo(GateRef obj)
1350 {
1351     GateRef handlerInfoOffset = IntPtr(TransitionHandler::HANDLER_INFO_OFFSET);
1352     return Load(VariableType::JS_ANY(), obj, handlerInfoOffset);
1353 }
1354 
GetTransWithProtoHClass(GateRef obj)1355 inline GateRef StubBuilder::GetTransWithProtoHClass(GateRef obj)
1356 {
1357     GateRef transitionHClassOffset = IntPtr(TransWithProtoHandler::TRANSITION_HCLASS_OFFSET);
1358     return Load(VariableType::JS_POINTER(), obj, transitionHClassOffset);
1359 }
1360 
GetTransWithProtoHandlerInfo(GateRef obj)1361 inline GateRef StubBuilder::GetTransWithProtoHandlerInfo(GateRef obj)
1362 {
1363     GateRef handlerInfoOffset = IntPtr(TransWithProtoHandler::HANDLER_INFO_OFFSET);
1364     return Load(VariableType::JS_ANY(), obj, handlerInfoOffset);
1365 }
1366 
PropAttrGetOffset(GateRef attr)1367 inline GateRef StubBuilder::PropAttrGetOffset(GateRef attr)
1368 {
1369     return Int32And(
1370         Int32LSR(attr, Int32(PropertyAttributes::OffsetField::START_BIT)),
1371         Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1));
1372 }
1373 
1374 // SetDictionaryOrder func in property_attribute.h
SetDictionaryOrderFieldInPropAttr(GateRef attr,GateRef value)1375 inline GateRef StubBuilder::SetDictionaryOrderFieldInPropAttr(GateRef attr, GateRef value)
1376 {
1377     GateRef mask = Int32LSL(
1378         Int32((1LLU << PropertyAttributes::DictionaryOrderField::SIZE) - 1),
1379         Int32(PropertyAttributes::DictionaryOrderField::START_BIT));
1380     GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
1381         Int32LSL(value, Int32(PropertyAttributes::DictionaryOrderField::START_BIT)));
1382     return newVal;
1383 }
1384 
GetPrototypeFromHClass(GateRef hClass)1385 inline GateRef StubBuilder::GetPrototypeFromHClass(GateRef hClass)
1386 {
1387     GateRef protoOffset = IntPtr(JSHClass::PROTOTYPE_OFFSET);
1388     return Load(VariableType::JS_ANY(), hClass, protoOffset);
1389 }
1390 
GetLayoutFromHClass(GateRef hClass)1391 inline GateRef StubBuilder::GetLayoutFromHClass(GateRef hClass)
1392 {
1393     GateRef attrOffset = IntPtr(JSHClass::LAYOUT_OFFSET);
1394     return Load(VariableType::JS_POINTER(), hClass, attrOffset);
1395 }
1396 
GetBitFieldFromHClass(GateRef hClass)1397 inline GateRef StubBuilder::GetBitFieldFromHClass(GateRef hClass)
1398 {
1399     GateRef offset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
1400     return Load(VariableType::INT32(), hClass, offset);
1401 }
1402 
GetLengthFromString(GateRef value)1403 inline GateRef StubBuilder::GetLengthFromString(GateRef value)
1404 {
1405     GateRef len = Load(VariableType::INT32(), value, IntPtr(EcmaString::MIX_LENGTH_OFFSET));
1406     return Int32LSR(len, Int32(2));  // 2 : 2 means len must be right shift 2 bits
1407 }
1408 
SetBitFieldToHClass(GateRef glue,GateRef hClass,GateRef bitfield)1409 inline void StubBuilder::SetBitFieldToHClass(GateRef glue, GateRef hClass, GateRef bitfield)
1410 {
1411     GateRef offset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
1412     Store(VariableType::INT32(), glue, hClass, offset, bitfield);
1413 }
1414 
SetPrototypeToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef proto)1415 inline void StubBuilder::SetPrototypeToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef proto)
1416 {
1417     GateRef offset = IntPtr(JSHClass::PROTOTYPE_OFFSET);
1418     Store(type, glue, hClass, offset, proto);
1419 }
1420 
SetProtoChangeDetailsToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef protoChange)1421 inline void StubBuilder::SetProtoChangeDetailsToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef protoChange)
1422 {
1423     GateRef offset = IntPtr(JSHClass::PROTO_CHANGE_DETAILS_OFFSET);
1424     Store(type, glue, hClass, offset, protoChange);
1425 }
1426 
SetLayoutToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef attr)1427 inline void StubBuilder::SetLayoutToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef attr)
1428 {
1429     GateRef offset = IntPtr(JSHClass::LAYOUT_OFFSET);
1430     Store(type, glue, hClass, offset, attr);
1431 }
1432 
SetEnumCacheToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef key)1433 inline void StubBuilder::SetEnumCacheToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef key)
1434 {
1435     GateRef offset = IntPtr(JSHClass::ENUM_CACHE_OFFSET);
1436     Store(type, glue, hClass, offset, key);
1437 }
1438 
SetTransitionsToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef transition)1439 inline void StubBuilder::SetTransitionsToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef transition)
1440 {
1441     GateRef offset = IntPtr(JSHClass::TRANSTIONS_OFFSET);
1442     Store(type, glue, hClass, offset, transition);
1443 }
1444 
SetIsProtoTypeToHClass(GateRef glue,GateRef hClass,GateRef value)1445 inline void StubBuilder::SetIsProtoTypeToHClass(GateRef glue, GateRef hClass, GateRef value)
1446 {
1447     GateRef oldValue = ZExtInt1ToInt32(value);
1448     GateRef bitfield = GetBitFieldFromHClass(hClass);
1449     GateRef mask = Int32LSL(
1450         Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1),
1451         Int32(JSHClass::IsPrototypeBit::START_BIT));
1452     GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
1453         Int32LSL(oldValue, Int32(JSHClass::IsPrototypeBit::START_BIT)));
1454     SetBitFieldToHClass(glue, hClass, newVal);
1455 }
1456 
IsProtoTypeHClass(GateRef hClass)1457 inline GateRef StubBuilder::IsProtoTypeHClass(GateRef hClass)
1458 {
1459     GateRef bitfield = GetBitFieldFromHClass(hClass);
1460     return TruncInt32ToInt1(Int32And(Int32LSR(bitfield,
1461         Int32(JSHClass::IsPrototypeBit::START_BIT)),
1462         Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1)));
1463 }
1464 
SetPropertyInlinedProps(GateRef glue,GateRef obj,GateRef hClass,GateRef value,GateRef attrOffset,VariableType type)1465 inline void StubBuilder::SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass,
1466     GateRef value, GateRef attrOffset, VariableType type)
1467 {
1468     ASM_ASSERT_WITH_GLUE(GET_MESSAGE_STRING_ID(IsNotDictionaryMode), BoolNot(IsDictionaryModeByHClass(hClass)), glue);
1469     GateRef bitfield = Load(VariableType::INT32(), hClass,
1470                             IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1471     GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield,
1472         Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1473         Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1474     GateRef propOffset = Int32Mul(
1475         Int32Add(inlinedPropsStart, attrOffset), Int32(JSTaggedValue::TaggedTypeSize()));
1476 
1477     // NOTE: need to translate MarkingBarrier
1478     Store(type, glue, obj, ZExtInt32ToPtr(propOffset), value);
1479     EXITENTRY();
1480 }
1481 
GetPropertyInlinedProps(GateRef obj,GateRef hClass,GateRef index)1482 inline GateRef StubBuilder::GetPropertyInlinedProps(GateRef obj, GateRef hClass,
1483     GateRef index)
1484 {
1485     GateRef inlinedPropsStart = GetInlinedPropsStartFromHClass(hClass);
1486     GateRef propOffset = Int32Mul(
1487         Int32Add(inlinedPropsStart, index), Int32(JSTaggedValue::TaggedTypeSize()));
1488     return Load(VariableType::JS_ANY(), obj, ZExtInt32ToInt64(propOffset));
1489 }
1490 
IncNumberOfProps(GateRef glue,GateRef hClass)1491 inline void StubBuilder::IncNumberOfProps(GateRef glue, GateRef hClass)
1492 {
1493     GateRef propNums = GetNumberOfPropsFromHClass(hClass);
1494     SetNumberOfPropsToHClass(glue, hClass, Int32Add(propNums, Int32(1)));
1495 }
1496 
GetNumberOfPropsFromHClass(GateRef hClass)1497 inline GateRef StubBuilder::GetNumberOfPropsFromHClass(GateRef hClass)
1498 {
1499     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1500     return Int32And(Int32LSR(bitfield,
1501         Int32(JSHClass::NumberOfPropsBits::START_BIT)),
1502         Int32((1LLU << JSHClass::NumberOfPropsBits::SIZE) - 1));
1503 }
1504 
IsTSHClass(GateRef hClass)1505 inline GateRef StubBuilder::IsTSHClass(GateRef hClass)
1506 {
1507     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
1508     return Int32NotEqual(Int32And(Int32LSR(bitfield,
1509         Int32(JSHClass::IsTSBit::START_BIT)),
1510         Int32((1LU << JSHClass::IsTSBit::SIZE) - 1)),
1511         Int32(0));
1512 }
1513 
SetNumberOfPropsToHClass(GateRef glue,GateRef hClass,GateRef value)1514 inline void StubBuilder::SetNumberOfPropsToHClass(GateRef glue, GateRef hClass, GateRef value)
1515 {
1516     GateRef bitfield1 = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1517     GateRef oldWithMask = Int32And(bitfield1,
1518         Int32(~static_cast<uint32_t>(JSHClass::NumberOfPropsBits::Mask())));
1519     GateRef newValue = Int32LSR(value, Int32(JSHClass::NumberOfPropsBits::START_BIT));
1520     Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET),
1521         Int32Or(oldWithMask, newValue));
1522 }
1523 
GetInlinedPropertiesFromHClass(GateRef hClass)1524 inline GateRef StubBuilder::GetInlinedPropertiesFromHClass(GateRef hClass)
1525 {
1526     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1527     GateRef objectSizeInWords = Int32And(Int32LSR(bitfield,
1528         Int32(JSHClass::ObjectSizeInWordsBits::START_BIT)),
1529         Int32((1LU << JSHClass::ObjectSizeInWordsBits::SIZE) - 1));
1530     GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield,
1531         Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1532         Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1533     return Int32Sub(objectSizeInWords, inlinedPropsStart);
1534 }
1535 
GetObjectSizeFromHClass(GateRef hClass)1536 inline GateRef StubBuilder::GetObjectSizeFromHClass(GateRef hClass)
1537 {
1538     return env_->GetBuilder()->GetObjectSizeFromHClass(hClass);
1539 }
1540 
GetInlinedPropsStartFromHClass(GateRef hClass)1541 inline GateRef StubBuilder::GetInlinedPropsStartFromHClass(GateRef hClass)
1542 {
1543     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1544     return Int32And(Int32LSR(bitfield,
1545         Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1546         Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1547 }
1548 
SetValueToTaggedArray(VariableType valType,GateRef glue,GateRef array,GateRef index,GateRef val)1549 inline void StubBuilder::SetValueToTaggedArray(VariableType valType, GateRef glue, GateRef array,
1550                                                GateRef index, GateRef val)
1551 {
1552     // NOTE: need to translate MarkingBarrier
1553     GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1554     GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1555     Store(valType, glue, array, dataOffset, val);
1556 }
1557 
GetValueFromTaggedArray(GateRef array,GateRef index)1558 inline GateRef StubBuilder::GetValueFromTaggedArray(GateRef array, GateRef index)
1559 {
1560     GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1561     GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1562     return Load(VariableType::JS_ANY(), array, dataOffset);
1563 }
1564 
IsSpecialIndexedObj(GateRef jsType)1565 inline GateRef StubBuilder::IsSpecialIndexedObj(GateRef jsType)
1566 {
1567     return Int32GreaterThan(jsType, Int32(static_cast<int32_t>(JSType::JS_ARRAY)));
1568 }
1569 
IsSpecialContainer(GateRef jsType)1570 inline GateRef StubBuilder::IsSpecialContainer(GateRef jsType)
1571 {
1572     // arraylist and vector has fast pass now
1573     return BoolAnd(
1574         Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST))),
1575         Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_API_VECTOR))));
1576 }
1577 
IsFastTypeArray(GateRef jsType)1578 inline GateRef StubBuilder::IsFastTypeArray(GateRef jsType)
1579 {
1580     return BoolAnd(
1581             Int32GreaterThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_FIRST))),
1582             Int32LessThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::JS_FLOAT64_ARRAY))));
1583 }
1584 
IsAccessorInternal(GateRef value)1585 inline GateRef StubBuilder::IsAccessorInternal(GateRef value)
1586 {
1587     return Int32Equal(GetObjectType(LoadHClass(value)),
1588                       Int32(static_cast<int32_t>(JSType::INTERNAL_ACCESSOR)));
1589 }
1590 
GetPropAttrFromLayoutInfo(GateRef layout,GateRef entry)1591 inline GateRef StubBuilder::GetPropAttrFromLayoutInfo(GateRef layout, GateRef entry)
1592 {
1593     GateRef index = Int32Add(Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2)),
1594         Int32(LayoutInfo::ATTR_INDEX_OFFSET));
1595     return GetInt64OfTInt(GetValueFromTaggedArray(layout, index));
1596 }
1597 
GetPropertyMetaDataFromAttr(GateRef attr)1598 inline GateRef StubBuilder::GetPropertyMetaDataFromAttr(GateRef attr)
1599 {
1600     return Int32And(Int32LSR(attr, Int32(PropertyAttributes::PropertyMetaDataField::START_BIT)),
1601         Int32((1LLU << PropertyAttributes::PropertyMetaDataField::SIZE) - 1));
1602 }
1603 
GetKeyFromLayoutInfo(GateRef layout,GateRef entry)1604 inline GateRef StubBuilder::GetKeyFromLayoutInfo(GateRef layout, GateRef entry)
1605 {
1606     GateRef index = Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2));
1607     return GetValueFromTaggedArray(layout, index);
1608 }
1609 
GetPropertiesAddrFromLayoutInfo(GateRef layout)1610 inline GateRef StubBuilder::GetPropertiesAddrFromLayoutInfo(GateRef layout)
1611 {
1612     return PtrAdd(layout, IntPtr(TaggedArray::DATA_OFFSET));
1613 }
1614 
GetInt64OfTInt(GateRef x)1615 inline GateRef StubBuilder::GetInt64OfTInt(GateRef x)
1616 {
1617     return env_->GetBuilder()->GetInt64OfTInt(x);
1618 }
1619 
GetInt32OfTInt(GateRef x)1620 inline GateRef StubBuilder::GetInt32OfTInt(GateRef x)
1621 {
1622     return TruncInt64ToInt32(GetInt64OfTInt(x));
1623 }
1624 
TaggedCastToIntPtr(GateRef x)1625 inline GateRef StubBuilder::TaggedCastToIntPtr(GateRef x)
1626 {
1627     return env_->Is32Bit() ? TruncInt64ToInt32(GetInt64OfTInt(x)) : GetInt64OfTInt(x);
1628 }
1629 
GetDoubleOfTDouble(GateRef x)1630 inline GateRef StubBuilder::GetDoubleOfTDouble(GateRef x)
1631 {
1632     return env_->GetBuilder()->GetDoubleOfTDouble(x);
1633 }
1634 
GetDoubleOfTNumber(GateRef x)1635 inline GateRef StubBuilder::GetDoubleOfTNumber(GateRef x)
1636 {
1637     return env_->GetBuilder()->GetDoubleOfTNumber(x);
1638 }
1639 
LoadObjectFromWeakRef(GateRef x)1640 inline GateRef StubBuilder::LoadObjectFromWeakRef(GateRef x)
1641 {
1642     return env_->GetBuilder()->PtrAdd(x, IntPtr(-JSTaggedValue::TAG_WEAK));
1643 }
1644 
ChangeInt32ToFloat64(GateRef x)1645 inline GateRef StubBuilder::ChangeInt32ToFloat64(GateRef x)
1646 {
1647     return env_->GetBuilder()->ChangeInt32ToFloat64(x);
1648 }
1649 
ChangeUInt32ToFloat64(GateRef x)1650 inline GateRef StubBuilder::ChangeUInt32ToFloat64(GateRef x)
1651 {
1652     return env_->GetBuilder()->ChangeUInt32ToFloat64(x);
1653 }
1654 
ChangeFloat64ToInt32(GateRef x)1655 inline GateRef StubBuilder::ChangeFloat64ToInt32(GateRef x)
1656 {
1657     return env_->GetBuilder()->ChangeFloat64ToInt32(x);
1658 }
1659 
ChangeTaggedPointerToInt64(GateRef x)1660 inline GateRef StubBuilder::ChangeTaggedPointerToInt64(GateRef x)
1661 {
1662     return env_->GetBuilder()->ChangeTaggedPointerToInt64(x);
1663 }
1664 
Int64ToTaggedPtr(GateRef x)1665 inline GateRef StubBuilder::Int64ToTaggedPtr(GateRef x)
1666 {
1667     return env_->GetBuilder()->Int64ToTaggedPtr(x);
1668 }
1669 
CastInt64ToFloat64(GateRef x)1670 inline GateRef StubBuilder::CastInt64ToFloat64(GateRef x)
1671 {
1672     return env_->GetBuilder()->CastInt64ToFloat64(x);
1673 }
1674 
SExtInt32ToInt64(GateRef x)1675 inline GateRef StubBuilder::SExtInt32ToInt64(GateRef x)
1676 {
1677     return env_->GetBuilder()->SExtInt32ToInt64(x);
1678 }
1679 
SExtInt16ToInt64(GateRef x)1680 inline GateRef StubBuilder::SExtInt16ToInt64(GateRef x)
1681 {
1682     return env_->GetBuilder()->SExtInt16ToInt64(x);
1683 }
1684 
SExtInt8ToInt64(GateRef x)1685 inline GateRef StubBuilder::SExtInt8ToInt64(GateRef x)
1686 {
1687     return env_->GetBuilder()->SExtInt8ToInt64(x);
1688 }
1689 
SExtInt1ToInt64(GateRef x)1690 inline GateRef StubBuilder::SExtInt1ToInt64(GateRef x)
1691 {
1692     return env_->GetBuilder()->SExtInt1ToInt64(x);
1693 }
1694 
SExtInt1ToInt32(GateRef x)1695 inline GateRef StubBuilder::SExtInt1ToInt32(GateRef x)
1696 {
1697     return env_->GetBuilder()->SExtInt1ToInt32(x);
1698 }
1699 
ZExtInt8ToInt16(GateRef x)1700 inline GateRef StubBuilder::ZExtInt8ToInt16(GateRef x)
1701 {
1702     return env_->GetBuilder()->ZExtInt8ToInt16(x);
1703 }
1704 
ZExtInt32ToInt64(GateRef x)1705 inline GateRef StubBuilder::ZExtInt32ToInt64(GateRef x)
1706 {
1707     return env_->GetBuilder()->ZExtInt32ToInt64(x);
1708 }
1709 
ZExtInt1ToInt64(GateRef x)1710 inline GateRef StubBuilder::ZExtInt1ToInt64(GateRef x)
1711 {
1712     return env_->GetBuilder()->ZExtInt1ToInt64(x);
1713 }
1714 
ZExtInt1ToInt32(GateRef x)1715 inline GateRef StubBuilder::ZExtInt1ToInt32(GateRef x)
1716 {
1717     return env_->GetBuilder()->ZExtInt1ToInt32(x);
1718 }
1719 
ZExtInt8ToInt32(GateRef x)1720 inline GateRef StubBuilder::ZExtInt8ToInt32(GateRef x)
1721 {
1722     return env_->GetBuilder()->ZExtInt8ToInt32(x);
1723 }
1724 
ZExtInt8ToInt64(GateRef x)1725 inline GateRef StubBuilder::ZExtInt8ToInt64(GateRef x)
1726 {
1727     return env_->GetBuilder()->ZExtInt8ToInt64(x);
1728 }
1729 
ZExtInt8ToPtr(GateRef x)1730 inline GateRef StubBuilder::ZExtInt8ToPtr(GateRef x)
1731 {
1732     return env_->GetBuilder()->ZExtInt8ToPtr(x);
1733 }
1734 
ZExtInt16ToPtr(GateRef x)1735 inline GateRef StubBuilder::ZExtInt16ToPtr(GateRef x)
1736 {
1737     return env_->GetBuilder()->ZExtInt16ToPtr(x);
1738 }
1739 
SExtInt32ToPtr(GateRef x)1740 inline GateRef StubBuilder::SExtInt32ToPtr(GateRef x)
1741 {
1742     return env_->GetBuilder()->SExtInt32ToPtr(x);
1743 }
1744 
ZExtInt16ToInt32(GateRef x)1745 inline GateRef StubBuilder::ZExtInt16ToInt32(GateRef x)
1746 {
1747     return env_->GetBuilder()->ZExtInt16ToInt32(x);
1748 }
1749 
ZExtInt16ToInt64(GateRef x)1750 inline GateRef StubBuilder::ZExtInt16ToInt64(GateRef x)
1751 {
1752     return env_->GetBuilder()->ZExtInt16ToInt64(x);
1753 }
1754 
TruncInt64ToInt32(GateRef x)1755 inline GateRef StubBuilder::TruncInt64ToInt32(GateRef x)
1756 {
1757     return env_->GetBuilder()->TruncInt64ToInt32(x);
1758 }
1759 
TruncPtrToInt32(GateRef x)1760 inline GateRef StubBuilder::TruncPtrToInt32(GateRef x)
1761 {
1762     if (env_->Is32Bit()) {
1763         return x;
1764     }
1765     return TruncInt64ToInt32(x);
1766 }
1767 
TruncInt64ToInt1(GateRef x)1768 inline GateRef StubBuilder::TruncInt64ToInt1(GateRef x)
1769 {
1770     return env_->GetBuilder()->TruncInt64ToInt1(x);
1771 }
1772 
TruncInt32ToInt1(GateRef x)1773 inline GateRef StubBuilder::TruncInt32ToInt1(GateRef x)
1774 {
1775     return env_->GetBuilder()->TruncInt32ToInt1(x);
1776 }
1777 
GetObjectFromConstPool(GateRef constpool,GateRef index)1778 inline GateRef StubBuilder::GetObjectFromConstPool(GateRef constpool, GateRef index)
1779 {
1780     return GetValueFromTaggedArray(constpool, index);
1781 }
1782 
GetGlobalConstantAddr(GateRef index)1783 inline GateRef StubBuilder::GetGlobalConstantAddr(GateRef index)
1784 {
1785     return Int64Mul(Int64(sizeof(JSTaggedValue)), index);
1786 }
1787 
GetGlobalConstantString(ConstantIndex index)1788 inline GateRef StubBuilder::GetGlobalConstantString(ConstantIndex index)
1789 {
1790     if (env_->Is32Bit()) {
1791         return Int32Mul(Int32(sizeof(JSTaggedValue)), Int32(static_cast<int>(index)));
1792     } else {
1793         return Int64Mul(Int64(sizeof(JSTaggedValue)), Int64(static_cast<int>(index)));
1794     }
1795 }
1796 
IsCallableFromBitField(GateRef bitfield)1797 inline GateRef StubBuilder::IsCallableFromBitField(GateRef bitfield)
1798 {
1799     return env_->GetBuilder()->IsCallableFromBitField(bitfield);
1800 }
1801 
IsCallable(GateRef obj)1802 inline GateRef StubBuilder::IsCallable(GateRef obj)
1803 {
1804     ASM_ASSERT(GET_MESSAGE_STRING_ID(IsCallable), TaggedIsHeapObject(obj));
1805     GateRef res = env_->GetBuilder()->IsCallable(obj);
1806     EXITENTRY();
1807     return res;
1808 }
1809 
1810 // GetOffset func in property_attribute.h
GetOffsetFieldInPropAttr(GateRef attr)1811 inline GateRef StubBuilder::GetOffsetFieldInPropAttr(GateRef attr)
1812 {
1813     return Int32And(
1814         Int32LSR(attr, Int32(PropertyAttributes::OffsetField::START_BIT)),
1815         Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1));
1816 }
1817 
1818 // SetOffset func in property_attribute.h
SetOffsetFieldInPropAttr(GateRef attr,GateRef value)1819 inline GateRef StubBuilder::SetOffsetFieldInPropAttr(GateRef attr, GateRef value)
1820 {
1821     GateRef mask = Int32LSL(
1822         Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1),
1823         Int32(PropertyAttributes::OffsetField::START_BIT));
1824     GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
1825         Int32LSL(value, Int32(PropertyAttributes::OffsetField::START_BIT)));
1826     return newVal;
1827 }
1828 
1829 // SetIsInlinedProps func in property_attribute.h
SetIsInlinePropsFieldInPropAttr(GateRef attr,GateRef value)1830 inline GateRef StubBuilder::SetIsInlinePropsFieldInPropAttr(GateRef attr, GateRef value)
1831 {
1832     GateRef mask = Int32LSL(
1833         Int32((1LU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1),
1834         Int32(PropertyAttributes::IsInlinedPropsField::START_BIT));
1835     GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
1836         Int32LSL(value, Int32(PropertyAttributes::IsInlinedPropsField::START_BIT)));
1837     return newVal;
1838 }
1839 
SetHasConstructorToHClass(GateRef glue,GateRef hClass,GateRef value)1840 inline void StubBuilder::SetHasConstructorToHClass(GateRef glue, GateRef hClass, GateRef value)
1841 {
1842     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
1843     GateRef mask = Int32LSL(
1844         Int32((1LU << JSHClass::HasConstructorBits::SIZE) - 1),
1845         Int32(JSHClass::HasConstructorBits::START_BIT));
1846     GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
1847         Int32LSL(value, Int32(JSHClass::HasConstructorBits::START_BIT)));
1848     Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET), newVal);
1849 }
1850 
IntPtrEuqal(GateRef x,GateRef y)1851 inline GateRef StubBuilder::IntPtrEuqal(GateRef x, GateRef y)
1852 {
1853     return env_->Is32Bit() ? Int32Equal(x, y) : Int64Equal(x, y);
1854 }
1855 
GetBitMask(GateRef bitoffset)1856 inline GateRef StubBuilder::GetBitMask(GateRef bitoffset)
1857 {
1858     // BIT_PER_WORD_MASK
1859     GateRef bitPerWordMask = Int32(GCBitset::BIT_PER_WORD_MASK);
1860     // IndexInWord(bitOffset) = bitOffset & BIT_PER_WORD_MASK
1861     GateRef indexInWord = Int32And(bitoffset, bitPerWordMask);
1862     // Mask(indeInWord) = 1 << index
1863     return Int32LSL(Int32(1), indexInWord);
1864 }
1865 
ObjectAddressToRange(GateRef x)1866 inline GateRef StubBuilder::ObjectAddressToRange(GateRef x)
1867 {
1868     // This function may cause GateRef x is not an object. GC may not mark this x object.
1869     return IntPtrAnd(TaggedCastToIntPtr(x), IntPtr(~panda::ecmascript::DEFAULT_REGION_MASK));
1870 }
1871 
InYoungGeneration(GateRef region)1872 inline GateRef StubBuilder::InYoungGeneration(GateRef region)
1873 {
1874     auto offset = Region::PackedData::GetFlagOffset(env_->Is32Bit());
1875     GateRef x = Load(VariableType::NATIVE_POINTER(), PtrAdd(IntPtr(offset), region),
1876         IntPtr(0));
1877     if (env_->Is32Bit()) {
1878         return Int32Equal(Int32And(x,
1879             Int32(RegionSpaceFlag::VALID_SPACE_MASK)), Int32(RegionSpaceFlag::IN_YOUNG_SPACE));
1880     } else {
1881         return Int64Equal(Int64And(x,
1882             Int64(RegionSpaceFlag::VALID_SPACE_MASK)), Int64(RegionSpaceFlag::IN_YOUNG_SPACE));
1883     }
1884 }
1885 
GetParentEnv(GateRef object)1886 inline GateRef StubBuilder::GetParentEnv(GateRef object)
1887 {
1888     GateRef index = Int32(LexicalEnv::PARENT_ENV_INDEX);
1889     return GetValueFromTaggedArray(object, index);
1890 }
1891 
GetPropertiesFromLexicalEnv(GateRef object,GateRef index)1892 inline GateRef StubBuilder::GetPropertiesFromLexicalEnv(GateRef object, GateRef index)
1893 {
1894     GateRef valueIndex = Int32Add(index, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
1895     return GetValueFromTaggedArray(object, valueIndex);
1896 }
1897 
SetPropertiesToLexicalEnv(GateRef glue,GateRef object,GateRef index,GateRef value)1898 inline void StubBuilder::SetPropertiesToLexicalEnv(GateRef glue, GateRef object, GateRef index, GateRef value)
1899 {
1900     GateRef valueIndex = Int32Add(index, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
1901     SetValueToTaggedArray(VariableType::JS_ANY(), glue, object, valueIndex, value);
1902 }
1903 
GetHomeObjectFromJSFunction(GateRef object)1904 inline GateRef StubBuilder::GetHomeObjectFromJSFunction(GateRef object)
1905 {
1906     GateRef offset = IntPtr(JSFunction::HOME_OBJECT_OFFSET);
1907     return Load(VariableType::JS_ANY(), object, offset);
1908 }
1909 
GetMethodFromJSFunction(GateRef object)1910 inline GateRef StubBuilder::GetMethodFromJSFunction(GateRef object)
1911 {
1912     auto env = GetEnvironment();
1913     Label subentry(env);
1914     env->SubCfgEntry(&subentry);
1915 
1916     GateRef methodOffset;
1917     Label funcIsJSFunctionBase(env);
1918     Label funcIsJSProxy(env);
1919     Label getMethod(env);
1920     Branch(IsJSFunctionBase(object), &funcIsJSFunctionBase, &funcIsJSProxy);
1921     Bind(&funcIsJSFunctionBase);
1922     {
1923         methodOffset = IntPtr(JSFunctionBase::METHOD_OFFSET);
1924         Jump(&getMethod);
1925     }
1926     Bind(&funcIsJSProxy);
1927     {
1928         methodOffset = IntPtr(JSProxy::METHOD_OFFSET);
1929         Jump(&getMethod);
1930     }
1931     Bind(&getMethod);
1932     GateRef method = Load(VariableType::JS_ANY(), object, methodOffset);
1933     env->SubCfgExit();
1934     return method;
1935 }
1936 
GetCallFieldFromMethod(GateRef method)1937 inline GateRef StubBuilder::GetCallFieldFromMethod(GateRef method)
1938 {
1939     GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
1940     return Load(VariableType::INT64(), method, callFieldOffset);
1941 }
1942 
SetLexicalEnvToFunction(GateRef glue,GateRef object,GateRef lexicalEnv)1943 inline void StubBuilder::SetLexicalEnvToFunction(GateRef glue, GateRef object, GateRef lexicalEnv)
1944 {
1945     GateRef offset = IntPtr(JSFunction::LEXICAL_ENV_OFFSET);
1946     Store(VariableType::JS_ANY(), glue, object, offset, lexicalEnv);
1947 }
1948 
GetGlobalObject(GateRef glue)1949 inline GateRef StubBuilder::GetGlobalObject(GateRef glue)
1950 {
1951     GateRef offset = IntPtr(JSThread::GlueData::GetGlobalObjOffset(env_->Is32Bit()));
1952     return Load(VariableType::JS_ANY(), glue, offset);
1953 }
1954 
GetEntryIndexOfGlobalDictionary(GateRef entry)1955 inline GateRef StubBuilder::GetEntryIndexOfGlobalDictionary(GateRef entry)
1956 {
1957     return Int32Add(Int32(OrderTaggedHashTable<GlobalDictionary>::TABLE_HEADER_SIZE),
1958         Int32Mul(entry, Int32(GlobalDictionary::ENTRY_SIZE)));
1959 }
1960 
GetBoxFromGlobalDictionary(GateRef object,GateRef entry)1961 inline GateRef StubBuilder::GetBoxFromGlobalDictionary(GateRef object, GateRef entry)
1962 {
1963     GateRef index = GetEntryIndexOfGlobalDictionary(entry);
1964     GateRef offset = PtrAdd(ZExtInt32ToPtr(index),
1965         IntPtr(GlobalDictionary::ENTRY_VALUE_INDEX));
1966     return GetValueFromTaggedArray(object, offset);
1967 }
1968 
GetValueFromGlobalDictionary(GateRef object,GateRef entry)1969 inline GateRef StubBuilder::GetValueFromGlobalDictionary(GateRef object, GateRef entry)
1970 {
1971     GateRef box = GetBoxFromGlobalDictionary(object, entry);
1972     return Load(VariableType::JS_ANY(), box, IntPtr(PropertyBox::VALUE_OFFSET));
1973 }
1974 
GetPropertiesFromJSObject(GateRef object)1975 inline GateRef StubBuilder::GetPropertiesFromJSObject(GateRef object)
1976 {
1977     GateRef offset = IntPtr(JSObject::PROPERTIES_OFFSET);
1978     return Load(VariableType::JS_ANY(), object, offset);
1979 }
1980 
IsJSFunction(GateRef obj)1981 inline GateRef StubBuilder::IsJSFunction(GateRef obj)
1982 {
1983     GateRef objectType = GetObjectType(LoadHClass(obj));
1984     GateRef greater = Int32GreaterThanOrEqual(objectType,
1985         Int32(static_cast<int32_t>(JSType::JS_FUNCTION_FIRST)));
1986     GateRef less = Int32LessThanOrEqual(objectType,
1987         Int32(static_cast<int32_t>(JSType::JS_FUNCTION_LAST)));
1988     return BoolAnd(greater, less);
1989 }
1990 
IsBoundFunction(GateRef obj)1991 inline GateRef StubBuilder::IsBoundFunction(GateRef obj)
1992 {
1993     GateRef objectType = GetObjectType(LoadHClass(obj));
1994     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_BOUND_FUNCTION)));
1995 }
1996 
IsNativeMethod(GateRef method)1997 inline GateRef StubBuilder::IsNativeMethod(GateRef method)
1998 {
1999     GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2000     GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
2001     return Int64NotEqual(
2002         Int64And(
2003             Int64LSR(callfield, Int64(MethodLiteral::IsNativeBit::START_BIT)),
2004             Int64((1LU << MethodLiteral::IsNativeBit::SIZE) - 1)),
2005         Int64(0));
2006 }
2007 
HasAotCode(GateRef method)2008 inline GateRef StubBuilder::HasAotCode(GateRef method)
2009 {
2010     GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2011     GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
2012     return Int64NotEqual(
2013         Int64And(
2014             Int64LSR(callfield, Int64(MethodLiteral::IsAotCodeBit::START_BIT)),
2015             Int64((1LU << MethodLiteral::IsAotCodeBit::SIZE) - 1)),
2016         Int64(0));
2017 }
2018 
GetExpectedNumOfArgs(GateRef method)2019 inline GateRef StubBuilder::GetExpectedNumOfArgs(GateRef method)
2020 {
2021     GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2022     GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
2023     return TruncInt64ToInt32(Int64And(
2024         Int64LSR(callfield, Int64(MethodLiteral::NumArgsBits::START_BIT)),
2025         Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1)));
2026 }
2027 
GetMethodFromJSProxy(GateRef proxy)2028 inline GateRef StubBuilder::GetMethodFromJSProxy(GateRef proxy)
2029 {
2030     GateRef offset = IntPtr(JSProxy::METHOD_OFFSET);
2031     return Load(VariableType::JS_ANY(), proxy, offset);
2032 }
2033 
GetHandlerFromJSProxy(GateRef proxy)2034 inline GateRef StubBuilder::GetHandlerFromJSProxy(GateRef proxy)
2035 {
2036     GateRef offset = IntPtr(JSProxy::HANDLER_OFFSET);
2037     return Load(VariableType::JS_ANY(), proxy, offset);
2038 }
2039 
GetTargetFromJSProxy(GateRef proxy)2040 inline GateRef StubBuilder::GetTargetFromJSProxy(GateRef proxy)
2041 {
2042     GateRef offset = IntPtr(JSProxy::TARGET_OFFSET);
2043     return Load(VariableType::JS_ANY(), proxy, offset);
2044 }
2045 
ComputeTaggedArraySize(GateRef length)2046 inline GateRef StubBuilder::ComputeTaggedArraySize(GateRef length)
2047 {
2048     return PtrAdd(IntPtr(TaggedArray::DATA_OFFSET),
2049         PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), length));
2050 }
2051 
GetGlobalConstantValue(VariableType type,GateRef glue,ConstantIndex index)2052 inline GateRef StubBuilder::GetGlobalConstantValue(VariableType type, GateRef glue, ConstantIndex index)
2053 {
2054     GateRef gConstAddr = PtrAdd(glue,
2055         IntPtr(JSThread::GlueData::GetGlobalConstOffset(env_->Is32Bit())));
2056     auto constantIndex = IntPtr(JSTaggedValue::TaggedTypeSize() * static_cast<size_t>(index));
2057     return Load(type, gConstAddr, constantIndex);
2058 }
2059 
GetGlobalEnvValue(VariableType type,GateRef env,size_t index)2060 inline GateRef StubBuilder::GetGlobalEnvValue(VariableType type, GateRef env, size_t index)
2061 {
2062     auto valueIndex = IntPtr(GlobalEnv::HEADER_SIZE + JSTaggedValue::TaggedTypeSize() * index);
2063     return Load(type, env, valueIndex);
2064 }
2065 
HasPendingException(GateRef glue)2066 inline GateRef StubBuilder::HasPendingException(GateRef glue)
2067 {
2068     GateRef exceptionOffset = IntPtr(JSThread::GlueData::GetExceptionOffset(env_->IsArch32Bit()));
2069     GateRef exception = Load(VariableType::JS_ANY(), glue, exceptionOffset);
2070     return TaggedIsNotHole(exception);
2071 }
2072 
DispatchBuiltins(GateRef glue,GateRef builtinsId,const std::initializer_list<GateRef> & args)2073 inline GateRef StubBuilder::DispatchBuiltins(GateRef glue, GateRef builtinsId,
2074                                              const std::initializer_list<GateRef>& args)
2075 {
2076     GateRef target = PtrMul(ZExtInt32ToPtr(builtinsId), IntPtrSize());
2077     return env_->GetBuilder()->CallBuiltin(glue, target, args);
2078 }
2079 
DispatchBuiltinsWithArgv(GateRef glue,GateRef builtinsId,const std::initializer_list<GateRef> & args)2080 inline GateRef StubBuilder::DispatchBuiltinsWithArgv(GateRef glue, GateRef builtinsId,
2081                                                      const std::initializer_list<GateRef>& args)
2082 {
2083     GateRef target = PtrMul(ZExtInt32ToPtr(builtinsId), IntPtrSize());
2084     return env_->GetBuilder()->CallBuiltinWithArgv(glue, target, args);
2085 }
2086 
GetBuiltinId(GateRef method)2087 inline GateRef StubBuilder::GetBuiltinId(GateRef method)
2088 {
2089     GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
2090     GateRef extraLiteralInfo = Load(VariableType::INT64(), method, extraLiteralInfoOffset);
2091     return TruncInt64ToInt32(Int64And(
2092         Int64LSR(extraLiteralInfo, Int64(MethodLiteral::BuiltinIdBits::START_BIT)),
2093         Int64((1LU << MethodLiteral::BuiltinIdBits::SIZE) - 1)));
2094 }
2095 
ComputeSizeUtf8(GateRef length)2096 inline GateRef StubBuilder::ComputeSizeUtf8(GateRef length)
2097 {
2098     return PtrAdd(IntPtr(EcmaString::DATA_OFFSET), length);
2099 }
2100 
ComputeSizeUtf16(GateRef length)2101 inline GateRef StubBuilder::ComputeSizeUtf16(GateRef length)
2102 {
2103     return PtrAdd(IntPtr(EcmaString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t))));
2104 }
2105 
AlignUp(GateRef x,GateRef alignment)2106 inline GateRef StubBuilder::AlignUp(GateRef x, GateRef alignment)
2107 {
2108     GateRef x1 = PtrAdd(x, PtrSub(alignment, IntPtr(1)));
2109     return IntPtrAnd(x1, IntPtrNot(PtrSub(alignment, IntPtr(1))));
2110 }
2111 
SetLength(GateRef glue,GateRef str,GateRef length,bool compressed)2112 inline void StubBuilder::SetLength(GateRef glue, GateRef str, GateRef length, bool compressed)
2113 {
2114     GateRef len = Int32LSL(length, Int32(2));
2115     GateRef mixLength;
2116     if (compressed) {
2117         mixLength = Int32Or(len, Int32(EcmaString::STRING_COMPRESSED));
2118     } else {
2119         mixLength = Int32Or(len, Int32(EcmaString::STRING_UNCOMPRESSED));
2120     }
2121     Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::MIX_LENGTH_OFFSET), mixLength);
2122 }
2123 
SetRawHashcode(GateRef glue,GateRef str,GateRef rawHashcode)2124 inline void StubBuilder::SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode)
2125 {
2126     Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::HASHCODE_OFFSET), rawHashcode);
2127 }
2128 
SetExtensibleToBitfield(GateRef glue,GateRef obj,bool isExtensible)2129 inline void StubBuilder::SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible)
2130 {
2131     GateRef jsHclass = LoadHClass(obj);
2132     GateRef bitfield = Load(VariableType::INT32(), jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
2133     GateRef boolVal = Boolean(isExtensible);
2134     GateRef boolToInt32 = ZExtInt1ToInt32(boolVal);
2135     GateRef encodeValue = Int32LSL(boolToInt32, Int32(JSHClass::ExtensibleBit::START_BIT));
2136     GateRef mask = Int32(((1LU << JSHClass::ExtensibleBit::SIZE) - 1) << JSHClass::ExtensibleBit::START_BIT);
2137     bitfield = Int32Or(Int32And(bitfield, Int32Not(mask)), encodeValue);
2138     Store(VariableType::INT32(), glue, jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET), bitfield);
2139 }
2140 } //  namespace panda::ecmascript::kungfu
2141 #endif // ECMASCRIPT_COMPILER_STUB_INL_H
2142