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