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