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