• 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, GateRef glue, GateRef hClass, GateRef protoChange)
1550 {
1551     GateRef offset = IntPtr(JSHClass::PROTO_CHANGE_DETAILS_OFFSET);
1552     Store(type, glue, hClass, offset, protoChange);
1553 }
1554 
SetLayoutToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef attr)1555 inline void StubBuilder::SetLayoutToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef attr)
1556 {
1557     GateRef offset = IntPtr(JSHClass::LAYOUT_OFFSET);
1558     Store(type, glue, hClass, offset, attr);
1559 }
1560 
SetEnumCacheToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef key)1561 inline void StubBuilder::SetEnumCacheToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef key)
1562 {
1563     GateRef offset = IntPtr(JSHClass::ENUM_CACHE_OFFSET);
1564     Store(type, glue, hClass, offset, key);
1565 }
1566 
SetTransitionsToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef transition)1567 inline void StubBuilder::SetTransitionsToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef transition)
1568 {
1569     GateRef offset = IntPtr(JSHClass::TRANSTIONS_OFFSET);
1570     Store(type, glue, hClass, offset, transition);
1571 }
1572 
SetIsProtoTypeToHClass(GateRef glue,GateRef hClass,GateRef value)1573 inline void StubBuilder::SetIsProtoTypeToHClass(GateRef glue, GateRef hClass, GateRef value)
1574 {
1575     GateRef oldValue = ZExtInt1ToInt32(value);
1576     GateRef bitfield = GetBitFieldFromHClass(hClass);
1577     GateRef mask = Int32LSL(
1578         Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1),
1579         Int32(JSHClass::IsPrototypeBit::START_BIT));
1580     GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
1581         Int32LSL(oldValue, Int32(JSHClass::IsPrototypeBit::START_BIT)));
1582     SetBitFieldToHClass(glue, hClass, newVal);
1583 }
1584 
IsProtoTypeHClass(GateRef hClass)1585 inline GateRef StubBuilder::IsProtoTypeHClass(GateRef hClass)
1586 {
1587     GateRef bitfield = GetBitFieldFromHClass(hClass);
1588     return TruncInt32ToInt1(Int32And(Int32LSR(bitfield,
1589         Int32(JSHClass::IsPrototypeBit::START_BIT)),
1590         Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1)));
1591 }
1592 
SetPropertyInlinedProps(GateRef glue,GateRef obj,GateRef hClass,GateRef value,GateRef attrOffset,VariableType type)1593 inline void StubBuilder::SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass,
1594     GateRef value, GateRef attrOffset, VariableType type)
1595 {
1596     ASM_ASSERT_WITH_GLUE(GET_MESSAGE_STRING_ID(IsNotDictionaryMode), BoolNot(IsDictionaryModeByHClass(hClass)), glue);
1597     GateRef bitfield = Load(VariableType::INT32(), hClass,
1598                             IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1599     GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield,
1600         Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1601         Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1602     GateRef propOffset = Int32Mul(
1603         Int32Add(inlinedPropsStart, attrOffset), Int32(JSTaggedValue::TaggedTypeSize()));
1604 
1605     // NOTE: need to translate MarkingBarrier
1606     Store(type, glue, obj, ZExtInt32ToPtr(propOffset), value);
1607     EXITENTRY();
1608 }
1609 
GetPropertyInlinedProps(GateRef obj,GateRef hClass,GateRef index)1610 inline GateRef StubBuilder::GetPropertyInlinedProps(GateRef obj, GateRef hClass,
1611     GateRef index)
1612 {
1613     GateRef inlinedPropsStart = GetInlinedPropsStartFromHClass(hClass);
1614     GateRef propOffset = Int32Mul(
1615         Int32Add(inlinedPropsStart, index), Int32(JSTaggedValue::TaggedTypeSize()));
1616     return Load(VariableType::JS_ANY(), obj, ZExtInt32ToInt64(propOffset));
1617 }
1618 
GetInlinedPropOffsetFromHClass(GateRef hclass,GateRef index)1619 inline GateRef StubBuilder::GetInlinedPropOffsetFromHClass(GateRef hclass, GateRef index)
1620 {
1621     GateRef inlinedPropsStart = GetInlinedPropsStartFromHClass(hclass);
1622     GateRef propOffset = Int32Mul(
1623         Int32Add(inlinedPropsStart, index), Int32(JSTaggedValue::TaggedTypeSize()));
1624     return ZExtInt32ToInt64(propOffset);
1625 }
1626 
IncNumberOfProps(GateRef glue,GateRef hClass)1627 inline void StubBuilder::IncNumberOfProps(GateRef glue, GateRef hClass)
1628 {
1629     GateRef propNums = GetNumberOfPropsFromHClass(hClass);
1630     SetNumberOfPropsToHClass(glue, hClass, Int32Add(propNums, Int32(1)));
1631 }
1632 
GetNumberOfPropsFromHClass(GateRef hClass)1633 inline GateRef StubBuilder::GetNumberOfPropsFromHClass(GateRef hClass)
1634 {
1635     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1636     return Int32And(Int32LSR(bitfield,
1637         Int32(JSHClass::NumberOfPropsBits::START_BIT)),
1638         Int32((1LLU << JSHClass::NumberOfPropsBits::SIZE) - 1));
1639 }
1640 
IsTSHClass(GateRef hClass)1641 inline GateRef StubBuilder::IsTSHClass(GateRef hClass)
1642 {
1643     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
1644     return Int32NotEqual(Int32And(Int32LSR(bitfield,
1645         Int32(JSHClass::IsTSBit::START_BIT)),
1646         Int32((1LU << JSHClass::IsTSBit::SIZE) - 1)),
1647         Int32(0));
1648 }
1649 
SetNumberOfPropsToHClass(GateRef glue,GateRef hClass,GateRef value)1650 inline void StubBuilder::SetNumberOfPropsToHClass(GateRef glue, GateRef hClass, GateRef value)
1651 {
1652     GateRef bitfield1 = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1653     GateRef oldWithMask = Int32And(bitfield1,
1654         Int32(~static_cast<uint32_t>(JSHClass::NumberOfPropsBits::Mask())));
1655     GateRef newValue = Int32LSR(value, Int32(JSHClass::NumberOfPropsBits::START_BIT));
1656     Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET),
1657         Int32Or(oldWithMask, newValue));
1658 }
1659 
GetInlinedPropertiesFromHClass(GateRef hClass)1660 inline GateRef StubBuilder::GetInlinedPropertiesFromHClass(GateRef hClass)
1661 {
1662     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1663     GateRef objectSizeInWords = Int32And(Int32LSR(bitfield,
1664         Int32(JSHClass::ObjectSizeInWordsBits::START_BIT)),
1665         Int32((1LU << JSHClass::ObjectSizeInWordsBits::SIZE) - 1));
1666     GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield,
1667         Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1668         Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1669     return Int32Sub(objectSizeInWords, inlinedPropsStart);
1670 }
1671 
GetElementsKindFromHClass(GateRef hClass)1672 inline GateRef StubBuilder::GetElementsKindFromHClass(GateRef hClass)
1673 {
1674     return env_->GetBuilder()->GetElementsKindByHClass(hClass);
1675 }
1676 
GetObjectSizeFromHClass(GateRef hClass)1677 inline GateRef StubBuilder::GetObjectSizeFromHClass(GateRef hClass)
1678 {
1679     return env_->GetBuilder()->GetObjectSizeFromHClass(hClass);
1680 }
1681 
GetInlinedPropsStartFromHClass(GateRef hClass)1682 inline GateRef StubBuilder::GetInlinedPropsStartFromHClass(GateRef hClass)
1683 {
1684     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1685     return Int32And(Int32LSR(bitfield,
1686         Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1687         Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1688 }
1689 
SetValueToTaggedArrayWithAttr(GateRef glue,GateRef array,GateRef index,GateRef key,GateRef val,GateRef attr)1690 inline void StubBuilder::SetValueToTaggedArrayWithAttr(
1691     GateRef glue, GateRef array, GateRef index, GateRef key, GateRef val, GateRef attr)
1692 {
1693     GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1694     GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1695     SetValueWithAttr(glue, array, dataOffset, key, val, attr);
1696 }
1697 
SetValueToTaggedArrayWithRep(GateRef glue,GateRef array,GateRef index,GateRef val,GateRef rep,Label * repChange)1698 inline void StubBuilder::SetValueToTaggedArrayWithRep(
1699     GateRef glue, GateRef array, GateRef index, GateRef val, GateRef rep, Label *repChange)
1700 {
1701     GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1702     GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1703     SetValueWithRep(glue, array, dataOffset, val, rep, repChange);
1704 }
1705 
SetValueToTaggedArray(VariableType valType,GateRef glue,GateRef array,GateRef index,GateRef val)1706 inline void StubBuilder::SetValueToTaggedArray(VariableType valType, GateRef glue, GateRef array,
1707                                                GateRef index, GateRef val)
1708 {
1709     // NOTE: need to translate MarkingBarrier
1710     GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1711     GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1712     Store(valType, glue, array, dataOffset, val);
1713 }
1714 
GetValueFromTaggedArray(GateRef array,GateRef index)1715 inline GateRef StubBuilder::GetValueFromTaggedArray(GateRef array, GateRef index)
1716 {
1717     GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1718     GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1719     return Load(VariableType::JS_ANY(), array, dataOffset);
1720 }
1721 
IsSpecialIndexedObj(GateRef jsType)1722 inline GateRef StubBuilder::IsSpecialIndexedObj(GateRef jsType)
1723 {
1724     return Int32GreaterThan(jsType, Int32(static_cast<int32_t>(JSType::JS_ARRAY)));
1725 }
1726 
IsSpecialContainer(GateRef jsType)1727 inline GateRef StubBuilder::IsSpecialContainer(GateRef jsType)
1728 {
1729     // arraylist and vector has fast pass now
1730     return BoolAnd(
1731         Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST))),
1732         Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_API_VECTOR))));
1733 }
1734 
IsFastTypeArray(GateRef jsType)1735 inline GateRef StubBuilder::IsFastTypeArray(GateRef jsType)
1736 {
1737     return BoolAnd(
1738             Int32GreaterThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_FIRST))),
1739             Int32LessThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::JS_FLOAT64_ARRAY))));
1740 }
1741 
IsAccessorInternal(GateRef value)1742 inline GateRef StubBuilder::IsAccessorInternal(GateRef value)
1743 {
1744     return Int32Equal(GetObjectType(LoadHClass(value)),
1745                       Int32(static_cast<int32_t>(JSType::INTERNAL_ACCESSOR)));
1746 }
1747 
GetPropAttrFromLayoutInfo(GateRef layout,GateRef entry)1748 inline GateRef StubBuilder::GetPropAttrFromLayoutInfo(GateRef layout, GateRef entry)
1749 {
1750     GateRef index = Int32Add(Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2)),
1751         Int32(LayoutInfo::ATTR_INDEX_OFFSET));
1752     return GetInt64OfTInt(GetValueFromTaggedArray(layout, index));
1753 }
1754 
SetPropAttrToLayoutInfo(GateRef glue,GateRef layout,GateRef entry,GateRef attr)1755 inline void StubBuilder::SetPropAttrToLayoutInfo(GateRef glue, GateRef layout, GateRef entry, GateRef attr)
1756 {
1757     GateRef index = Int32Add(Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2)),
1758         Int32(LayoutInfo::ATTR_INDEX_OFFSET));
1759     GateRef taggedAttr = Int64ToTaggedInt(ZExtInt32ToInt64(attr));
1760     SetValueToTaggedArray(VariableType::JS_ANY(), glue, layout, index, taggedAttr);
1761 }
1762 
GetPropertyMetaDataFromAttr(GateRef attr)1763 inline GateRef StubBuilder::GetPropertyMetaDataFromAttr(GateRef attr)
1764 {
1765     return Int32And(Int32LSR(attr, Int32(PropertyAttributes::PropertyMetaDataField::START_BIT)),
1766         Int32((1LLU << PropertyAttributes::PropertyMetaDataField::SIZE) - 1));
1767 }
1768 
GetKeyFromLayoutInfo(GateRef layout,GateRef entry)1769 inline GateRef StubBuilder::GetKeyFromLayoutInfo(GateRef layout, GateRef entry)
1770 {
1771     GateRef index = Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2));
1772     return GetValueFromTaggedArray(layout, index);
1773 }
1774 
GetPropertiesAddrFromLayoutInfo(GateRef layout)1775 inline GateRef StubBuilder::GetPropertiesAddrFromLayoutInfo(GateRef layout)
1776 {
1777     return PtrAdd(layout, IntPtr(TaggedArray::DATA_OFFSET));
1778 }
1779 
GetInt64OfTInt(GateRef x)1780 inline GateRef StubBuilder::GetInt64OfTInt(GateRef x)
1781 {
1782     return env_->GetBuilder()->GetInt64OfTInt(x);
1783 }
1784 
GetInt32OfTInt(GateRef x)1785 inline GateRef StubBuilder::GetInt32OfTInt(GateRef x)
1786 {
1787     return TruncInt64ToInt32(GetInt64OfTInt(x));
1788 }
1789 
TaggedCastToIntPtr(GateRef x)1790 inline GateRef StubBuilder::TaggedCastToIntPtr(GateRef x)
1791 {
1792     return env_->Is32Bit() ? TruncInt64ToInt32(GetInt64OfTInt(x)) : GetInt64OfTInt(x);
1793 }
1794 
GetDoubleOfTInt(GateRef x)1795 inline GateRef StubBuilder::GetDoubleOfTInt(GateRef x)
1796 {
1797     return ChangeInt32ToFloat64(GetInt32OfTInt(x));
1798 }
1799 
GetDoubleOfTDouble(GateRef x)1800 inline GateRef StubBuilder::GetDoubleOfTDouble(GateRef x)
1801 {
1802     return env_->GetBuilder()->GetDoubleOfTDouble(x);
1803 }
1804 
GetDoubleOfTNumber(GateRef x)1805 inline GateRef StubBuilder::GetDoubleOfTNumber(GateRef x)
1806 {
1807     return env_->GetBuilder()->GetDoubleOfTNumber(x);
1808 }
1809 
LoadObjectFromWeakRef(GateRef x)1810 inline GateRef StubBuilder::LoadObjectFromWeakRef(GateRef x)
1811 {
1812     return env_->GetBuilder()->LoadObjectFromWeakRef(x);
1813 }
1814 
ExtFloat32ToDouble(GateRef x)1815 inline GateRef StubBuilder::ExtFloat32ToDouble(GateRef x)
1816 {
1817     return env_->GetBuilder()->ExtFloat32ToDouble(x);
1818 }
1819 
ChangeInt32ToFloat32(GateRef x)1820 inline GateRef StubBuilder::ChangeInt32ToFloat32(GateRef x)
1821 {
1822     return env_->GetBuilder()->ChangeInt32ToFloat32(x);
1823 }
1824 
ChangeInt32ToFloat64(GateRef x)1825 inline GateRef StubBuilder::ChangeInt32ToFloat64(GateRef x)
1826 {
1827     return env_->GetBuilder()->ChangeInt32ToFloat64(x);
1828 }
1829 
ChangeUInt32ToFloat64(GateRef x)1830 inline GateRef StubBuilder::ChangeUInt32ToFloat64(GateRef x)
1831 {
1832     return env_->GetBuilder()->ChangeUInt32ToFloat64(x);
1833 }
1834 
ChangeFloat64ToInt32(GateRef x)1835 inline GateRef StubBuilder::ChangeFloat64ToInt32(GateRef x)
1836 {
1837     return env_->GetBuilder()->ChangeFloat64ToInt32(x);
1838 }
1839 
ChangeTaggedPointerToInt64(GateRef x)1840 inline GateRef StubBuilder::ChangeTaggedPointerToInt64(GateRef x)
1841 {
1842     return env_->GetBuilder()->ChangeTaggedPointerToInt64(x);
1843 }
1844 
Int64ToTaggedPtr(GateRef x)1845 inline GateRef StubBuilder::Int64ToTaggedPtr(GateRef x)
1846 {
1847     return env_->GetBuilder()->Int64ToTaggedPtr(x);
1848 }
1849 
CastInt32ToFloat32(GateRef x)1850 inline GateRef StubBuilder::CastInt32ToFloat32(GateRef x)
1851 {
1852     return env_->GetBuilder()->CastInt32ToFloat32(x);
1853 }
1854 
CastInt64ToFloat64(GateRef x)1855 inline GateRef StubBuilder::CastInt64ToFloat64(GateRef x)
1856 {
1857     return env_->GetBuilder()->CastInt64ToFloat64(x);
1858 }
1859 
SExtInt32ToInt64(GateRef x)1860 inline GateRef StubBuilder::SExtInt32ToInt64(GateRef x)
1861 {
1862     return env_->GetBuilder()->SExtInt32ToInt64(x);
1863 }
1864 
SExtInt16ToInt64(GateRef x)1865 inline GateRef StubBuilder::SExtInt16ToInt64(GateRef x)
1866 {
1867     return env_->GetBuilder()->SExtInt16ToInt64(x);
1868 }
1869 
SExtInt8ToInt64(GateRef x)1870 inline GateRef StubBuilder::SExtInt8ToInt64(GateRef x)
1871 {
1872     return env_->GetBuilder()->SExtInt8ToInt64(x);
1873 }
1874 
SExtInt8ToInt32(GateRef x)1875 inline GateRef StubBuilder::SExtInt8ToInt32(GateRef x)
1876 {
1877     return env_->GetBuilder()->SExtInt8ToInt32(x);
1878 }
1879 
SExtInt16ToInt32(GateRef x)1880 inline GateRef StubBuilder::SExtInt16ToInt32(GateRef x)
1881 {
1882     return env_->GetBuilder()->SExtInt16ToInt32(x);
1883 }
1884 
SExtInt1ToInt64(GateRef x)1885 inline GateRef StubBuilder::SExtInt1ToInt64(GateRef x)
1886 {
1887     return env_->GetBuilder()->SExtInt1ToInt64(x);
1888 }
1889 
SExtInt1ToInt32(GateRef x)1890 inline GateRef StubBuilder::SExtInt1ToInt32(GateRef x)
1891 {
1892     return env_->GetBuilder()->SExtInt1ToInt32(x);
1893 }
1894 
ZExtInt8ToInt16(GateRef x)1895 inline GateRef StubBuilder::ZExtInt8ToInt16(GateRef x)
1896 {
1897     return env_->GetBuilder()->ZExtInt8ToInt16(x);
1898 }
1899 
ZExtInt32ToInt64(GateRef x)1900 inline GateRef StubBuilder::ZExtInt32ToInt64(GateRef x)
1901 {
1902     return env_->GetBuilder()->ZExtInt32ToInt64(x);
1903 }
1904 
ZExtInt1ToInt64(GateRef x)1905 inline GateRef StubBuilder::ZExtInt1ToInt64(GateRef x)
1906 {
1907     return env_->GetBuilder()->ZExtInt1ToInt64(x);
1908 }
1909 
ZExtInt1ToInt32(GateRef x)1910 inline GateRef StubBuilder::ZExtInt1ToInt32(GateRef x)
1911 {
1912     return env_->GetBuilder()->ZExtInt1ToInt32(x);
1913 }
1914 
ZExtInt8ToInt32(GateRef x)1915 inline GateRef StubBuilder::ZExtInt8ToInt32(GateRef x)
1916 {
1917     return env_->GetBuilder()->ZExtInt8ToInt32(x);
1918 }
1919 
ZExtInt8ToInt64(GateRef x)1920 inline GateRef StubBuilder::ZExtInt8ToInt64(GateRef x)
1921 {
1922     return env_->GetBuilder()->ZExtInt8ToInt64(x);
1923 }
1924 
ZExtInt8ToPtr(GateRef x)1925 inline GateRef StubBuilder::ZExtInt8ToPtr(GateRef x)
1926 {
1927     return env_->GetBuilder()->ZExtInt8ToPtr(x);
1928 }
1929 
ZExtInt16ToPtr(GateRef x)1930 inline GateRef StubBuilder::ZExtInt16ToPtr(GateRef x)
1931 {
1932     return env_->GetBuilder()->ZExtInt16ToPtr(x);
1933 }
1934 
SExtInt32ToPtr(GateRef x)1935 inline GateRef StubBuilder::SExtInt32ToPtr(GateRef x)
1936 {
1937     return env_->GetBuilder()->SExtInt32ToPtr(x);
1938 }
1939 
ZExtInt16ToInt32(GateRef x)1940 inline GateRef StubBuilder::ZExtInt16ToInt32(GateRef x)
1941 {
1942     return env_->GetBuilder()->ZExtInt16ToInt32(x);
1943 }
1944 
ZExtInt16ToInt64(GateRef x)1945 inline GateRef StubBuilder::ZExtInt16ToInt64(GateRef x)
1946 {
1947     return env_->GetBuilder()->ZExtInt16ToInt64(x);
1948 }
1949 
TruncInt64ToInt32(GateRef x)1950 inline GateRef StubBuilder::TruncInt64ToInt32(GateRef x)
1951 {
1952     return env_->GetBuilder()->TruncInt64ToInt32(x);
1953 }
1954 
TruncPtrToInt32(GateRef x)1955 inline GateRef StubBuilder::TruncPtrToInt32(GateRef x)
1956 {
1957     if (env_->Is32Bit()) {
1958         return x;
1959     }
1960     return TruncInt64ToInt32(x);
1961 }
1962 
TruncInt64ToInt1(GateRef x)1963 inline GateRef StubBuilder::TruncInt64ToInt1(GateRef x)
1964 {
1965     return env_->GetBuilder()->TruncInt64ToInt1(x);
1966 }
1967 
TruncInt32ToInt1(GateRef x)1968 inline GateRef StubBuilder::TruncInt32ToInt1(GateRef x)
1969 {
1970     return env_->GetBuilder()->TruncInt32ToInt1(x);
1971 }
1972 
GetObjectFromConstPool(GateRef constpool,GateRef index)1973 inline GateRef StubBuilder::GetObjectFromConstPool(GateRef constpool, GateRef index)
1974 {
1975     return GetValueFromTaggedArray(constpool, index);
1976 }
1977 
GetGlobalConstantAddr(GateRef index)1978 inline GateRef StubBuilder::GetGlobalConstantAddr(GateRef index)
1979 {
1980     return Int64Mul(Int64(sizeof(JSTaggedValue)), index);
1981 }
1982 
GetGlobalConstantString(ConstantIndex index)1983 inline GateRef StubBuilder::GetGlobalConstantString(ConstantIndex index)
1984 {
1985     if (env_->Is32Bit()) {
1986         return Int32Mul(Int32(sizeof(JSTaggedValue)), Int32(static_cast<int>(index)));
1987     } else {
1988         return Int64Mul(Int64(sizeof(JSTaggedValue)), Int64(static_cast<int>(index)));
1989     }
1990 }
1991 
IsCallableFromBitField(GateRef bitfield)1992 inline GateRef StubBuilder::IsCallableFromBitField(GateRef bitfield)
1993 {
1994     return env_->GetBuilder()->IsCallableFromBitField(bitfield);
1995 }
1996 
IsCallable(GateRef obj)1997 inline GateRef StubBuilder::IsCallable(GateRef obj)
1998 {
1999     ASM_ASSERT(GET_MESSAGE_STRING_ID(IsCallable), TaggedIsHeapObject(obj));
2000     GateRef res = env_->GetBuilder()->IsCallable(obj);
2001     EXITENTRY();
2002     return res;
2003 }
2004 
2005 // GetOffset func in property_attribute.h
GetOffsetFieldInPropAttr(GateRef attr)2006 inline GateRef StubBuilder::GetOffsetFieldInPropAttr(GateRef attr)
2007 {
2008     return Int32And(
2009         Int32LSR(attr, Int32(PropertyAttributes::OffsetField::START_BIT)),
2010         Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1));
2011 }
2012 
2013 // SetOffset func in property_attribute.h
SetOffsetFieldInPropAttr(GateRef attr,GateRef value)2014 inline GateRef StubBuilder::SetOffsetFieldInPropAttr(GateRef attr, GateRef value)
2015 {
2016     GateRef mask = Int32LSL(
2017         Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1),
2018         Int32(PropertyAttributes::OffsetField::START_BIT));
2019     GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
2020         Int32LSL(value, Int32(PropertyAttributes::OffsetField::START_BIT)));
2021     return newVal;
2022 }
2023 
2024 // SetIsInlinedProps func in property_attribute.h
SetIsInlinePropsFieldInPropAttr(GateRef attr,GateRef value)2025 inline GateRef StubBuilder::SetIsInlinePropsFieldInPropAttr(GateRef attr, GateRef value)
2026 {
2027     GateRef mask = Int32LSL(
2028         Int32((1LU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1),
2029         Int32(PropertyAttributes::IsInlinedPropsField::START_BIT));
2030     GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
2031         Int32LSL(value, Int32(PropertyAttributes::IsInlinedPropsField::START_BIT)));
2032     return newVal;
2033 }
2034 
2035 
SetTrackTypeInPropAttr(GateRef attr,GateRef type)2036 inline GateRef StubBuilder::SetTrackTypeInPropAttr(GateRef attr, GateRef type)
2037 {
2038     GateRef mask = Int32LSL(
2039         Int32((1LU << PropertyAttributes::TrackTypeField::SIZE) - 1),
2040         Int32(PropertyAttributes::TrackTypeField::START_BIT));
2041     GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
2042         Int32LSL(type, Int32(PropertyAttributes::TrackTypeField::START_BIT)));
2043     return newVal;
2044 }
2045 
GetTrackTypeInPropAttr(GateRef attr)2046 inline GateRef StubBuilder::GetTrackTypeInPropAttr(GateRef attr)
2047 {
2048     return Int32And(
2049         Int32LSR(attr, Int32(PropertyAttributes::TrackTypeField::START_BIT)),
2050         Int32((1LLU << PropertyAttributes::TrackTypeField::SIZE) - 1));
2051 }
2052 
GetRepInPropAttr(GateRef attr)2053 inline GateRef StubBuilder::GetRepInPropAttr(GateRef attr)
2054 {
2055     return Int32And(
2056         Int32LSR(attr, Int32(PropertyAttributes::RepresentationField::START_BIT)),
2057         Int32((1LLU << PropertyAttributes::RepresentationField::SIZE) - 1));
2058 }
2059 
IsIntRepInPropAttr(GateRef rep)2060 inline GateRef StubBuilder::IsIntRepInPropAttr(GateRef rep)
2061 {
2062     return Int32Equal(rep, Int32(static_cast<int32_t>(Representation::INT)));
2063 }
2064 
IsDoubleRepInPropAttr(GateRef rep)2065 inline GateRef StubBuilder::IsDoubleRepInPropAttr(GateRef rep)
2066 {
2067     return Int32Equal(rep, Int32(static_cast<int32_t>(Representation::DOUBLE)));
2068 }
2069 
SetTaggedRepInPropAttr(GateRef attr)2070 inline GateRef StubBuilder::SetTaggedRepInPropAttr(GateRef attr)
2071 {
2072     GateRef mask = Int32LSL(
2073         Int32((1LU << PropertyAttributes::RepresentationField::SIZE) - 1),
2074         Int32(PropertyAttributes::RepresentationField::START_BIT));
2075     GateRef targetType = Int32(static_cast<int32_t>(Representation::TAGGED));
2076     GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
2077         Int32LSL(targetType, Int32(PropertyAttributes::RepresentationField::START_BIT)));
2078     return newVal;
2079 }
2080 
SetHasConstructorToHClass(GateRef glue,GateRef hClass,GateRef value)2081 inline void StubBuilder::SetHasConstructorToHClass(GateRef glue, GateRef hClass, GateRef value)
2082 {
2083     GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
2084     GateRef mask = Int32LSL(
2085         Int32((1LU << JSHClass::HasConstructorBits::SIZE) - 1),
2086         Int32(JSHClass::HasConstructorBits::START_BIT));
2087     GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
2088         Int32LSL(value, Int32(JSHClass::HasConstructorBits::START_BIT)));
2089     Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET), newVal);
2090 }
2091 
IntPtrEuqal(GateRef x,GateRef y)2092 inline GateRef StubBuilder::IntPtrEuqal(GateRef x, GateRef y)
2093 {
2094     return env_->Is32Bit() ? Int32Equal(x, y) : Int64Equal(x, y);
2095 }
2096 
GetBitMask(GateRef bitoffset)2097 inline GateRef StubBuilder::GetBitMask(GateRef bitoffset)
2098 {
2099     // BIT_PER_WORD_MASK
2100     GateRef bitPerWordMask = Int32(GCBitset::BIT_PER_WORD_MASK);
2101     // IndexInWord(bitOffset) = bitOffset & BIT_PER_WORD_MASK
2102     GateRef indexInWord = Int32And(bitoffset, bitPerWordMask);
2103     // Mask(indeInWord) = 1 << index
2104     return Int32LSL(Int32(1), indexInWord);
2105 }
2106 
ObjectAddressToRange(GateRef x)2107 inline GateRef StubBuilder::ObjectAddressToRange(GateRef x)
2108 {
2109     // This function may cause GateRef x is not an object. GC may not mark this x object.
2110     return IntPtrAnd(TaggedCastToIntPtr(x), IntPtr(~panda::ecmascript::DEFAULT_REGION_MASK));
2111 }
2112 
InYoungGeneration(GateRef region)2113 inline GateRef StubBuilder::InYoungGeneration(GateRef region)
2114 {
2115     auto offset = Region::PackedData::GetFlagOffset(env_->Is32Bit());
2116     GateRef x = Load(VariableType::NATIVE_POINTER(), PtrAdd(IntPtr(offset), region),
2117         IntPtr(0));
2118     if (env_->Is32Bit()) {
2119         return Int32Equal(Int32And(x,
2120             Int32(RegionSpaceFlag::VALID_SPACE_MASK)), Int32(RegionSpaceFlag::IN_YOUNG_SPACE));
2121     } else {
2122         return Int64Equal(Int64And(x,
2123             Int64(RegionSpaceFlag::VALID_SPACE_MASK)), Int64(RegionSpaceFlag::IN_YOUNG_SPACE));
2124     }
2125 }
2126 
GetParentEnv(GateRef object)2127 inline GateRef StubBuilder::GetParentEnv(GateRef object)
2128 {
2129     GateRef index = Int32(LexicalEnv::PARENT_ENV_INDEX);
2130     return GetValueFromTaggedArray(object, index);
2131 }
2132 
GetPropertiesFromLexicalEnv(GateRef object,GateRef index)2133 inline GateRef StubBuilder::GetPropertiesFromLexicalEnv(GateRef object, GateRef index)
2134 {
2135     GateRef valueIndex = Int32Add(index, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
2136     return GetValueFromTaggedArray(object, valueIndex);
2137 }
2138 
SetPropertiesToLexicalEnv(GateRef glue,GateRef object,GateRef index,GateRef value)2139 inline void StubBuilder::SetPropertiesToLexicalEnv(GateRef glue, GateRef object, GateRef index, GateRef value)
2140 {
2141     GateRef valueIndex = Int32Add(index, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
2142     SetValueToTaggedArray(VariableType::JS_ANY(), glue, object, valueIndex, value);
2143 }
2144 
GetHomeObjectFromJSFunction(GateRef object)2145 inline GateRef StubBuilder::GetHomeObjectFromJSFunction(GateRef object)
2146 {
2147     GateRef offset = IntPtr(JSFunction::HOME_OBJECT_OFFSET);
2148     return Load(VariableType::JS_ANY(), object, offset);
2149 }
2150 
GetMethodFromJSFunction(GateRef object)2151 inline GateRef StubBuilder::GetMethodFromJSFunction(GateRef object)
2152 {
2153     auto env = GetEnvironment();
2154     Label subentry(env);
2155     env->SubCfgEntry(&subentry);
2156 
2157     GateRef methodOffset;
2158     Label funcIsJSFunctionBase(env);
2159     Label funcIsJSProxy(env);
2160     Label getMethod(env);
2161     Branch(IsJSFunctionBase(object), &funcIsJSFunctionBase, &funcIsJSProxy);
2162     Bind(&funcIsJSFunctionBase);
2163     {
2164         methodOffset = IntPtr(JSFunctionBase::METHOD_OFFSET);
2165         Jump(&getMethod);
2166     }
2167     Bind(&funcIsJSProxy);
2168     {
2169         methodOffset = IntPtr(JSProxy::METHOD_OFFSET);
2170         Jump(&getMethod);
2171     }
2172     Bind(&getMethod);
2173     GateRef method = Load(VariableType::JS_ANY(), object, methodOffset);
2174     env->SubCfgExit();
2175     return method;
2176 }
2177 
GetCallFieldFromMethod(GateRef method)2178 inline GateRef StubBuilder::GetCallFieldFromMethod(GateRef method)
2179 {
2180     GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2181     return Load(VariableType::INT64(), method, callFieldOffset);
2182 }
2183 
SetLexicalEnvToFunction(GateRef glue,GateRef object,GateRef lexicalEnv)2184 inline void StubBuilder::SetLexicalEnvToFunction(GateRef glue, GateRef object, GateRef lexicalEnv)
2185 {
2186     GateRef offset = IntPtr(JSFunction::LEXICAL_ENV_OFFSET);
2187     Store(VariableType::JS_ANY(), glue, object, offset, lexicalEnv);
2188 }
2189 
GetGlobalObject(GateRef glue)2190 inline GateRef StubBuilder::GetGlobalObject(GateRef glue)
2191 {
2192     GateRef offset = IntPtr(JSThread::GlueData::GetGlobalObjOffset(env_->Is32Bit()));
2193     return Load(VariableType::JS_ANY(), glue, offset);
2194 }
2195 
GetMethodFromFunction(GateRef function)2196 inline GateRef StubBuilder::GetMethodFromFunction(GateRef function)
2197 {
2198     return env_->GetBuilder()->GetMethodFromFunction(function);
2199 }
2200 
GetModuleFromFunction(GateRef function)2201 inline GateRef StubBuilder::GetModuleFromFunction(GateRef function)
2202 {
2203     return env_->GetBuilder()->GetModuleFromFunction(function);
2204 }
2205 
GetEntryIndexOfGlobalDictionary(GateRef entry)2206 inline GateRef StubBuilder::GetEntryIndexOfGlobalDictionary(GateRef entry)
2207 {
2208     return Int32Add(Int32(OrderTaggedHashTable<GlobalDictionary>::TABLE_HEADER_SIZE),
2209         Int32Mul(entry, Int32(GlobalDictionary::ENTRY_SIZE)));
2210 }
2211 
GetBoxFromGlobalDictionary(GateRef object,GateRef entry)2212 inline GateRef StubBuilder::GetBoxFromGlobalDictionary(GateRef object, GateRef entry)
2213 {
2214     GateRef index = GetEntryIndexOfGlobalDictionary(entry);
2215     GateRef offset = PtrAdd(ZExtInt32ToPtr(index),
2216         IntPtr(GlobalDictionary::ENTRY_VALUE_INDEX));
2217     return GetValueFromTaggedArray(object, offset);
2218 }
2219 
GetValueFromGlobalDictionary(GateRef object,GateRef entry)2220 inline GateRef StubBuilder::GetValueFromGlobalDictionary(GateRef object, GateRef entry)
2221 {
2222     GateRef box = GetBoxFromGlobalDictionary(object, entry);
2223     return Load(VariableType::JS_ANY(), box, IntPtr(PropertyBox::VALUE_OFFSET));
2224 }
2225 
GetPropertiesFromJSObject(GateRef object)2226 inline GateRef StubBuilder::GetPropertiesFromJSObject(GateRef object)
2227 {
2228     GateRef offset = IntPtr(JSObject::PROPERTIES_OFFSET);
2229     return Load(VariableType::JS_ANY(), object, offset);
2230 }
2231 
IsJSFunction(GateRef obj)2232 inline GateRef StubBuilder::IsJSFunction(GateRef obj)
2233 {
2234     GateRef objectType = GetObjectType(LoadHClass(obj));
2235     GateRef greater = Int32GreaterThanOrEqual(objectType,
2236         Int32(static_cast<int32_t>(JSType::JS_FUNCTION_FIRST)));
2237     GateRef less = Int32LessThanOrEqual(objectType,
2238         Int32(static_cast<int32_t>(JSType::JS_FUNCTION_LAST)));
2239     return BoolAnd(greater, less);
2240 }
2241 
IsBoundFunction(GateRef obj)2242 inline GateRef StubBuilder::IsBoundFunction(GateRef obj)
2243 {
2244     GateRef objectType = GetObjectType(LoadHClass(obj));
2245     return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_BOUND_FUNCTION)));
2246 }
2247 
IsNativeMethod(GateRef method)2248 inline GateRef StubBuilder::IsNativeMethod(GateRef method)
2249 {
2250     GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2251     GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
2252     return Int64NotEqual(
2253         Int64And(
2254             Int64LSR(callfield, Int64(MethodLiteral::IsNativeBit::START_BIT)),
2255             Int64((1LU << MethodLiteral::IsNativeBit::SIZE) - 1)),
2256         Int64(0));
2257 }
2258 
IsOptimizedWithBitField(GateRef bitfield)2259 inline GateRef StubBuilder::IsOptimizedWithBitField(GateRef bitfield)
2260 {
2261     return env_->GetBuilder()->IsOptimizedWithBitField(bitfield);
2262 }
2263 
CanFastCallWithBitField(GateRef bitfield)2264 inline GateRef StubBuilder::CanFastCallWithBitField(GateRef bitfield)
2265 {
2266     return env_->GetBuilder()->CanFastCallWithBitField(bitfield);
2267 }
2268 
GetExpectedNumOfArgs(GateRef method)2269 inline GateRef StubBuilder::GetExpectedNumOfArgs(GateRef method)
2270 {
2271     GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2272     GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
2273     return TruncInt64ToInt32(Int64And(
2274         Int64LSR(callfield, Int64(MethodLiteral::NumArgsBits::START_BIT)),
2275         Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1)));
2276 }
2277 
GetMethodFromJSProxy(GateRef proxy)2278 inline GateRef StubBuilder::GetMethodFromJSProxy(GateRef proxy)
2279 {
2280     GateRef offset = IntPtr(JSProxy::METHOD_OFFSET);
2281     return Load(VariableType::JS_ANY(), proxy, offset);
2282 }
2283 
GetHandlerFromJSProxy(GateRef proxy)2284 inline GateRef StubBuilder::GetHandlerFromJSProxy(GateRef proxy)
2285 {
2286     GateRef offset = IntPtr(JSProxy::HANDLER_OFFSET);
2287     return Load(VariableType::JS_ANY(), proxy, offset);
2288 }
2289 
GetTargetFromJSProxy(GateRef proxy)2290 inline GateRef StubBuilder::GetTargetFromJSProxy(GateRef proxy)
2291 {
2292     GateRef offset = IntPtr(JSProxy::TARGET_OFFSET);
2293     return Load(VariableType::JS_ANY(), proxy, offset);
2294 }
2295 
ComputeTaggedArraySize(GateRef length)2296 inline GateRef StubBuilder::ComputeTaggedArraySize(GateRef length)
2297 {
2298     return PtrAdd(IntPtr(TaggedArray::DATA_OFFSET),
2299         PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), length));
2300 }
2301 
GetGlobalConstantValue(VariableType type,GateRef glue,ConstantIndex index)2302 inline GateRef StubBuilder::GetGlobalConstantValue(VariableType type, GateRef glue, ConstantIndex index)
2303 {
2304     GateRef gConstAddr = Load(VariableType::JS_ANY(), glue,
2305         IntPtr(JSThread::GlueData::GetGlobalConstOffset(env_->Is32Bit())));
2306     auto constantIndex = IntPtr(JSTaggedValue::TaggedTypeSize() * static_cast<size_t>(index));
2307     return Load(type, gConstAddr, constantIndex);
2308 }
2309 
GetGlobalEnvValue(VariableType type,GateRef env,size_t index)2310 inline GateRef StubBuilder::GetGlobalEnvValue(VariableType type, GateRef env, size_t index)
2311 {
2312     auto valueIndex = IntPtr(GlobalEnv::HEADER_SIZE + JSTaggedValue::TaggedTypeSize() * index);
2313     return Load(type, env, valueIndex);
2314 }
2315 
HasPendingException(GateRef glue)2316 inline GateRef StubBuilder::HasPendingException(GateRef glue)
2317 {
2318     GateRef exceptionOffset = IntPtr(JSThread::GlueData::GetExceptionOffset(env_->IsArch32Bit()));
2319     GateRef exception = Load(VariableType::JS_ANY(), glue, exceptionOffset);
2320     return TaggedIsNotHole(exception);
2321 }
2322 
DispatchBuiltins(GateRef glue,GateRef builtinsId,const std::initializer_list<GateRef> & args)2323 inline GateRef StubBuilder::DispatchBuiltins(GateRef glue, GateRef builtinsId,
2324                                              const std::initializer_list<GateRef>& args)
2325 {
2326     GateRef target = PtrMul(ZExtInt32ToPtr(builtinsId), IntPtrSize());
2327     return env_->GetBuilder()->CallBuiltin(glue, target, args);
2328 }
2329 
DispatchBuiltinsWithArgv(GateRef glue,GateRef builtinsId,const std::initializer_list<GateRef> & args)2330 inline GateRef StubBuilder::DispatchBuiltinsWithArgv(GateRef glue, GateRef builtinsId,
2331                                                      const std::initializer_list<GateRef>& args)
2332 {
2333     GateRef target = PtrMul(ZExtInt32ToPtr(builtinsId), IntPtrSize());
2334     return env_->GetBuilder()->CallBuiltinWithArgv(glue, target, args);
2335 }
2336 
GetBuiltinId(GateRef method)2337 inline GateRef StubBuilder::GetBuiltinId(GateRef method)
2338 {
2339     GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
2340     GateRef extraLiteralInfo = Load(VariableType::INT64(), method, extraLiteralInfoOffset);
2341     return TruncInt64ToInt32(Int64And(
2342         Int64LSR(extraLiteralInfo, Int64(MethodLiteral::BuiltinIdBits::START_BIT)),
2343         Int64((1LU << MethodLiteral::BuiltinIdBits::SIZE) - 1)));
2344 }
2345 
ComputeSizeUtf8(GateRef length)2346 inline GateRef StubBuilder::ComputeSizeUtf8(GateRef length)
2347 {
2348     return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), length);
2349 }
2350 
ComputeSizeUtf16(GateRef length)2351 inline GateRef StubBuilder::ComputeSizeUtf16(GateRef length)
2352 {
2353     return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t))));
2354 }
2355 
AlignUp(GateRef x,GateRef alignment)2356 inline GateRef StubBuilder::AlignUp(GateRef x, GateRef alignment)
2357 {
2358     GateRef x1 = PtrAdd(x, PtrSub(alignment, IntPtr(1)));
2359     return IntPtrAnd(x1, IntPtrNot(PtrSub(alignment, IntPtr(1))));
2360 }
2361 
SetLength(GateRef glue,GateRef str,GateRef length,bool compressed)2362 inline void StubBuilder::SetLength(GateRef glue, GateRef str, GateRef length, bool compressed)
2363 {
2364     GateRef len = Int32LSL(length, Int32(2));
2365     GateRef mixLength;
2366     if (compressed) {
2367         mixLength = Int32Or(len, Int32(EcmaString::STRING_COMPRESSED));
2368     } else {
2369         mixLength = Int32Or(len, Int32(EcmaString::STRING_UNCOMPRESSED));
2370     }
2371     Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::MIX_LENGTH_OFFSET), mixLength);
2372 }
2373 
SetRawHashcode(GateRef glue,GateRef str,GateRef rawHashcode)2374 inline void StubBuilder::SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode)
2375 {
2376     Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::HASHCODE_OFFSET), rawHashcode);
2377 }
2378 
TryGetHashcodeFromString(GateRef string)2379 inline GateRef StubBuilder::TryGetHashcodeFromString(GateRef string)
2380 {
2381     return env_->GetBuilder()->TryGetHashcodeFromString(string);
2382 }
2383 
SetExtensibleToBitfield(GateRef glue,GateRef obj,bool isExtensible)2384 inline void StubBuilder::SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible)
2385 {
2386     GateRef jsHclass = LoadHClass(obj);
2387     GateRef bitfield = Load(VariableType::INT32(), jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
2388     GateRef boolVal = Boolean(isExtensible);
2389     GateRef boolToInt32 = ZExtInt1ToInt32(boolVal);
2390     GateRef encodeValue = Int32LSL(boolToInt32, Int32(JSHClass::ExtensibleBit::START_BIT));
2391     GateRef mask = Int32(((1LU << JSHClass::ExtensibleBit::SIZE) - 1) << JSHClass::ExtensibleBit::START_BIT);
2392     bitfield = Int32Or(Int32And(bitfield, Int32Not(mask)), encodeValue);
2393     Store(VariableType::INT32(), glue, jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET), bitfield);
2394 }
2395 
Comment(GateRef glue,const std::string & str)2396 inline void StubBuilder::Comment(GateRef glue, const std::string &str)
2397 {
2398     CallNGCRuntime(glue, RTSTUB_ID(Comment), { StringPtr(str) });
2399 }
2400 
IsStableElements(GateRef hClass)2401 inline GateRef StubBuilder::IsStableElements(GateRef hClass)
2402 {
2403     return env_->GetBuilder()->IsStableElements(hClass);
2404 }
2405 
IsStableArguments(GateRef hClass)2406 inline GateRef StubBuilder::IsStableArguments(GateRef hClass)
2407 {
2408     return env_->GetBuilder()->IsStableArguments(hClass);
2409 }
2410 
IsStableArray(GateRef hClass)2411 inline GateRef StubBuilder::IsStableArray(GateRef hClass)
2412 {
2413     return env_->GetBuilder()->IsStableArray(hClass);
2414 }
2415 
IsTypedArray(GateRef obj)2416 inline GateRef StubBuilder::IsTypedArray(GateRef obj)
2417 {
2418     GateRef jsHclass = LoadHClass(obj);
2419     GateRef jsType = GetObjectType(jsHclass);
2420     return BoolAnd(Int32GreaterThan(jsType, Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_FIRST))),
2421                    Int32GreaterThanOrEqual(Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_LAST)), jsType));
2422 }
2423 
GetProfileTypeInfo(GateRef jsFunc)2424 inline GateRef StubBuilder::GetProfileTypeInfo(GateRef jsFunc)
2425 {
2426     GateRef method = GetMethodFromFunction(jsFunc);
2427     return Load(VariableType::JS_POINTER(), method, IntPtr(Method::PROFILE_TYPE_INFO_OFFSET));
2428 }
2429 
LoadObjectFromConstPool(GateRef jsFunc,GateRef index)2430 inline GateRef StubBuilder::LoadObjectFromConstPool(GateRef jsFunc, GateRef index)
2431 {
2432     return env_->GetBuilder()->LoadObjectFromConstPool(jsFunc, index);
2433 }
2434 
LoadPfHeaderFromConstPool(GateRef jsFunc)2435 inline GateRef StubBuilder::LoadPfHeaderFromConstPool(GateRef jsFunc)
2436 {
2437     GateRef method = Load(VariableType::JS_ANY(), jsFunc, IntPtr(JSFunctionBase::METHOD_OFFSET));
2438     GateRef constPool = Load(VariableType::JS_ANY(), method, IntPtr(Method::CONSTANT_POOL_OFFSET));
2439     auto length = GetLengthOfTaggedArray(constPool);
2440     auto index = Int32Sub(length, Int32(ConstantPool::JS_PANDA_FILE_INDEX));
2441     auto jsPandaFile = GetValueFromTaggedArray(constPool, index);
2442     auto jsPfAddr = ChangeInt64ToIntPtr(ChangeTaggedPointerToInt64(jsPandaFile));
2443     auto pfAddr = Load(VariableType::NATIVE_POINTER(), jsPfAddr, Int32(JSPandaFile::PF_OFFSET));
2444     auto pfHeader = Load(VariableType::NATIVE_POINTER(), pfAddr, Int32(0));
2445     return pfHeader;
2446 }
2447 } //  namespace panda::ecmascript::kungfu
2448 #endif // ECMASCRIPT_COMPILER_STUB_INL_H
2449