• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "ecmascript/compiler/native_inline_lowering.h"
16 #include "ecmascript/builtins/builtins_number.h"
17 #include "ecmascript/builtins/builtins_string.h"
18 #include "ecmascript/base/number_helper.h"
19 #include "ecmascript/compiler/circuit.h"
20 #include "ecmascript/compiler/circuit_builder-inl.h"
21 #include "ecmascript/compiler/circuit_builder_helper.h"
22 #include "ecmascript/compiler/share_gate_meta_data.h"
23 #include "ecmascript/js_dataview.h"
24 #include "ecmascript/compiler/circuit.h"
25 #include "ecmascript/compiler/new_object_stub_builder.h"
26 #include "ecmascript/global_env.h"
27 #include "ecmascript/js_iterator.h"
28 #include "ecmascript/js_thread.h"
29 #include "ecmascript/message_string.h"
30 
31 namespace panda::ecmascript::kungfu {
32 
GetCallInfo(GateRef gate)33 std::optional<std::pair<size_t, bool>> NativeInlineLowering::GetCallInfo(GateRef gate)
34 {
35     EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate);
36     switch (ecmaOpcode) {
37         case EcmaOpcode::CALLARG0_IMM8:
38             return {{0U, false}};
39         case EcmaOpcode::CALLTHIS0_IMM8_V8:
40             return {{0U, true}};
41         case EcmaOpcode::CALLARG1_IMM8_V8:
42             return {{1U, false}};
43         case EcmaOpcode::CALLTHIS1_IMM8_V8_V8:
44             return {{1U, true}};
45         case EcmaOpcode::CALLARGS2_IMM8_V8_V8:
46             return {{2U, false}};
47         case EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8:
48             return {{2U, true}};
49         case EcmaOpcode::CALLARGS3_IMM8_V8_V8_V8:
50             return {{3U, false}};
51         case EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8:
52             return {{3U, true}};
53         case EcmaOpcode::CALLRANGE_IMM8_IMM8_V8: {
54             CallRangeTypeInfoAccessor tia(compilationEnv_, circuit_, gate);
55             return {{tia.GetArgc(), false}};
56         }
57         case EcmaOpcode::CALLTHISRANGE_IMM8_IMM8_V8: {
58             CallThisRangeTypeInfoAccessor tia(compilationEnv_, circuit_, gate);
59             return {{tia.GetArgc(), true}};
60         }
61         default:
62             return std::nullopt;
63     }
64 }
65 
RunNativeInlineLowering()66 void NativeInlineLowering::RunNativeInlineLowering()
67 {
68     std::vector<GateRef> gateList;
69     circuit_->GetAllGates(gateList);
70     for (const auto &gate : gateList) {
71         auto op = acc_.GetOpCode(gate);
72         if (op != OpCode::JS_BYTECODE) {
73             continue;
74         }
75         auto optCallInfo = GetCallInfo(gate);
76         if (!optCallInfo) {
77             continue;
78         }
79         auto [argc, skipThis] = optCallInfo.value();
80         CallTypeInfoAccessor ctia(compilationEnv_, circuit_, gate);
81         BuiltinsStubCSigns::ID id = ctia.TryGetPGOBuiltinMethodId();
82         if (IS_INVALID_ID(id) && id != BuiltinsStubCSigns::ID::BigIntConstructor) {
83             continue;
84         }
85         switch (id) {
86             case BuiltinsStubCSigns::ID::StringFromCharCode:
87                 TryInlineStringFromCharCode(gate, argc, skipThis);
88                 break;
89             case BuiltinsStubCSigns::ID::StringSubstring:
90                 TryInlineStringSubstring(gate, argc, skipThis);
91                 break;
92             case BuiltinsStubCSigns::ID::StringSubStr:
93                 TryInlineStringSubStr(gate, argc, skipThis);
94                 break;
95             case BuiltinsStubCSigns::ID::StringSlice:
96                 TryInlineStringSlice(gate, argc, skipThis);
97                 break;
98             case BuiltinsStubCSigns::ID::NumberIsFinite:
99                 TryInlineNumberIsFinite(gate, argc, skipThis);
100                 break;
101             case BuiltinsStubCSigns::ID::NumberIsInteger:
102                 TryInlineNumberIsInteger(gate, argc, skipThis);
103                 break;
104             case BuiltinsStubCSigns::ID::NumberIsNaN:
105                 TryInlineNumberIsNaN(gate, argc, skipThis);
106                 break;
107             case BuiltinsStubCSigns::ID::NumberParseFloat:
108                 TryInlineNumberParseFloat(gate, argc, skipThis);
109                 break;
110             case BuiltinsStubCSigns::ID::NumberParseInt:
111                 TryInlineNumberParseInt(gate, argc, skipThis);
112                 break;
113             case BuiltinsStubCSigns::ID::NumberIsSafeInteger:
114                 TryInlineNumberIsSafeInteger(gate, argc, skipThis);
115                 break;
116             case BuiltinsStubCSigns::ID::TypedArrayEntries:
117                 TryInlineTypedArrayIteratorBuiltin(gate, id, circuit_->TypedArrayEntries(), skipThis);
118                 break;
119             case BuiltinsStubCSigns::ID::TypedArrayKeys:
120                 TryInlineTypedArrayIteratorBuiltin(gate, id, circuit_->TypedArrayKeys(), skipThis);
121                 break;
122             case BuiltinsStubCSigns::ID::TypedArrayValues:
123                 TryInlineTypedArrayIteratorBuiltin(gate, id, circuit_->TypedArrayValues(), skipThis);
124                 break;
125             case BuiltinsStubCSigns::ID::ArrayValues:
126                 TryInlineArrayIterator(gate, id, skipThis);
127                 break;
128             case BuiltinsStubCSigns::ID::ArrayKeys:
129                 TryInlineArrayIterator(gate, id, skipThis);
130                 break;
131             case BuiltinsStubCSigns::ID::ArrayEntries:
132                 TryInlineArrayIterator(gate, id, skipThis);
133                 break;
134             case BuiltinsStubCSigns::ID::MathAcos:
135                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAcos(), skipThis);
136                 break;
137             case BuiltinsStubCSigns::ID::MathAcosh:
138                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAcosh(), skipThis);
139                 break;
140             case BuiltinsStubCSigns::ID::MathAsin:
141                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAsin(), skipThis);
142                 break;
143             case BuiltinsStubCSigns::ID::MathAsinh:
144                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAsinh(), skipThis);
145                 break;
146             case BuiltinsStubCSigns::ID::MathAtan:
147                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAtan(), skipThis);
148                 break;
149             case BuiltinsStubCSigns::ID::MathAtan2:
150                 TryInlineMathBinaryBuiltin(gate, argc, id, circuit_->MathAtan2(), skipThis);
151                 break;
152             case BuiltinsStubCSigns::ID::MathAtanh:
153                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathAtanh(), skipThis);
154                 break;
155             case BuiltinsStubCSigns::ID::MathCos:
156                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathCos(), skipThis);
157                 break;
158             case BuiltinsStubCSigns::ID::MathCosh:
159                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathCosh(), skipThis);
160                 break;
161             case BuiltinsStubCSigns::ID::MathSign:
162                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathSign(), skipThis);
163                 break;
164             case BuiltinsStubCSigns::ID::MathSin:
165                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathSin(), skipThis);
166                 break;
167             case BuiltinsStubCSigns::ID::MathSinh:
168                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathSinh(), skipThis);
169                 break;
170             case BuiltinsStubCSigns::ID::MathSqrt:
171                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathSqrt(), skipThis);
172                 break;
173             case BuiltinsStubCSigns::ID::MathTan:
174                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathTan(), skipThis);
175                 break;
176             case BuiltinsStubCSigns::ID::MathTanh:
177                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathTanh(), skipThis);
178                 break;
179             case BuiltinsStubCSigns::ID::MathTrunc:
180                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathTrunc(), skipThis);
181                 break;
182             case BuiltinsStubCSigns::ID::MathAbs:
183                 TryInlineMathAbsBuiltin(gate, argc, skipThis);
184                 break;
185             case BuiltinsStubCSigns::ID::MathLog:
186                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathLog(), skipThis);
187                 break;
188             case BuiltinsStubCSigns::ID::MathLog2:
189                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathLog2(), skipThis);
190                 break;
191             case BuiltinsStubCSigns::ID::MathLog10:
192                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathLog10(), skipThis);
193                 break;
194             case BuiltinsStubCSigns::ID::MathLog1p:
195                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathLog1p(), skipThis);
196                 break;
197             case BuiltinsStubCSigns::ID::MathExp:
198                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathExp(), skipThis);
199                 break;
200             case BuiltinsStubCSigns::ID::MathExpm1:
201                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathExpm1(), skipThis);
202                 break;
203             case BuiltinsStubCSigns::ID::MathClz32:
204                 TryInlineMathClz32Builtin(gate, argc, skipThis);
205                 break;
206             case BuiltinsStubCSigns::ID::MathPow:
207                 TryInlineMathBinaryBuiltin(gate, argc, id, circuit_->MathPow(), skipThis);
208                 break;
209             case BuiltinsStubCSigns::ID::MathCbrt:
210                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathCbrt(), skipThis);
211                 break;
212             case BuiltinsStubCSigns::ID::MathImul:
213                 TryInlineMathImulBuiltin(gate, argc, id, circuit_->MathImul(), skipThis);
214                 break;
215             case BuiltinsStubCSigns::ID::GlobalIsFinite:
216                 TryInlineGlobalFiniteBuiltin(gate, argc, id, circuit_->GlobalIsFinite(), skipThis);
217                 break;
218             case BuiltinsStubCSigns::ID::GlobalIsNan:
219                 TryInlineGlobalNanBuiltin(gate, argc, id, circuit_->GlobalIsNan(), skipThis);
220                 break;
221             case BuiltinsStubCSigns::ID::DateGetTime:
222                 TryInlineDateGetTime(gate, argc, skipThis);
223                 break;
224             case BuiltinsStubCSigns::ID::MathMin:
225                 TryInlineMathMinMaxBuiltin(gate, argc, id, circuit_->MathMin(), base::POSITIVE_INFINITY, skipThis);
226                 break;
227             case BuiltinsStubCSigns::ID::MathMax:
228                 TryInlineMathMinMaxBuiltin(gate, argc, id, circuit_->MathMax(), -base::POSITIVE_INFINITY, skipThis);
229                 break;
230             case BuiltinsStubCSigns::ID::MathRound:
231                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathRound(), skipThis);
232                 break;
233             case BuiltinsStubCSigns::ID::MathFRound:
234                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathFRound(), skipThis);
235                 break;
236             case BuiltinsStubCSigns::ID::MathCeil:
237                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathCeil(), skipThis);
238                 break;
239             case BuiltinsStubCSigns::ID::MathFloor:
240                 TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathFloor(), skipThis);
241                 break;
242             case BuiltinsStubCSigns::ID::ArrayBufferIsView:
243                 TryInlineArrayBufferIsView(gate, argc, id, skipThis);
244                 break;
245             case BuiltinsStubCSigns::ID::DataViewGetFloat32:
246             case BuiltinsStubCSigns::ID::DataViewGetFloat64:
247             case BuiltinsStubCSigns::ID::DataViewGetInt8:
248             case BuiltinsStubCSigns::ID::DataViewGetInt16:
249             case BuiltinsStubCSigns::ID::DataViewGetInt32:
250             case BuiltinsStubCSigns::ID::DataViewGetUint16:
251             case BuiltinsStubCSigns::ID::DataViewGetUint32:
252             case BuiltinsStubCSigns::ID::DataViewGetUint8:
253                 TryInlineDataViewGet(gate, argc, id, skipThis);
254                 break;
255             case BuiltinsStubCSigns::ID::DataViewSetFloat32:
256             case BuiltinsStubCSigns::ID::DataViewSetFloat64:
257             case BuiltinsStubCSigns::ID::DataViewSetInt8:
258             case BuiltinsStubCSigns::ID::DataViewSetInt16:
259             case BuiltinsStubCSigns::ID::DataViewSetInt32:
260             case BuiltinsStubCSigns::ID::DataViewSetUint8:
261             case BuiltinsStubCSigns::ID::DataViewSetUint16:
262             case BuiltinsStubCSigns::ID::DataViewSetUint32:
263                 TryInlineDataViewSet(gate, argc, id, skipThis);
264                 break;
265             case BuiltinsStubCSigns::ID::BigIntAsIntN:
266             case BuiltinsStubCSigns::ID::BigIntAsUintN:
267                 TryInlineBigIntAsIntN(gate, argc, id, skipThis);
268                 break;
269             case BuiltinsStubCSigns::ID::MapGet:
270                 InlineStubBuiltin(gate, 1U, argc, id, circuit_->MapGet(), skipThis);
271                 break;
272             case BuiltinsStubCSigns::ID::MapHas:
273                 InlineStubBuiltin(gate, 1U, argc, id, circuit_->MapHas(), skipThis);
274                 break;
275             case BuiltinsStubCSigns::ID::MapKeys:
276                 InlineStubBuiltin(gate, 0U, argc, id, circuit_->MapKeys(), skipThis);
277                 break;
278             case BuiltinsStubCSigns::ID::MapValues:
279                 InlineStubBuiltin(gate, 0U, argc, id, circuit_->MapValues(), skipThis);
280                 break;
281             case BuiltinsStubCSigns::ID::MapEntries:
282                 InlineStubBuiltin(gate, 0U, argc, id, circuit_->MapEntries(), skipThis);
283                 break;
284             case BuiltinsStubCSigns::ID::SetHas:
285                 InlineStubBuiltin(gate, 1U, argc, id, circuit_->SetHas(), skipThis);
286                 break;
287             case BuiltinsStubCSigns::ID::SetAdd:
288                 InlineStubBuiltin(gate, 1U, argc, id, circuit_->SetAdd(), skipThis);
289                 break;
290             case BuiltinsStubCSigns::ID::DateNow:
291                 TryInlineWhitoutParamBuiltin(gate, argc, id, circuit_->DateNow(), skipThis);
292                 break;
293             case BuiltinsStubCSigns::ID::MapDelete:
294                 InlineStubBuiltin(gate, 1U, argc, id, circuit_->MapDelete(), skipThis);
295                 break;
296             case BuiltinsStubCSigns::ID::SetDelete:
297                 InlineStubBuiltin(gate, 1U, argc, id, circuit_->SetDelete(), skipThis);
298                 break;
299             case BuiltinsStubCSigns::ID::SetValues:
300                 InlineStubBuiltin(gate, 0U, argc, id, circuit_->SetValues(), skipThis);
301                 break;
302             case BuiltinsStubCSigns::ID::SetEntries:
303                 InlineStubBuiltin(gate, 0U, argc, id, circuit_->SetEntries(), skipThis);
304                 break;
305             case BuiltinsStubCSigns::ID::BigIntConstructor:
306                 TryInlineBigIntConstructor(gate, argc, skipThis);
307                 break;
308             case BuiltinsStubCSigns::ID::MapClear:
309                 InlineStubBuiltin(gate, 0U, argc, id, circuit_->MapClear(), skipThis);
310                 break;
311             case BuiltinsStubCSigns::ID::SetClear:
312                 InlineStubBuiltin(gate, 0U, argc, id, circuit_->SetClear(), skipThis);
313                 break;
314             case BuiltinsStubCSigns::ID::ArraySort:
315                 TryInlineArraySort(gate, argc, id, skipThis);
316                 break;
317             case BuiltinsStubCSigns::ID::ObjectIs:
318                 TryInlineObjectIs(gate, argc, id, skipThis);
319                 break;
320             case BuiltinsStubCSigns::ID::ObjectGetPrototypeOf:
321                 TryInlineObjectGetPrototypeOf(gate, argc, id, skipThis);
322                 break;
323             case BuiltinsStubCSigns::ID::ObjectGetProto:
324                 TryInlineObjectGetProto(gate, argc, id, skipThis);
325                 break;
326             case BuiltinsStubCSigns::ID::ObjectCreate:
327                 TryInlineObjectCreate(gate, argc, id, skipThis);
328                 break;
329             case BuiltinsStubCSigns::ID::ObjectIsPrototypeOf:
330                 TryInlineObjectIsPrototypeOf(gate, argc, id, skipThis);
331                 break;
332             case BuiltinsStubCSigns::ID::ObjectHasOwnProperty:
333                 TryInlineObjectHasOwnProperty(gate, argc, id, skipThis);
334                 break;
335             case BuiltinsStubCSigns::ID::ReflectGetPrototypeOf:
336                 TryInlineReflectGetPrototypeOf(gate, argc, id, skipThis);
337                 break;
338             case BuiltinsStubCSigns::ID::ReflectGet:
339                 TryInlineReflectGet(gate, argc, id, skipThis);
340                 break;
341             case BuiltinsStubCSigns::ID::ReflectHas:
342                 TryInlineReflectHas(gate, argc, id, skipThis);
343                 break;
344             case BuiltinsStubCSigns::ID::ReflectConstruct:
345                 TryInlineReflectConstruct(gate, argc, id, skipThis);
346                 break;
347             case BuiltinsStubCSigns::ID::ReflectApply:
348                 TryInlineReflectApply(gate, argc, id, skipThis);
349                 break;
350             case BuiltinsStubCSigns::ID::FunctionPrototypeHasInstance:
351                 TryInlineFunctionPrototypeHasInstance(gate, argc, id, skipThis);
352                 break;
353             case BuiltinsStubCSigns::ID::ArrayIndexOf:
354                 TryInlineIndexOfIncludes(gate, argc, id, skipThis);
355                 break;
356             case BuiltinsStubCSigns::ID::ArrayIncludes:
357                 TryInlineIndexOfIncludes(gate, argc, id, skipThis);
358                 break;
359             case BuiltinsStubCSigns::ID::ArrayForEach:
360                 TryInlineArrayForEach(gate, argc, id, skipThis);
361                 break;
362             case BuiltinsStubCSigns::ID::ArrayFind:
363                 TryInlineArrayFindOrFindIndex(gate, argc, id, skipThis);
364                 break;
365             case BuiltinsStubCSigns::ID::ArrayFindIndex:
366                 TryInlineArrayFindOrFindIndex(gate, argc, id, skipThis);
367                 break;
368             case BuiltinsStubCSigns::ID::ArrayFilter:
369                 TryInlineArrayFilter(gate, argc, id, skipThis);
370                 break;
371             case BuiltinsStubCSigns::ID::ArrayMap:
372                 TryInlineArrayMap(gate, argc, id, skipThis);
373                 break;
374             case BuiltinsStubCSigns::ID::ArraySome:
375                 TryInlineArraySome(gate, argc, id, skipThis);
376                 break;
377             case BuiltinsStubCSigns::ID::ArrayEvery:
378                 TryInlineArrayEvery(gate, argc, id, skipThis);
379                 break;
380             case BuiltinsStubCSigns::ID::ArrayPop:
381                 TryInlineArrayPop(gate, argc, id, skipThis);
382                 break;
383             case BuiltinsStubCSigns::ID::ArraySlice:
384                 TryInlineArraySlice(gate, argc, id, skipThis);
385                 break;
386             default:
387                 break;
388         }
389     }
390 
391     if (EnableLog()) {
392         LOG_COMPILER(INFO) << " ";
393         LOG_COMPILER(INFO) << "\033[34m" << "================="
394                            << " After Native Inline Lowering "
395                            << "[" << GetMethodName() << "] "
396                            << "=================" << "\033[0m";
397         circuit_->PrintAllGatesWithBytecode();
398         LOG_COMPILER(INFO) << "\033[34m" << "=========================== End ===========================" << "\033[0m";
399     }
400 }
401 
AddTraceLogs(GateRef gate,BuiltinsStubCSigns::ID id)402 void NativeInlineLowering::AddTraceLogs(GateRef gate, BuiltinsStubCSigns::ID id)
403 {
404     size_t index = RTSTUB_ID(AotInlineBuiltinTrace);
405 
406     GateRef frameState = acc_.GetFrameState(gate);
407     GateRef frameArgs = acc_.GetValueIn(frameState);
408     GateRef callerFunc = acc_.GetValueIn(frameArgs, 0);
409     std::vector<GateRef> args{callerFunc, builder_.Int32(id)};
410 
411     builder_.CallRuntime(glue_, index, Gate::InvalidGateRef, args, gate);
412 }
413 
TryInlineStringFromCharCode(GateRef gate,size_t argc,bool skipThis)414 void NativeInlineLowering::TryInlineStringFromCharCode(GateRef gate, size_t argc, bool skipThis)
415 {
416     if (!skipThis) {
417         return;
418     }
419     if (argc != 1) {
420         return;
421     }
422     CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
423     Environment env(gate, circuit_, &builder_);
424     if (!Uncheck()) {
425         builder_.CallTargetCheck(gate, tacc.GetFunc(),
426                                  builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::StringFromCharCode)),
427                                  {tacc.GetArg0()});
428     }
429 
430     if (EnableTrace()) {
431         AddTraceLogs(gate, BuiltinsStubCSigns::ID::StringFromCharCode);
432     }
433 
434     GateRef ret = builder_.StringFromSingleCharCode(tacc.GetArg0());
435     acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), ret);
436 }
437 
TryInlineStringSubstring(GateRef gate,size_t argc,bool skipThis)438 void NativeInlineLowering::TryInlineStringSubstring(GateRef gate, size_t argc, bool skipThis)
439 {
440     if (!skipThis) {
441         return;
442     }
443     if (argc != 1 && argc != 2) { // only optimize one or two parameters scene
444         return;
445     }
446     Environment env(gate, circuit_, &builder_);
447     GateRef ret = Circuit::NullGate();
448     if (argc == 1) {
449         CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
450         GateRef thisValue = acc_.GetValueIn(gate, 0);
451         GateRef startTag = tacc.GetArg0();
452         GateRef endTag = builder_.GetLengthFromString(thisValue);
453         if (!Uncheck()) {
454             builder_.CallTargetCheck(gate, tacc.GetFunc(),
455                                      builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::StringSubstring)),
456                                      {tacc.GetArg0()});
457             builder_.EcmaStringCheck(thisValue);
458             auto param_check = builder_.TaggedIsNumber(startTag);
459             builder_.DeoptCheck(param_check, acc_.GetFrameState(gate), DeoptType::BUILTIN_INLINING_TYPE_GUARD);
460         }
461         ret = builder_.StringSubstring(thisValue, startTag, endTag);
462     } else {
463         GateRef thisValue = acc_.GetValueIn(gate, 0);
464         GateRef startTag = acc_.GetValueIn(gate, 1);
465         GateRef endTag = acc_.GetValueIn(gate, 2);
466         GateRef func = acc_.GetValueIn(gate, 3);
467         if (!Uncheck()) {
468             builder_.CallTargetCheck(gate, func,
469                                      builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::StringSubstring)));
470             builder_.EcmaStringCheck(thisValue);
471             auto param_check = LogicAndBuilder(&env).And(builder_.TaggedIsNumber(startTag))
472                 .And(builder_.TaggedIsNumber(endTag)).Done();
473             builder_.DeoptCheck(param_check, acc_.GetFrameState(gate), DeoptType::BUILTIN_INLINING_TYPE_GUARD);
474         }
475         ret = builder_.StringSubstring(thisValue, startTag, endTag);
476     }
477     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
478 }
479 
TryInlineStringSubStr(GateRef gate,size_t argc,bool skipThis)480 void NativeInlineLowering::TryInlineStringSubStr(GateRef gate, size_t argc, bool skipThis)
481 {
482     if (!skipThis) {
483         return;
484     }
485     if (argc != 1 && argc != 2) { // only optimize one or two parameters scene
486         return;
487     }
488     Environment env(gate, circuit_, &builder_);
489     GateRef ret = Circuit::NullGate();
490     if (argc == 1) {
491         CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
492         GateRef thisValue = acc_.GetValueIn(gate, 0);
493         GateRef intStart = tacc.GetArg0();
494         GateRef lengthTag = builder_.Int32(INT_MAX);
495         if (!Uncheck()) {
496             builder_.CallTargetCheck(gate, tacc.GetFunc(),
497                                      builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::StringSubStr)),
498                                      {tacc.GetArg0()});
499             builder_.EcmaStringCheck(thisValue);
500             auto param_check = builder_.TaggedIsNumber(intStart);
501             builder_.DeoptCheck(param_check, acc_.GetFrameState(gate), DeoptType::BUILTIN_INLINING_TYPE_GUARD);
502         }
503         ret = builder_.StringSubStr(thisValue, intStart, lengthTag);
504     } else {
505         GateRef thisValue = acc_.GetValueIn(gate, 0);
506         GateRef intStart = acc_.GetValueIn(gate, 1);
507         GateRef lengthTag = acc_.GetValueIn(gate, 2);
508         GateRef func = acc_.GetValueIn(gate, 3);  //acc
509         if (!Uncheck()) {
510             builder_.CallTargetCheck(gate, func,
511                                      builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::StringSubStr)));
512             builder_.EcmaStringCheck(thisValue);
513             auto param_check = LogicAndBuilder(&env).And(builder_.TaggedIsNumber(intStart))
514                 .And(builder_.TaggedIsNumber(lengthTag)).Done();
515             builder_.DeoptCheck(param_check, acc_.GetFrameState(gate), DeoptType::BUILTIN_INLINING_TYPE_GUARD);
516         }
517         ret = builder_.StringSubStr(thisValue, intStart, lengthTag);
518     }
519     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
520 }
521 
TryInlineStringSlice(GateRef gate,size_t argc,bool skipThis)522 void NativeInlineLowering::TryInlineStringSlice(GateRef gate, size_t argc, bool skipThis)
523 {
524     if (!skipThis) {
525         return;
526     }
527     if (argc != 1 && argc != 2) { // only optimize one or two parameters scene
528         return;
529     }
530     Environment env(gate, circuit_, &builder_);
531     GateRef ret = Circuit::NullGate();
532     if (argc == 1) {
533         CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
534         GateRef thisValue = acc_.GetValueIn(gate, 0);
535         GateRef startTag = tacc.GetArg0();
536         GateRef endTag = builder_.GetLengthFromString(thisValue);
537         if (!Uncheck()) {
538             builder_.CallTargetCheck(gate, tacc.GetFunc(),
539                                      builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::StringSlice)),
540                                      {tacc.GetArg0()});
541             builder_.EcmaStringCheck(thisValue);
542             auto param_check = builder_.TaggedIsNumber(startTag);
543             builder_.DeoptCheck(param_check, acc_.GetFrameState(gate), DeoptType::BUILTIN_INLINING_TYPE_GUARD);
544         }
545         ret = builder_.StringSlice(thisValue, startTag, endTag);
546     } else {
547         GateRef thisValue = acc_.GetValueIn(gate, 0);
548         GateRef startTag = acc_.GetValueIn(gate, 1);
549         GateRef endTag = acc_.GetValueIn(gate, 2);
550         GateRef func = acc_.GetValueIn(gate, 3);
551         if (!Uncheck()) {
552             builder_.CallTargetCheck(gate, func,
553                                      builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::StringSlice)));
554             builder_.EcmaStringCheck(thisValue);
555             auto param_check = LogicAndBuilder(&env).And(builder_.TaggedIsNumber(startTag))
556                 .And(builder_.TaggedIsNumber(endTag)).Done();
557             builder_.DeoptCheck(param_check, acc_.GetFrameState(gate), DeoptType::BUILTIN_INLINING_TYPE_GUARD);
558         }
559         ret = builder_.StringSlice(thisValue, startTag, endTag);
560     }
561     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
562 }
563 
TryInlineNumberIsFinite(GateRef gate,size_t argc,bool skipThis)564 void NativeInlineLowering::TryInlineNumberIsFinite(GateRef gate, size_t argc, bool skipThis)
565 {
566     if (!skipThis) {
567         return;
568     }
569     if (argc != 1) {
570         return;
571     }
572     CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
573     Environment env(gate, circuit_, &builder_);
574     if (!Uncheck()) {
575         builder_.CallTargetCheck(gate, tacc.GetFunc(),
576                                  builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::NumberIsFinite)));
577     }
578     GateRef ret = builder_.NumberIsFinite(tacc.GetArg0());
579     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
580 }
581 
TryInlineNumberIsInteger(GateRef gate,size_t argc,bool skipThis)582 void NativeInlineLowering::TryInlineNumberIsInteger(GateRef gate, size_t argc, bool skipThis)
583 {
584     if (!skipThis) {
585         return;
586     }
587     if (argc != 1) {
588         return;
589     }
590     CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
591     Environment env(gate, circuit_, &builder_);
592     auto id = BuiltinsStubCSigns::ID::NumberIsInteger;
593     if (!Uncheck()) {
594         builder_.CallTargetCheck(gate, tacc.GetFunc(),
595                                  builder_.IntPtr(static_cast<int64_t>(id)));
596     }
597     if (EnableTrace()) {
598         AddTraceLogs(gate, id);
599     }
600     GateRef ret = builder_.NumberIsInteger(tacc.GetArg0());
601     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
602 }
603 
TryInlineNumberIsNaN(GateRef gate,size_t argc,bool skipThis)604 void NativeInlineLowering::TryInlineNumberIsNaN(GateRef gate, size_t argc, bool skipThis)
605 {
606     if (!skipThis) {
607         return;
608     }
609     if (argc != 1) {
610         return;
611     }
612     CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
613     Environment env(gate, circuit_, &builder_);
614     if (!Uncheck()) {
615         builder_.CallTargetCheck(gate, tacc.GetFunc(),
616                                  builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::NumberIsNaN)));
617     }
618     GateRef ret = builder_.NumberIsNaN(tacc.GetArg0());
619     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
620 }
621 
TryInlineNumberParseFloat(GateRef gate,size_t argc,bool skipThis)622 void NativeInlineLowering::TryInlineNumberParseFloat(GateRef gate, size_t argc, bool skipThis)
623 {
624     auto firstParam = skipThis ? 1 : 0;
625     auto func = acc_.GetValueIn(gate, argc + firstParam);
626     auto arg = acc_.GetValueIn(gate, firstParam);
627 
628     Environment env(gate, circuit_, &builder_);
629     auto id = BuiltinsStubCSigns::ID::NumberParseFloat;
630     if (!Uncheck()) {
631         builder_.CallTargetCheck(gate, func, builder_.IntPtr(static_cast<int64_t>(id)));
632     }
633     if (EnableTrace()) {
634         AddTraceLogs(gate, id);
635     }
636     GateRef ret = builder_.NumberParseFloat(arg, acc_.GetFrameState(gate));
637     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
638 }
639 
TryInlineNumberParseInt(GateRef gate,size_t argc,bool skipThis)640 void NativeInlineLowering::TryInlineNumberParseInt(GateRef gate, size_t argc, bool skipThis)
641 {
642     auto firstParam = skipThis ? 1 : 0;
643     auto func = acc_.GetValueIn(gate, argc + firstParam);
644     auto arg = acc_.GetValueIn(gate, firstParam);
645     auto radix = builder_.Undefined();
646     if (argc > 1) {
647         radix = acc_.GetValueIn(gate, firstParam + 1);
648     }
649 
650     Environment env(gate, circuit_, &builder_);
651     auto id = BuiltinsStubCSigns::ID::NumberParseInt;
652     if (!Uncheck()) {
653         builder_.CallTargetCheck(gate, func, builder_.IntPtr(static_cast<int64_t>(id)));
654     }
655     if (EnableTrace()) {
656         AddTraceLogs(gate, id);
657     }
658     GateRef ret = builder_.NumberParseInt(arg, radix);
659     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
660 }
661 
TryInlineNumberIsSafeInteger(GateRef gate,size_t argc,bool skipThis)662 void NativeInlineLowering::TryInlineNumberIsSafeInteger(GateRef gate, size_t argc, bool skipThis)
663 {
664     if (!skipThis) {
665         return;
666     }
667     if (argc != 1) {
668         return;
669     }
670     CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
671     Environment env(gate, circuit_, &builder_);
672     auto id = BuiltinsStubCSigns::ID::NumberIsSafeInteger;
673     if (!Uncheck()) {
674         builder_.CallTargetCheck(gate, tacc.GetFunc(),
675                                  builder_.IntPtr(static_cast<int64_t>(id)));
676     }
677     if (EnableTrace()) {
678         AddTraceLogs(gate, id);
679     }
680     GateRef ret = builder_.NumberIsSafeInteger(tacc.GetArg0());
681     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
682 }
683 
TryInlineBigIntAsIntN(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)684 void NativeInlineLowering::TryInlineBigIntAsIntN(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
685                                                  bool skipThis)
686 {
687     Environment env(gate, circuit_, &builder_);
688     bool firstParam = skipThis ? 1 : 0;
689     if (argc < 2U) {
690         return;
691     }
692     if (!Uncheck()) {
693         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
694                                  builder_.IntPtr(static_cast<int64_t>(id)));
695     }
696     if (EnableTrace()) {
697         AddTraceLogs(gate, id);
698     }
699     GateRef bits = acc_.GetValueIn(gate, firstParam);
700     GateRef bigint = acc_.GetValueIn(gate, firstParam + 1);
701     GateRef frameState = acc_.GetFrameState(gate);
702     bool isUnsigned = (id == BuiltinsStubCSigns::ID::BigIntAsUintN);
703     const auto* op = isUnsigned ? circuit_->BigIntAsUintN() : circuit_->BigIntAsIntN();
704     GateRef ret = builder_.BuildBigIntAsIntN(op, {bits, bigint, frameState});
705     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
706 }
707 
TryInlineTypedArrayIteratorBuiltin(GateRef gate,BuiltinsStubCSigns::ID id,const GateMetaData * op,bool skipThis)708 void NativeInlineLowering::TryInlineTypedArrayIteratorBuiltin(GateRef gate,
709                                                               BuiltinsStubCSigns::ID id,
710                                                               const GateMetaData* op, bool skipThis)
711 {
712     if (!skipThis) {
713         return;
714     }
715 
716     CallThis0TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
717     Environment env(gate, circuit_, &builder_);
718 
719     if (!Uncheck()) {
720         builder_.CallTargetCheck(gate, tacc.GetFunc(), builder_.IntPtr(static_cast<int64_t>(id)), {tacc.GetThisObj()});
721     }
722 
723     if (EnableTrace()) {
724         AddTraceLogs(gate, id);
725     }
726 
727     GateRef ret = builder_.BuildTypedArrayIterator(acc_.GetValueIn(gate, 0), op);
728     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
729 }
730 
TryInlineMathUnaryBuiltin(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,const GateMetaData * op,bool skipThis)731 void NativeInlineLowering::TryInlineMathUnaryBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
732                                                      const GateMetaData* op, bool skipThis)
733 {
734     Environment env(gate, circuit_, &builder_);
735     bool firstParam = skipThis ? 1 : 0;
736     if (!Uncheck()) {
737         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
738                                  builder_.IntPtr(static_cast<int64_t>(id)));
739     }
740 
741     if (EnableTrace()) {
742         AddTraceLogs(gate, id);
743     }
744 
745     if (argc == 0) {
746         acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), builder_.NanValue());
747         return;
748     }
749     GateRef ret = builder_.BuildControlDependOp(op, {acc_.GetValueIn(gate, firstParam)});
750     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
751 }
752 
TryInlineWhitoutParamBuiltin(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,const GateMetaData * op,bool skipThis)753 void NativeInlineLowering::TryInlineWhitoutParamBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
754                                                         const GateMetaData* op, bool skipThis)
755 {
756     Environment env(gate, circuit_, &builder_);
757     bool firstParam = skipThis ? 1 : 0;
758     if (!Uncheck()) {
759         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
760                                  builder_.IntPtr(static_cast<int64_t>(id)));
761     }
762 
763     if (EnableTrace()) {
764         AddTraceLogs(gate, id);
765     }
766 
767     GateRef ret = builder_.BuildControlDependOp(op, {});
768     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
769 }
770 
TryInlineMathAbsBuiltin(GateRef gate,size_t argc,bool skipThis)771 void NativeInlineLowering::TryInlineMathAbsBuiltin(GateRef gate, size_t argc, bool skipThis)
772 {
773     Environment env(gate, circuit_, &builder_);
774     bool firstParam = skipThis ? 1 : 0;
775     if (!Uncheck()) {
776         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
777                                  builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::MathAbs)));
778     }
779 
780     if (EnableTrace()) {
781         AddTraceLogs(gate, BuiltinsStubCSigns::ID::MathAbs);
782     }
783 
784     if (argc == 0) {
785         acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), builder_.NanValue());
786         return;
787     }
788     GateRef ret = builder_.BuildControlDependOp(circuit_->MathAbs(), {acc_.GetValueIn(gate, firstParam)},
789                                                 {acc_.GetFrameState(gate)});
790     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
791 }
792 
TryInlineMathClz32Builtin(GateRef gate,size_t argc,bool skipThis)793 void NativeInlineLowering::TryInlineMathClz32Builtin(GateRef gate, size_t argc, bool skipThis)
794 {
795     Environment env(gate, circuit_, &builder_);
796     bool firstParam = skipThis ? 1 : 0;
797     if (!Uncheck()) {
798         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
799                                  builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::MathClz32)));
800     }
801     if (EnableTrace()) {
802         AddTraceLogs(gate, BuiltinsStubCSigns::ID::MathClz32);
803     }
804     if (argc == 0) {
805         const int32_t defaultValue = 32;
806         acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), builder_.Int32(defaultValue));
807         return;
808     }
809     GateRef ret = builder_.BuildControlDependOp(circuit_->MathClz32(), {acc_.GetValueIn(gate, firstParam)});
810     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
811 }
812 
TryInlineGlobalFiniteBuiltin(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,const GateMetaData * op,bool skipThis)813 void NativeInlineLowering::TryInlineGlobalFiniteBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
814                                                         const GateMetaData* op, bool skipThis)
815 {
816     Environment env(gate, circuit_, &builder_);
817     bool firstParam = skipThis ? 1 : 0;
818     if (!Uncheck()) {
819         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
820                                  builder_.IntPtr(static_cast<int64_t>(id)));
821     }
822     if (EnableTrace()) {
823         AddTraceLogs(gate, id);
824     }
825     if (argc == 0) {
826         acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), builder_.Boolean(false));
827         return;
828     }
829     GateRef ret = builder_.BuildControlDependOp(op, {acc_.GetValueIn(gate, firstParam)});
830     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
831 }
832 
TryInlineGlobalNanBuiltin(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,const GateMetaData * op,bool skipThis)833 void NativeInlineLowering::TryInlineGlobalNanBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
834                                                      const GateMetaData* op, bool skipThis)
835 {
836     Environment env(gate, circuit_, &builder_);
837     bool firstParam = skipThis ? 1 : 0;
838     if (!Uncheck()) {
839         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
840                                  builder_.IntPtr(static_cast<int64_t>(id)));
841     }
842     if (EnableTrace()) {
843         AddTraceLogs(gate, id);
844     }
845     if (argc == 0) {
846         acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), builder_.Boolean(true));
847         return;
848     }
849     GateRef ret = builder_.BuildControlDependOp(op, {acc_.GetValueIn(gate, firstParam)});
850     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
851 }
852 
TryInlineMathImulBuiltin(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,const GateMetaData * op,bool skipThis)853 void NativeInlineLowering::TryInlineMathImulBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
854                                                     const GateMetaData* op, bool skipThis)
855 {
856     Environment env(gate, circuit_, &builder_);
857     bool firstParam = skipThis ? 1 : 0;
858     if (!Uncheck()) {
859         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
860                                  builder_.IntPtr(static_cast<int64_t>(id)));
861     }
862     if (EnableTrace()) {
863         AddTraceLogs(gate, id);
864     }
865     if (argc < 2U) {
866         acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), builder_.Int32(0));
867         return;
868     }
869     GateRef ret = builder_.BuildControlDependOp(op, {acc_.GetValueIn(gate, firstParam),
870                                               acc_.GetValueIn(gate, firstParam + 1)});
871     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
872     return;
873 }
874 
TryInlineMathBinaryBuiltin(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,const GateMetaData * op,bool skipThis)875 void NativeInlineLowering::TryInlineMathBinaryBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
876                                                       const GateMetaData* op, bool skipThis)
877 {
878     Environment env(gate, circuit_, &builder_);
879     bool firstParam = skipThis ? 1 : 0;
880     if (!Uncheck()) {
881         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
882                                  builder_.IntPtr(static_cast<int64_t>(id)));
883     }
884     if (EnableTrace()) {
885         AddTraceLogs(gate, id);
886     }
887     if (argc < 2U) {
888         acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), builder_.NanValue());
889         return;
890     }
891     GateRef ret = builder_.BuildControlDependOp(op, {acc_.GetValueIn(gate, firstParam),
892                                               acc_.GetValueIn(gate, firstParam + 1)});
893     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
894     return;
895 }
896 
TryInlineMathMinMaxBuiltin(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,const GateMetaData * op,double defaultValue,bool skipThis)897 void NativeInlineLowering::TryInlineMathMinMaxBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
898                                                       const GateMetaData* op, double defaultValue, bool skipThis)
899 {
900     Environment env(gate, circuit_, &builder_);
901     bool firstParam = skipThis ? 1 : 0;
902     if (!Uncheck()) {
903         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
904                                  builder_.IntPtr(static_cast<int64_t>(id)));
905     }
906     if (EnableTrace()) {
907         AddTraceLogs(gate, id);
908     }
909     if (argc == 0) {
910         acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), builder_.Double(defaultValue));
911         return;
912     }
913     GateRef ret = acc_.GetValueIn(gate, firstParam);
914     if (argc == 1) {
915         builder_.TypeOfCheck(ret, ParamType::NumberType());
916         acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
917         return;
918     }
919     for (size_t i = 1; i < argc; i++) {
920         auto param = acc_.GetValueIn(gate, i + firstParam);
921         ret = builder_.BuildControlDependOp(op, {ret, param});
922     }
923     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
924 }
925 
TryInlineArrayBufferIsView(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)926 void NativeInlineLowering::TryInlineArrayBufferIsView(GateRef gate,
927                                                       size_t argc,
928                                                       BuiltinsStubCSigns::ID id,
929                                                       bool skipThis)
930 {
931     if (!skipThis) {
932         return;
933     }
934     if (argc != 1) {
935         return;
936     }
937     CallThis1TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
938     Environment env(gate, circuit_, &builder_);
939     if (!Uncheck()) {
940         builder_.CallTargetCheck(gate, tacc.GetFunc(), builder_.IntPtr(static_cast<int64_t>(id)), {tacc.GetArg0()});
941     }
942     GateRef arg0 = tacc.GetArg0();
943     GateRef ret = builder_.ArrayBufferIsView(arg0);
944     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
945 }
946 
TryInlineDataViewGet(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)947 void NativeInlineLowering::TryInlineDataViewGet(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
948 {
949     if (!skipThis) {
950         return;
951     }
952     if (argc != 1 && argc != 2) { // number of args must be 1/2
953         return;
954     }
955     Environment env(gate, circuit_, &builder_);
956     if (!Uncheck()) {
957         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
958     }
959     GateRef thisObj = acc_.GetValueIn(gate, 0); // 0: this
960     builder_.EcmaObjectCheck(thisObj);
961     builder_.IsDataViewCheck(thisObj);
962     GateRef dataViewCallID = builder_.Int32(id);
963     GateRef index = acc_.GetValueIn(gate, 1); // 1: index of dataView
964     GateRef ret = Circuit::NullGate();
965     GateRef frameState = acc_.GetFrameState(gate);
966     builder_.DeoptCheck(builder_.TaggedIsInt(index), frameState, DeoptType::INDEXNOTINT);
967     GateRef indexInt = builder_.TaggedGetInt(index);
968     if (argc == 1) { // if not provide isLittleEndian, default use big endian
969         ret = builder_.DataViewGet(thisObj, indexInt, dataViewCallID, builder_.False(), frameState);
970     } else if (argc == 2) { // 2: provide isLittleEndian
971         GateRef isLittleEndian = acc_.GetValueIn(gate, 2); // 2: is little endian mode
972         ret = builder_.DataViewGet(thisObj, indexInt, dataViewCallID, isLittleEndian, frameState);
973     }
974     if (EnableTrace()) {
975         AddTraceLogs(gate, id);
976     }
977     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
978 }
979 
TryInlineDataViewSet(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)980 void NativeInlineLowering::TryInlineDataViewSet(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
981 {
982     if (!skipThis) {
983         return;
984     }
985     if (argc != 1 && argc != 2 && argc != 3) { // number of args must be 1/2/3
986         return;
987     }
988     Environment env(gate, circuit_, &builder_);
989     if (!Uncheck()) {
990         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
991     }
992     GateRef thisObj = acc_.GetValueIn(gate, 0); // 0: this
993     builder_.EcmaObjectCheck(thisObj);
994     builder_.IsDataViewCheck(thisObj);
995     GateRef dataViewCallID = builder_.Int32(id);
996     GateRef index = acc_.GetValueIn(gate, 1); // 1: index
997     GateRef frameState = acc_.GetFrameState(gate);
998     builder_.DeoptCheck(builder_.TaggedIsInt(index), frameState, DeoptType::INDEXNOTINT);
999     GateRef indexInt = builder_.TaggedGetInt(index);
1000     GateRef ret = Circuit::NullGate();
1001     if (argc == 1) { // arg counts is 1
1002         ret = builder_.DataViewSet(
1003             thisObj, indexInt, builder_.Double(base::NAN_VALUE), dataViewCallID, builder_.False(), frameState);
1004     } else if (argc == 2) { // arg counts is 2
1005         GateRef value = acc_.GetValueIn(gate, 2); // 2: value
1006         ret = builder_.DataViewSet(thisObj, indexInt, value, dataViewCallID, builder_.False(), frameState);
1007     } else if (argc == 3) { // arg counts is 3
1008         GateRef value = acc_.GetValueIn(gate, 2); // 2: value
1009         GateRef isLittleEndian = acc_.GetValueIn(gate, 3); // 3: is little endian mode
1010         ret = builder_.DataViewSet(thisObj, indexInt, value, dataViewCallID, isLittleEndian, frameState);
1011     }
1012     if (EnableTrace()) {
1013         AddTraceLogs(gate, id);
1014     }
1015     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1016 }
1017 
InlineStubBuiltin(GateRef gate,size_t builtinArgc,size_t realArgc,BuiltinsStubCSigns::ID id,const GateMetaData * op,bool skipThis)1018 void NativeInlineLowering::InlineStubBuiltin(GateRef gate, size_t builtinArgc, size_t realArgc,
1019     BuiltinsStubCSigns::ID id, const GateMetaData* op, bool skipThis)
1020 {
1021     if (!skipThis) {
1022         return;
1023     }
1024     Environment env(gate, circuit_, &builder_);
1025     if (!Uncheck()) {
1026         GateRef obj = acc_.GetValueIn(gate, 0);
1027         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, realArgc + 1U),
1028                                  builder_.IntPtr(static_cast<int64_t>(id)), {obj});
1029     }
1030     if (EnableTrace()) {
1031         AddTraceLogs(gate, id);
1032     }
1033 
1034     std::vector<GateRef> args {};
1035     for (size_t i = 0; i <= builtinArgc; i++) {
1036         args.push_back(i <= realArgc ? acc_.GetValueIn(gate, i) : builder_.Undefined());
1037     }
1038     GateRef ret = builder_.BuildControlDependOp(op, args);
1039     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1040 }
1041 
ReplaceGateWithPendingException(GateRef hirGate,GateRef value)1042 void NativeInlineLowering::ReplaceGateWithPendingException(GateRef hirGate, GateRef value)
1043 {
1044     GateRef state = builder_.GetState();
1045     // copy depend-wire of hirGate to value
1046     GateRef depend = builder_.GetDepend();
1047     // exception condition
1048     GateRef condition = builder_.HasPendingException(glue_);
1049     auto ifBranch = builder_.Branch(state, condition, 1, BranchWeight::DEOPT_WEIGHT, "checkException");
1050 
1051     GateRef ifTrue = builder_.IfTrue(ifBranch);
1052     GateRef ifFalse = builder_.IfFalse(ifBranch);
1053     GateRef eDepend = builder_.DependRelay(ifTrue, depend);
1054     GateRef sDepend = builder_.DependRelay(ifFalse, depend);
1055     StateDepend success(ifFalse, sDepend);
1056     StateDepend exception(ifTrue, eDepend);
1057     acc_.ReplaceHirWithIfBranch(hirGate, success, exception, value);
1058 }
1059 
TryInlineBigIntConstructor(GateRef gate,size_t argc,bool skipThis)1060 void NativeInlineLowering::TryInlineBigIntConstructor(GateRef gate, size_t argc, bool skipThis)
1061 {
1062     Environment env(gate, circuit_, &builder_);
1063     bool firstParam = skipThis ? 1 : 0;
1064     auto id = BuiltinsStubCSigns::ID::BigIntConstructor;
1065     if (!Uncheck()) {
1066         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
1067                                  builder_.IntPtr(static_cast<int64_t>(id)));
1068     }
1069     if (EnableTrace()) {
1070         AddTraceLogs(gate, id);
1071     }
1072 
1073     auto param = builder_.Undefined();
1074     if (argc > 0) {
1075         param = acc_.GetValueIn(gate, firstParam);
1076     }
1077 
1078     GateRef ret = builder_.BuildControlDependOp(circuit_->BigIntConstructor(), {param});
1079     ReplaceGateWithPendingException(gate, ret);
1080     return;
1081 }
1082 
TryInlineDateGetTime(GateRef gate,size_t argc,bool skipThis)1083 void NativeInlineLowering::TryInlineDateGetTime(GateRef gate, size_t argc, bool skipThis)
1084 {
1085     // Always shout be "this", we can't inline this function without instance of object
1086     if (!skipThis) {
1087         return;
1088     }
1089     Environment env(gate, circuit_, &builder_);
1090     // We are sure, that "this" is passed to this function, so always need to do +1
1091     bool firstParam = 1;
1092     if (!Uncheck()) {
1093         GateRef obj = acc_.GetValueIn(gate, 0);
1094         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
1095                                  builder_.IntPtr(static_cast<int64_t>(BuiltinsStubCSigns::ID::DateGetTime)), {obj});
1096     }
1097     if (EnableTrace()) {
1098         AddTraceLogs(gate, BuiltinsStubCSigns::ID::DateGetTime);
1099     }
1100     // Take object using "this"
1101     GateRef obj = acc_.GetValueIn(gate, 0);
1102     GateRef ret = builder_.BuildControlDependOp(circuit_->DateGetTime(), {obj});
1103     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1104 }
1105 
TryInlineObjectIs(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1106 void NativeInlineLowering::TryInlineObjectIs(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1107 {
1108     Environment env(gate, circuit_, &builder_);
1109     if (argc != 2) {  // 2: left and right
1110         return;
1111     }
1112 
1113     size_t firstParam = skipThis ? 1 : 0;
1114     if (!Uncheck()) {
1115         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
1116                                  builder_.IntPtr(static_cast<int64_t>(id)));
1117     }
1118 
1119     if (EnableTrace()) {
1120         AddTraceLogs(gate, id);
1121     }
1122 
1123     GateRef left = acc_.GetValueIn(gate, firstParam);
1124     GateRef right = acc_.GetValueIn(gate, firstParam + 1);
1125     GateRef ret = builder_.BuildControlDependOp(circuit_->ObjectIs(), { left, right });
1126     ReplaceGateWithPendingException(gate, ret);
1127 }
1128 
TryInlineObjectGetPrototypeOf(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1129 void NativeInlineLowering::TryInlineObjectGetPrototypeOf(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
1130                                                          bool skipThis)
1131 {
1132     Environment env(gate, circuit_, &builder_);
1133     if (argc != 1) {
1134         return;
1135     }
1136 
1137     size_t firstParam = skipThis ? 1 : 0;
1138     if (!Uncheck()) {
1139         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
1140                                  builder_.IntPtr(static_cast<int64_t>(id)));
1141     }
1142 
1143     if (EnableTrace()) {
1144         AddTraceLogs(gate, id);
1145     }
1146 
1147     GateRef value = acc_.GetValueIn(gate, firstParam);
1148     GateRef ret = builder_.BuildControlDependOp(circuit_->ObjectGetPrototypeOf(), { value });
1149     ReplaceGateWithPendingException(gate, ret);
1150 }
1151 
TryInlineObjectGetProto(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1152 void NativeInlineLowering::TryInlineObjectGetProto(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1153 {
1154     if (!skipThis || argc != 0) {
1155         return;
1156     }
1157 
1158     Environment env(gate, circuit_, &builder_);
1159     if (!Uncheck()) {
1160         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, 1), builder_.IntPtr(static_cast<int64_t>(id)));  // 1: func
1161     }
1162 
1163     if (EnableTrace()) {
1164         AddTraceLogs(gate, id);
1165     }
1166 
1167     GateRef thisValue = acc_.GetValueIn(gate, 0);
1168     GateRef ret = builder_.BuildControlDependOp(circuit_->ObjectGetPrototypeOf(), { thisValue });
1169     ReplaceGateWithPendingException(gate, ret);
1170 }
1171 
TryInlineObjectCreate(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1172 void NativeInlineLowering::TryInlineObjectCreate(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1173 {
1174     Environment env(gate, circuit_, &builder_);
1175     if (argc != 1) {
1176         return;
1177     }
1178 
1179     size_t firstParam = skipThis ? 1 : 0;
1180     if (!Uncheck()) {
1181         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
1182                                  builder_.IntPtr(static_cast<int64_t>(id)));
1183     }
1184 
1185     if (EnableTrace()) {
1186         AddTraceLogs(gate, id);
1187     }
1188 
1189     GateRef proto = acc_.GetValueIn(gate, firstParam);
1190     GateRef ret = builder_.BuildControlDependOp(circuit_->ObjectCreate(), { proto });
1191     ReplaceGateWithPendingException(gate, ret);
1192 }
1193 
TryInlineObjectIsPrototypeOf(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1194 void NativeInlineLowering::TryInlineObjectIsPrototypeOf(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
1195                                                         bool skipThis)
1196 {
1197     if (!skipThis || argc != 1) {
1198         return;
1199     }
1200 
1201     Environment env(gate, circuit_, &builder_);
1202     if (!Uncheck()) {
1203         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, 2), builder_.IntPtr(static_cast<int64_t>(id)));  // 2: func
1204     }
1205 
1206     if (EnableTrace()) {
1207         AddTraceLogs(gate, id);
1208     }
1209 
1210     GateRef thisValue = acc_.GetValueIn(gate, 0);
1211     GateRef value = acc_.GetValueIn(gate, 1);
1212     GateRef ret = builder_.BuildControlDependOp(circuit_->ObjectIsPrototypeOf(), {thisValue, value});
1213     ReplaceGateWithPendingException(gate, ret);
1214 }
1215 
TryInlineObjectHasOwnProperty(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1216 void NativeInlineLowering::TryInlineObjectHasOwnProperty(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
1217                                                          bool skipThis)
1218 {
1219     if (!skipThis || argc != 1) {
1220         return;
1221     }
1222 
1223     Environment env(gate, circuit_, &builder_);
1224     if (!Uncheck()) {
1225         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, 2), builder_.IntPtr(static_cast<int64_t>(id)));  // 2: func
1226     }
1227 
1228     if (EnableTrace()) {
1229         AddTraceLogs(gate, id);
1230     }
1231 
1232     GateRef thisValue = acc_.GetValueIn(gate, 0);
1233     GateRef key = acc_.GetValueIn(gate, 1);
1234     GateRef ret = builder_.BuildControlDependOp(circuit_->ObjectHasOwnProperty(), { thisValue, key });
1235     ReplaceGateWithPendingException(gate, ret);
1236 }
1237 
TryInlineReflectGetPrototypeOf(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1238 void NativeInlineLowering::TryInlineReflectGetPrototypeOf(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
1239                                                           bool skipThis)
1240 {
1241     Environment env(gate, circuit_, &builder_);
1242     if (argc != 1) {
1243         return;
1244     }
1245 
1246     size_t firstParam = skipThis ? 1 : 0;
1247     if (!Uncheck()) {
1248         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
1249                                  builder_.IntPtr(static_cast<int64_t>(id)));
1250     }
1251 
1252     if (EnableTrace()) {
1253         AddTraceLogs(gate, id);
1254     }
1255 
1256     GateRef value = acc_.GetValueIn(gate, firstParam);
1257     GateRef ret = builder_.BuildControlDependOp(circuit_->ReflectGetPrototypeOf(), { value });
1258     ReplaceGateWithPendingException(gate, ret);
1259 }
1260 
TryInlineReflectGet(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1261 void NativeInlineLowering::TryInlineReflectGet(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1262 {
1263     Environment env(gate, circuit_, &builder_);
1264     if (argc != 2) {  // 2: target and key, do not handle receiver argument scene
1265         return;
1266     }
1267 
1268     size_t firstParam = skipThis ? 1 : 0;
1269     GateRef key = acc_.GetValueIn(gate, firstParam + 1);
1270     if (!TypeInfoAccessor::IsTrustedStringType(compilationEnv_, circuit_, chunk_, acc_, key)) {
1271         return;
1272     }
1273 
1274     if (!Uncheck()) {
1275         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
1276                                  builder_.IntPtr(static_cast<int64_t>(id)));
1277     }
1278 
1279     if (EnableTrace()) {
1280         AddTraceLogs(gate, id);
1281     }
1282 
1283     GateRef target = acc_.GetValueIn(gate, firstParam);
1284     GateRef ret = builder_.BuildControlDependOp(circuit_->ReflectGet(), { target, key });
1285     ReplaceGateWithPendingException(gate, ret);
1286 }
1287 
TryInlineReflectHas(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1288 void NativeInlineLowering::TryInlineReflectHas(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1289 {
1290     Environment env(gate, circuit_, &builder_);
1291     if (argc != 2) {  // 2: target and key
1292         return;
1293     }
1294 
1295     size_t firstParam = skipThis ? 1 : 0;
1296     if (!Uncheck()) {
1297         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
1298                                  builder_.IntPtr(static_cast<int64_t>(id)));
1299     }
1300 
1301     if (EnableTrace()) {
1302         AddTraceLogs(gate, id);
1303     }
1304 
1305     GateRef target = acc_.GetValueIn(gate, firstParam);
1306     GateRef key = acc_.GetValueIn(gate, firstParam + 1);
1307     GateRef ret = builder_.BuildControlDependOp(circuit_->ReflectHas(), { target, key });
1308     ReplaceGateWithPendingException(gate, ret);
1309 }
1310 
TryInlineReflectConstruct(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1311 void NativeInlineLowering::TryInlineReflectConstruct(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
1312                                                      bool skipThis)
1313 {
1314     Environment env(gate, circuit_, &builder_);
1315     if (argc != 2) {  // 2: optimize newtarget equal target
1316         return;
1317     }
1318 
1319     size_t firstParam = skipThis ? 1 : 0;
1320     GateRef target = acc_.GetValueIn(gate, firstParam);
1321     GateRef argumentsList = acc_.GetValueIn(gate, firstParam + 1);
1322 
1323     OpCode op = acc_.GetOpCode(argumentsList);
1324     if (op != OpCode::JS_BYTECODE) {
1325         return;
1326     }
1327 
1328     EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(argumentsList);
1329     // optimize empty array literal argumentsList
1330     if ((ecmaOpcode != EcmaOpcode::CREATEEMPTYARRAY_IMM8) && (ecmaOpcode != EcmaOpcode::CREATEEMPTYARRAY_IMM16)) {
1331         return;
1332     }
1333 
1334     if (!Uncheck()) {
1335         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
1336                                  builder_.IntPtr(static_cast<int64_t>(id)));
1337     }
1338 
1339     if (EnableTrace()) {
1340         AddTraceLogs(gate, id);
1341     }
1342 
1343     GateRef ret = builder_.BuildControlDependOp(circuit_->ReflectConstruct(), { target });
1344     ReplaceGateWithPendingException(gate, ret);
1345 }
1346 
TryInlineReflectApply(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1347 void NativeInlineLowering::TryInlineReflectApply(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
1348                                                  bool skipThis)
1349 {
1350     Environment env(gate, circuit_, &builder_);
1351     if (argc != 3) {  // 3: target key and  argumentsList
1352         return;
1353     }
1354 
1355     size_t firstParam = skipThis ? 1 : 0;
1356     GateRef target = acc_.GetValueIn(gate, firstParam);
1357     GateRef thisValue = acc_.GetValueIn(gate, firstParam + 1);
1358     GateRef argumentsList = acc_.GetValueIn(gate, firstParam + 2);
1359 
1360     if (!Uncheck()) {
1361         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + firstParam),
1362                                  builder_.IntPtr(static_cast<int64_t>(id)));
1363     }
1364 
1365     if (EnableTrace()) {
1366         AddTraceLogs(gate, id);
1367     }
1368 
1369     GateRef ret = builder_.BuildControlDependOp(circuit_->ReflectApply(), { target, thisValue, argumentsList });
1370     ReplaceGateWithPendingException(gate, ret);
1371 }
1372 
TryInlineFunctionPrototypeApply(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1373 void NativeInlineLowering::TryInlineFunctionPrototypeApply(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
1374                                                            bool skipThis)
1375 {
1376     Environment env(gate, circuit_, &builder_);
1377     if (!skipThis || argc == 0) {
1378         return;
1379     }
1380 
1381     if (!Uncheck()) {
1382         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1383     }
1384 
1385     if (EnableTrace()) {
1386         AddTraceLogs(gate, id);
1387     }
1388 
1389     GateRef thisFunc = acc_.GetValueIn(gate, 0);
1390     GateRef thisArg = acc_.GetValueIn(gate, 1);
1391     GateRef argArray = (argc == 2) ? (acc_.GetValueIn(gate, 2)) : (builder_.UndefineConstant());
1392     GateRef ret = builder_.BuildControlDependOp(circuit_->FunctionPrototypeApply(), { thisFunc, thisArg, argArray });
1393     ReplaceGateWithPendingException(gate, ret);
1394 }
1395 
TryInlineFunctionPrototypeBind(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1396 void NativeInlineLowering::TryInlineFunctionPrototypeBind(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
1397                                                           bool skipThis)
1398 {
1399     Environment env(gate, circuit_, &builder_);
1400     if (!skipThis || argc != 1) {
1401         return;
1402     }
1403 
1404     if (!Uncheck()) {
1405         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, 2), builder_.IntPtr(static_cast<int64_t>(id)));  // 2: func
1406     }
1407 
1408     if (EnableTrace()) {
1409         AddTraceLogs(gate, id);
1410     }
1411 
1412     GateRef target = acc_.GetValueIn(gate, 0);
1413     GateRef thisArg = acc_.GetValueIn(gate, 1);
1414     GateRef ret = builder_.BuildControlDependOp(circuit_->FunctionPrototypeBind(), { target, thisArg });
1415     ReplaceGateWithPendingException(gate, ret);
1416 }
1417 
TryInlineFunctionPrototypeCall(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1418 void NativeInlineLowering::TryInlineFunctionPrototypeCall(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
1419                                                           bool skipThis)
1420 {
1421     Environment env(gate, circuit_, &builder_);
1422     if (!skipThis || argc == 0) {
1423         return;
1424     }
1425 
1426     if (!Uncheck()) {
1427         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1428     }
1429 
1430     if (EnableTrace()) {
1431         AddTraceLogs(gate, id);
1432     }
1433 
1434     std::vector<GateRef> args(argc + 1);  // 1: thisFunc
1435     for (size_t i = 0; i <= argc; ++i) {
1436         args[i] = acc_.GetValueIn(gate, i);
1437     }
1438     GateRef ret = builder_.BuildControlDependOp(circuit_->FunctionPrototypeCall(argc + 1), args);
1439     ReplaceGateWithPendingException(gate, ret);
1440 }
1441 
TryInlineFunctionPrototypeHasInstance(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1442 void NativeInlineLowering::TryInlineFunctionPrototypeHasInstance(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id,
1443                                                                  bool skipThis)
1444 {
1445     Environment env(gate, circuit_, &builder_);
1446     if (!skipThis || argc != 1) {
1447         return;
1448     }
1449 
1450     if (!Uncheck()) {
1451         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, 2), builder_.IntPtr(static_cast<int64_t>(id)));  // 2: func
1452     }
1453 
1454     if (EnableTrace()) {
1455         AddTraceLogs(gate, id);
1456     }
1457 
1458     GateRef function = acc_.GetValueIn(gate, 0);
1459     GateRef value = acc_.GetValueIn(gate, 1);
1460     GateRef ret = builder_.OrdinaryHasInstance(value, function);
1461     ReplaceGateWithPendingException(gate, ret);
1462 }
1463 
TryInlineIndexOfIncludes(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1464 void NativeInlineLowering::TryInlineIndexOfIncludes(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1465 {
1466     if (!skipThis) {
1467         return;
1468     }
1469     if (argc == 0) {
1470         return;
1471     }
1472     Environment env(gate, circuit_, &builder_);
1473     GateRef thisArray = acc_.GetValueIn(gate, 0);
1474     GateRef targetElement = acc_.GetValueIn(gate, 1);
1475     ElementsKind kind = acc_.TryGetArrayElementsKind(thisArray);
1476     if (!Uncheck()) {
1477         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1478     }
1479     builder_.BuiltinPrototypeHClassCheck(thisArray, BuiltinTypeId::ARRAY, kind, false);
1480     builder_.StableArrayCheck(thisArray, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
1481     GateRef ret = Circuit::NullGate();
1482     GateRef callID = builder_.Int32(static_cast<int32_t>(id));
1483     GateRef arrayKind = builder_.Int32(static_cast<int32_t>(kind));
1484     if (argc == 1) {
1485         ret = builder_.ArrayIncludesIndexOf(thisArray, builder_.Int32(0), targetElement, callID, arrayKind);
1486     } else {
1487         GateRef fromIndexHandler = acc_.GetValueIn(gate, 2);
1488         builder_.DeoptCheck(builder_.TaggedIsInt(fromIndexHandler), acc_.GetFrameState(gate), DeoptType::INDEXNOTINT);
1489         GateRef fromIndex = builder_.TaggedGetInt(fromIndexHandler);
1490         ret = builder_.ArrayIncludesIndexOf(thisArray, fromIndex, targetElement, callID, arrayKind);
1491     }
1492     if (EnableTrace()) {
1493         AddTraceLogs(gate, id);
1494     }
1495     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1496 }
1497 
TryInlineArrayIterator(GateRef gate,BuiltinsStubCSigns::ID id,bool skipThis)1498 void NativeInlineLowering::TryInlineArrayIterator(GateRef gate, BuiltinsStubCSigns::ID id, bool skipThis)
1499 {
1500     if (!skipThis) {
1501         return;
1502     }
1503     CallThis0TypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
1504     Environment env(gate, circuit_, &builder_);
1505 
1506     if (!Uncheck()) {
1507         builder_.CallTargetCheck(gate, tacc.GetFunc(), builder_.IntPtr(static_cast<int64_t>(id)), {tacc.GetThisObj()});
1508     }
1509     GateRef thisObj = acc_.GetValueIn(gate, 0);
1510     builder_.EcmaObjectCheck(thisObj);
1511     if (EnableTrace()) {
1512         AddTraceLogs(gate, id);
1513     }
1514     GateRef CallIDRef = builder_.Int32(static_cast<int32_t>(id));
1515     GateRef ret = builder_.ArrayIteratorBuiltin(thisObj, CallIDRef);
1516     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1517 }
1518 
TryInlineArrayForEach(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1519 void NativeInlineLowering::TryInlineArrayForEach(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1520 {
1521     if (argc == 0) { // 0: Must have a callBackFn
1522         return;
1523     }
1524     if (!skipThis) {
1525         return;
1526     }
1527     Environment env(gate, circuit_, &builder_);
1528     auto pcOffset = acc_.TryGetPcOffset(gate);
1529     GateRef ret = Circuit::NullGate();
1530     GateRef thisValue = acc_.GetValueIn(gate, 0);
1531     ElementsKind kind = acc_.TryGetArrayElementsKind(thisValue);
1532     if (Elements::IsHole(kind)) {
1533         return;
1534     }
1535     if (!Uncheck()) {
1536         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1537     }
1538     builder_.BuiltinPrototypeHClassCheck(thisValue, BuiltinTypeId::ARRAY, kind, false);
1539     builder_.StableArrayCheck(thisValue, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
1540     GateRef callBackFn = acc_.GetValueIn(gate, 1);
1541     builder_.IsCallableCheck(callBackFn);
1542     if (EnableTrace()) {
1543         AddTraceLogs(gate, id);
1544     }
1545     if (argc == 1) {
1546         ret = builder_.ArrayForEach(thisValue, callBackFn, builder_.UndefineConstant(), pcOffset);
1547     } else {
1548         ret = builder_.ArrayForEach(thisValue, callBackFn, acc_.GetValueIn(gate, 2), pcOffset); // 2:provide using This
1549     }
1550     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1551 }
1552 
TryInlineArrayFindOrFindIndex(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1553 void NativeInlineLowering::TryInlineArrayFindOrFindIndex(GateRef gate,
1554                                                          size_t argc,
1555                                                          BuiltinsStubCSigns::ID id,
1556                                                          bool skipThis)
1557 {
1558     if (argc == 0) { // 0: Must have a callBackFn
1559         return;
1560     }
1561     if (!skipThis) {
1562         return;
1563     }
1564     Environment env(gate, circuit_, &builder_);
1565     GateRef thisValue = acc_.GetValueIn(gate, 0);
1566     ElementsKind kind = acc_.TryGetArrayElementsKind(thisValue);
1567     if (Elements::IsHole(kind)) {
1568         return;
1569     }
1570     if (!Uncheck()) {
1571         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1572     }
1573     uint32_t pcOffset = acc_.TryGetPcOffset(gate);
1574     GateRef ret = Circuit::NullGate();
1575 
1576     builder_.BuiltinPrototypeHClassCheck(thisValue, BuiltinTypeId::ARRAY, kind, false);
1577     builder_.StableArrayCheck(thisValue, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
1578     GateRef callBackFn = acc_.GetValueIn(gate, 1);
1579     builder_.IsCallableCheck(callBackFn);
1580     if (EnableTrace()) {
1581         AddTraceLogs(gate, id);
1582     }
1583     GateRef callIDRef = builder_.Int32(static_cast<int32_t>(id));
1584 
1585     if (argc == 1) {
1586         ret = builder_.ArrayFindOrFindIndex(thisValue, callBackFn, builder_.UndefineConstant(), callIDRef, pcOffset);
1587     } else {
1588         ret = builder_.ArrayFindOrFindIndex(
1589             thisValue, callBackFn, acc_.GetValueIn(gate, 2), callIDRef, pcOffset); // 2:provide using This
1590     }
1591     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1592 }
1593 
TryInlineArrayFilter(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1594 void NativeInlineLowering::TryInlineArrayFilter(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1595 {
1596     if (argc == 0) {
1597         return;
1598     }
1599     if (!skipThis) {
1600         return;
1601     }
1602     Environment env(gate, circuit_, &builder_);
1603     GateRef thisValue = acc_.GetValueIn(gate, 0);
1604     ElementsKind kind = acc_.TryGetArrayElementsKind(thisValue);
1605     if (Elements::IsHole(kind)) {
1606         return;
1607     }
1608     if (!Uncheck()) {
1609         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1610     }
1611     builder_.BuiltinPrototypeHClassCheck(thisValue, BuiltinTypeId::ARRAY, kind, false);
1612     builder_.StableArrayCheck(thisValue, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
1613     GateRef callBackFn = acc_.GetValueIn(gate, 1);
1614     builder_.IsCallableCheck(callBackFn);
1615     if (EnableTrace()) {
1616         AddTraceLogs(gate, id);
1617     }
1618     uint32_t pcOffset = acc_.TryGetPcOffset(gate);
1619     GateRef frameState = acc_.GetFrameState(gate);
1620     GateRef ret = Circuit::NullGate();
1621     if (argc == 1) {
1622         ret = builder_.ArrayFilter(thisValue, callBackFn, builder_.UndefineConstant(), frameState, pcOffset);
1623     } else {
1624         ret = builder_.ArrayFilter(
1625             thisValue, callBackFn, acc_.GetValueIn(gate, 2), frameState, pcOffset); //2: provide usingThis
1626     }
1627     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1628 }
1629 
TryInlineArrayMap(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1630 void NativeInlineLowering::TryInlineArrayMap(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1631 {
1632     if (argc == 0) {
1633         return;
1634     }
1635     if (!skipThis) {
1636         return;
1637     }
1638     Environment env(gate, circuit_, &builder_);
1639     GateRef thisValue = acc_.GetValueIn(gate, 0);
1640     ElementsKind kind = acc_.TryGetArrayElementsKind(thisValue);
1641     if (Elements::IsHole(kind)) {
1642         return;
1643     }
1644     if (!Uncheck()) {
1645         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1646     }
1647     builder_.BuiltinPrototypeHClassCheck(thisValue, BuiltinTypeId::ARRAY, kind, false);
1648     builder_.StableArrayCheck(thisValue, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
1649     GateRef callBackFn = acc_.GetValueIn(gate, 1);
1650     builder_.IsCallableCheck(callBackFn);
1651     if (EnableTrace()) {
1652         AddTraceLogs(gate, id);
1653     }
1654     uint32_t pcOffset = acc_.TryGetPcOffset(gate);
1655     GateRef frameState = acc_.GetFrameState(gate);
1656     GateRef ret = Circuit::NullGate();
1657     if (argc == 1) {
1658         ret = builder_.ArrayMap(thisValue, callBackFn, builder_.UndefineConstant(), frameState, pcOffset);
1659     } else {
1660         ret = builder_.ArrayMap(
1661             thisValue, callBackFn, acc_.GetValueIn(gate, 2), frameState, pcOffset); //2: provide usingThis
1662     }
1663     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1664 }
1665 
TryInlineArraySome(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1666 void NativeInlineLowering::TryInlineArraySome(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1667 {
1668     if (argc == 0) {
1669         return;
1670     }
1671     if (!skipThis) {
1672         return;
1673     }
1674     Environment env(gate, circuit_, &builder_);
1675     GateRef thisValue = acc_.GetValueIn(gate, 0);
1676     ElementsKind kind = acc_.TryGetArrayElementsKind(thisValue);
1677     if (Elements::IsHole(kind)) {
1678         return;
1679     }
1680     if (!Uncheck()) {
1681         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1682     }
1683     builder_.BuiltinPrototypeHClassCheck(thisValue, BuiltinTypeId::ARRAY, kind, false);
1684     builder_.StableArrayCheck(thisValue, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
1685     GateRef callBackFn = acc_.GetValueIn(gate, 1);
1686     builder_.IsCallableCheck(callBackFn);
1687     if (EnableTrace()) {
1688         AddTraceLogs(gate, id);
1689     }
1690     uint32_t pcOffset = acc_.TryGetPcOffset(gate);
1691     GateRef ret = Circuit::NullGate();
1692     if (argc == 1) {
1693         ret = builder_.ArraySome(thisValue, callBackFn, builder_.UndefineConstant(), pcOffset);
1694     } else {
1695         ret = builder_.ArraySome(thisValue, callBackFn, acc_.GetValueIn(gate, 2), pcOffset); //2: provide usingThis
1696     }
1697     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1698 }
1699 
TryInlineArrayEvery(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1700 void NativeInlineLowering::TryInlineArrayEvery(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1701 {
1702     if (argc == 0) {
1703         return;
1704     }
1705     if (!skipThis) {
1706         return;
1707     }
1708     Environment env(gate, circuit_, &builder_);
1709     GateRef thisValue = acc_.GetValueIn(gate, 0);
1710     ElementsKind kind = acc_.TryGetArrayElementsKind(thisValue);
1711     if (Elements::IsHole(kind)) {
1712         return;
1713     }
1714     if (!Uncheck()) {
1715         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1716     }
1717     builder_.BuiltinPrototypeHClassCheck(thisValue, BuiltinTypeId::ARRAY, kind, false);
1718     builder_.StableArrayCheck(thisValue, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
1719     GateRef callBackFn = acc_.GetValueIn(gate, 1);
1720     builder_.IsCallableCheck(callBackFn);
1721     if (EnableTrace()) {
1722         AddTraceLogs(gate, id);
1723     }
1724     uint32_t pcOffset = acc_.TryGetPcOffset(gate);
1725     GateRef ret = Circuit::NullGate();
1726     if (argc == 1) {
1727         ret = builder_.ArrayEvery(thisValue, callBackFn, builder_.UndefineConstant(), pcOffset);
1728     } else {
1729         ret = builder_.ArrayEvery(thisValue, callBackFn, acc_.GetValueIn(gate, 2), pcOffset); //2: provide usingThis
1730     }
1731     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1732 }
1733 
TryInlineArrayPop(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1734 void NativeInlineLowering::TryInlineArrayPop(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1735 {
1736     if (!skipThis) {
1737         return;
1738     }
1739     Environment env(gate, circuit_, &builder_);
1740     if (!Uncheck()) {
1741         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1742     }
1743     GateRef thisValue = acc_.GetValueIn(gate, 0);
1744     ElementsKind kind = acc_.TryGetArrayElementsKind(thisValue);
1745     builder_.BuiltinPrototypeHClassCheck(thisValue, BuiltinTypeId::ARRAY, kind, false);
1746     builder_.StableArrayCheck(thisValue, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
1747     if (EnableTrace()) {
1748         AddTraceLogs(gate, id);
1749     }
1750     GateRef ret = builder_.ArrayPop(thisValue, acc_.GetFrameState(gate));
1751     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1752 }
1753 
TryInlineArraySlice(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1754 void NativeInlineLowering::TryInlineArraySlice(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1755 {
1756     if (!skipThis) {
1757         return;
1758     }
1759     Environment env(gate, circuit_, &builder_);
1760     GateRef thisValue = acc_.GetValueIn(gate, 0);
1761     ElementsKind kind = acc_.TryGetArrayElementsKind(thisValue);
1762     builder_.BuiltinPrototypeHClassCheck(thisValue, BuiltinTypeId::ARRAY, kind, false);
1763     builder_.StableArrayCheck(thisValue, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
1764     GateRef frameState = acc_.GetFrameState(gate);
1765     if (!Uncheck()) {
1766         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1767     }
1768     GateRef ret = Circuit::NullGate();
1769     if (argc == 0) {
1770         ret = builder_.ArraySlice(thisValue, builder_.UndefineConstant(), builder_.UndefineConstant(), frameState);
1771     } else if (argc == 1) {
1772         GateRef startIndex = acc_.GetValueIn(gate, 1);
1773         builder_.DeoptCheck(builder_.TaggedIsInt(startIndex), acc_.GetFrameState(gate), DeoptType::INDEXNOTINT);
1774         ret = builder_.ArraySlice(thisValue, startIndex, builder_.UndefineConstant(), frameState);
1775     } else {
1776         GateRef startIndex = acc_.GetValueIn(gate, 1);
1777         GateRef endIndex = acc_.GetValueIn(gate, 2);
1778         builder_.DeoptCheck(builder_.TaggedIsInt(startIndex), acc_.GetFrameState(gate), DeoptType::INDEXNOTINT);
1779         builder_.DeoptCheck(builder_.TaggedIsInt(endIndex), acc_.GetFrameState(gate), DeoptType::INDEXNOTINT);
1780         ret = builder_.ArraySlice(thisValue, startIndex, endIndex, frameState);
1781     }
1782     if (EnableTrace()) {
1783         AddTraceLogs(gate, id);
1784     }
1785     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1786 }
1787 
TryInlineArraySort(GateRef gate,size_t argc,BuiltinsStubCSigns::ID id,bool skipThis)1788 void NativeInlineLowering::TryInlineArraySort(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis)
1789 {
1790     if (!skipThis) {
1791         return;
1792     }
1793     if (argc > 1) {
1794         return;
1795     }
1796     Environment env(gate, circuit_, &builder_);
1797     if (argc == 1) {
1798         GateRef callBackFn = acc_.GetValueIn(gate, 1);
1799         auto fnType = acc_.GetGateType(callBackFn);
1800         if (!fnType.IsUndefinedType()) {
1801             return;
1802         }
1803     }
1804     GateRef thisValue = acc_.GetValueIn(gate, 0);
1805     ElementsKind kind = acc_.TryGetArrayElementsKind(thisValue);
1806     if (Elements::IsHole(kind)) {
1807         return;
1808     }
1809     if (!Uncheck()) {
1810         builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
1811     }
1812     GateRef ret = Circuit::NullGate();
1813 
1814     builder_.BuiltinPrototypeHClassCheck(thisValue, BuiltinTypeId::ARRAY, kind, false);
1815     builder_.StableArrayCheck(thisValue, kind, ArrayMetaDataAccessor::Mode::LOAD_ELEMENT);
1816     ret = builder_.ArraySort(thisValue, builder_.UndefineConstant());
1817     acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
1818 }
1819 
1820 }  // namespace panda::ecmascript
1821