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,
1550 GateRef glue, GateRef hClass, GateRef protoChange)
1551 {
1552 GateRef offset = IntPtr(JSHClass::PROTO_CHANGE_DETAILS_OFFSET);
1553 Store(type, glue, hClass, offset, protoChange);
1554 }
1555
SetLayoutToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef attr)1556 inline void StubBuilder::SetLayoutToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef attr)
1557 {
1558 GateRef offset = IntPtr(JSHClass::LAYOUT_OFFSET);
1559 Store(type, glue, hClass, offset, attr);
1560 }
1561
SetEnumCacheToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef key)1562 inline void StubBuilder::SetEnumCacheToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef key)
1563 {
1564 GateRef offset = IntPtr(JSHClass::ENUM_CACHE_OFFSET);
1565 Store(type, glue, hClass, offset, key);
1566 }
1567
SetTransitionsToHClass(VariableType type,GateRef glue,GateRef hClass,GateRef transition)1568 inline void StubBuilder::SetTransitionsToHClass(VariableType type, GateRef glue, GateRef hClass, GateRef transition)
1569 {
1570 GateRef offset = IntPtr(JSHClass::TRANSTIONS_OFFSET);
1571 Store(type, glue, hClass, offset, transition);
1572 }
1573
SetIsProtoTypeToHClass(GateRef glue,GateRef hClass,GateRef value)1574 inline void StubBuilder::SetIsProtoTypeToHClass(GateRef glue, GateRef hClass, GateRef value)
1575 {
1576 GateRef oldValue = ZExtInt1ToInt32(value);
1577 GateRef bitfield = GetBitFieldFromHClass(hClass);
1578 GateRef mask = Int32LSL(
1579 Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1),
1580 Int32(JSHClass::IsPrototypeBit::START_BIT));
1581 GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
1582 Int32LSL(oldValue, Int32(JSHClass::IsPrototypeBit::START_BIT)));
1583 SetBitFieldToHClass(glue, hClass, newVal);
1584 }
1585
IsProtoTypeHClass(GateRef hClass)1586 inline GateRef StubBuilder::IsProtoTypeHClass(GateRef hClass)
1587 {
1588 GateRef bitfield = GetBitFieldFromHClass(hClass);
1589 return TruncInt32ToInt1(Int32And(Int32LSR(bitfield,
1590 Int32(JSHClass::IsPrototypeBit::START_BIT)),
1591 Int32((1LU << JSHClass::IsPrototypeBit::SIZE) - 1)));
1592 }
1593
SetPropertyInlinedProps(GateRef glue,GateRef obj,GateRef hClass,GateRef value,GateRef attrOffset,VariableType type)1594 inline void StubBuilder::SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass,
1595 GateRef value, GateRef attrOffset, VariableType type)
1596 {
1597 ASM_ASSERT_WITH_GLUE(GET_MESSAGE_STRING_ID(IsNotDictionaryMode), BoolNot(IsDictionaryModeByHClass(hClass)), glue);
1598 GateRef bitfield = Load(VariableType::INT32(), hClass,
1599 IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1600 GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield,
1601 Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1602 Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1603 GateRef propOffset = Int32Mul(
1604 Int32Add(inlinedPropsStart, attrOffset), Int32(JSTaggedValue::TaggedTypeSize()));
1605
1606 // NOTE: need to translate MarkingBarrier
1607 Store(type, glue, obj, ZExtInt32ToPtr(propOffset), value);
1608 EXITENTRY();
1609 }
1610
GetPropertyInlinedProps(GateRef obj,GateRef hClass,GateRef index)1611 inline GateRef StubBuilder::GetPropertyInlinedProps(GateRef obj, GateRef hClass,
1612 GateRef index)
1613 {
1614 GateRef inlinedPropsStart = GetInlinedPropsStartFromHClass(hClass);
1615 GateRef propOffset = Int32Mul(
1616 Int32Add(inlinedPropsStart, index), Int32(JSTaggedValue::TaggedTypeSize()));
1617 return Load(VariableType::JS_ANY(), obj, ZExtInt32ToInt64(propOffset));
1618 }
1619
GetInlinedPropOffsetFromHClass(GateRef hclass,GateRef index)1620 inline GateRef StubBuilder::GetInlinedPropOffsetFromHClass(GateRef hclass, GateRef index)
1621 {
1622 GateRef inlinedPropsStart = GetInlinedPropsStartFromHClass(hclass);
1623 GateRef propOffset = Int32Mul(
1624 Int32Add(inlinedPropsStart, index), Int32(JSTaggedValue::TaggedTypeSize()));
1625 return ZExtInt32ToInt64(propOffset);
1626 }
1627
IncNumberOfProps(GateRef glue,GateRef hClass)1628 inline void StubBuilder::IncNumberOfProps(GateRef glue, GateRef hClass)
1629 {
1630 GateRef propNums = GetNumberOfPropsFromHClass(hClass);
1631 SetNumberOfPropsToHClass(glue, hClass, Int32Add(propNums, Int32(1)));
1632 }
1633
GetNumberOfPropsFromHClass(GateRef hClass)1634 inline GateRef StubBuilder::GetNumberOfPropsFromHClass(GateRef hClass)
1635 {
1636 GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1637 return Int32And(Int32LSR(bitfield,
1638 Int32(JSHClass::NumberOfPropsBits::START_BIT)),
1639 Int32((1LLU << JSHClass::NumberOfPropsBits::SIZE) - 1));
1640 }
1641
IsTSHClass(GateRef hClass)1642 inline GateRef StubBuilder::IsTSHClass(GateRef hClass)
1643 {
1644 GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
1645 return Int32NotEqual(Int32And(Int32LSR(bitfield,
1646 Int32(JSHClass::IsTSBit::START_BIT)),
1647 Int32((1LU << JSHClass::IsTSBit::SIZE) - 1)),
1648 Int32(0));
1649 }
1650
SetNumberOfPropsToHClass(GateRef glue,GateRef hClass,GateRef value)1651 inline void StubBuilder::SetNumberOfPropsToHClass(GateRef glue, GateRef hClass, GateRef value)
1652 {
1653 GateRef bitfield1 = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1654 GateRef oldWithMask = Int32And(bitfield1,
1655 Int32(~static_cast<uint32_t>(JSHClass::NumberOfPropsBits::Mask())));
1656 GateRef newValue = Int32LSR(value, Int32(JSHClass::NumberOfPropsBits::START_BIT));
1657 Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET),
1658 Int32Or(oldWithMask, newValue));
1659 }
1660
GetInlinedPropertiesFromHClass(GateRef hClass)1661 inline GateRef StubBuilder::GetInlinedPropertiesFromHClass(GateRef hClass)
1662 {
1663 GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1664 GateRef objectSizeInWords = Int32And(Int32LSR(bitfield,
1665 Int32(JSHClass::ObjectSizeInWordsBits::START_BIT)),
1666 Int32((1LU << JSHClass::ObjectSizeInWordsBits::SIZE) - 1));
1667 GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield,
1668 Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1669 Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1670 return Int32Sub(objectSizeInWords, inlinedPropsStart);
1671 }
1672
GetElementsKindFromHClass(GateRef hClass)1673 inline GateRef StubBuilder::GetElementsKindFromHClass(GateRef hClass)
1674 {
1675 return env_->GetBuilder()->GetElementsKindByHClass(hClass);
1676 }
1677
GetObjectSizeFromHClass(GateRef hClass)1678 inline GateRef StubBuilder::GetObjectSizeFromHClass(GateRef hClass)
1679 {
1680 return env_->GetBuilder()->GetObjectSizeFromHClass(hClass);
1681 }
1682
GetInlinedPropsStartFromHClass(GateRef hClass)1683 inline GateRef StubBuilder::GetInlinedPropsStartFromHClass(GateRef hClass)
1684 {
1685 GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
1686 return Int32And(Int32LSR(bitfield,
1687 Int32(JSHClass::InlinedPropsStartBits::START_BIT)),
1688 Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1));
1689 }
1690
SetValueToTaggedArrayWithAttr(GateRef glue,GateRef array,GateRef index,GateRef key,GateRef val,GateRef attr)1691 inline void StubBuilder::SetValueToTaggedArrayWithAttr(
1692 GateRef glue, GateRef array, GateRef index, GateRef key, GateRef val, GateRef attr)
1693 {
1694 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1695 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1696 SetValueWithAttr(glue, array, dataOffset, key, val, attr);
1697 }
1698
SetValueToTaggedArrayWithRep(GateRef glue,GateRef array,GateRef index,GateRef val,GateRef rep,Label * repChange)1699 inline void StubBuilder::SetValueToTaggedArrayWithRep(
1700 GateRef glue, GateRef array, GateRef index, GateRef val, GateRef rep, Label *repChange)
1701 {
1702 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1703 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1704 SetValueWithRep(glue, array, dataOffset, val, rep, repChange);
1705 }
1706
SetValueToTaggedArray(VariableType valType,GateRef glue,GateRef array,GateRef index,GateRef val)1707 inline void StubBuilder::SetValueToTaggedArray(VariableType valType, GateRef glue, GateRef array,
1708 GateRef index, GateRef val)
1709 {
1710 // NOTE: need to translate MarkingBarrier
1711 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1712 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1713 Store(valType, glue, array, dataOffset, val);
1714 }
1715
GetValueFromTaggedArray(GateRef array,GateRef index)1716 inline GateRef StubBuilder::GetValueFromTaggedArray(GateRef array, GateRef index)
1717 {
1718 GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
1719 GateRef dataOffset = PtrAdd(offset, IntPtr(TaggedArray::DATA_OFFSET));
1720 return Load(VariableType::JS_ANY(), array, dataOffset);
1721 }
1722
IsSpecialIndexedObj(GateRef jsType)1723 inline GateRef StubBuilder::IsSpecialIndexedObj(GateRef jsType)
1724 {
1725 return Int32GreaterThan(jsType, Int32(static_cast<int32_t>(JSType::JS_ARRAY)));
1726 }
1727
IsSpecialContainer(GateRef jsType)1728 inline GateRef StubBuilder::IsSpecialContainer(GateRef jsType)
1729 {
1730 // arraylist and vector has fast pass now
1731 return BoolAnd(
1732 Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_API_ARRAY_LIST))),
1733 Int32Equal(jsType, Int32(static_cast<int32_t>(JSType::JS_API_VECTOR))));
1734 }
1735
IsFastTypeArray(GateRef jsType)1736 inline GateRef StubBuilder::IsFastTypeArray(GateRef jsType)
1737 {
1738 return BoolAnd(
1739 Int32GreaterThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_FIRST))),
1740 Int32LessThanOrEqual(jsType, Int32(static_cast<int32_t>(JSType::JS_FLOAT64_ARRAY))));
1741 }
1742
IsAccessorInternal(GateRef value)1743 inline GateRef StubBuilder::IsAccessorInternal(GateRef value)
1744 {
1745 return Int32Equal(GetObjectType(LoadHClass(value)),
1746 Int32(static_cast<int32_t>(JSType::INTERNAL_ACCESSOR)));
1747 }
1748
GetPropAttrFromLayoutInfo(GateRef layout,GateRef entry)1749 inline GateRef StubBuilder::GetPropAttrFromLayoutInfo(GateRef layout, GateRef entry)
1750 {
1751 GateRef index = Int32Add(Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2)),
1752 Int32(LayoutInfo::ATTR_INDEX_OFFSET));
1753 return GetInt64OfTInt(GetValueFromTaggedArray(layout, index));
1754 }
1755
SetPropAttrToLayoutInfo(GateRef glue,GateRef layout,GateRef entry,GateRef attr)1756 inline void StubBuilder::SetPropAttrToLayoutInfo(GateRef glue, GateRef layout, GateRef entry, GateRef attr)
1757 {
1758 GateRef index = Int32Add(Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2)),
1759 Int32(LayoutInfo::ATTR_INDEX_OFFSET));
1760 GateRef taggedAttr = Int64ToTaggedInt(ZExtInt32ToInt64(attr));
1761 SetValueToTaggedArray(VariableType::JS_ANY(), glue, layout, index, taggedAttr);
1762 }
1763
GetPropertyMetaDataFromAttr(GateRef attr)1764 inline GateRef StubBuilder::GetPropertyMetaDataFromAttr(GateRef attr)
1765 {
1766 return Int32And(Int32LSR(attr, Int32(PropertyAttributes::PropertyMetaDataField::START_BIT)),
1767 Int32((1LLU << PropertyAttributes::PropertyMetaDataField::SIZE) - 1));
1768 }
1769
GetKeyFromLayoutInfo(GateRef layout,GateRef entry)1770 inline GateRef StubBuilder::GetKeyFromLayoutInfo(GateRef layout, GateRef entry)
1771 {
1772 GateRef index = Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2));
1773 return GetValueFromTaggedArray(layout, index);
1774 }
1775
GetPropertiesAddrFromLayoutInfo(GateRef layout)1776 inline GateRef StubBuilder::GetPropertiesAddrFromLayoutInfo(GateRef layout)
1777 {
1778 return PtrAdd(layout, IntPtr(TaggedArray::DATA_OFFSET));
1779 }
1780
GetInt64OfTInt(GateRef x)1781 inline GateRef StubBuilder::GetInt64OfTInt(GateRef x)
1782 {
1783 return env_->GetBuilder()->GetInt64OfTInt(x);
1784 }
1785
GetInt32OfTInt(GateRef x)1786 inline GateRef StubBuilder::GetInt32OfTInt(GateRef x)
1787 {
1788 return TruncInt64ToInt32(GetInt64OfTInt(x));
1789 }
1790
TaggedCastToIntPtr(GateRef x)1791 inline GateRef StubBuilder::TaggedCastToIntPtr(GateRef x)
1792 {
1793 return env_->Is32Bit() ? TruncInt64ToInt32(GetInt64OfTInt(x)) : GetInt64OfTInt(x);
1794 }
1795
GetDoubleOfTInt(GateRef x)1796 inline GateRef StubBuilder::GetDoubleOfTInt(GateRef x)
1797 {
1798 return ChangeInt32ToFloat64(GetInt32OfTInt(x));
1799 }
1800
GetDoubleOfTDouble(GateRef x)1801 inline GateRef StubBuilder::GetDoubleOfTDouble(GateRef x)
1802 {
1803 return env_->GetBuilder()->GetDoubleOfTDouble(x);
1804 }
1805
GetDoubleOfTNumber(GateRef x)1806 inline GateRef StubBuilder::GetDoubleOfTNumber(GateRef x)
1807 {
1808 return env_->GetBuilder()->GetDoubleOfTNumber(x);
1809 }
1810
LoadObjectFromWeakRef(GateRef x)1811 inline GateRef StubBuilder::LoadObjectFromWeakRef(GateRef x)
1812 {
1813 return env_->GetBuilder()->LoadObjectFromWeakRef(x);
1814 }
1815
ExtFloat32ToDouble(GateRef x)1816 inline GateRef StubBuilder::ExtFloat32ToDouble(GateRef x)
1817 {
1818 return env_->GetBuilder()->ExtFloat32ToDouble(x);
1819 }
1820
ChangeInt32ToFloat32(GateRef x)1821 inline GateRef StubBuilder::ChangeInt32ToFloat32(GateRef x)
1822 {
1823 return env_->GetBuilder()->ChangeInt32ToFloat32(x);
1824 }
1825
ChangeInt32ToFloat64(GateRef x)1826 inline GateRef StubBuilder::ChangeInt32ToFloat64(GateRef x)
1827 {
1828 return env_->GetBuilder()->ChangeInt32ToFloat64(x);
1829 }
1830
ChangeUInt32ToFloat64(GateRef x)1831 inline GateRef StubBuilder::ChangeUInt32ToFloat64(GateRef x)
1832 {
1833 return env_->GetBuilder()->ChangeUInt32ToFloat64(x);
1834 }
1835
ChangeFloat64ToInt32(GateRef x)1836 inline GateRef StubBuilder::ChangeFloat64ToInt32(GateRef x)
1837 {
1838 return env_->GetBuilder()->ChangeFloat64ToInt32(x);
1839 }
1840
ChangeTaggedPointerToInt64(GateRef x)1841 inline GateRef StubBuilder::ChangeTaggedPointerToInt64(GateRef x)
1842 {
1843 return env_->GetBuilder()->ChangeTaggedPointerToInt64(x);
1844 }
1845
Int64ToTaggedPtr(GateRef x)1846 inline GateRef StubBuilder::Int64ToTaggedPtr(GateRef x)
1847 {
1848 return env_->GetBuilder()->Int64ToTaggedPtr(x);
1849 }
1850
CastInt32ToFloat32(GateRef x)1851 inline GateRef StubBuilder::CastInt32ToFloat32(GateRef x)
1852 {
1853 return env_->GetBuilder()->CastInt32ToFloat32(x);
1854 }
1855
CastInt64ToFloat64(GateRef x)1856 inline GateRef StubBuilder::CastInt64ToFloat64(GateRef x)
1857 {
1858 return env_->GetBuilder()->CastInt64ToFloat64(x);
1859 }
1860
SExtInt32ToInt64(GateRef x)1861 inline GateRef StubBuilder::SExtInt32ToInt64(GateRef x)
1862 {
1863 return env_->GetBuilder()->SExtInt32ToInt64(x);
1864 }
1865
SExtInt16ToInt64(GateRef x)1866 inline GateRef StubBuilder::SExtInt16ToInt64(GateRef x)
1867 {
1868 return env_->GetBuilder()->SExtInt16ToInt64(x);
1869 }
1870
SExtInt8ToInt64(GateRef x)1871 inline GateRef StubBuilder::SExtInt8ToInt64(GateRef x)
1872 {
1873 return env_->GetBuilder()->SExtInt8ToInt64(x);
1874 }
1875
SExtInt8ToInt32(GateRef x)1876 inline GateRef StubBuilder::SExtInt8ToInt32(GateRef x)
1877 {
1878 return env_->GetBuilder()->SExtInt8ToInt32(x);
1879 }
1880
SExtInt16ToInt32(GateRef x)1881 inline GateRef StubBuilder::SExtInt16ToInt32(GateRef x)
1882 {
1883 return env_->GetBuilder()->SExtInt16ToInt32(x);
1884 }
1885
SExtInt1ToInt64(GateRef x)1886 inline GateRef StubBuilder::SExtInt1ToInt64(GateRef x)
1887 {
1888 return env_->GetBuilder()->SExtInt1ToInt64(x);
1889 }
1890
SExtInt1ToInt32(GateRef x)1891 inline GateRef StubBuilder::SExtInt1ToInt32(GateRef x)
1892 {
1893 return env_->GetBuilder()->SExtInt1ToInt32(x);
1894 }
1895
ZExtInt8ToInt16(GateRef x)1896 inline GateRef StubBuilder::ZExtInt8ToInt16(GateRef x)
1897 {
1898 return env_->GetBuilder()->ZExtInt8ToInt16(x);
1899 }
1900
ZExtInt32ToInt64(GateRef x)1901 inline GateRef StubBuilder::ZExtInt32ToInt64(GateRef x)
1902 {
1903 return env_->GetBuilder()->ZExtInt32ToInt64(x);
1904 }
1905
ZExtInt1ToInt64(GateRef x)1906 inline GateRef StubBuilder::ZExtInt1ToInt64(GateRef x)
1907 {
1908 return env_->GetBuilder()->ZExtInt1ToInt64(x);
1909 }
1910
ZExtInt1ToInt32(GateRef x)1911 inline GateRef StubBuilder::ZExtInt1ToInt32(GateRef x)
1912 {
1913 return env_->GetBuilder()->ZExtInt1ToInt32(x);
1914 }
1915
ZExtInt8ToInt32(GateRef x)1916 inline GateRef StubBuilder::ZExtInt8ToInt32(GateRef x)
1917 {
1918 return env_->GetBuilder()->ZExtInt8ToInt32(x);
1919 }
1920
ZExtInt8ToInt64(GateRef x)1921 inline GateRef StubBuilder::ZExtInt8ToInt64(GateRef x)
1922 {
1923 return env_->GetBuilder()->ZExtInt8ToInt64(x);
1924 }
1925
ZExtInt8ToPtr(GateRef x)1926 inline GateRef StubBuilder::ZExtInt8ToPtr(GateRef x)
1927 {
1928 return env_->GetBuilder()->ZExtInt8ToPtr(x);
1929 }
1930
ZExtInt16ToPtr(GateRef x)1931 inline GateRef StubBuilder::ZExtInt16ToPtr(GateRef x)
1932 {
1933 return env_->GetBuilder()->ZExtInt16ToPtr(x);
1934 }
1935
SExtInt32ToPtr(GateRef x)1936 inline GateRef StubBuilder::SExtInt32ToPtr(GateRef x)
1937 {
1938 return env_->GetBuilder()->SExtInt32ToPtr(x);
1939 }
1940
ZExtInt16ToInt32(GateRef x)1941 inline GateRef StubBuilder::ZExtInt16ToInt32(GateRef x)
1942 {
1943 return env_->GetBuilder()->ZExtInt16ToInt32(x);
1944 }
1945
ZExtInt16ToInt64(GateRef x)1946 inline GateRef StubBuilder::ZExtInt16ToInt64(GateRef x)
1947 {
1948 return env_->GetBuilder()->ZExtInt16ToInt64(x);
1949 }
1950
TruncInt64ToInt32(GateRef x)1951 inline GateRef StubBuilder::TruncInt64ToInt32(GateRef x)
1952 {
1953 return env_->GetBuilder()->TruncInt64ToInt32(x);
1954 }
1955
TruncPtrToInt32(GateRef x)1956 inline GateRef StubBuilder::TruncPtrToInt32(GateRef x)
1957 {
1958 if (env_->Is32Bit()) {
1959 return x;
1960 }
1961 return TruncInt64ToInt32(x);
1962 }
1963
TruncInt64ToInt1(GateRef x)1964 inline GateRef StubBuilder::TruncInt64ToInt1(GateRef x)
1965 {
1966 return env_->GetBuilder()->TruncInt64ToInt1(x);
1967 }
1968
TruncInt32ToInt1(GateRef x)1969 inline GateRef StubBuilder::TruncInt32ToInt1(GateRef x)
1970 {
1971 return env_->GetBuilder()->TruncInt32ToInt1(x);
1972 }
1973
GetObjectFromConstPool(GateRef constpool,GateRef index)1974 inline GateRef StubBuilder::GetObjectFromConstPool(GateRef constpool, GateRef index)
1975 {
1976 return GetValueFromTaggedArray(constpool, index);
1977 }
1978
GetGlobalConstantAddr(GateRef index)1979 inline GateRef StubBuilder::GetGlobalConstantAddr(GateRef index)
1980 {
1981 return Int64Mul(Int64(sizeof(JSTaggedValue)), index);
1982 }
1983
GetGlobalConstantString(ConstantIndex index)1984 inline GateRef StubBuilder::GetGlobalConstantString(ConstantIndex index)
1985 {
1986 if (env_->Is32Bit()) {
1987 return Int32Mul(Int32(sizeof(JSTaggedValue)), Int32(static_cast<int>(index)));
1988 } else {
1989 return Int64Mul(Int64(sizeof(JSTaggedValue)), Int64(static_cast<int>(index)));
1990 }
1991 }
1992
IsCallableFromBitField(GateRef bitfield)1993 inline GateRef StubBuilder::IsCallableFromBitField(GateRef bitfield)
1994 {
1995 return env_->GetBuilder()->IsCallableFromBitField(bitfield);
1996 }
1997
IsCallable(GateRef obj)1998 inline GateRef StubBuilder::IsCallable(GateRef obj)
1999 {
2000 ASM_ASSERT(GET_MESSAGE_STRING_ID(IsCallable), TaggedIsHeapObject(obj));
2001 GateRef res = env_->GetBuilder()->IsCallable(obj);
2002 EXITENTRY();
2003 return res;
2004 }
2005
2006 // GetOffset func in property_attribute.h
GetOffsetFieldInPropAttr(GateRef attr)2007 inline GateRef StubBuilder::GetOffsetFieldInPropAttr(GateRef attr)
2008 {
2009 return Int32And(
2010 Int32LSR(attr, Int32(PropertyAttributes::OffsetField::START_BIT)),
2011 Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1));
2012 }
2013
2014 // SetOffset func in property_attribute.h
SetOffsetFieldInPropAttr(GateRef attr,GateRef value)2015 inline GateRef StubBuilder::SetOffsetFieldInPropAttr(GateRef attr, GateRef value)
2016 {
2017 GateRef mask = Int32LSL(
2018 Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1),
2019 Int32(PropertyAttributes::OffsetField::START_BIT));
2020 GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
2021 Int32LSL(value, Int32(PropertyAttributes::OffsetField::START_BIT)));
2022 return newVal;
2023 }
2024
2025 // SetIsInlinedProps func in property_attribute.h
SetIsInlinePropsFieldInPropAttr(GateRef attr,GateRef value)2026 inline GateRef StubBuilder::SetIsInlinePropsFieldInPropAttr(GateRef attr, GateRef value)
2027 {
2028 GateRef mask = Int32LSL(
2029 Int32((1LU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1),
2030 Int32(PropertyAttributes::IsInlinedPropsField::START_BIT));
2031 GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
2032 Int32LSL(value, Int32(PropertyAttributes::IsInlinedPropsField::START_BIT)));
2033 return newVal;
2034 }
2035
2036
SetTrackTypeInPropAttr(GateRef attr,GateRef type)2037 inline GateRef StubBuilder::SetTrackTypeInPropAttr(GateRef attr, GateRef type)
2038 {
2039 GateRef mask = Int32LSL(
2040 Int32((1LU << PropertyAttributes::TrackTypeField::SIZE) - 1),
2041 Int32(PropertyAttributes::TrackTypeField::START_BIT));
2042 GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
2043 Int32LSL(type, Int32(PropertyAttributes::TrackTypeField::START_BIT)));
2044 return newVal;
2045 }
2046
GetTrackTypeInPropAttr(GateRef attr)2047 inline GateRef StubBuilder::GetTrackTypeInPropAttr(GateRef attr)
2048 {
2049 return Int32And(
2050 Int32LSR(attr, Int32(PropertyAttributes::TrackTypeField::START_BIT)),
2051 Int32((1LLU << PropertyAttributes::TrackTypeField::SIZE) - 1));
2052 }
2053
GetRepInPropAttr(GateRef attr)2054 inline GateRef StubBuilder::GetRepInPropAttr(GateRef attr)
2055 {
2056 return Int32And(
2057 Int32LSR(attr, Int32(PropertyAttributes::RepresentationField::START_BIT)),
2058 Int32((1LLU << PropertyAttributes::RepresentationField::SIZE) - 1));
2059 }
2060
IsIntRepInPropAttr(GateRef rep)2061 inline GateRef StubBuilder::IsIntRepInPropAttr(GateRef rep)
2062 {
2063 return Int32Equal(rep, Int32(static_cast<int32_t>(Representation::INT)));
2064 }
2065
IsDoubleRepInPropAttr(GateRef rep)2066 inline GateRef StubBuilder::IsDoubleRepInPropAttr(GateRef rep)
2067 {
2068 return Int32Equal(rep, Int32(static_cast<int32_t>(Representation::DOUBLE)));
2069 }
2070
SetTaggedRepInPropAttr(GateRef attr)2071 inline GateRef StubBuilder::SetTaggedRepInPropAttr(GateRef attr)
2072 {
2073 GateRef mask = Int32LSL(
2074 Int32((1LU << PropertyAttributes::RepresentationField::SIZE) - 1),
2075 Int32(PropertyAttributes::RepresentationField::START_BIT));
2076 GateRef targetType = Int32(static_cast<int32_t>(Representation::TAGGED));
2077 GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
2078 Int32LSL(targetType, Int32(PropertyAttributes::RepresentationField::START_BIT)));
2079 return newVal;
2080 }
2081
SetHasConstructorToHClass(GateRef glue,GateRef hClass,GateRef value)2082 inline void StubBuilder::SetHasConstructorToHClass(GateRef glue, GateRef hClass, GateRef value)
2083 {
2084 GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
2085 GateRef mask = Int32LSL(
2086 Int32((1LU << JSHClass::HasConstructorBits::SIZE) - 1),
2087 Int32(JSHClass::HasConstructorBits::START_BIT));
2088 GateRef newVal = Int32Or(Int32And(bitfield, Int32Not(mask)),
2089 Int32LSL(value, Int32(JSHClass::HasConstructorBits::START_BIT)));
2090 Store(VariableType::INT32(), glue, hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET), newVal);
2091 }
2092
IntPtrEuqal(GateRef x,GateRef y)2093 inline GateRef StubBuilder::IntPtrEuqal(GateRef x, GateRef y)
2094 {
2095 return env_->Is32Bit() ? Int32Equal(x, y) : Int64Equal(x, y);
2096 }
2097
GetBitMask(GateRef bitoffset)2098 inline GateRef StubBuilder::GetBitMask(GateRef bitoffset)
2099 {
2100 // BIT_PER_WORD_MASK
2101 GateRef bitPerWordMask = Int32(GCBitset::BIT_PER_WORD_MASK);
2102 // IndexInWord(bitOffset) = bitOffset & BIT_PER_WORD_MASK
2103 GateRef indexInWord = Int32And(bitoffset, bitPerWordMask);
2104 // Mask(indeInWord) = 1 << index
2105 return Int32LSL(Int32(1), indexInWord);
2106 }
2107
ObjectAddressToRange(GateRef x)2108 inline GateRef StubBuilder::ObjectAddressToRange(GateRef x)
2109 {
2110 // This function may cause GateRef x is not an object. GC may not mark this x object.
2111 return IntPtrAnd(TaggedCastToIntPtr(x), IntPtr(~panda::ecmascript::DEFAULT_REGION_MASK));
2112 }
2113
InYoungGeneration(GateRef region)2114 inline GateRef StubBuilder::InYoungGeneration(GateRef region)
2115 {
2116 auto offset = Region::PackedData::GetFlagOffset(env_->Is32Bit());
2117 GateRef x = Load(VariableType::NATIVE_POINTER(), PtrAdd(IntPtr(offset), region),
2118 IntPtr(0));
2119 if (env_->Is32Bit()) {
2120 return Int32Equal(Int32And(x,
2121 Int32(RegionSpaceFlag::VALID_SPACE_MASK)), Int32(RegionSpaceFlag::IN_YOUNG_SPACE));
2122 } else {
2123 return Int64Equal(Int64And(x,
2124 Int64(RegionSpaceFlag::VALID_SPACE_MASK)), Int64(RegionSpaceFlag::IN_YOUNG_SPACE));
2125 }
2126 }
2127
GetParentEnv(GateRef object)2128 inline GateRef StubBuilder::GetParentEnv(GateRef object)
2129 {
2130 GateRef index = Int32(LexicalEnv::PARENT_ENV_INDEX);
2131 return GetValueFromTaggedArray(object, index);
2132 }
2133
GetPropertiesFromLexicalEnv(GateRef object,GateRef index)2134 inline GateRef StubBuilder::GetPropertiesFromLexicalEnv(GateRef object, GateRef index)
2135 {
2136 GateRef valueIndex = Int32Add(index, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
2137 return GetValueFromTaggedArray(object, valueIndex);
2138 }
2139
SetPropertiesToLexicalEnv(GateRef glue,GateRef object,GateRef index,GateRef value)2140 inline void StubBuilder::SetPropertiesToLexicalEnv(GateRef glue, GateRef object, GateRef index, GateRef value)
2141 {
2142 GateRef valueIndex = Int32Add(index, Int32(LexicalEnv::RESERVED_ENV_LENGTH));
2143 SetValueToTaggedArray(VariableType::JS_ANY(), glue, object, valueIndex, value);
2144 }
2145
GetHomeObjectFromJSFunction(GateRef object)2146 inline GateRef StubBuilder::GetHomeObjectFromJSFunction(GateRef object)
2147 {
2148 GateRef offset = IntPtr(JSFunction::HOME_OBJECT_OFFSET);
2149 return Load(VariableType::JS_ANY(), object, offset);
2150 }
2151
GetMethodFromJSFunction(GateRef object)2152 inline GateRef StubBuilder::GetMethodFromJSFunction(GateRef object)
2153 {
2154 auto env = GetEnvironment();
2155 Label subentry(env);
2156 env->SubCfgEntry(&subentry);
2157
2158 GateRef methodOffset;
2159 Label funcIsJSFunctionBase(env);
2160 Label funcIsJSProxy(env);
2161 Label getMethod(env);
2162 Branch(IsJSFunctionBase(object), &funcIsJSFunctionBase, &funcIsJSProxy);
2163 Bind(&funcIsJSFunctionBase);
2164 {
2165 methodOffset = IntPtr(JSFunctionBase::METHOD_OFFSET);
2166 Jump(&getMethod);
2167 }
2168 Bind(&funcIsJSProxy);
2169 {
2170 methodOffset = IntPtr(JSProxy::METHOD_OFFSET);
2171 Jump(&getMethod);
2172 }
2173 Bind(&getMethod);
2174 GateRef method = Load(VariableType::JS_ANY(), object, methodOffset);
2175 env->SubCfgExit();
2176 return method;
2177 }
2178
GetCallFieldFromMethod(GateRef method)2179 inline GateRef StubBuilder::GetCallFieldFromMethod(GateRef method)
2180 {
2181 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2182 return Load(VariableType::INT64(), method, callFieldOffset);
2183 }
2184
SetLexicalEnvToFunction(GateRef glue,GateRef object,GateRef lexicalEnv)2185 inline void StubBuilder::SetLexicalEnvToFunction(GateRef glue, GateRef object, GateRef lexicalEnv)
2186 {
2187 GateRef offset = IntPtr(JSFunction::LEXICAL_ENV_OFFSET);
2188 Store(VariableType::JS_ANY(), glue, object, offset, lexicalEnv);
2189 }
2190
GetGlobalObject(GateRef glue)2191 inline GateRef StubBuilder::GetGlobalObject(GateRef glue)
2192 {
2193 GateRef offset = IntPtr(JSThread::GlueData::GetGlobalObjOffset(env_->Is32Bit()));
2194 return Load(VariableType::JS_ANY(), glue, offset);
2195 }
2196
GetMethodFromFunction(GateRef function)2197 inline GateRef StubBuilder::GetMethodFromFunction(GateRef function)
2198 {
2199 return env_->GetBuilder()->GetMethodFromFunction(function);
2200 }
2201
GetModuleFromFunction(GateRef function)2202 inline GateRef StubBuilder::GetModuleFromFunction(GateRef function)
2203 {
2204 return env_->GetBuilder()->GetModuleFromFunction(function);
2205 }
2206
GetEntryIndexOfGlobalDictionary(GateRef entry)2207 inline GateRef StubBuilder::GetEntryIndexOfGlobalDictionary(GateRef entry)
2208 {
2209 return Int32Add(Int32(OrderTaggedHashTable<GlobalDictionary>::TABLE_HEADER_SIZE),
2210 Int32Mul(entry, Int32(GlobalDictionary::ENTRY_SIZE)));
2211 }
2212
GetBoxFromGlobalDictionary(GateRef object,GateRef entry)2213 inline GateRef StubBuilder::GetBoxFromGlobalDictionary(GateRef object, GateRef entry)
2214 {
2215 GateRef index = GetEntryIndexOfGlobalDictionary(entry);
2216 GateRef offset = PtrAdd(ZExtInt32ToPtr(index),
2217 IntPtr(GlobalDictionary::ENTRY_VALUE_INDEX));
2218 return GetValueFromTaggedArray(object, offset);
2219 }
2220
GetValueFromGlobalDictionary(GateRef object,GateRef entry)2221 inline GateRef StubBuilder::GetValueFromGlobalDictionary(GateRef object, GateRef entry)
2222 {
2223 GateRef box = GetBoxFromGlobalDictionary(object, entry);
2224 return Load(VariableType::JS_ANY(), box, IntPtr(PropertyBox::VALUE_OFFSET));
2225 }
2226
GetPropertiesFromJSObject(GateRef object)2227 inline GateRef StubBuilder::GetPropertiesFromJSObject(GateRef object)
2228 {
2229 GateRef offset = IntPtr(JSObject::PROPERTIES_OFFSET);
2230 return Load(VariableType::JS_ANY(), object, offset);
2231 }
2232
IsJSFunction(GateRef obj)2233 inline GateRef StubBuilder::IsJSFunction(GateRef obj)
2234 {
2235 GateRef objectType = GetObjectType(LoadHClass(obj));
2236 GateRef greater = Int32GreaterThanOrEqual(objectType,
2237 Int32(static_cast<int32_t>(JSType::JS_FUNCTION_FIRST)));
2238 GateRef less = Int32LessThanOrEqual(objectType,
2239 Int32(static_cast<int32_t>(JSType::JS_FUNCTION_LAST)));
2240 return BoolAnd(greater, less);
2241 }
2242
IsBoundFunction(GateRef obj)2243 inline GateRef StubBuilder::IsBoundFunction(GateRef obj)
2244 {
2245 GateRef objectType = GetObjectType(LoadHClass(obj));
2246 return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_BOUND_FUNCTION)));
2247 }
2248
IsNativeMethod(GateRef method)2249 inline GateRef StubBuilder::IsNativeMethod(GateRef method)
2250 {
2251 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2252 GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
2253 return Int64NotEqual(
2254 Int64And(
2255 Int64LSR(callfield, Int64(MethodLiteral::IsNativeBit::START_BIT)),
2256 Int64((1LU << MethodLiteral::IsNativeBit::SIZE) - 1)),
2257 Int64(0));
2258 }
2259
IsOptimizedWithBitField(GateRef bitfield)2260 inline GateRef StubBuilder::IsOptimizedWithBitField(GateRef bitfield)
2261 {
2262 return env_->GetBuilder()->IsOptimizedWithBitField(bitfield);
2263 }
2264
CanFastCallWithBitField(GateRef bitfield)2265 inline GateRef StubBuilder::CanFastCallWithBitField(GateRef bitfield)
2266 {
2267 return env_->GetBuilder()->CanFastCallWithBitField(bitfield);
2268 }
2269
GetExpectedNumOfArgs(GateRef method)2270 inline GateRef StubBuilder::GetExpectedNumOfArgs(GateRef method)
2271 {
2272 GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
2273 GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
2274 return TruncInt64ToInt32(Int64And(
2275 Int64LSR(callfield, Int64(MethodLiteral::NumArgsBits::START_BIT)),
2276 Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1)));
2277 }
2278
GetMethodFromJSProxy(GateRef proxy)2279 inline GateRef StubBuilder::GetMethodFromJSProxy(GateRef proxy)
2280 {
2281 GateRef offset = IntPtr(JSProxy::METHOD_OFFSET);
2282 return Load(VariableType::JS_ANY(), proxy, offset);
2283 }
2284
GetHandlerFromJSProxy(GateRef proxy)2285 inline GateRef StubBuilder::GetHandlerFromJSProxy(GateRef proxy)
2286 {
2287 GateRef offset = IntPtr(JSProxy::HANDLER_OFFSET);
2288 return Load(VariableType::JS_ANY(), proxy, offset);
2289 }
2290
GetTargetFromJSProxy(GateRef proxy)2291 inline GateRef StubBuilder::GetTargetFromJSProxy(GateRef proxy)
2292 {
2293 GateRef offset = IntPtr(JSProxy::TARGET_OFFSET);
2294 return Load(VariableType::JS_ANY(), proxy, offset);
2295 }
2296
ComputeTaggedArraySize(GateRef length)2297 inline GateRef StubBuilder::ComputeTaggedArraySize(GateRef length)
2298 {
2299 return PtrAdd(IntPtr(TaggedArray::DATA_OFFSET),
2300 PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), length));
2301 }
2302
GetGlobalConstantValue(VariableType type,GateRef glue,ConstantIndex index)2303 inline GateRef StubBuilder::GetGlobalConstantValue(VariableType type, GateRef glue, ConstantIndex index)
2304 {
2305 GateRef gConstAddr = Load(VariableType::JS_ANY(), glue,
2306 IntPtr(JSThread::GlueData::GetGlobalConstOffset(env_->Is32Bit())));
2307 auto constantIndex = IntPtr(JSTaggedValue::TaggedTypeSize() * static_cast<size_t>(index));
2308 return Load(type, gConstAddr, constantIndex);
2309 }
2310
GetGlobalEnvValue(VariableType type,GateRef env,size_t index)2311 inline GateRef StubBuilder::GetGlobalEnvValue(VariableType type, GateRef env, size_t index)
2312 {
2313 auto valueIndex = IntPtr(GlobalEnv::HEADER_SIZE + JSTaggedValue::TaggedTypeSize() * index);
2314 return Load(type, env, valueIndex);
2315 }
2316
HasPendingException(GateRef glue)2317 inline GateRef StubBuilder::HasPendingException(GateRef glue)
2318 {
2319 GateRef exceptionOffset = IntPtr(JSThread::GlueData::GetExceptionOffset(env_->IsArch32Bit()));
2320 GateRef exception = Load(VariableType::JS_ANY(), glue, exceptionOffset);
2321 return TaggedIsNotHole(exception);
2322 }
2323
DispatchBuiltins(GateRef glue,GateRef builtinsId,const std::initializer_list<GateRef> & args)2324 inline GateRef StubBuilder::DispatchBuiltins(GateRef glue, GateRef builtinsId,
2325 const std::initializer_list<GateRef>& args)
2326 {
2327 GateRef target = PtrMul(ZExtInt32ToPtr(builtinsId), IntPtrSize());
2328 return env_->GetBuilder()->CallBuiltin(glue, target, args);
2329 }
2330
DispatchBuiltinsWithArgv(GateRef glue,GateRef builtinsId,const std::initializer_list<GateRef> & args)2331 inline GateRef StubBuilder::DispatchBuiltinsWithArgv(GateRef glue, GateRef builtinsId,
2332 const std::initializer_list<GateRef>& args)
2333 {
2334 GateRef target = PtrMul(ZExtInt32ToPtr(builtinsId), IntPtrSize());
2335 return env_->GetBuilder()->CallBuiltinWithArgv(glue, target, args);
2336 }
2337
GetBuiltinId(GateRef method)2338 inline GateRef StubBuilder::GetBuiltinId(GateRef method)
2339 {
2340 GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET);
2341 GateRef extraLiteralInfo = Load(VariableType::INT64(), method, extraLiteralInfoOffset);
2342 return TruncInt64ToInt32(Int64And(
2343 Int64LSR(extraLiteralInfo, Int64(MethodLiteral::BuiltinIdBits::START_BIT)),
2344 Int64((1LU << MethodLiteral::BuiltinIdBits::SIZE) - 1)));
2345 }
2346
ComputeSizeUtf8(GateRef length)2347 inline GateRef StubBuilder::ComputeSizeUtf8(GateRef length)
2348 {
2349 return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), length);
2350 }
2351
ComputeSizeUtf16(GateRef length)2352 inline GateRef StubBuilder::ComputeSizeUtf16(GateRef length)
2353 {
2354 return PtrAdd(IntPtr(LineEcmaString::DATA_OFFSET), PtrMul(length, IntPtr(sizeof(uint16_t))));
2355 }
2356
AlignUp(GateRef x,GateRef alignment)2357 inline GateRef StubBuilder::AlignUp(GateRef x, GateRef alignment)
2358 {
2359 GateRef x1 = PtrAdd(x, PtrSub(alignment, IntPtr(1)));
2360 return IntPtrAnd(x1, IntPtrNot(PtrSub(alignment, IntPtr(1))));
2361 }
2362
SetLength(GateRef glue,GateRef str,GateRef length,bool compressed)2363 inline void StubBuilder::SetLength(GateRef glue, GateRef str, GateRef length, bool compressed)
2364 {
2365 GateRef len = Int32LSL(length, Int32(2));
2366 GateRef mixLength;
2367 if (compressed) {
2368 mixLength = Int32Or(len, Int32(EcmaString::STRING_COMPRESSED));
2369 } else {
2370 mixLength = Int32Or(len, Int32(EcmaString::STRING_UNCOMPRESSED));
2371 }
2372 Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::MIX_LENGTH_OFFSET), mixLength);
2373 }
2374
SetRawHashcode(GateRef glue,GateRef str,GateRef rawHashcode)2375 inline void StubBuilder::SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode)
2376 {
2377 Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::HASHCODE_OFFSET), rawHashcode);
2378 }
2379
TryGetHashcodeFromString(GateRef string)2380 inline GateRef StubBuilder::TryGetHashcodeFromString(GateRef string)
2381 {
2382 return env_->GetBuilder()->TryGetHashcodeFromString(string);
2383 }
2384
SetExtensibleToBitfield(GateRef glue,GateRef obj,bool isExtensible)2385 inline void StubBuilder::SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible)
2386 {
2387 GateRef jsHclass = LoadHClass(obj);
2388 GateRef bitfield = Load(VariableType::INT32(), jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
2389 GateRef boolVal = Boolean(isExtensible);
2390 GateRef boolToInt32 = ZExtInt1ToInt32(boolVal);
2391 GateRef encodeValue = Int32LSL(boolToInt32, Int32(JSHClass::ExtensibleBit::START_BIT));
2392 GateRef mask = Int32(((1LU << JSHClass::ExtensibleBit::SIZE) - 1) << JSHClass::ExtensibleBit::START_BIT);
2393 bitfield = Int32Or(Int32And(bitfield, Int32Not(mask)), encodeValue);
2394 Store(VariableType::INT32(), glue, jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET), bitfield);
2395 }
2396
Comment(GateRef glue,const std::string & str)2397 inline void StubBuilder::Comment(GateRef glue, const std::string &str)
2398 {
2399 CallNGCRuntime(glue, RTSTUB_ID(Comment), { StringPtr(str) });
2400 }
2401
IsStableElements(GateRef hClass)2402 inline GateRef StubBuilder::IsStableElements(GateRef hClass)
2403 {
2404 return env_->GetBuilder()->IsStableElements(hClass);
2405 }
2406
IsStableArguments(GateRef hClass)2407 inline GateRef StubBuilder::IsStableArguments(GateRef hClass)
2408 {
2409 return env_->GetBuilder()->IsStableArguments(hClass);
2410 }
2411
IsStableArray(GateRef hClass)2412 inline GateRef StubBuilder::IsStableArray(GateRef hClass)
2413 {
2414 return env_->GetBuilder()->IsStableArray(hClass);
2415 }
2416
IsTypedArray(GateRef obj)2417 inline GateRef StubBuilder::IsTypedArray(GateRef obj)
2418 {
2419 GateRef jsHclass = LoadHClass(obj);
2420 GateRef jsType = GetObjectType(jsHclass);
2421 return BoolAnd(Int32GreaterThan(jsType, Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_FIRST))),
2422 Int32GreaterThanOrEqual(Int32(static_cast<int32_t>(JSType::JS_TYPED_ARRAY_LAST)), jsType));
2423 }
2424
GetProfileTypeInfo(GateRef jsFunc)2425 inline GateRef StubBuilder::GetProfileTypeInfo(GateRef jsFunc)
2426 {
2427 GateRef method = GetMethodFromFunction(jsFunc);
2428 return Load(VariableType::JS_POINTER(), method, IntPtr(Method::PROFILE_TYPE_INFO_OFFSET));
2429 }
2430
LoadObjectFromConstPool(GateRef jsFunc,GateRef index)2431 inline GateRef StubBuilder::LoadObjectFromConstPool(GateRef jsFunc, GateRef index)
2432 {
2433 return env_->GetBuilder()->LoadObjectFromConstPool(jsFunc, index);
2434 }
2435
LoadPfHeaderFromConstPool(GateRef jsFunc)2436 inline GateRef StubBuilder::LoadPfHeaderFromConstPool(GateRef jsFunc)
2437 {
2438 GateRef method = Load(VariableType::JS_ANY(), jsFunc, IntPtr(JSFunctionBase::METHOD_OFFSET));
2439 GateRef constPool = Load(VariableType::JS_ANY(), method, IntPtr(Method::CONSTANT_POOL_OFFSET));
2440 auto length = GetLengthOfTaggedArray(constPool);
2441 auto index = Int32Sub(length, Int32(ConstantPool::JS_PANDA_FILE_INDEX));
2442 auto jsPandaFile = GetValueFromTaggedArray(constPool, index);
2443 auto jsPfAddr = ChangeInt64ToIntPtr(ChangeTaggedPointerToInt64(jsPandaFile));
2444 auto pfAddr = Load(VariableType::NATIVE_POINTER(), jsPfAddr, Int32(JSPandaFile::PF_OFFSET));
2445 auto pfHeader = Load(VariableType::NATIVE_POINTER(), pfAddr, Int32(0));
2446 return pfHeader;
2447 }
2448 } // namespace panda::ecmascript::kungfu
2449 #endif // ECMASCRIPT_COMPILER_STUB_INL_H
2450