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