1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef ECMASCRIPT_COMPILER_STUB_INL_H
17 #define ECMASCRIPT_COMPILER_STUB_INL_H
18
19 #include "ecmascript/compiler/stub_builder.h"
20
21 #include "ecmascript/accessor_data.h"
22 #include "ecmascript/base/number_helper.h"
23 #include "ecmascript/compiler/assembler_module.h"
24 #include "ecmascript/compiler/bc_call_signature.h"
25 #include "ecmascript/global_dictionary.h"
26 #include "ecmascript/global_env.h"
27 #include "ecmascript/global_env_constants.h"
28 #include "ecmascript/ic/ic_handler.h"
29 #include "ecmascript/ic/proto_change_details.h"
30 #include "ecmascript/js_array.h"
31 #include "ecmascript/js_function.h"
32 #include "ecmascript/js_generator_object.h"
33 #include "ecmascript/js_object.h"
34 #include "ecmascript/js_tagged_value.h"
35 #include "ecmascript/layout_info.h"
36 #include "ecmascript/message_string.h"
37 #include "ecmascript/mem/slots.h"
38 #include "ecmascript/mem/visitor.h"
39
40 namespace panda::ecmascript::kungfu {
41 using JSFunction = panda::ecmascript::JSFunction;
42 using PropertyBox = panda::ecmascript::PropertyBox;
43
Int8(int8_t value)44 inline GateRef StubBuilder::Int8(int8_t value)
45 {
46 return env_->GetBuilder()->Int8(value);
47 }
48
Int16(int16_t value)49 inline GateRef StubBuilder::Int16(int16_t value)
50 {
51 return env_->GetBuilder()->Int16(value);
52 }
53
Int32(int32_t value)54 inline GateRef StubBuilder::Int32(int32_t value)
55 {
56 return env_->GetBuilder()->Int32(value);
57 };
58
Int64(int64_t value)59 inline GateRef StubBuilder::Int64(int64_t value)
60 {
61 return env_->GetBuilder()->Int64(value);
62 }
63
IntPtr(int64_t value)64 inline GateRef StubBuilder::IntPtr(int64_t value)
65 {
66 return env_->Is32Bit() ? Int32(value) : Int64(value);
67 };
68
IntPtrSize()69 inline GateRef StubBuilder::IntPtrSize()
70 {
71 return env_->Is32Bit() ? Int32(sizeof(uint32_t)) : Int64(sizeof(uint64_t));
72 }
73
True()74 inline GateRef StubBuilder::True()
75 {
76 return TruncInt32ToInt1(Int32(1));
77 }
78
False()79 inline GateRef StubBuilder::False()
80 {
81 return TruncInt32ToInt1(Int32(0));
82 }
83
Boolean(bool value)84 inline GateRef StubBuilder::Boolean(bool value)
85 {
86 return env_->GetBuilder()->Boolean(value);
87 }
88
Double(double value)89 inline GateRef StubBuilder::Double(double value)
90 {
91 return env_->GetBuilder()->Double(value);
92 }
93
Undefined()94 inline GateRef StubBuilder::Undefined()
95 {
96 return env_->GetBuilder()->UndefineConstant();
97 }
98
Hole()99 inline GateRef StubBuilder::Hole()
100 {
101 return env_->GetBuilder()->HoleConstant();
102 }
103
Null()104 inline GateRef StubBuilder::Null()
105 {
106 return env_->GetBuilder()->NullConstant();
107 }
108
Exception()109 inline GateRef StubBuilder::Exception()
110 {
111 return env_->GetBuilder()->ExceptionConstant();
112 }
113
RelocatableData(uint64_t value)114 inline GateRef StubBuilder::RelocatableData(uint64_t value)
115 {
116 return env_->GetBuilder()->RelocatableData(value);
117 }
118
119 // parameter
Argument(size_t index)120 inline GateRef StubBuilder::Argument(size_t index)
121 {
122 return env_->GetArgument(index);
123 }
124
Int1Argument(size_t index)125 inline GateRef StubBuilder::Int1Argument(size_t index)
126 {
127 return Argument(index);
128 }
129
Int32Argument(size_t index)130 inline GateRef StubBuilder::Int32Argument(size_t index)
131 {
132 return Argument(index);
133 }
134
Int64Argument(size_t index)135 inline GateRef StubBuilder::Int64Argument(size_t index)
136 {
137 return Argument(index);
138 }
139
TaggedArgument(size_t index)140 inline GateRef StubBuilder::TaggedArgument(size_t index)
141 {
142 return Argument(index);
143 }
144
TaggedPointerArgument(size_t index)145 inline GateRef StubBuilder::TaggedPointerArgument(size_t index)
146 {
147 return Argument(index);
148 }
149
PtrArgument(size_t index)150 inline GateRef StubBuilder::PtrArgument(size_t index)
151 {
152 return Argument(index);
153 }
154
Float32Argument(size_t index)155 inline GateRef StubBuilder::Float32Argument(size_t index)
156 {
157 return Argument(index);
158 }
159
Float64Argument(size_t index)160 inline GateRef StubBuilder::Float64Argument(size_t index)
161 {
162 return Argument(index);
163 }
164
Alloca(int size)165 inline GateRef StubBuilder::Alloca(int size)
166 {
167 return env_->GetBuilder()->Alloca(size);
168 }
169
Return(GateRef value)170 inline GateRef StubBuilder::Return(GateRef value)
171 {
172 auto control = env_->GetCurrentLabel()->GetControl();
173 auto depend = env_->GetCurrentLabel()->GetDepend();
174 return env_->GetBuilder()->Return(control, depend, value);
175 }
176
Return()177 inline GateRef StubBuilder::Return()
178 {
179 auto control = env_->GetCurrentLabel()->GetControl();
180 auto depend = env_->GetCurrentLabel()->GetDepend();
181 return env_->GetBuilder()->ReturnVoid(control, depend);
182 }
183
Bind(Label * label)184 inline void StubBuilder::Bind(Label *label)
185 {
186 env_->GetBuilder()->Bind(label);
187 }
188
CallRuntime(GateRef glue,int index,const std::initializer_list<GateRef> & args)189 inline GateRef StubBuilder::CallRuntime(GateRef glue, int index, const std::initializer_list<GateRef>& args)
190 {
191 SavePcIfNeeded(glue);
192 GateRef result = env_->GetBuilder()->CallRuntime(glue, index, Gate::InvalidGateRef, args);
193 return result;
194 }
195
CallRuntime(GateRef glue,int index,GateRef argc,GateRef argv)196 inline GateRef StubBuilder::CallRuntime(GateRef glue, int index, GateRef argc, GateRef argv)
197 {
198 SavePcIfNeeded(glue);
199 GateRef result = env_->GetBuilder()->CallRuntimeVarargs(glue, index, argc, argv);
200 return result;
201 }
202
CallNGCRuntime(GateRef glue,int index,const std::initializer_list<GateRef> & args)203 inline GateRef StubBuilder::CallNGCRuntime(GateRef glue, int index, const std::initializer_list<GateRef>& args)
204 {
205 GateRef result = env_->GetBuilder()->CallNGCRuntime(glue, index, Gate::InvalidGateRef, args);
206 return result;
207 }
208
CallStub(GateRef glue,int index,const std::initializer_list<GateRef> & args)209 inline GateRef StubBuilder::CallStub(GateRef glue, int index, const std::initializer_list<GateRef>& args)
210 {
211 SavePcIfNeeded(glue);
212 GateRef result = env_->GetBuilder()->CallStub(glue, index, args);
213 return result;
214 }
215
CallBuiltinRuntime(GateRef glue,const std::initializer_list<GateRef> & args,bool isNew)216 inline GateRef StubBuilder::CallBuiltinRuntime(GateRef glue, const std::initializer_list<GateRef>& args, bool isNew)
217 {
218 GateRef result = env_->GetBuilder()->CallBuiltinRuntime(glue, Gate::InvalidGateRef, args, isNew);
219 return result;
220 }
221
DebugPrint(GateRef glue,std::initializer_list<GateRef> args)222 inline void StubBuilder::DebugPrint(GateRef glue, std::initializer_list<GateRef> args)
223 {
224 CallNGCRuntime(glue, RTSTUB_ID(DebugPrint), args);
225 }
226
FatalPrint(GateRef glue,std::initializer_list<GateRef> args)227 inline void StubBuilder::FatalPrint(GateRef glue, std::initializer_list<GateRef> args)
228 {
229 CallNGCRuntime(glue, RTSTUB_ID(FatalPrint), args);
230 }
231
SavePcIfNeeded(GateRef glue)232 void StubBuilder::SavePcIfNeeded(GateRef glue)
233 {
234 if (env_->IsAsmInterp()) {
235 GateRef sp = Argument(static_cast<size_t>(InterpreterHandlerInputs::SP));
236 GateRef pc = Argument(static_cast<size_t>(InterpreterHandlerInputs::PC));
237 GateRef frame = PtrSub(sp,
238 IntPtr(AsmInterpretedFrame::GetSize(GetEnvironment()->IsArch32Bit())));
239 Store(VariableType::INT64(), glue, frame,
240 IntPtr(AsmInterpretedFrame::GetPcOffset(GetEnvironment()->IsArch32Bit())), pc);
241 }
242 }
243
SaveJumpSizeIfNeeded(GateRef glue,GateRef jumpSize)244 void StubBuilder::SaveJumpSizeIfNeeded(GateRef glue, GateRef jumpSize)
245 {
246 if (env_->IsAsmInterp()) {
247 GateRef sp = Argument(static_cast<size_t>(InterpreterHandlerInputs::SP));
248 GateRef frame = PtrSub(sp,
249 IntPtr(AsmInterpretedFrame::GetSize(GetEnvironment()->IsArch32Bit())));
250 Store(VariableType::INT64(), glue, frame,
251 IntPtr(AsmInterpretedFrame::GetCallSizeOffset(GetEnvironment()->IsArch32Bit())), jumpSize);
252 }
253 }
254
SetHotnessCounter(GateRef glue,GateRef method,GateRef value)255 void StubBuilder::SetHotnessCounter(GateRef glue, GateRef method, GateRef value)
256 {
257 auto env = GetEnvironment();
258 GateRef newValue = env->GetBuilder()->TruncInt64ToInt16(value);
259 Store(VariableType::INT16(), glue, method, IntPtr(Method::LITERAL_INFO_OFFSET), newValue);
260 }
261
SaveHotnessCounterIfNeeded(GateRef glue,GateRef sp,GateRef hotnessCounter,JSCallMode mode)262 void StubBuilder::SaveHotnessCounterIfNeeded(GateRef glue, GateRef sp, GateRef hotnessCounter, JSCallMode mode)
263 {
264 if (env_->IsAsmInterp() && kungfu::AssemblerModule::IsJumpToCallCommonEntry(mode)) {
265 ASSERT(hotnessCounter != Circuit::NullGate());
266 GateRef frame = PtrSub(sp, IntPtr(AsmInterpretedFrame::GetSize(env_->IsArch32Bit())));
267 GateRef function = Load(VariableType::JS_POINTER(), frame,
268 IntPtr(AsmInterpretedFrame::GetFunctionOffset(env_->IsArch32Bit())));
269 GateRef method = Load(VariableType::JS_ANY(), function, IntPtr(JSFunctionBase::METHOD_OFFSET));
270 SetHotnessCounter(glue, method, hotnessCounter);
271 }
272 }
273
274 // memory
Load(VariableType type,GateRef base,GateRef offset)275 inline GateRef StubBuilder::Load(VariableType type, GateRef base, GateRef offset)
276 {
277 if (type == VariableType::NATIVE_POINTER()) {
278 type = env_->IsArch64Bit() ? VariableType::INT64() : VariableType::INT32();
279 }
280 return env_->GetBuilder()->Load(type, base, offset);
281 }
282
Load(VariableType type,GateRef base)283 inline GateRef StubBuilder::Load(VariableType type, GateRef base)
284 {
285 return Load(type, base, IntPtr(0));
286 }
287
288 // arithmetic
Int16Add(GateRef x,GateRef y)289 inline GateRef StubBuilder::Int16Add(GateRef x, GateRef y)
290 {
291 return env_->GetBuilder()->Int16Add(x, y);
292 }
293
Int32Add(GateRef x,GateRef y)294 inline GateRef StubBuilder::Int32Add(GateRef x, GateRef y)
295 {
296 return env_->GetBuilder()->Int32Add(x, y);
297 }
298
Int64Add(GateRef x,GateRef y)299 inline GateRef StubBuilder::Int64Add(GateRef x, GateRef y)
300 {
301 return env_->GetBuilder()->Int64Add(x, y);
302 }
303
DoubleAdd(GateRef x,GateRef y)304 inline GateRef StubBuilder::DoubleAdd(GateRef x, GateRef y)
305 {
306 return env_->GetBuilder()->DoubleAdd(x, y);
307 }
308
PtrMul(GateRef x,GateRef y)309 inline GateRef StubBuilder::PtrMul(GateRef x, GateRef y)
310 {
311 return env_->GetBuilder()->PtrMul(x, y);
312 }
313
PtrAdd(GateRef x,GateRef y)314 inline GateRef StubBuilder::PtrAdd(GateRef x, GateRef y)
315 {
316 return env_->GetBuilder()->PtrAdd(x, y);
317 }
318
PtrSub(GateRef x,GateRef y)319 inline GateRef StubBuilder::PtrSub(GateRef x, GateRef y)
320 {
321 return env_->GetBuilder()->PtrSub(x, y);
322 }
323
IntPtrAnd(GateRef x,GateRef y)324 inline GateRef StubBuilder::IntPtrAnd(GateRef x, GateRef y)
325 {
326 return env_->Is32Bit() ? Int32And(x, y) : Int64And(x, y);
327 }
328
IntPtrEqual(GateRef x,GateRef y)329 inline GateRef StubBuilder::IntPtrEqual(GateRef x, GateRef y)
330 {
331 if (env_->Is32Bit()) {
332 return Int32Equal(x, y);
333 }
334 return Int64Equal(x, y);
335 }
336
Int16Sub(GateRef x,GateRef y)337 inline GateRef StubBuilder::Int16Sub(GateRef x, GateRef y)
338 {
339 return env_->GetBuilder()->Int16Sub(x, y);
340 }
341
Int32Sub(GateRef x,GateRef y)342 inline GateRef StubBuilder::Int32Sub(GateRef x, GateRef y)
343 {
344 return env_->GetBuilder()->Int32Sub(x, y);
345 }
346
Int64Sub(GateRef x,GateRef y)347 inline GateRef StubBuilder::Int64Sub(GateRef x, GateRef y)
348 {
349 return env_->GetBuilder()->Int64Sub(x, y);
350 }
351
DoubleSub(GateRef x,GateRef y)352 inline GateRef StubBuilder::DoubleSub(GateRef x, GateRef y)
353 {
354 return env_->GetBuilder()->DoubleSub(x, y);
355 }
356
Int32Mul(GateRef x,GateRef y)357 inline GateRef StubBuilder::Int32Mul(GateRef x, GateRef y)
358 {
359 return env_->GetBuilder()->Int32Mul(x, y);
360 }
361
Int64Mul(GateRef x,GateRef y)362 inline GateRef StubBuilder::Int64Mul(GateRef x, GateRef y)
363 {
364 return env_->GetBuilder()->Int64Mul(x, y);
365 }
366
DoubleMul(GateRef x,GateRef y)367 inline GateRef StubBuilder::DoubleMul(GateRef x, GateRef y)
368 {
369 return env_->GetBuilder()->DoubleMul(x, y);
370 }
371
DoubleDiv(GateRef x,GateRef y)372 inline GateRef StubBuilder::DoubleDiv(GateRef x, GateRef y)
373 {
374 return env_->GetBuilder()->DoubleDiv(x, y);
375 }
376
Int32Div(GateRef x,GateRef y)377 inline GateRef StubBuilder::Int32Div(GateRef x, GateRef y)
378 {
379 return env_->GetBuilder()->Int32Div(x, y);
380 }
381
Int64Div(GateRef x,GateRef y)382 inline GateRef StubBuilder::Int64Div(GateRef x, GateRef y)
383 {
384 return env_->GetBuilder()->Int64Div(x, y);
385 }
386
IntPtrDiv(GateRef x,GateRef y)387 inline GateRef StubBuilder::IntPtrDiv(GateRef x, GateRef y)
388 {
389 return env_->GetBuilder()->IntPtrDiv(x, y);
390 }
391
Int32Mod(GateRef x,GateRef y)392 inline GateRef StubBuilder::Int32Mod(GateRef x, GateRef y)
393 {
394 return env_->GetBuilder()->Int32Mod(x, y);
395 }
396
DoubleMod(GateRef x,GateRef y)397 inline GateRef StubBuilder::DoubleMod(GateRef x, GateRef y)
398 {
399 return env_->GetBuilder()->DoubleMod(x, y);
400 }
401
402 // bit operation
Int32Or(GateRef x,GateRef y)403 inline GateRef StubBuilder::Int32Or(GateRef x, GateRef y)
404 {
405 return env_->GetBuilder()->Int32Or(x, y);
406 }
407
Int8And(GateRef x,GateRef y)408 inline GateRef StubBuilder::Int8And(GateRef x, GateRef y)
409 {
410 return env_->GetBuilder()->Int8And(x, y);
411 }
412
Int32And(GateRef x,GateRef y)413 inline GateRef StubBuilder::Int32And(GateRef x, GateRef y)
414 {
415 return env_->GetBuilder()->Int32And(x, y);
416 }
417
BoolAnd(GateRef x,GateRef y)418 inline GateRef StubBuilder::BoolAnd(GateRef x, GateRef y)
419 {
420 return env_->GetBuilder()->BoolAnd(x, y);
421 }
422
BoolOr(GateRef x,GateRef y)423 inline GateRef StubBuilder::BoolOr(GateRef x, GateRef y)
424 {
425 return env_->GetBuilder()->BoolOr(x, y);
426 }
427
Int32Not(GateRef x)428 inline GateRef StubBuilder::Int32Not(GateRef x)
429 {
430 return env_->GetBuilder()->Int32Not(x);
431 }
432
IntPtrNot(GateRef x)433 inline GateRef StubBuilder::IntPtrNot(GateRef x)
434 {
435 return env_->Is32Bit() ? Int32Not(x) : Int64Not(x);
436 }
437
BoolNot(GateRef x)438 inline GateRef StubBuilder::BoolNot(GateRef x)
439 {
440 return env_->GetBuilder()->BoolNot(x);
441 }
442
Int64Or(GateRef x,GateRef y)443 inline GateRef StubBuilder::Int64Or(GateRef x, GateRef y)
444 {
445 return env_->GetBuilder()->Int64Or(x, y);
446 }
447
IntPtrOr(GateRef x,GateRef y)448 inline GateRef StubBuilder::IntPtrOr(GateRef x, GateRef y)
449 {
450 return env_->GetBuilder()->IntPtrOr(x, y);
451 }
452
Int64And(GateRef x,GateRef y)453 inline GateRef StubBuilder::Int64And(GateRef x, GateRef y)
454 {
455 return env_->GetBuilder()->Int64And(x, y);
456 }
457
Int16LSL(GateRef x,GateRef y)458 inline GateRef StubBuilder::Int16LSL(GateRef x, GateRef y)
459 {
460 return env_->GetBuilder()->Int16LSL(x, y);
461 }
462
Int64Xor(GateRef x,GateRef y)463 inline GateRef StubBuilder::Int64Xor(GateRef x, GateRef y)
464 {
465 return env_->GetBuilder()->Int64Xor(x, y);
466 }
467
Int32Xor(GateRef x,GateRef y)468 inline GateRef StubBuilder::Int32Xor(GateRef x, GateRef y)
469 {
470 return env_->GetBuilder()->Int32Xor(x, y);
471 }
472
Int8LSR(GateRef x,GateRef y)473 inline GateRef StubBuilder::Int8LSR(GateRef x, GateRef y)
474 {
475 return env_->GetBuilder()->Int8LSR(x, y);
476 }
477
Int64Not(GateRef x)478 inline GateRef StubBuilder::Int64Not(GateRef x)
479 {
480 return env_->GetBuilder()->Int64Not(x);
481 }
482
Int32LSL(GateRef x,GateRef y)483 inline GateRef StubBuilder::Int32LSL(GateRef x, GateRef y)
484 {
485 return env_->GetBuilder()->Int32LSL(x, y);
486 }
487
Int64LSL(GateRef x,GateRef y)488 inline GateRef StubBuilder::Int64LSL(GateRef x, GateRef y)
489 {
490 return env_->GetBuilder()->Int64LSL(x, y);
491 }
492
IntPtrLSL(GateRef x,GateRef y)493 inline GateRef StubBuilder::IntPtrLSL(GateRef x, GateRef y)
494 {
495 return env_->GetBuilder()->IntPtrLSL(x, y);
496 }
497
Int32ASR(GateRef x,GateRef y)498 inline GateRef StubBuilder::Int32ASR(GateRef x, GateRef y)
499 {
500 return env_->GetBuilder()->Int32ASR(x, y);
501 }
502
Int32LSR(GateRef x,GateRef y)503 inline GateRef StubBuilder::Int32LSR(GateRef x, GateRef y)
504 {
505 return env_->GetBuilder()->Int32LSR(x, y);
506 }
507
Int64LSR(GateRef x,GateRef y)508 inline GateRef StubBuilder::Int64LSR(GateRef x, GateRef y)
509 {
510 return env_->GetBuilder()->Int64LSR(x, y);
511 }
512
IntPtrLSR(GateRef x,GateRef y)513 inline GateRef StubBuilder::IntPtrLSR(GateRef x, GateRef y)
514 {
515 return env_->GetBuilder()->IntPtrLSR(x, y);
516 }
517
518 template<OpCode Op, MachineType Type>
BinaryOp(GateRef x,GateRef y)519 inline GateRef StubBuilder::BinaryOp(GateRef x, GateRef y)
520 {
521 return env_->GetBuilder()->BinaryOp<Op, Type>(x, y);
522 }
523
TaggedIsInt(GateRef x)524 inline GateRef StubBuilder::TaggedIsInt(GateRef x)
525 {
526 return env_->GetBuilder()->TaggedIsInt(x);
527 }
528
TaggedIsDouble(GateRef x)529 inline GateRef StubBuilder::TaggedIsDouble(GateRef x)
530 {
531 return BoolAnd(TaggedIsNumber(x), BoolNot(TaggedIsInt(x)));
532 }
533
TaggedIsObject(GateRef x)534 inline GateRef StubBuilder::TaggedIsObject(GateRef x)
535 {
536 return env_->GetBuilder()->TaggedIsObject(x);
537 }
538
TaggedIsString(GateRef obj)539 inline GateRef StubBuilder::TaggedIsString(GateRef obj)
540 {
541 return env_->GetBuilder()->TaggedIsString(obj);
542 }
543
TaggedIsStringOrSymbol(GateRef obj)544 inline GateRef StubBuilder::TaggedIsStringOrSymbol(GateRef obj)
545 {
546 return env_->GetBuilder()->TaggedIsStringOrSymbol(obj);
547 }
548
BothAreString(GateRef x,GateRef y)549 inline GateRef StubBuilder::BothAreString(GateRef x, GateRef y)
550 {
551 auto allHeapObject = BoolAnd(TaggedIsHeapObject(x), TaggedIsHeapObject(y));
552 auto allString = env_->GetBuilder()->TaggedObjectBothAreString(x, y);
553 return env_->GetBuilder()->LogicAnd(allHeapObject, allString);
554 }
555
TaggedIsNumber(GateRef x)556 inline GateRef StubBuilder::TaggedIsNumber(GateRef x)
557 {
558 return BoolNot(TaggedIsObject(x));
559 }
560
TaggedIsNumeric(GateRef x)561 inline GateRef StubBuilder::TaggedIsNumeric(GateRef x)
562 {
563 return BoolOr(TaggedIsNumber(x), TaggedIsBigInt(x));
564 }
565
TaggedIsHole(GateRef x)566 inline GateRef StubBuilder::TaggedIsHole(GateRef x)
567 {
568 return env_->GetBuilder()->TaggedIsHole(x);
569 }
570
TaggedIsNotHole(GateRef x)571 inline GateRef StubBuilder::TaggedIsNotHole(GateRef x)
572 {
573 return env_->GetBuilder()->TaggedIsNotHole(x);
574 }
575
TaggedIsUndefined(GateRef x)576 inline GateRef StubBuilder::TaggedIsUndefined(GateRef x)
577 {
578 return env_->GetBuilder()->TaggedIsUndefined(x);
579 }
580
TaggedIsException(GateRef x)581 inline GateRef StubBuilder::TaggedIsException(GateRef x)
582 {
583 return env_->GetBuilder()->TaggedIsException(x);
584 }
585
TaggedIsSpecial(GateRef x)586 inline GateRef StubBuilder::TaggedIsSpecial(GateRef x)
587 {
588 return env_->GetBuilder()->TaggedIsSpecial(x);
589 }
590
TaggedIsHeapObject(GateRef x)591 inline GateRef StubBuilder::TaggedIsHeapObject(GateRef x)
592 {
593 return env_->GetBuilder()->TaggedIsHeapObject(x);
594 }
595
TaggedIsGeneratorObject(GateRef x)596 inline GateRef StubBuilder::TaggedIsGeneratorObject(GateRef x)
597 {
598 return env_->GetBuilder()->TaggedIsGeneratorObject(x);
599 }
600
TaggedIsAsyncGeneratorObject(GateRef x)601 inline GateRef StubBuilder::TaggedIsAsyncGeneratorObject(GateRef x)
602 {
603 return env_->GetBuilder()->TaggedIsAsyncGeneratorObject(x);
604 }
605
606
TaggedIsWeak(GateRef x)607 inline GateRef StubBuilder::TaggedIsWeak(GateRef x)
608 {
609 return env_->GetBuilder()->TaggedIsWeak(x);
610 }
611
TaggedIsPrototypeHandler(GateRef x)612 inline GateRef StubBuilder::TaggedIsPrototypeHandler(GateRef x)
613 {
614 return env_->GetBuilder()->TaggedIsPrototypeHandler(x);
615 }
616
TaggedIsStoreTSHandler(GateRef x)617 inline GateRef StubBuilder::TaggedIsStoreTSHandler(GateRef x)
618 {
619 return env_->GetBuilder()->TaggedIsStoreTSHandler(x);
620 }
621
TaggedIsTransWithProtoHandler(GateRef x)622 inline GateRef StubBuilder::TaggedIsTransWithProtoHandler(GateRef x)
623 {
624 return env_->GetBuilder()->TaggedIsTransWithProtoHandler(x);
625 }
626
TaggedIsTransitionHandler(GateRef x)627 inline GateRef StubBuilder::TaggedIsTransitionHandler(GateRef x)
628 {
629 return env_->GetBuilder()->TaggedIsTransitionHandler(x);
630 }
631
GetNextPositionForHash(GateRef last,GateRef count,GateRef size)632 inline GateRef StubBuilder::GetNextPositionForHash(GateRef last, GateRef count, GateRef size)
633 {
634 auto nextOffset = Int32LSR(Int32Mul(count, Int32Add(count, Int32(1))),
635 Int32(1));
636 return Int32And(Int32Add(last, nextOffset), Int32Sub(size, Int32(1)));
637 }
638
DoubleIsNAN(GateRef x)639 inline GateRef StubBuilder::DoubleIsNAN(GateRef x)
640 {
641 return env_->GetBuilder()->DoubleIsNAN(x);
642 }
643
DoubleIsINF(GateRef x)644 inline GateRef StubBuilder::DoubleIsINF(GateRef x)
645 {
646 return env_->GetBuilder()->DoubleIsINF(x);
647 }
648
TaggedIsNull(GateRef x)649 inline GateRef StubBuilder::TaggedIsNull(GateRef x)
650 {
651 return env_->GetBuilder()->TaggedIsNull(x);
652 }
653
TaggedIsUndefinedOrNull(GateRef x)654 inline GateRef StubBuilder::TaggedIsUndefinedOrNull(GateRef x)
655 {
656 return env_->GetBuilder()->TaggedIsUndefinedOrNull(x);
657 }
658
TaggedIsTrue(GateRef x)659 inline GateRef StubBuilder::TaggedIsTrue(GateRef x)
660 {
661 return env_->GetBuilder()->TaggedIsTrue(x);
662 }
663
TaggedIsFalse(GateRef x)664 inline GateRef StubBuilder::TaggedIsFalse(GateRef x)
665 {
666 return env_->GetBuilder()->TaggedIsFalse(x);
667 }
668
TaggedIsBoolean(GateRef x)669 inline GateRef StubBuilder::TaggedIsBoolean(GateRef x)
670 {
671 return env_->GetBuilder()->TaggedIsBoolean(x);
672 }
673
TaggedGetInt(GateRef x)674 inline GateRef StubBuilder::TaggedGetInt(GateRef x)
675 {
676 return env_->GetBuilder()->TaggedGetInt(x);
677 }
678
Int8ToTaggedInt(GateRef x)679 inline GateRef StubBuilder::Int8ToTaggedInt(GateRef x)
680 {
681 GateRef val = SExtInt8ToInt64(x);
682 return env_->GetBuilder()->ToTaggedInt(val);
683 }
684
Int16ToTaggedInt(GateRef x)685 inline GateRef StubBuilder::Int16ToTaggedInt(GateRef x)
686 {
687 GateRef val = SExtInt16ToInt64(x);
688 return env_->GetBuilder()->ToTaggedInt(val);
689 }
690
IntToTaggedPtr(GateRef x)691 inline GateRef StubBuilder::IntToTaggedPtr(GateRef x)
692 {
693 GateRef val = SExtInt32ToInt64(x);
694 return env_->GetBuilder()->ToTaggedIntPtr(val);
695 }
696
IntToTaggedInt(GateRef x)697 inline GateRef StubBuilder::IntToTaggedInt(GateRef x)
698 {
699 GateRef val = SExtInt32ToInt64(x);
700 return env_->GetBuilder()->ToTaggedInt(val);
701 }
702
Int64ToTaggedInt(GateRef x)703 inline GateRef StubBuilder::Int64ToTaggedInt(GateRef x)
704 {
705 return env_->GetBuilder()->ToTaggedInt(x);
706 }
707
DoubleToTaggedDoublePtr(GateRef x)708 inline GateRef StubBuilder::DoubleToTaggedDoublePtr(GateRef x)
709 {
710 return env_->GetBuilder()->DoubleToTaggedDoublePtr(x);
711 }
712
CastDoubleToInt64(GateRef x)713 inline GateRef StubBuilder::CastDoubleToInt64(GateRef x)
714 {
715 return env_->GetBuilder()->CastDoubleToInt64(x);
716 }
717
TaggedTrue()718 inline GateRef StubBuilder::TaggedTrue()
719 {
720 return env_->GetBuilder()->TaggedTrue();
721 }
722
TaggedFalse()723 inline GateRef StubBuilder::TaggedFalse()
724 {
725 return env_->GetBuilder()->TaggedFalse();
726 }
727
728 // compare operation
Int8Equal(GateRef x,GateRef y)729 inline GateRef StubBuilder::Int8Equal(GateRef x, GateRef y)
730 {
731 return env_->GetBuilder()->Int8Equal(x, y);
732 }
733
Equal(GateRef x,GateRef y)734 inline GateRef StubBuilder::Equal(GateRef x, GateRef y)
735 {
736 return env_->GetBuilder()->Equal(x, y);
737 }
738
Int32Equal(GateRef x,GateRef y)739 inline GateRef StubBuilder::Int32Equal(GateRef x, GateRef y)
740 {
741 return env_->GetBuilder()->Int32Equal(x, y);
742 }
743
Int32NotEqual(GateRef x,GateRef y)744 inline GateRef StubBuilder::Int32NotEqual(GateRef x, GateRef y)
745 {
746 return env_->GetBuilder()->Int32NotEqual(x, y);
747 }
748
Int64Equal(GateRef x,GateRef y)749 inline GateRef StubBuilder::Int64Equal(GateRef x, GateRef y)
750 {
751 return env_->GetBuilder()->Int64Equal(x, y);
752 }
753
DoubleEqual(GateRef x,GateRef y)754 inline GateRef StubBuilder::DoubleEqual(GateRef x, GateRef y)
755 {
756 return env_->GetBuilder()->DoubleEqual(x, y);
757 }
758
DoubleNotEqual(GateRef x,GateRef y)759 inline GateRef StubBuilder::DoubleNotEqual(GateRef x, GateRef y)
760 {
761 return env_->GetBuilder()->DoubleNotEqual(x, y);
762 }
763
DoubleLessThan(GateRef x,GateRef y)764 inline GateRef StubBuilder::DoubleLessThan(GateRef x, GateRef y)
765 {
766 return env_->GetBuilder()->DoubleLessThan(x, y);
767 }
768
DoubleLessThanOrEqual(GateRef x,GateRef y)769 inline GateRef StubBuilder::DoubleLessThanOrEqual(GateRef x, GateRef y)
770 {
771 return env_->GetBuilder()->DoubleLessThanOrEqual(x, y);
772 }
773
DoubleGreaterThan(GateRef x,GateRef y)774 inline GateRef StubBuilder::DoubleGreaterThan(GateRef x, GateRef y)
775 {
776 return env_->GetBuilder()->DoubleGreaterThan(x, y);
777 }
778
DoubleGreaterThanOrEqual(GateRef x,GateRef y)779 inline GateRef StubBuilder::DoubleGreaterThanOrEqual(GateRef x, GateRef y)
780 {
781 return env_->GetBuilder()->DoubleGreaterThanOrEqual(x, y);
782 }
783
Int64NotEqual(GateRef x,GateRef y)784 inline GateRef StubBuilder::Int64NotEqual(GateRef x, GateRef y)
785 {
786 return env_->GetBuilder()->Int64NotEqual(x, y);
787 }
788
Int32GreaterThan(GateRef x,GateRef y)789 inline GateRef StubBuilder::Int32GreaterThan(GateRef x, GateRef y)
790 {
791 return env_->GetBuilder()->Int32GreaterThan(x, y);
792 }
793
Int32LessThan(GateRef x,GateRef y)794 inline GateRef StubBuilder::Int32LessThan(GateRef x, GateRef y)
795 {
796 return env_->GetBuilder()->Int32LessThan(x, y);
797 }
798
Int32GreaterThanOrEqual(GateRef x,GateRef y)799 inline GateRef StubBuilder::Int32GreaterThanOrEqual(GateRef x, GateRef y)
800 {
801 return env_->GetBuilder()->Int32GreaterThanOrEqual(x, y);
802 }
803
Int32LessThanOrEqual(GateRef x,GateRef y)804 inline GateRef StubBuilder::Int32LessThanOrEqual(GateRef x, GateRef y)
805 {
806 return env_->GetBuilder()->Int32LessThanOrEqual(x, y);
807 }
808
Int32UnsignedGreaterThan(GateRef x,GateRef y)809 inline GateRef StubBuilder::Int32UnsignedGreaterThan(GateRef x, GateRef y)
810 {
811 return env_->GetBuilder()->Int32UnsignedGreaterThan(x, y);
812 }
813
Int32UnsignedLessThan(GateRef x,GateRef y)814 inline GateRef StubBuilder::Int32UnsignedLessThan(GateRef x, GateRef y)
815 {
816 return env_->GetBuilder()->Int32UnsignedLessThan(x, y);
817 }
818
Int32UnsignedGreaterThanOrEqual(GateRef x,GateRef y)819 inline GateRef StubBuilder::Int32UnsignedGreaterThanOrEqual(GateRef x, GateRef y)
820 {
821 return env_->GetBuilder()->Int32UnsignedGreaterThanOrEqual(x, y);
822 }
823
Int64GreaterThan(GateRef x,GateRef y)824 inline GateRef StubBuilder::Int64GreaterThan(GateRef x, GateRef y)
825 {
826 return env_->GetBuilder()->Int64GreaterThan(x, y);
827 }
828
Int64LessThan(GateRef x,GateRef y)829 inline GateRef StubBuilder::Int64LessThan(GateRef x, GateRef y)
830 {
831 return env_->GetBuilder()->Int64LessThan(x, y);
832 }
833
Int64LessThanOrEqual(GateRef x,GateRef y)834 inline GateRef StubBuilder::Int64LessThanOrEqual(GateRef x, GateRef y)
835 {
836 return env_->GetBuilder()->Int64LessThanOrEqual(x, y);
837 }
838
Int64GreaterThanOrEqual(GateRef x,GateRef y)839 inline GateRef StubBuilder::Int64GreaterThanOrEqual(GateRef x, GateRef y)
840 {
841 return env_->GetBuilder()->Int64GreaterThanOrEqual(x, y);
842 }
843
Int64UnsignedLessThanOrEqual(GateRef x,GateRef y)844 inline GateRef StubBuilder::Int64UnsignedLessThanOrEqual(GateRef x, GateRef y)
845 {
846 return env_->GetBuilder()->Int64UnsignedLessThanOrEqual(x, y);
847 }
848
IntPtrGreaterThan(GateRef x,GateRef y)849 inline GateRef StubBuilder::IntPtrGreaterThan(GateRef x, GateRef y)
850 {
851 return env_->GetBuilder()->IntPtrGreaterThan(x, y);
852 }
853
854 // cast operation
TruncInt16ToInt8(GateRef val)855 inline GateRef StubBuilder::TruncInt16ToInt8(GateRef val)
856 {
857 return env_->GetBuilder()->TruncInt16ToInt8(val);
858 }
859
ChangeInt64ToIntPtr(GateRef val)860 inline GateRef StubBuilder::ChangeInt64ToIntPtr(GateRef val)
861 {
862 if (env_->IsArch32Bit()) {
863 return TruncInt64ToInt32(val);
864 }
865 return val;
866 }
867
ZExtInt32ToPtr(GateRef val)868 inline GateRef StubBuilder::ZExtInt32ToPtr(GateRef val)
869 {
870 if (env_->IsArch32Bit()) {
871 return val;
872 }
873 return ZExtInt32ToInt64(val);
874 }
875
ChangeIntPtrToInt32(GateRef val)876 inline GateRef StubBuilder::ChangeIntPtrToInt32(GateRef val)
877 {
878 if (env_->IsArch32Bit()) {
879 return val;
880 }
881 return TruncInt64ToInt32(val);
882 }
883
GetSetterFromAccessor(GateRef accessor)884 inline GateRef StubBuilder::GetSetterFromAccessor(GateRef accessor)
885 {
886 GateRef setterOffset = IntPtr(AccessorData::SETTER_OFFSET);
887 return Load(VariableType::JS_ANY(), accessor, setterOffset);
888 }
889
GetElementsArray(GateRef object)890 inline GateRef StubBuilder::GetElementsArray(GateRef object)
891 {
892 GateRef elementsOffset = IntPtr(JSObject::ELEMENTS_OFFSET);
893 return Load(VariableType::JS_POINTER(), object, elementsOffset);
894 }
895
SetElementsArray(VariableType type,GateRef glue,GateRef object,GateRef elementsArray)896 inline void StubBuilder::SetElementsArray(VariableType type, GateRef glue, GateRef object, GateRef elementsArray)
897 {
898 GateRef elementsOffset = IntPtr(JSObject::ELEMENTS_OFFSET);
899 Store(type, glue, object, elementsOffset, elementsArray);
900 }
901
GetPropertiesArray(GateRef object)902 inline GateRef StubBuilder::GetPropertiesArray(GateRef object)
903 {
904 GateRef propertiesOffset = IntPtr(JSObject::PROPERTIES_OFFSET);
905 return Load(VariableType::JS_POINTER(), object, propertiesOffset);
906 }
907
908 // SetProperties in js_object.h
SetPropertiesArray(VariableType type,GateRef glue,GateRef object,GateRef propsArray)909 inline void StubBuilder::SetPropertiesArray(VariableType type, GateRef glue, GateRef object, GateRef propsArray)
910 {
911 GateRef propertiesOffset = IntPtr(JSObject::PROPERTIES_OFFSET);
912 Store(type, glue, object, propertiesOffset, propsArray);
913 }
914
SetHash(GateRef glue,GateRef object,GateRef hash)915 inline void StubBuilder::SetHash(GateRef glue, GateRef object, GateRef hash)
916 {
917 GateRef hashOffset = IntPtr(ECMAObject::HASH_OFFSET);
918 Store(VariableType::INT64(), glue, object, hashOffset, hash);
919 }
920
GetLengthOfTaggedArray(GateRef array)921 inline GateRef StubBuilder::GetLengthOfTaggedArray(GateRef array)
922 {
923 return Load(VariableType::INT32(), array, IntPtr(TaggedArray::LENGTH_OFFSET));
924 }
925
IsJSHClass(GateRef obj)926 inline GateRef StubBuilder::IsJSHClass(GateRef obj)
927 {
928 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsJSHClass), TaggedIsHeapObject(obj));
929 GateRef res = env_->GetBuilder()->IsJSHClass(obj);
930 EXITENTRY();
931 return res;
932 }
933
934 // object operation
LoadHClass(GateRef object)935 inline GateRef StubBuilder::LoadHClass(GateRef object)
936 {
937 ASM_ASSERT(GET_MESSAGE_STRING_ID(LoadHClass), TaggedIsHeapObject(object));
938 GateRef res = env_->GetBuilder()->LoadHClass(object);
939 EXITENTRY();
940 return res;
941 }
942
StoreHClass(GateRef glue,GateRef object,GateRef hClass)943 inline void StubBuilder::StoreHClass(GateRef glue, GateRef object, GateRef hClass)
944 {
945 return env_->GetBuilder()->StoreHClass(glue, object, hClass);
946 }
947
GetObjectType(GateRef hClass)948 inline GateRef StubBuilder::GetObjectType(GateRef hClass)
949 {
950 return env_->GetBuilder()->GetObjectType(hClass);
951 }
952
IsDictionaryMode(GateRef object)953 inline GateRef StubBuilder::IsDictionaryMode(GateRef object)
954 {
955 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsDictionaryMode), TaggedIsHeapObject(object));
956 GateRef res = env_->GetBuilder()->IsDictionaryMode(object);
957 EXITENTRY();
958 return res;
959 }
960
IsDictionaryModeByHClass(GateRef hClass)961 inline GateRef StubBuilder::IsDictionaryModeByHClass(GateRef hClass)
962 {
963 return env_->GetBuilder()->IsDictionaryModeByHClass(hClass);
964 }
965
IsDictionaryElement(GateRef hClass)966 inline GateRef StubBuilder::IsDictionaryElement(GateRef hClass)
967 {
968 return env_->GetBuilder()->IsDictionaryElement(hClass);
969 }
970
IsClassConstructorFromBitField(GateRef bitfield)971 inline GateRef StubBuilder::IsClassConstructorFromBitField(GateRef bitfield)
972 {
973 // decode
974 return Int32NotEqual(
975 Int32And(Int32LSR(bitfield, Int32(JSHClass::ClassConstructorBit::START_BIT)),
976 Int32((1LU << JSHClass::ClassConstructorBit::SIZE) - 1)),
977 Int32(0));
978 }
979
IsClassConstructor(GateRef object)980 inline GateRef StubBuilder::IsClassConstructor(GateRef object)
981 {
982 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsClassConstructor), TaggedIsHeapObject(object));
983 GateRef res = env_->GetBuilder()->IsClassConstructor(object);
984 EXITENTRY();
985 return res;
986 }
987
IsClassPrototype(GateRef object)988 inline GateRef StubBuilder::IsClassPrototype(GateRef object)
989 {
990 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsClassPrototype), TaggedIsHeapObject(object));
991 GateRef res = env_->GetBuilder()->IsClassPrototype(object);
992 EXITENTRY();
993 return res;
994 }
995
IsExtensible(GateRef object)996 inline GateRef StubBuilder::IsExtensible(GateRef object)
997 {
998 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsExtensible), TaggedIsHeapObject(object));
999 GateRef res = env_->GetBuilder()->IsExtensible(object);
1000 EXITENTRY();
1001 return res;
1002 }
1003
TaggedObjectIsEcmaObject(GateRef obj)1004 inline GateRef StubBuilder::TaggedObjectIsEcmaObject(GateRef obj)
1005 {
1006 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsEcmaObject), TaggedIsHeapObject(obj));
1007 GateRef res = env_->GetBuilder()->TaggedObjectIsEcmaObject(obj);
1008 EXITENTRY();
1009 return res;
1010 }
1011
IsEcmaObject(GateRef obj)1012 inline GateRef StubBuilder::IsEcmaObject(GateRef obj)
1013 {
1014 auto isEcmaObject = TaggedObjectIsEcmaObject(obj);
1015 return env_->GetBuilder()->LogicAnd(TaggedIsHeapObject(obj), isEcmaObject);
1016 }
1017
IsJSObject(GateRef obj)1018 inline GateRef StubBuilder::IsJSObject(GateRef obj)
1019 {
1020 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsJSObject), TaggedIsHeapObject(obj));
1021 GateRef res = env_->GetBuilder()->IsJSObject(obj);
1022 EXITENTRY();
1023 return res;
1024 }
1025
IsJSFunctionBase(GateRef obj)1026 inline GateRef StubBuilder::IsJSFunctionBase(GateRef obj)
1027 {
1028 GateRef objectType = GetObjectType(LoadHClass(obj));
1029 GateRef greater = Int32GreaterThanOrEqual(objectType,
1030 Int32(static_cast<int32_t>(JSType::JS_FUNCTION_BASE)));
1031 GateRef less = Int32LessThanOrEqual(objectType,
1032 Int32(static_cast<int32_t>(JSType::JS_BOUND_FUNCTION)));
1033 return BoolAnd(greater, less);
1034 }
1035
IsConstructor(GateRef object)1036 inline GateRef StubBuilder::IsConstructor(GateRef object)
1037 {
1038 GateRef hClass = LoadHClass(object);
1039 GateRef bitfieldOffset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
1040 GateRef bitfield = Load(VariableType::INT32(), hClass, bitfieldOffset);
1041 // decode
1042 return Int32NotEqual(
1043 Int32And(Int32LSR(bitfield, Int32(JSHClass::ConstructorBit::START_BIT)),
1044 Int32((1LU << JSHClass::ConstructorBit::SIZE) - 1)),
1045 Int32(0));
1046 }
1047
IsBase(GateRef func)1048 inline GateRef StubBuilder::IsBase(GateRef func)
1049 {
1050 return env_->GetBuilder()->IsBase(func);
1051 }
1052
IsSymbol(GateRef obj)1053 inline GateRef StubBuilder::IsSymbol(GateRef obj)
1054 {
1055 GateRef objectType = GetObjectType(LoadHClass(obj));
1056 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::SYMBOL)));
1057 }
1058
IsString(GateRef obj)1059 inline GateRef StubBuilder::IsString(GateRef obj)
1060 {
1061 GateRef objectType = GetObjectType(LoadHClass(obj));
1062 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::STRING)));
1063 }
1064
TaggedObjectIsBigInt(GateRef obj)1065 inline GateRef StubBuilder::TaggedObjectIsBigInt(GateRef obj)
1066 {
1067 GateRef objectType = GetObjectType(LoadHClass(obj));
1068 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::BIGINT)));
1069 }
1070
IsJsProxy(GateRef obj)1071 inline GateRef StubBuilder::IsJsProxy(GateRef obj)
1072 {
1073 GateRef objectType = GetObjectType(LoadHClass(obj));
1074 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_PROXY)));
1075 }
1076
IsJsArray(GateRef obj)1077 inline GateRef StubBuilder::IsJsArray(GateRef obj)
1078 {
1079 GateRef objectType = GetObjectType(LoadHClass(obj));
1080 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_ARRAY)));
1081 }
1082
IsJSAPIVector(GateRef obj)1083 inline GateRef StubBuilder::IsJSAPIVector(GateRef obj)
1084 {
1085 GateRef objectType = GetObjectType(LoadHClass(obj));
1086 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_VECTOR)));
1087 }
1088
IsJSAPIStack(GateRef obj)1089 inline GateRef StubBuilder::IsJSAPIStack(GateRef obj)
1090 {
1091 GateRef objectType = GetObjectType(LoadHClass(obj));
1092 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_STACK)));
1093 }
1094
IsJSAPIPlainArray(GateRef obj)1095 inline GateRef StubBuilder::IsJSAPIPlainArray(GateRef obj)
1096 {
1097 GateRef objectType = GetObjectType(LoadHClass(obj));
1098 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_PLAIN_ARRAY)));
1099 }
1100
IsJSAPIQueue(GateRef obj)1101 inline GateRef StubBuilder::IsJSAPIQueue(GateRef obj)
1102 {
1103 GateRef objectType = GetObjectType(LoadHClass(obj));
1104 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_QUEUE)));
1105 }
1106
IsJSAPIDeque(GateRef obj)1107 inline GateRef StubBuilder::IsJSAPIDeque(GateRef obj)
1108 {
1109 GateRef objectType = GetObjectType(LoadHClass(obj));
1110 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_DEQUE)));
1111 }
1112
IsJSAPILightWeightMap(GateRef obj)1113 inline GateRef StubBuilder::IsJSAPILightWeightMap(GateRef obj)
1114 {
1115 GateRef objectType = GetObjectType(LoadHClass(obj));
1116 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LIGHT_WEIGHT_MAP)));
1117 }
1118
IsJSAPILightWeightSet(GateRef obj)1119 inline GateRef StubBuilder::IsJSAPILightWeightSet(GateRef obj)
1120 {
1121 GateRef objectType = GetObjectType(LoadHClass(obj));
1122 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LIGHT_WEIGHT_SET)));
1123 }
1124
IsLinkedNode(GateRef obj)1125 inline GateRef StubBuilder::IsLinkedNode(GateRef obj)
1126 {
1127 GateRef objectType = GetObjectType(LoadHClass(obj));
1128 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::LINKED_NODE)));
1129 }
1130
IsJSAPIHashMap(GateRef obj)1131 inline GateRef StubBuilder::IsJSAPIHashMap(GateRef obj)
1132 {
1133 GateRef objectType = GetObjectType(LoadHClass(obj));
1134 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_HASH_MAP)));
1135 }
1136
IsJSAPIHashSet(GateRef obj)1137 inline GateRef StubBuilder::IsJSAPIHashSet(GateRef obj)
1138 {
1139 GateRef objectType = GetObjectType(LoadHClass(obj));
1140 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_HASH_SET)));
1141 }
1142
IsJSAPILinkedList(GateRef obj)1143 inline GateRef StubBuilder::IsJSAPILinkedList(GateRef obj)
1144 {
1145 GateRef objectType = GetObjectType(LoadHClass(obj));
1146 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LINKED_LIST)));
1147 }
1148
IsJSAPIList(GateRef obj)1149 inline GateRef StubBuilder::IsJSAPIList(GateRef obj)
1150 {
1151 GateRef objectType = GetObjectType(LoadHClass(obj));
1152 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_LIST)));
1153 }
1154
IsJSAPIArrayList(GateRef obj)1155 inline GateRef StubBuilder::IsJSAPIArrayList(GateRef obj)
1156 {
1157 GateRef objectType = GetObjectType(LoadHClass(obj));
1158 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST)));
1159 }
1160
GetTarget(GateRef proxyObj)1161 inline GateRef StubBuilder::GetTarget(GateRef proxyObj)
1162 {
1163 GateRef offset = IntPtr(JSProxy::TARGET_OFFSET);
1164 return Load(VariableType::JS_ANY(), proxyObj, offset);
1165 }
1166
IsJsCOWArray(GateRef obj)1167 inline GateRef StubBuilder::IsJsCOWArray(GateRef obj)
1168 {
1169 // Elements of JSArray are shared and properties are not yet.
1170 GateRef elements = GetElementsArray(obj);
1171 return IsCOWArray(elements);
1172 }
1173
IsCOWArray(GateRef obj)1174 inline GateRef StubBuilder::IsCOWArray(GateRef obj)
1175 {
1176 GateRef objectType = GetObjectType(LoadHClass(obj));
1177 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::COW_TAGGED_ARRAY)));
1178 }
1179
IsWritable(GateRef attr)1180 inline GateRef StubBuilder::IsWritable(GateRef attr)
1181 {
1182 return Int32NotEqual(
1183 Int32And(
1184 Int32LSR(attr, Int32(PropertyAttributes::WritableField::START_BIT)),
1185 Int32((1LLU << PropertyAttributes::WritableField::SIZE) - 1)),
1186 Int32(0));
1187 }
1188
IsAccessor(GateRef attr)1189 inline GateRef StubBuilder::IsAccessor(GateRef attr)
1190 {
1191 return Int32NotEqual(
1192 Int32And(Int32LSR(attr,
1193 Int32(PropertyAttributes::IsAccessorField::START_BIT)),
1194 Int32((1LLU << PropertyAttributes::IsAccessorField::SIZE) - 1)),
1195 Int32(0));
1196 }
1197
IsInlinedProperty(GateRef attr)1198 inline GateRef StubBuilder::IsInlinedProperty(GateRef attr)
1199 {
1200 return Int32NotEqual(
1201 Int32And(Int32LSR(attr,
1202 Int32(PropertyAttributes::IsInlinedPropsField::START_BIT)),
1203 Int32((1LLU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1)),
1204 Int32(0));
1205 }
1206
GetProtoCell(GateRef object)1207 inline GateRef StubBuilder::GetProtoCell(GateRef object)
1208 {
1209 GateRef protoCellOffset = IntPtr(PrototypeHandler::PROTO_CELL_OFFSET);
1210 return Load(VariableType::JS_POINTER(), object, protoCellOffset);
1211 }
1212
GetPrototypeHandlerHolder(GateRef object)1213 inline GateRef StubBuilder::GetPrototypeHandlerHolder(GateRef object)
1214 {
1215 GateRef holderOffset = IntPtr(PrototypeHandler::HOLDER_OFFSET);
1216 return Load(VariableType::JS_ANY(), object, holderOffset);
1217 }
1218
GetPrototypeHandlerHandlerInfo(GateRef object)1219 inline GateRef StubBuilder::GetPrototypeHandlerHandlerInfo(GateRef object)
1220 {
1221 GateRef handlerInfoOffset = IntPtr(PrototypeHandler::HANDLER_INFO_OFFSET);
1222 return Load(VariableType::JS_ANY(), object, handlerInfoOffset);
1223 }
1224
GetStoreTSHandlerHolder(GateRef object)1225 inline GateRef StubBuilder::GetStoreTSHandlerHolder(GateRef object)
1226 {
1227 GateRef holderOffset = IntPtr(StoreTSHandler::HOLDER_OFFSET);
1228 return Load(VariableType::JS_ANY(), object, holderOffset);
1229 }
1230
GetStoreTSHandlerHandlerInfo(GateRef object)1231 inline GateRef StubBuilder::GetStoreTSHandlerHandlerInfo(GateRef object)
1232 {
1233 GateRef handlerInfoOffset = IntPtr(StoreTSHandler::HANDLER_INFO_OFFSET);
1234 return Load(VariableType::JS_ANY(), object, handlerInfoOffset);
1235 }
1236
GetHasChanged(GateRef object)1237 inline GateRef StubBuilder::GetHasChanged(GateRef object)
1238 {
1239 GateRef bitfieldOffset = IntPtr(ProtoChangeMarker::BIT_FIELD_OFFSET);
1240 GateRef bitfield = Load(VariableType::INT32(), object, bitfieldOffset);
1241 GateRef mask = Int32(1LLU << (ProtoChangeMarker::HAS_CHANGED_BITS - 1));
1242 return Int32NotEqual(Int32And(bitfield, mask), Int32(0));
1243 }
1244
HclassIsPrototypeHandler(GateRef hClass)1245 inline GateRef StubBuilder::HclassIsPrototypeHandler(GateRef hClass)
1246 {
1247 return Int32Equal(GetObjectType(hClass),
1248 Int32(static_cast<int32_t>(JSType::PROTOTYPE_HANDLER)));
1249 }
1250
HclassIsTransitionHandler(GateRef hClass)1251 inline GateRef StubBuilder::HclassIsTransitionHandler(GateRef hClass)
1252 {
1253 return Int32Equal(GetObjectType(hClass),
1254 Int32(static_cast<int32_t>(JSType::TRANSITION_HANDLER)));
1255 }
1256
HclassIsPropertyBox(GateRef hClass)1257 inline GateRef StubBuilder::HclassIsPropertyBox(GateRef hClass)
1258 {
1259 return Int32Equal(GetObjectType(hClass),
1260 Int32(static_cast<int32_t>(JSType::PROPERTY_BOX)));
1261 }
1262
IsField(GateRef attr)1263 inline GateRef StubBuilder::IsField(GateRef attr)
1264 {
1265 return Int32Equal(
1266 Int32And(
1267 Int32LSR(attr, Int32(HandlerBase::KindBit::START_BIT)),
1268 Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
1269 Int32(HandlerBase::HandlerKind::FIELD));
1270 }
1271
IsNonExist(GateRef attr)1272 inline GateRef StubBuilder::IsNonExist(GateRef attr)
1273 {
1274 return Int32Equal(
1275 Int32And(
1276 Int32LSR(attr, Int32(HandlerBase::KindBit::START_BIT)),
1277 Int32((1LLU << HandlerBase::KindBit::SIZE) - 1)),
1278 Int32(HandlerBase::HandlerKind::NON_EXIST));
1279 }
1280
HandlerBaseIsAccessor(GateRef attr)1281 inline GateRef StubBuilder::HandlerBaseIsAccessor(GateRef attr)
1282 {
1283 return Int32NotEqual(
1284 Int32And(Int32LSR(attr,
1285 Int32(HandlerBase::AccessorBit::START_BIT)),
1286 Int32((1LLU << HandlerBase::AccessorBit::SIZE) - 1)),
1287 Int32(0));
1288 }
1289
HandlerBaseIsJSArray(GateRef attr)1290 inline GateRef StubBuilder::HandlerBaseIsJSArray(GateRef attr)
1291 {
1292 return Int32NotEqual(
1293 Int32And(Int32LSR(attr,
1294 Int32(HandlerBase::IsJSArrayBit::START_BIT)),
1295 Int32((1LLU << HandlerBase::IsJSArrayBit::SIZE) - 1)),
1296 Int32(0));
1297 }
1298
HandlerBaseIsInlinedProperty(GateRef attr)1299 inline GateRef StubBuilder::HandlerBaseIsInlinedProperty(GateRef attr)
1300 {
1301 return Int32NotEqual(
1302 Int32And(Int32LSR(attr,
1303 Int32(HandlerBase::InlinedPropsBit::START_BIT)),
1304 Int32((1LLU << HandlerBase::InlinedPropsBit::SIZE) - 1)),
1305 Int32(0));
1306 }
1307
HandlerBaseGetOffset(GateRef attr)1308 inline GateRef StubBuilder::HandlerBaseGetOffset(GateRef attr)
1309 {
1310 return Int32And(Int32LSR(attr,
1311 Int32(HandlerBase::OffsetBit::START_BIT)),
1312 Int32((1LLU << HandlerBase::OffsetBit::SIZE) - 1));
1313 }
1314
IsInternalAccessor(GateRef attr)1315 inline GateRef StubBuilder::IsInternalAccessor(GateRef attr)
1316 {
1317 return Int32NotEqual(
1318 Int32And(Int32LSR(attr,
1319 Int32(HandlerBase::InternalAccessorBit::START_BIT)),
1320 Int32((1LLU << HandlerBase::InternalAccessorBit::SIZE) - 1)),
1321 Int32(0));
1322 }
1323
IsInvalidPropertyBox(GateRef obj)1324 inline GateRef StubBuilder::IsInvalidPropertyBox(GateRef obj)
1325 {
1326 GateRef valueOffset = IntPtr(PropertyBox::VALUE_OFFSET);
1327 GateRef value = Load(VariableType::JS_ANY(), obj, valueOffset);
1328 return TaggedIsHole(value);
1329 }
1330
GetValueFromPropertyBox(GateRef obj)1331 inline GateRef StubBuilder::GetValueFromPropertyBox(GateRef obj)
1332 {
1333 GateRef valueOffset = IntPtr(PropertyBox::VALUE_OFFSET);
1334 return Load(VariableType::JS_ANY(), obj, valueOffset);
1335 }
1336
SetValueToPropertyBox(GateRef glue,GateRef obj,GateRef value)1337 inline void StubBuilder::SetValueToPropertyBox(GateRef glue, GateRef obj, GateRef value)
1338 {
1339 GateRef valueOffset = IntPtr(PropertyBox::VALUE_OFFSET);
1340 Store(VariableType::JS_ANY(), glue, obj, valueOffset, value);
1341 }
1342
GetTransitionHClass(GateRef obj)1343 inline GateRef StubBuilder::GetTransitionHClass(GateRef obj)
1344 {
1345 GateRef transitionHClassOffset = IntPtr(TransitionHandler::TRANSITION_HCLASS_OFFSET);
1346 return Load(VariableType::JS_POINTER(), obj, transitionHClassOffset);
1347 }
1348
GetTransitionHandlerInfo(GateRef obj)1349 inline GateRef StubBuilder::GetTransitionHandlerInfo(GateRef obj)
1350 {
1351 GateRef handlerInfoOffset = IntPtr(TransitionHandler::HANDLER_INFO_OFFSET);
1352 return Load(VariableType::JS_ANY(), obj, handlerInfoOffset);
1353 }
1354
GetTransWithProtoHClass(GateRef obj)1355 inline GateRef StubBuilder::GetTransWithProtoHClass(GateRef obj)
1356 {
1357 GateRef transitionHClassOffset = IntPtr(TransWithProtoHandler::TRANSITION_HCLASS_OFFSET);
1358 return Load(VariableType::JS_POINTER(), obj, transitionHClassOffset);
1359 }
1360
GetTransWithProtoHandlerInfo(GateRef obj)1361 inline GateRef StubBuilder::GetTransWithProtoHandlerInfo(GateRef obj)
1362 {
1363 GateRef handlerInfoOffset = IntPtr(TransWithProtoHandler::HANDLER_INFO_OFFSET);
1364 return Load(VariableType::JS_ANY(), obj, handlerInfoOffset);
1365 }
1366
PropAttrGetOffset(GateRef attr)1367 inline GateRef StubBuilder::PropAttrGetOffset(GateRef attr)
1368 {
1369 return Int32And(
1370 Int32LSR(attr, Int32(PropertyAttributes::OffsetField::START_BIT)),
1371 Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1));
1372 }
1373
1374 // SetDictionaryOrder func in property_attribute.h
SetDictionaryOrderFieldInPropAttr(GateRef attr,GateRef value)1375 inline GateRef StubBuilder::SetDictionaryOrderFieldInPropAttr(GateRef attr, GateRef value)
1376 {
1377 GateRef mask = Int32LSL(
1378 Int32((1LLU << PropertyAttributes::DictionaryOrderField::SIZE) - 1),
1379 Int32(PropertyAttributes::DictionaryOrderField::START_BIT));
1380 GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
1381 Int32LSL(value, Int32(PropertyAttributes::DictionaryOrderField::START_BIT)));
1382 return newVal;
1383 }
1384
GetPrototypeFromHClass(GateRef hClass)1385 inline GateRef StubBuilder::GetPrototypeFromHClass(GateRef hClass)
1386 {
1387 GateRef protoOffset = IntPtr(JSHClass::PROTOTYPE_OFFSET);
1388 return Load(VariableType::JS_ANY(), hClass, protoOffset);
1389 }
1390
GetLayoutFromHClass(GateRef hClass)1391 inline GateRef StubBuilder::GetLayoutFromHClass(GateRef hClass)
1392 {
1393 GateRef attrOffset = IntPtr(JSHClass::LAYOUT_OFFSET);
1394 return Load(VariableType::JS_POINTER(), hClass, attrOffset);
1395 }
1396
GetBitFieldFromHClass(GateRef hClass)1397 inline GateRef StubBuilder::GetBitFieldFromHClass(GateRef hClass)
1398 {
1399 GateRef offset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
1400 return Load(VariableType::INT32(), hClass, offset);
1401 }
1402
GetLengthFromString(GateRef value)1403 inline GateRef StubBuilder::GetLengthFromString(GateRef value)
1404 {
1405 GateRef len = Load(VariableType::INT32(), value, IntPtr(EcmaString::MIX_LENGTH_OFFSET));
1406 return Int32LSR(len, Int32(2)); // 2 : 2 means len must be right shift 2 bits
1407 }
1408
SetBitFieldToHClass(GateRef glue,GateRef hClass,GateRef bitfield)1409 inline void StubBuilder::SetBitFieldToHClass(GateRef glue, GateRef hClass, GateRef bitfield)
1410 {
1411 GateRef offset = IntPtr(JSHClass::BIT_FIELD_OFFSET);
1412 Store(VariableType::INT32(), glue, hClass, offset, bitfield);
1413 }
1414
SetPrototypeToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef proto)1415 inline void StubBuilder::SetPrototypeToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef proto)
1416 {
1417 GateRef offset = IntPtr(JSHClass::PROTOTYPE_OFFSET);
1418 Store(type, glue, hClass, offset, proto);
1419 }
1420
SetProtoChangeDetailsToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef protoChange)1421 inline void StubBuilder::SetProtoChangeDetailsToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef protoChange)
1422 {
1423 GateRef offset = IntPtr(JSHClass::PROTO_CHANGE_DETAILS_OFFSET);
1424 Store(type, glue, hClass, offset, protoChange);
1425 }
1426
SetLayoutToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef attr)1427 inline void StubBuilder::SetLayoutToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef attr)
1428 {
1429 GateRef offset = IntPtr(JSHClass::LAYOUT_OFFSET);
1430 Store(type, glue, hClass, offset, attr);
1431 }
1432
SetEnumCacheToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef key)1433 inline void StubBuilder::SetEnumCacheToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef key)
1434 {
1435 GateRef offset = IntPtr(JSHClass::ENUM_CACHE_OFFSET);
1436 Store(type, glue, hClass, offset, key);
1437 }
1438
SetTransitionsToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef transition)1439 inline void StubBuilder::SetTransitionsToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef transition)
1440 {
1441 GateRef offset = IntPtr(JSHClass::TRANSTIONS_OFFSET);
1442 Store(type, glue, hClass, offset, transition);
1443 }
1444
SetIsProtoTypeToHClass(GateRef glue,GateRef hClass,GateRef value)1445 inline void StubBuilder::SetIsProtoTypeToHClass(GateRef glue, GateRef hClass, GateRef value)
1446 {
1447 GateRef oldValue = ZExtInt1ToInt32(value);
1448 GateRef bitfield = GetBitFieldFromHClass(hClass);
1449 GateRef mask = Int32LSL(
1450 Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1),
1451 Int32(JSHClass::IsPrototypeBit::START_BIT));
1452 GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
1453 Int32LSL(oldValue, Int32(JSHClass::IsPrototypeBit::START_BIT)));
1454 SetBitFieldToHClass(glue, hClass, newVal);
1455 }
1456
IsProtoTypeHClass(GateRef hClass)1457 inline GateRef StubBuilder::IsProtoTypeHClass(GateRef hClass)
1458 {
1459 GateRef bitfield = GetBitFieldFromHClass(hClass);
1460 return TruncInt32ToInt1(Int32And(Int32LSR(bitfield,
1461 Int32(JSHClass::IsPrototypeBit::START_BIT)),
1462 Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1)));
1463 }
1464
SetPropertyInlinedProps(GateRef glue,GateRef obj,GateRef hClass,GateRef value,GateRef attrOffset,VariableType type)1465 inline void StubBuilder::SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass,
1466 GateRef value, GateRef attrOffset, VariableType type)
1467 {
1468 ASM_ASSERT_WITH_GLUE(GET_MESSAGE_STRING_ID(IsNotDictionaryMode), BoolNot(IsDictionaryModeByHClass(hClass)), glue);
1469 GateRef bitfield = Load(VariableType::INT32(), hClass,
1470 IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1471 GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield,
1472 Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1473 Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1474 GateRef propOffset = Int32Mul(
1475 Int32Add(inlinedPropsStart, attrOffset), Int32(JSTaggedValue::TaggedTypeSize()));
1476
1477 // NOTE: need to translate MarkingBarrier
1478 Store(type, glue, obj, ZExtInt32ToPtr(propOffset), value);
1479 EXITENTRY();
1480 }
1481
GetPropertyInlinedProps(GateRef obj,GateRef hClass,GateRef index)1482 inline GateRef StubBuilder::GetPropertyInlinedProps(GateRef obj, GateRef hClass,
1483 GateRef index)
1484 {
1485 GateRef inlinedPropsStart = GetInlinedPropsStartFromHClass(hClass);
1486 GateRef propOffset = Int32Mul(
1487 Int32Add(inlinedPropsStart, index), Int32(JSTaggedValue::TaggedTypeSize()));
1488 return Load(VariableType::JS_ANY(), obj, ZExtInt32ToInt64(propOffset));
1489 }
1490
IncNumberOfProps(GateRef glue,GateRef hClass)1491 inline void StubBuilder::IncNumberOfProps(GateRef glue, GateRef hClass)
1492 {
1493 GateRef propNums = GetNumberOfPropsFromHClass(hClass);
1494 SetNumberOfPropsToHClass(glue, hClass, Int32Add(propNums, Int32(1)));
1495 }
1496
GetNumberOfPropsFromHClass(GateRef hClass)1497 inline GateRef StubBuilder::GetNumberOfPropsFromHClass(GateRef hClass)
1498 {
1499 GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1500 return Int32And(Int32LSR(bitfield,
1501 Int32(JSHClass::NumberOfPropsBits::START_BIT)),
1502 Int32((1LLU << JSHClass::NumberOfPropsBits::SIZE) - 1));
1503 }
1504
IsTSHClass(GateRef hClass)1505 inline GateRef StubBuilder::IsTSHClass(GateRef hClass)
1506 {
1507 GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
1508 return Int32NotEqual(Int32And(Int32LSR(bitfield,
1509 Int32(JSHClass::IsTSBit::START_BIT)),
1510 Int32((1LU << JSHClass::IsTSBit::SIZE) - 1)),
1511 Int32(0));
1512 }
1513
SetNumberOfPropsToHClass(GateRef glue,GateRef hClass,GateRef value)1514 inline void StubBuilder::SetNumberOfPropsToHClass(GateRef glue, GateRef hClass, GateRef value)
1515 {
1516 GateRef bitfield1 = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1517 GateRef oldWithMask = Int32And(bitfield1,
1518 Int32(~static_cast<uint32_t>(JSHClass::NumberOfPropsBits::Mask())));
1519 GateRef newValue = Int32LSR(value, Int32(JSHClass::NumberOfPropsBits::START_BIT));
1520 Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET),
1521 Int32Or(oldWithMask, newValue));
1522 }
1523
GetInlinedPropertiesFromHClass(GateRef hClass)1524 inline GateRef StubBuilder::GetInlinedPropertiesFromHClass(GateRef hClass)
1525 {
1526 GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1527 GateRef objectSizeInWords = Int32And(Int32LSR(bitfield,
1528 Int32(JSHClass::ObjectSizeInWordsBits::START_BIT)),
1529 Int32((1LU << JSHClass::ObjectSizeInWordsBits::SIZE) - 1));
1530 GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield,
1531 Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1532 Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1533 return Int32Sub(objectSizeInWords, inlinedPropsStart);
1534 }
1535
GetObjectSizeFromHClass(GateRef hClass)1536 inline GateRef StubBuilder::GetObjectSizeFromHClass(GateRef hClass)
1537 {
1538 return env_->GetBuilder()->GetObjectSizeFromHClass(hClass);
1539 }
1540
GetInlinedPropsStartFromHClass(GateRef hClass)1541 inline GateRef StubBuilder::GetInlinedPropsStartFromHClass(GateRef hClass)
1542 {
1543 GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1544 return Int32And(Int32LSR(bitfield,
1545 Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1546 Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1547 }
1548
SetValueToTaggedArray(VariableType valType,GateRef glue,GateRef array,GateRef index,GateRef val)1549 inline void StubBuilder::SetValueToTaggedArray(VariableType valType, GateRef glue, GateRef array,
1550 GateRef index, GateRef val)
1551 {
1552 // NOTE: need to translate MarkingBarrier
1553 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1554 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1555 Store(valType, glue, array, dataOffset, val);
1556 }
1557
GetValueFromTaggedArray(GateRef array,GateRef index)1558 inline GateRef StubBuilder::GetValueFromTaggedArray(GateRef array, GateRef index)
1559 {
1560 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1561 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1562 return Load(VariableType::JS_ANY(), array, dataOffset);
1563 }
1564
IsSpecialIndexedObj(GateRef jsType)1565 inline GateRef StubBuilder::IsSpecialIndexedObj(GateRef jsType)
1566 {
1567 return Int32GreaterThan(jsType, Int32(static_cast<int32_t>(JSType::JS_ARRAY)));
1568 }
1569
IsSpecialContainer(GateRef jsType)1570 inline GateRef StubBuilder::IsSpecialContainer(GateRef jsType)
1571 {
1572 // arraylist and vector has fast pass now
1573 return BoolAnd(
1574 Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST))),
1575 Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_API_VECTOR))));
1576 }
1577
IsFastTypeArray(GateRef jsType)1578 inline GateRef StubBuilder::IsFastTypeArray(GateRef jsType)
1579 {
1580 return BoolAnd(
1581 Int32GreaterThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_FIRST))),
1582 Int32LessThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::JS_FLOAT64_ARRAY))));
1583 }
1584
IsAccessorInternal(GateRef value)1585 inline GateRef StubBuilder::IsAccessorInternal(GateRef value)
1586 {
1587 return Int32Equal(GetObjectType(LoadHClass(value)),
1588 Int32(static_cast<int32_t>(JSType::INTERNAL_ACCESSOR)));
1589 }
1590
GetPropAttrFromLayoutInfo(GateRef layout,GateRef entry)1591 inline GateRef StubBuilder::GetPropAttrFromLayoutInfo(GateRef layout, GateRef entry)
1592 {
1593 GateRef index = Int32Add(Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2)),
1594 Int32(LayoutInfo::ATTR_INDEX_OFFSET));
1595 return GetInt64OfTInt(GetValueFromTaggedArray(layout, index));
1596 }
1597
GetPropertyMetaDataFromAttr(GateRef attr)1598 inline GateRef StubBuilder::GetPropertyMetaDataFromAttr(GateRef attr)
1599 {
1600 return Int32And(Int32LSR(attr, Int32(PropertyAttributes::PropertyMetaDataField::START_BIT)),
1601 Int32((1LLU << PropertyAttributes::PropertyMetaDataField::SIZE) - 1));
1602 }
1603
GetKeyFromLayoutInfo(GateRef layout,GateRef entry)1604 inline GateRef StubBuilder::GetKeyFromLayoutInfo(GateRef layout, GateRef entry)
1605 {
1606 GateRef index = Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2));
1607 return GetValueFromTaggedArray(layout, index);
1608 }
1609
GetPropertiesAddrFromLayoutInfo(GateRef layout)1610 inline GateRef StubBuilder::GetPropertiesAddrFromLayoutInfo(GateRef layout)
1611 {
1612 return PtrAdd(layout, IntPtr(TaggedArray::DATA_OFFSET));
1613 }
1614
GetInt64OfTInt(GateRef x)1615 inline GateRef StubBuilder::GetInt64OfTInt(GateRef x)
1616 {
1617 return env_->GetBuilder()->GetInt64OfTInt(x);
1618 }
1619
GetInt32OfTInt(GateRef x)1620 inline GateRef StubBuilder::GetInt32OfTInt(GateRef x)
1621 {
1622 return TruncInt64ToInt32(GetInt64OfTInt(x));
1623 }
1624
TaggedCastToIntPtr(GateRef x)1625 inline GateRef StubBuilder::TaggedCastToIntPtr(GateRef x)
1626 {
1627 return env_->Is32Bit() ? TruncInt64ToInt32(GetInt64OfTInt(x)) : GetInt64OfTInt(x);
1628 }
1629
GetDoubleOfTDouble(GateRef x)1630 inline GateRef StubBuilder::GetDoubleOfTDouble(GateRef x)
1631 {
1632 return env_->GetBuilder()->GetDoubleOfTDouble(x);
1633 }
1634
GetDoubleOfTNumber(GateRef x)1635 inline GateRef StubBuilder::GetDoubleOfTNumber(GateRef x)
1636 {
1637 return env_->GetBuilder()->GetDoubleOfTNumber(x);
1638 }
1639
LoadObjectFromWeakRef(GateRef x)1640 inline GateRef StubBuilder::LoadObjectFromWeakRef(GateRef x)
1641 {
1642 return env_->GetBuilder()->PtrAdd(x, IntPtr(-JSTaggedValue::TAG_WEAK));
1643 }
1644
ChangeInt32ToFloat64(GateRef x)1645 inline GateRef StubBuilder::ChangeInt32ToFloat64(GateRef x)
1646 {
1647 return env_->GetBuilder()->ChangeInt32ToFloat64(x);
1648 }
1649
ChangeUInt32ToFloat64(GateRef x)1650 inline GateRef StubBuilder::ChangeUInt32ToFloat64(GateRef x)
1651 {
1652 return env_->GetBuilder()->ChangeUInt32ToFloat64(x);
1653 }
1654
ChangeFloat64ToInt32(GateRef x)1655 inline GateRef StubBuilder::ChangeFloat64ToInt32(GateRef x)
1656 {
1657 return env_->GetBuilder()->ChangeFloat64ToInt32(x);
1658 }
1659
ChangeTaggedPointerToInt64(GateRef x)1660 inline GateRef StubBuilder::ChangeTaggedPointerToInt64(GateRef x)
1661 {
1662 return env_->GetBuilder()->ChangeTaggedPointerToInt64(x);
1663 }
1664
Int64ToTaggedPtr(GateRef x)1665 inline GateRef StubBuilder::Int64ToTaggedPtr(GateRef x)
1666 {
1667 return env_->GetBuilder()->Int64ToTaggedPtr(x);
1668 }
1669
CastInt64ToFloat64(GateRef x)1670 inline GateRef StubBuilder::CastInt64ToFloat64(GateRef x)
1671 {
1672 return env_->GetBuilder()->CastInt64ToFloat64(x);
1673 }
1674
SExtInt32ToInt64(GateRef x)1675 inline GateRef StubBuilder::SExtInt32ToInt64(GateRef x)
1676 {
1677 return env_->GetBuilder()->SExtInt32ToInt64(x);
1678 }
1679
SExtInt16ToInt64(GateRef x)1680 inline GateRef StubBuilder::SExtInt16ToInt64(GateRef x)
1681 {
1682 return env_->GetBuilder()->SExtInt16ToInt64(x);
1683 }
1684
SExtInt8ToInt64(GateRef x)1685 inline GateRef StubBuilder::SExtInt8ToInt64(GateRef x)
1686 {
1687 return env_->GetBuilder()->SExtInt8ToInt64(x);
1688 }
1689
SExtInt1ToInt64(GateRef x)1690 inline GateRef StubBuilder::SExtInt1ToInt64(GateRef x)
1691 {
1692 return env_->GetBuilder()->SExtInt1ToInt64(x);
1693 }
1694
SExtInt1ToInt32(GateRef x)1695 inline GateRef StubBuilder::SExtInt1ToInt32(GateRef x)
1696 {
1697 return env_->GetBuilder()->SExtInt1ToInt32(x);
1698 }
1699
ZExtInt8ToInt16(GateRef x)1700 inline GateRef StubBuilder::ZExtInt8ToInt16(GateRef x)
1701 {
1702 return env_->GetBuilder()->ZExtInt8ToInt16(x);
1703 }
1704
ZExtInt32ToInt64(GateRef x)1705 inline GateRef StubBuilder::ZExtInt32ToInt64(GateRef x)
1706 {
1707 return env_->GetBuilder()->ZExtInt32ToInt64(x);
1708 }
1709
ZExtInt1ToInt64(GateRef x)1710 inline GateRef StubBuilder::ZExtInt1ToInt64(GateRef x)
1711 {
1712 return env_->GetBuilder()->ZExtInt1ToInt64(x);
1713 }
1714
ZExtInt1ToInt32(GateRef x)1715 inline GateRef StubBuilder::ZExtInt1ToInt32(GateRef x)
1716 {
1717 return env_->GetBuilder()->ZExtInt1ToInt32(x);
1718 }
1719
ZExtInt8ToInt32(GateRef x)1720 inline GateRef StubBuilder::ZExtInt8ToInt32(GateRef x)
1721 {
1722 return env_->GetBuilder()->ZExtInt8ToInt32(x);
1723 }
1724
ZExtInt8ToInt64(GateRef x)1725 inline GateRef StubBuilder::ZExtInt8ToInt64(GateRef x)
1726 {
1727 return env_->GetBuilder()->ZExtInt8ToInt64(x);
1728 }
1729
ZExtInt8ToPtr(GateRef x)1730 inline GateRef StubBuilder::ZExtInt8ToPtr(GateRef x)
1731 {
1732 return env_->GetBuilder()->ZExtInt8ToPtr(x);
1733 }
1734
ZExtInt16ToPtr(GateRef x)1735 inline GateRef StubBuilder::ZExtInt16ToPtr(GateRef x)
1736 {
1737 return env_->GetBuilder()->ZExtInt16ToPtr(x);
1738 }
1739
SExtInt32ToPtr(GateRef x)1740 inline GateRef StubBuilder::SExtInt32ToPtr(GateRef x)
1741 {
1742 return env_->GetBuilder()->SExtInt32ToPtr(x);
1743 }
1744
ZExtInt16ToInt32(GateRef x)1745 inline GateRef StubBuilder::ZExtInt16ToInt32(GateRef x)
1746 {
1747 return env_->GetBuilder()->ZExtInt16ToInt32(x);
1748 }
1749
ZExtInt16ToInt64(GateRef x)1750 inline GateRef StubBuilder::ZExtInt16ToInt64(GateRef x)
1751 {
1752 return env_->GetBuilder()->ZExtInt16ToInt64(x);
1753 }
1754
TruncInt64ToInt32(GateRef x)1755 inline GateRef StubBuilder::TruncInt64ToInt32(GateRef x)
1756 {
1757 return env_->GetBuilder()->TruncInt64ToInt32(x);
1758 }
1759
TruncPtrToInt32(GateRef x)1760 inline GateRef StubBuilder::TruncPtrToInt32(GateRef x)
1761 {
1762 if (env_->Is32Bit()) {
1763 return x;
1764 }
1765 return TruncInt64ToInt32(x);
1766 }
1767
TruncInt64ToInt1(GateRef x)1768 inline GateRef StubBuilder::TruncInt64ToInt1(GateRef x)
1769 {
1770 return env_->GetBuilder()->TruncInt64ToInt1(x);
1771 }
1772
TruncInt32ToInt1(GateRef x)1773 inline GateRef StubBuilder::TruncInt32ToInt1(GateRef x)
1774 {
1775 return env_->GetBuilder()->TruncInt32ToInt1(x);
1776 }
1777
GetObjectFromConstPool(GateRef constpool,GateRef index)1778 inline GateRef StubBuilder::GetObjectFromConstPool(GateRef constpool, GateRef index)
1779 {
1780 return GetValueFromTaggedArray(constpool, index);
1781 }
1782
GetGlobalConstantAddr(GateRef index)1783 inline GateRef StubBuilder::GetGlobalConstantAddr(GateRef index)
1784 {
1785 return Int64Mul(Int64(sizeof(JSTaggedValue)), index);
1786 }
1787
GetGlobalConstantString(ConstantIndex index)1788 inline GateRef StubBuilder::GetGlobalConstantString(ConstantIndex index)
1789 {
1790 if (env_->Is32Bit()) {
1791 return Int32Mul(Int32(sizeof(JSTaggedValue)), Int32(static_cast<int>(index)));
1792 } else {
1793 return Int64Mul(Int64(sizeof(JSTaggedValue)), Int64(static_cast<int>(index)));
1794 }
1795 }
1796
IsCallableFromBitField(GateRef bitfield)1797 inline GateRef StubBuilder::IsCallableFromBitField(GateRef bitfield)
1798 {
1799 return env_->GetBuilder()->IsCallableFromBitField(bitfield);
1800 }
1801
IsCallable(GateRef obj)1802 inline GateRef StubBuilder::IsCallable(GateRef obj)
1803 {
1804 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsCallable), TaggedIsHeapObject(obj));
1805 GateRef res = env_->GetBuilder()->IsCallable(obj);
1806 EXITENTRY();
1807 return res;
1808 }
1809
1810 // GetOffset func in property_attribute.h
GetOffsetFieldInPropAttr(GateRef attr)1811 inline GateRef StubBuilder::GetOffsetFieldInPropAttr(GateRef attr)
1812 {
1813 return Int32And(
1814 Int32LSR(attr, Int32(PropertyAttributes::OffsetField::START_BIT)),
1815 Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1));
1816 }
1817
1818 // SetOffset func in property_attribute.h
SetOffsetFieldInPropAttr(GateRef attr,GateRef value)1819 inline GateRef StubBuilder::SetOffsetFieldInPropAttr(GateRef attr, GateRef value)
1820 {
1821 GateRef mask = Int32LSL(
1822 Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1),
1823 Int32(PropertyAttributes::OffsetField::START_BIT));
1824 GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
1825 Int32LSL(value, Int32(PropertyAttributes::OffsetField::START_BIT)));
1826 return newVal;
1827 }
1828
1829 // SetIsInlinedProps func in property_attribute.h
SetIsInlinePropsFieldInPropAttr(GateRef attr,GateRef value)1830 inline GateRef StubBuilder::SetIsInlinePropsFieldInPropAttr(GateRef attr, GateRef value)
1831 {
1832 GateRef mask = Int32LSL(
1833 Int32((1LU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1),
1834 Int32(PropertyAttributes::IsInlinedPropsField::START_BIT));
1835 GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
1836 Int32LSL(value, Int32(PropertyAttributes::IsInlinedPropsField::START_BIT)));
1837 return newVal;
1838 }
1839
SetHasConstructorToHClass(GateRef glue,GateRef hClass,GateRef value)1840 inline void StubBuilder::SetHasConstructorToHClass(GateRef glue, GateRef hClass, GateRef value)
1841 {
1842 GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
1843 GateRef mask = Int32LSL(
1844 Int32((1LU << JSHClass::HasConstructorBits::SIZE) - 1),
1845 Int32(JSHClass::HasConstructorBits::START_BIT));
1846 GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
1847 Int32LSL(value, Int32(JSHClass::HasConstructorBits::START_BIT)));
1848 Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET), newVal);
1849 }
1850
IntPtrEuqal(GateRef x,GateRef y)1851 inline GateRef StubBuilder::IntPtrEuqal(GateRef x, GateRef y)
1852 {
1853 return env_->Is32Bit() ? Int32Equal(x, y) : Int64Equal(x, y);
1854 }
1855
GetBitMask(GateRef bitoffset)1856 inline GateRef StubBuilder::GetBitMask(GateRef bitoffset)
1857 {
1858 // BIT_PER_WORD_MASK
1859 GateRef bitPerWordMask = Int32(GCBitset::BIT_PER_WORD_MASK);
1860 // IndexInWord(bitOffset) = bitOffset & BIT_PER_WORD_MASK
1861 GateRef indexInWord = Int32And(bitoffset, bitPerWordMask);
1862 // Mask(indeInWord) = 1 << index
1863 return Int32LSL(Int32(1), indexInWord);
1864 }
1865
ObjectAddressToRange(GateRef x)1866 inline GateRef StubBuilder::ObjectAddressToRange(GateRef x)
1867 {
1868 // This function may cause GateRef x is not an object. GC may not mark this x object.
1869 return IntPtrAnd(TaggedCastToIntPtr(x), IntPtr(~panda::ecmascript::DEFAULT_REGION_MASK));
1870 }
1871
InYoungGeneration(GateRef region)1872 inline GateRef StubBuilder::InYoungGeneration(GateRef region)
1873 {
1874 auto offset = Region::PackedData::GetFlagOffset(env_->Is32Bit());
1875 GateRef x = Load(VariableType::NATIVE_POINTER(), PtrAdd(IntPtr(offset), region),
1876 IntPtr(0));
1877 if (env_->Is32Bit()) {
1878 return Int32Equal(Int32And(x,
1879 Int32(RegionSpaceFlag::VALID_SPACE_MASK)), Int32(RegionSpaceFlag::IN_YOUNG_SPACE));
1880 } else {
1881 return Int64Equal(Int64And(x,
1882 Int64(RegionSpaceFlag::VALID_SPACE_MASK)), Int64(RegionSpaceFlag::IN_YOUNG_SPACE));
1883 }
1884 }
1885
GetParentEnv(GateRef object)1886 inline GateRef StubBuilder::GetParentEnv(GateRef object)
1887 {
1888 GateRef index = Int32(LexicalEnv::PARENT_ENV_INDEX);
1889 return GetValueFromTaggedArray(object, index);
1890 }
1891
GetPropertiesFromLexicalEnv(GateRef object,GateRef index)1892 inline GateRef StubBuilder::GetPropertiesFromLexicalEnv(GateRef object, GateRef index)
1893 {
1894 GateRef valueIndex = Int32Add(index, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
1895 return GetValueFromTaggedArray(object, valueIndex);
1896 }
1897
SetPropertiesToLexicalEnv(GateRef glue,GateRef object,GateRef index,GateRef value)1898 inline void StubBuilder::SetPropertiesToLexicalEnv(GateRef glue, GateRef object, GateRef index, GateRef value)
1899 {
1900 GateRef valueIndex = Int32Add(index, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
1901 SetValueToTaggedArray(VariableType::JS_ANY(), glue, object, valueIndex, value);
1902 }
1903
GetHomeObjectFromJSFunction(GateRef object)1904 inline GateRef StubBuilder::GetHomeObjectFromJSFunction(GateRef object)
1905 {
1906 GateRef offset = IntPtr(JSFunction::HOME_OBJECT_OFFSET);
1907 return Load(VariableType::JS_ANY(), object, offset);
1908 }
1909
GetMethodFromJSFunction(GateRef object)1910 inline GateRef StubBuilder::GetMethodFromJSFunction(GateRef object)
1911 {
1912 auto env = GetEnvironment();
1913 Label subentry(env);
1914 env->SubCfgEntry(&subentry);
1915
1916 GateRef methodOffset;
1917 Label funcIsJSFunctionBase(env);
1918 Label funcIsJSProxy(env);
1919 Label getMethod(env);
1920 Branch(IsJSFunctionBase(object), &funcIsJSFunctionBase, &funcIsJSProxy);
1921 Bind(&funcIsJSFunctionBase);
1922 {
1923 methodOffset = IntPtr(JSFunctionBase::METHOD_OFFSET);
1924 Jump(&getMethod);
1925 }
1926 Bind(&funcIsJSProxy);
1927 {
1928 methodOffset = IntPtr(JSProxy::METHOD_OFFSET);
1929 Jump(&getMethod);
1930 }
1931 Bind(&getMethod);
1932 GateRef method = Load(VariableType::JS_ANY(), object, methodOffset);
1933 env->SubCfgExit();
1934 return method;
1935 }
1936
GetCallFieldFromMethod(GateRef method)1937 inline GateRef StubBuilder::GetCallFieldFromMethod(GateRef method)
1938 {
1939 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
1940 return Load(VariableType::INT64(), method, callFieldOffset);
1941 }
1942
SetLexicalEnvToFunction(GateRef glue,GateRef object,GateRef lexicalEnv)1943 inline void StubBuilder::SetLexicalEnvToFunction(GateRef glue, GateRef object, GateRef lexicalEnv)
1944 {
1945 GateRef offset = IntPtr(JSFunction::LEXICAL_ENV_OFFSET);
1946 Store(VariableType::JS_ANY(), glue, object, offset, lexicalEnv);
1947 }
1948
GetGlobalObject(GateRef glue)1949 inline GateRef StubBuilder::GetGlobalObject(GateRef glue)
1950 {
1951 GateRef offset = IntPtr(JSThread::GlueData::GetGlobalObjOffset(env_->Is32Bit()));
1952 return Load(VariableType::JS_ANY(), glue, offset);
1953 }
1954
GetEntryIndexOfGlobalDictionary(GateRef entry)1955 inline GateRef StubBuilder::GetEntryIndexOfGlobalDictionary(GateRef entry)
1956 {
1957 return Int32Add(Int32(OrderTaggedHashTable<GlobalDictionary>::TABLE_HEADER_SIZE),
1958 Int32Mul(entry, Int32(GlobalDictionary::ENTRY_SIZE)));
1959 }
1960
GetBoxFromGlobalDictionary(GateRef object,GateRef entry)1961 inline GateRef StubBuilder::GetBoxFromGlobalDictionary(GateRef object, GateRef entry)
1962 {
1963 GateRef index = GetEntryIndexOfGlobalDictionary(entry);
1964 GateRef offset = PtrAdd(ZExtInt32ToPtr(index),
1965 IntPtr(GlobalDictionary::ENTRY_VALUE_INDEX));
1966 return GetValueFromTaggedArray(object, offset);
1967 }
1968
GetValueFromGlobalDictionary(GateRef object,GateRef entry)1969 inline GateRef StubBuilder::GetValueFromGlobalDictionary(GateRef object, GateRef entry)
1970 {
1971 GateRef box = GetBoxFromGlobalDictionary(object, entry);
1972 return Load(VariableType::JS_ANY(), box, IntPtr(PropertyBox::VALUE_OFFSET));
1973 }
1974
GetPropertiesFromJSObject(GateRef object)1975 inline GateRef StubBuilder::GetPropertiesFromJSObject(GateRef object)
1976 {
1977 GateRef offset = IntPtr(JSObject::PROPERTIES_OFFSET);
1978 return Load(VariableType::JS_ANY(), object, offset);
1979 }
1980
IsJSFunction(GateRef obj)1981 inline GateRef StubBuilder::IsJSFunction(GateRef obj)
1982 {
1983 GateRef objectType = GetObjectType(LoadHClass(obj));
1984 GateRef greater = Int32GreaterThanOrEqual(objectType,
1985 Int32(static_cast<int32_t>(JSType::JS_FUNCTION_FIRST)));
1986 GateRef less = Int32LessThanOrEqual(objectType,
1987 Int32(static_cast<int32_t>(JSType::JS_FUNCTION_LAST)));
1988 return BoolAnd(greater, less);
1989 }
1990
IsBoundFunction(GateRef obj)1991 inline GateRef StubBuilder::IsBoundFunction(GateRef obj)
1992 {
1993 GateRef objectType = GetObjectType(LoadHClass(obj));
1994 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_BOUND_FUNCTION)));
1995 }
1996
IsNativeMethod(GateRef method)1997 inline GateRef StubBuilder::IsNativeMethod(GateRef method)
1998 {
1999 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2000 GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
2001 return Int64NotEqual(
2002 Int64And(
2003 Int64LSR(callfield, Int64(MethodLiteral::IsNativeBit::START_BIT)),
2004 Int64((1LU << MethodLiteral::IsNativeBit::SIZE) - 1)),
2005 Int64(0));
2006 }
2007
HasAotCode(GateRef method)2008 inline GateRef StubBuilder::HasAotCode(GateRef method)
2009 {
2010 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2011 GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
2012 return Int64NotEqual(
2013 Int64And(
2014 Int64LSR(callfield, Int64(MethodLiteral::IsAotCodeBit::START_BIT)),
2015 Int64((1LU << MethodLiteral::IsAotCodeBit::SIZE) - 1)),
2016 Int64(0));
2017 }
2018
GetExpectedNumOfArgs(GateRef method)2019 inline GateRef StubBuilder::GetExpectedNumOfArgs(GateRef method)
2020 {
2021 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2022 GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
2023 return TruncInt64ToInt32(Int64And(
2024 Int64LSR(callfield, Int64(MethodLiteral::NumArgsBits::START_BIT)),
2025 Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1)));
2026 }
2027
GetMethodFromJSProxy(GateRef proxy)2028 inline GateRef StubBuilder::GetMethodFromJSProxy(GateRef proxy)
2029 {
2030 GateRef offset = IntPtr(JSProxy::METHOD_OFFSET);
2031 return Load(VariableType::JS_ANY(), proxy, offset);
2032 }
2033
GetHandlerFromJSProxy(GateRef proxy)2034 inline GateRef StubBuilder::GetHandlerFromJSProxy(GateRef proxy)
2035 {
2036 GateRef offset = IntPtr(JSProxy::HANDLER_OFFSET);
2037 return Load(VariableType::JS_ANY(), proxy, offset);
2038 }
2039
GetTargetFromJSProxy(GateRef proxy)2040 inline GateRef StubBuilder::GetTargetFromJSProxy(GateRef proxy)
2041 {
2042 GateRef offset = IntPtr(JSProxy::TARGET_OFFSET);
2043 return Load(VariableType::JS_ANY(), proxy, offset);
2044 }
2045
ComputeTaggedArraySize(GateRef length)2046 inline GateRef StubBuilder::ComputeTaggedArraySize(GateRef length)
2047 {
2048 return PtrAdd(IntPtr(TaggedArray::DATA_OFFSET),
2049 PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), length));
2050 }
2051
GetGlobalConstantValue(VariableType type,GateRef glue,ConstantIndex index)2052 inline GateRef StubBuilder::GetGlobalConstantValue(VariableType type, GateRef glue, ConstantIndex index)
2053 {
2054 GateRef gConstAddr = PtrAdd(glue,
2055 IntPtr(JSThread::GlueData::GetGlobalConstOffset(env_->Is32Bit())));
2056 auto constantIndex = IntPtr(JSTaggedValue::TaggedTypeSize() * static_cast<size_t>(index));
2057 return Load(type, gConstAddr, constantIndex);
2058 }
2059
GetGlobalEnvValue(VariableType type,GateRef env,size_t index)2060 inline GateRef StubBuilder::GetGlobalEnvValue(VariableType type, GateRef env, size_t index)
2061 {
2062 auto valueIndex = IntPtr(GlobalEnv::HEADER_SIZE + JSTaggedValue::TaggedTypeSize() * index);
2063 return Load(type, env, valueIndex);
2064 }
2065
HasPendingException(GateRef glue)2066 inline GateRef StubBuilder::HasPendingException(GateRef glue)
2067 {
2068 GateRef exceptionOffset = IntPtr(JSThread::GlueData::GetExceptionOffset(env_->IsArch32Bit()));
2069 GateRef exception = Load(VariableType::JS_ANY(), glue, exceptionOffset);
2070 return TaggedIsNotHole(exception);
2071 }
2072
DispatchBuiltins(GateRef glue,GateRef builtinsId,const std::initializer_list<GateRef> & args)2073 inline GateRef StubBuilder::DispatchBuiltins(GateRef glue, GateRef builtinsId,
2074 const std::initializer_list<GateRef>& args)
2075 {
2076 GateRef target = PtrMul(ZExtInt32ToPtr(builtinsId), IntPtrSize());
2077 return env_->GetBuilder()->CallBuiltin(glue, target, args);
2078 }
2079
DispatchBuiltinsWithArgv(GateRef glue,GateRef builtinsId,const std::initializer_list<GateRef> & args)2080 inline GateRef StubBuilder::DispatchBuiltinsWithArgv(GateRef glue, GateRef builtinsId,
2081 const std::initializer_list<GateRef>& args)
2082 {
2083 GateRef target = PtrMul(ZExtInt32ToPtr(builtinsId), IntPtrSize());
2084 return env_->GetBuilder()->CallBuiltinWithArgv(glue, target, args);
2085 }
2086
GetBuiltinId(GateRef method)2087 inline GateRef StubBuilder::GetBuiltinId(GateRef method)
2088 {
2089 GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
2090 GateRef extraLiteralInfo = Load(VariableType::INT64(), method, extraLiteralInfoOffset);
2091 return TruncInt64ToInt32(Int64And(
2092 Int64LSR(extraLiteralInfo, Int64(MethodLiteral::BuiltinIdBits::START_BIT)),
2093 Int64((1LU << MethodLiteral::BuiltinIdBits::SIZE) - 1)));
2094 }
2095
ComputeSizeUtf8(GateRef length)2096 inline GateRef StubBuilder::ComputeSizeUtf8(GateRef length)
2097 {
2098 return PtrAdd(IntPtr(EcmaString::DATA_OFFSET), length);
2099 }
2100
ComputeSizeUtf16(GateRef length)2101 inline GateRef StubBuilder::ComputeSizeUtf16(GateRef length)
2102 {
2103 return PtrAdd(IntPtr(EcmaString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t))));
2104 }
2105
AlignUp(GateRef x,GateRef alignment)2106 inline GateRef StubBuilder::AlignUp(GateRef x, GateRef alignment)
2107 {
2108 GateRef x1 = PtrAdd(x, PtrSub(alignment, IntPtr(1)));
2109 return IntPtrAnd(x1, IntPtrNot(PtrSub(alignment, IntPtr(1))));
2110 }
2111
SetLength(GateRef glue,GateRef str,GateRef length,bool compressed)2112 inline void StubBuilder::SetLength(GateRef glue, GateRef str, GateRef length, bool compressed)
2113 {
2114 GateRef len = Int32LSL(length, Int32(2));
2115 GateRef mixLength;
2116 if (compressed) {
2117 mixLength = Int32Or(len, Int32(EcmaString::STRING_COMPRESSED));
2118 } else {
2119 mixLength = Int32Or(len, Int32(EcmaString::STRING_UNCOMPRESSED));
2120 }
2121 Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::MIX_LENGTH_OFFSET), mixLength);
2122 }
2123
SetRawHashcode(GateRef glue,GateRef str,GateRef rawHashcode)2124 inline void StubBuilder::SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode)
2125 {
2126 Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::HASHCODE_OFFSET), rawHashcode);
2127 }
2128
SetExtensibleToBitfield(GateRef glue,GateRef obj,bool isExtensible)2129 inline void StubBuilder::SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible)
2130 {
2131 GateRef jsHclass = LoadHClass(obj);
2132 GateRef bitfield = Load(VariableType::INT32(), jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
2133 GateRef boolVal = Boolean(isExtensible);
2134 GateRef boolToInt32 = ZExtInt1ToInt32(boolVal);
2135 GateRef encodeValue = Int32LSL(boolToInt32, Int32(JSHClass::ExtensibleBit::START_BIT));
2136 GateRef mask = Int32(((1LU << JSHClass::ExtensibleBit::SIZE) - 1) << JSHClass::ExtensibleBit::START_BIT);
2137 bitfield = Int32Or(Int32And(bitfield, Int32Not(mask)), encodeValue);
2138 Store(VariableType::INT32(), glue, jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET), bitfield);
2139 }
2140 } // namespace panda::ecmascript::kungfu
2141 #endif // ECMASCRIPT_COMPILER_STUB_INL_H
2142