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