• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #include "ecmascript/compiler/builtins/containers_queue_stub_builder.h"
17 
18 #include "ecmascript/compiler/builtins/builtins_stubs.h"
19 #include "ecmascript/compiler/call_stub_builder.h"
20 #include "ecmascript/compiler/stub_builder-inl.h"
21 
22 namespace panda::ecmascript::kungfu {
ForEach(GateRef glue,GateRef thisValue,GateRef numArgs,Variable * result,Label * exit,Label * slowPath)23 void ContainersQueueStubBuilder::ForEach(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result,
24                                          Label *exit, Label *slowPath)
25 {
26     auto env = GetEnvironment();
27     DEFVARIABLE(thisObj, VariableType::JS_ANY(), thisValue);
28     DEFVARIABLE(thisArg, VariableType::JS_ANY(), Undefined());
29     DEFVARIABLE(key, VariableType::INT64(), Int64(0));
30     DEFVARIABLE(kValue, VariableType::JS_ANY(), Undefined());
31     DEFVARIABLE(length, VariableType::INT32(), Int32(0));
32     DEFVARIABLE(k, VariableType::INT32(), Int32(0));
33     DEFVARIABLE(index, VariableType::INT32(), Int32(0));
34     Label valueIsJSAPIQueue(env);
35     Label valueNotJSAPIQueue(env);
36     Label objIsJSProxy(env);
37     Label objNotJSProxy(env);
38     Label objIsJSAPIQueue(env);
39     Label thisArgUndefined(env);
40     Label thisArgNotUndefined(env);
41     Label callbackUndefined(env);
42     Label callbackNotUndefined(env);
43     Label nextCount(env);
44     Label loopHead(env);
45     Label loopEnd(env);
46     Label next(env);
47     Label afterLoop(env);
48     Label thisValueIsHeapObj(env);
49     GateRef callbackFnHandle;
50     BRANCH(TaggedIsHeapObject(thisValue), &thisValueIsHeapObj, slowPath);
51     Bind(&thisValueIsHeapObj);
52     BRANCH(IsJSAPIQueue(*thisObj), &valueIsJSAPIQueue, &valueNotJSAPIQueue);
53     Bind(&valueNotJSAPIQueue);
54     {
55         BRANCH(IsJsProxy(*thisObj), &objIsJSProxy, &objNotJSProxy);
56         Bind(&objIsJSProxy);
57         {
58             GateRef tempObj = GetTarget(*thisObj);
59             BRANCH(IsJSAPIQueue(tempObj), &objIsJSAPIQueue, slowPath);
60             Bind(&objIsJSAPIQueue);
61             {
62                 thisObj = tempObj;
63                 Jump(&valueIsJSAPIQueue);
64             }
65         }
66         Bind(&objNotJSProxy);
67         Jump(slowPath);
68     }
69     Bind(&valueIsJSAPIQueue);
70     {
71         BRANCH(Int64GreaterThanOrEqual(IntPtr(0), numArgs), &callbackUndefined, &callbackNotUndefined);
72         Bind(&callbackUndefined);
73         Jump(slowPath);
74         Bind(&callbackNotUndefined);
75         {
76             Label isCall(env);
77             Label notCall(env);
78             Label isHeapObj(env);
79             callbackFnHandle = GetCallArg0(numArgs);
80             BRANCH(TaggedIsHeapObject(callbackFnHandle), &isHeapObj, slowPath);
81             Bind(&isHeapObj);
82             BRANCH(IsCallable(callbackFnHandle), &isCall, &notCall);
83             Bind(&notCall);
84             Jump(slowPath);
85             Bind(&isCall);
86             {
87                 BRANCH(Int64GreaterThanOrEqual(IntPtr(1), numArgs), &thisArgUndefined, &thisArgNotUndefined);
88                 Bind(&thisArgUndefined);
89                 Jump(&nextCount);
90                 Bind(&thisArgNotUndefined);
91                 thisArg = GetCallArg1(numArgs);
92                 Jump(&nextCount);
93             }
94         }
95     }
96     Bind(&nextCount);
97     {
98         length = GetArrayLength(*thisObj);
99         Jump(&loopHead);
100         LoopBegin(&loopHead);
101         {
102             Label lenChange(env);
103             Label hasException(env);
104             Label notHasException(env);
105             Label setValue(env);
106             BRANCH(Int32LessThan(*k, *length), &next, &afterLoop);
107             Bind(&next);
108             {
109                 kValue = Get(*thisObj, *index);
110                 index = GetNextPosition(*thisObj, *index);
111                 key = IntToTaggedInt(*k);
112                 JSCallArgs callArgs(JSCallMode::CALL_THIS_ARG3_WITH_RETURN);
113                 callArgs.callThisArg3WithReturnArgs = { *thisArg, *kValue, *key, *thisObj };
114                 CallStubBuilder callBuilder(this, glue, callbackFnHandle, Int32(NUM_MANDATORY_JSFUNC_ARGS), 0, nullptr,
115                     Circuit::NullGate(), callArgs);
116                 GateRef retValue = callBuilder.JSCallDispatch();
117                 BRANCH(HasPendingException(glue), &hasException, &notHasException);
118                 Bind(&hasException);
119                 {
120                     result->WriteVariable(retValue);
121                     Jump(exit);
122                 }
123                 Bind(&notHasException);
124                 Jump(&loopEnd);
125             }
126         }
127         Bind(&loopEnd);
128         k = Int32Add(*k, Int32(1));
129         LoopEnd(&loopHead, env, glue);
130     }
131     Bind(&afterLoop);
132     Jump(exit);
133 }
134 }
135