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