14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/compiler/builtins/builtins_collection_stub_builder.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include "ecmascript/compiler/new_object_stub_builder.h" 194514f5e3Sopenharmony_ci#include "ecmascript/linked_hash_table.h" 204514f5e3Sopenharmony_ci#include "ecmascript/js_map.h" 214514f5e3Sopenharmony_ci#include "ecmascript/js_set.h" 224514f5e3Sopenharmony_ci#include "ecmascript/js_iterator.h" 234514f5e3Sopenharmony_ci 244514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 254514f5e3Sopenharmony_ci 264514f5e3Sopenharmony_citemplate <typename CollectionType> 274514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::CheckCollectionObj(Label *thisCollectionObj, Label *slowPath) 284514f5e3Sopenharmony_ci{ 294514f5e3Sopenharmony_ci // check target obj 304514f5e3Sopenharmony_ci auto jsType = std::is_same_v<CollectionType, JSSet> ? JSType::JS_SET : JSType::JS_MAP; 314514f5e3Sopenharmony_ci GateRef isJsCollectionObj = IsJSObjectType(thisValue_, jsType); 324514f5e3Sopenharmony_ci BRANCH(isJsCollectionObj, thisCollectionObj, slowPath); 334514f5e3Sopenharmony_ci} 344514f5e3Sopenharmony_ci 354514f5e3Sopenharmony_citemplate <typename CollectionType> 364514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::Clear(Variable *result, Label *exit, Label *slowPath) 374514f5e3Sopenharmony_ci{ 384514f5e3Sopenharmony_ci auto env = GetEnvironment(); 394514f5e3Sopenharmony_ci Label thisCollectionObj(env); 404514f5e3Sopenharmony_ci // check target obj 414514f5e3Sopenharmony_ci CheckCollectionObj(&thisCollectionObj, slowPath); 424514f5e3Sopenharmony_ci 434514f5e3Sopenharmony_ci Bind(&thisCollectionObj); 444514f5e3Sopenharmony_ci GateRef linkedTable = GetLinked(); 454514f5e3Sopenharmony_ci GateRef res = Circuit::NullGate(); 464514f5e3Sopenharmony_ci if constexpr (std::is_same_v<CollectionType, JSMap>) { 474514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> linkedHashTableStubBuilder(this, glue_); 484514f5e3Sopenharmony_ci res = linkedHashTableStubBuilder.Clear(linkedTable); 494514f5e3Sopenharmony_ci } else { 504514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> linkedHashTableStubBuilder(this, glue_); 514514f5e3Sopenharmony_ci res = linkedHashTableStubBuilder.Clear(linkedTable); 524514f5e3Sopenharmony_ci } 534514f5e3Sopenharmony_ci 544514f5e3Sopenharmony_ci Label exception(env); 554514f5e3Sopenharmony_ci Label noException(env); 564514f5e3Sopenharmony_ci BRANCH(TaggedIsException(res), &exception, &noException); 574514f5e3Sopenharmony_ci Bind(&noException); 584514f5e3Sopenharmony_ci SetLinked(res); 594514f5e3Sopenharmony_ci Jump(exit); 604514f5e3Sopenharmony_ci Bind(&exception); 614514f5e3Sopenharmony_ci *result = res; 624514f5e3Sopenharmony_ci Jump(exit); 634514f5e3Sopenharmony_ci} 644514f5e3Sopenharmony_ci 654514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSMap>::Clear(Variable *result, Label *exit, Label *slowPath); 664514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSSet>::Clear(Variable *result, Label *exit, Label *slowPath); 674514f5e3Sopenharmony_ci 684514f5e3Sopenharmony_citemplate <typename CollectionType> 694514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::CreateIterator(Variable *result, 704514f5e3Sopenharmony_ci Label *exit, Label *slowPath, GateRef kind) 714514f5e3Sopenharmony_ci{ 724514f5e3Sopenharmony_ci auto env = GetEnvironment(); 734514f5e3Sopenharmony_ci Label entry(env); 744514f5e3Sopenharmony_ci Label thisCollectionObj(env); 754514f5e3Sopenharmony_ci // check target obj 764514f5e3Sopenharmony_ci CheckCollectionObj(&thisCollectionObj, slowPath); 774514f5e3Sopenharmony_ci 784514f5e3Sopenharmony_ci Bind(&thisCollectionObj); 794514f5e3Sopenharmony_ci NewObjectStubBuilder newBuilder(this); 804514f5e3Sopenharmony_ci newBuilder.SetGlue(glue_); 814514f5e3Sopenharmony_ci if constexpr (std::is_same_v<CollectionType, JSSet>) { 824514f5e3Sopenharmony_ci newBuilder.CreateJSCollectionIterator<JSSetIterator, CollectionType>(result, exit, thisValue_, kind); 834514f5e3Sopenharmony_ci } else { 844514f5e3Sopenharmony_ci newBuilder.CreateJSCollectionIterator<JSMapIterator, CollectionType>(result, exit, thisValue_, kind); 854514f5e3Sopenharmony_ci } 864514f5e3Sopenharmony_ci} 874514f5e3Sopenharmony_ci 884514f5e3Sopenharmony_citemplate <typename CollectionType> 894514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::Values(Variable *result, Label *exit, Label *slowPath) 904514f5e3Sopenharmony_ci{ 914514f5e3Sopenharmony_ci GateRef kind = Int32(static_cast<int32_t>(IterationKind::VALUE)); 924514f5e3Sopenharmony_ci CreateIterator(result, exit, slowPath, kind); 934514f5e3Sopenharmony_ci} 944514f5e3Sopenharmony_ci 954514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSMap>::Values(Variable *result, Label *exit, Label *slowPath); 964514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSSet>::Values(Variable *result, Label *exit, Label *slowPath); 974514f5e3Sopenharmony_ci 984514f5e3Sopenharmony_citemplate <typename CollectionType> 994514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::Entries(Variable *result, Label *exit, Label *slowPath) 1004514f5e3Sopenharmony_ci{ 1014514f5e3Sopenharmony_ci GateRef kind = Int32(static_cast<int32_t>(IterationKind::KEY_AND_VALUE)); 1024514f5e3Sopenharmony_ci CreateIterator(result, exit, slowPath, kind); 1034514f5e3Sopenharmony_ci} 1044514f5e3Sopenharmony_ci 1054514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSMap>::Entries(Variable *result, Label *exit, Label *slowPath); 1064514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSSet>::Entries(Variable *result, Label *exit, Label *slowPath); 1074514f5e3Sopenharmony_ci 1084514f5e3Sopenharmony_citemplate <typename CollectionType> 1094514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::Keys(Variable *result, Label *exit, Label *slowPath) 1104514f5e3Sopenharmony_ci{ 1114514f5e3Sopenharmony_ci GateRef kind = Int32(static_cast<int32_t>(IterationKind::KEY)); 1124514f5e3Sopenharmony_ci CreateIterator(result, exit, slowPath, kind); 1134514f5e3Sopenharmony_ci} 1144514f5e3Sopenharmony_ci 1154514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSMap>::Keys(Variable *result, Label *exit, Label *slowPath); 1164514f5e3Sopenharmony_ci 1174514f5e3Sopenharmony_citemplate <typename CollectionType> 1184514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::ForEach(Variable *result, Label *exit, Label *slowPath) 1194514f5e3Sopenharmony_ci{ 1204514f5e3Sopenharmony_ci auto env = GetEnvironment(); 1214514f5e3Sopenharmony_ci Label thisCollectionObj(env); 1224514f5e3Sopenharmony_ci // check target obj 1234514f5e3Sopenharmony_ci CheckCollectionObj(&thisCollectionObj, slowPath); 1244514f5e3Sopenharmony_ci 1254514f5e3Sopenharmony_ci Bind(&thisCollectionObj); 1264514f5e3Sopenharmony_ci GateRef callbackFnHandle = GetCallArg0(numArgs_); 1274514f5e3Sopenharmony_ci Label callable(env); 1284514f5e3Sopenharmony_ci // check heap obj 1294514f5e3Sopenharmony_ci Label heapObj(env); 1304514f5e3Sopenharmony_ci BRANCH(TaggedIsHeapObject(callbackFnHandle), &heapObj, slowPath); 1314514f5e3Sopenharmony_ci Bind(&heapObj); 1324514f5e3Sopenharmony_ci BRANCH(IsCallable(callbackFnHandle), &callable, slowPath); 1334514f5e3Sopenharmony_ci Bind(&callable); 1344514f5e3Sopenharmony_ci 1354514f5e3Sopenharmony_ci GateRef linkedTable = GetLinked(); 1364514f5e3Sopenharmony_ci GateRef res = Circuit::NullGate(); 1374514f5e3Sopenharmony_ci GateRef thisArg = GetCallArg1(numArgs_); 1384514f5e3Sopenharmony_ci if constexpr (std::is_same_v<CollectionType, JSMap>) { 1394514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> linkedHashTableStubBuilder(this, glue_); 1404514f5e3Sopenharmony_ci res = linkedHashTableStubBuilder.ForEach(thisValue_, linkedTable, callbackFnHandle, thisArg); 1414514f5e3Sopenharmony_ci } else { 1424514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> linkedHashTableStubBuilder(this, glue_); 1434514f5e3Sopenharmony_ci res = linkedHashTableStubBuilder.ForEach(thisValue_, linkedTable, callbackFnHandle, thisArg); 1444514f5e3Sopenharmony_ci } 1454514f5e3Sopenharmony_ci 1464514f5e3Sopenharmony_ci Label exception(env); 1474514f5e3Sopenharmony_ci BRANCH(TaggedIsException(res), &exception, exit); 1484514f5e3Sopenharmony_ci Bind(&exception); 1494514f5e3Sopenharmony_ci *result = res; 1504514f5e3Sopenharmony_ci Jump(exit); 1514514f5e3Sopenharmony_ci} 1524514f5e3Sopenharmony_ci 1534514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSMap>::ForEach(Variable *result, Label *exit, Label *slowPath); 1544514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSSet>::ForEach(Variable *result, Label *exit, Label *slowPath); 1554514f5e3Sopenharmony_ci 1564514f5e3Sopenharmony_citemplate <typename CollectionType> 1574514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::MapSetOrSetAdd( 1584514f5e3Sopenharmony_ci Variable *result, Label *exit, Label *slowPath, bool isJsMapSet) 1594514f5e3Sopenharmony_ci{ 1604514f5e3Sopenharmony_ci auto env = GetEnvironment(); 1614514f5e3Sopenharmony_ci Label thisCollectionObj(env); 1624514f5e3Sopenharmony_ci // check target obj 1634514f5e3Sopenharmony_ci CheckCollectionObj(&thisCollectionObj, slowPath); 1644514f5e3Sopenharmony_ci Bind(&thisCollectionObj); 1654514f5e3Sopenharmony_ci GateRef key = GetCallArg0(numArgs_); 1664514f5e3Sopenharmony_ci // check key 1674514f5e3Sopenharmony_ci Label keyNotHole(env); 1684514f5e3Sopenharmony_ci BRANCH(TaggedIsHole(key), slowPath, &keyNotHole); 1694514f5e3Sopenharmony_ci Bind(&keyNotHole); 1704514f5e3Sopenharmony_ci GateRef value = isJsMapSet ? GetCallArg1(numArgs_) : key; 1714514f5e3Sopenharmony_ci GateRef linkedTable = GetLinked(); 1724514f5e3Sopenharmony_ci GateRef res = Circuit::NullGate(); 1734514f5e3Sopenharmony_ci if constexpr (std::is_same_v<CollectionType, JSMap>) { 1744514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> linkedHashTableStubBuilder(this, glue_); 1754514f5e3Sopenharmony_ci res = linkedHashTableStubBuilder.Insert(linkedTable, key, value); 1764514f5e3Sopenharmony_ci } else { 1774514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> linkedHashTableStubBuilder(this, glue_); 1784514f5e3Sopenharmony_ci res = linkedHashTableStubBuilder.Insert(linkedTable, key, value); 1794514f5e3Sopenharmony_ci } 1804514f5e3Sopenharmony_ci 1814514f5e3Sopenharmony_ci SetLinked(res); 1824514f5e3Sopenharmony_ci *result = thisValue_; 1834514f5e3Sopenharmony_ci Jump(exit); 1844514f5e3Sopenharmony_ci} 1854514f5e3Sopenharmony_ci 1864514f5e3Sopenharmony_citemplate <typename CollectionType> 1874514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::Set(Variable *result, Label *exit, Label *slowPath) 1884514f5e3Sopenharmony_ci{ 1894514f5e3Sopenharmony_ci MapSetOrSetAdd(result, exit, slowPath, true); 1904514f5e3Sopenharmony_ci} 1914514f5e3Sopenharmony_ci 1924514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSMap>::Set(Variable *result, Label *exit, Label *slowPath); 1934514f5e3Sopenharmony_ci 1944514f5e3Sopenharmony_citemplate <typename CollectionType> 1954514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::Add(Variable *result, Label *exit, Label *slowPath) 1964514f5e3Sopenharmony_ci{ 1974514f5e3Sopenharmony_ci MapSetOrSetAdd(result, exit, slowPath, false); 1984514f5e3Sopenharmony_ci} 1994514f5e3Sopenharmony_ci 2004514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSSet>::Add(Variable *result, Label *exit, Label *slowPath); 2014514f5e3Sopenharmony_ci 2024514f5e3Sopenharmony_citemplate <typename CollectionType> 2034514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::Delete(Variable *result, Label *exit, Label *slowPath) 2044514f5e3Sopenharmony_ci{ 2054514f5e3Sopenharmony_ci auto env = GetEnvironment(); 2064514f5e3Sopenharmony_ci Label thisCollectionObj(env); 2074514f5e3Sopenharmony_ci // check target obj 2084514f5e3Sopenharmony_ci CheckCollectionObj(&thisCollectionObj, slowPath); 2094514f5e3Sopenharmony_ci 2104514f5e3Sopenharmony_ci Bind(&thisCollectionObj); 2114514f5e3Sopenharmony_ci GateRef key = GetCallArg0(numArgs_); 2124514f5e3Sopenharmony_ci GateRef linkedTable = GetLinked(); 2134514f5e3Sopenharmony_ci GateRef res = Circuit::NullGate(); 2144514f5e3Sopenharmony_ci if constexpr (std::is_same_v<CollectionType, JSMap>) { 2154514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> linkedHashTableStubBuilder(this, glue_); 2164514f5e3Sopenharmony_ci res = linkedHashTableStubBuilder.Delete(linkedTable, key); 2174514f5e3Sopenharmony_ci } else { 2184514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> linkedHashTableStubBuilder(this, glue_); 2194514f5e3Sopenharmony_ci res = linkedHashTableStubBuilder.Delete(linkedTable, key); 2204514f5e3Sopenharmony_ci } 2214514f5e3Sopenharmony_ci *result = BooleanToTaggedBooleanPtr(res); 2224514f5e3Sopenharmony_ci Jump(exit); 2234514f5e3Sopenharmony_ci} 2244514f5e3Sopenharmony_ci 2254514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSMap>::Delete(Variable *result, Label *exit, Label *slowPath); 2264514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSSet>::Delete(Variable *result, Label *exit, Label *slowPath); 2274514f5e3Sopenharmony_ci 2284514f5e3Sopenharmony_citemplate <typename CollectionType> 2294514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::Has(Variable *result, Label *exit, Label *slowPath) 2304514f5e3Sopenharmony_ci{ 2314514f5e3Sopenharmony_ci auto env = GetEnvironment(); 2324514f5e3Sopenharmony_ci Label thisCollectionObj(env); 2334514f5e3Sopenharmony_ci // check target obj 2344514f5e3Sopenharmony_ci CheckCollectionObj(&thisCollectionObj, slowPath); 2354514f5e3Sopenharmony_ci 2364514f5e3Sopenharmony_ci Bind(&thisCollectionObj); 2374514f5e3Sopenharmony_ci GateRef key = GetCallArg0(numArgs_); 2384514f5e3Sopenharmony_ci GateRef linkedTable = GetLinked(); 2394514f5e3Sopenharmony_ci GateRef res = Circuit::NullGate(); 2404514f5e3Sopenharmony_ci if constexpr (std::is_same_v<CollectionType, JSMap>) { 2414514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> linkedHashTableStubBuilder(this, glue_); 2424514f5e3Sopenharmony_ci res = linkedHashTableStubBuilder.Has(linkedTable, key); 2434514f5e3Sopenharmony_ci } else { 2444514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> linkedHashTableStubBuilder(this, glue_); 2454514f5e3Sopenharmony_ci res = linkedHashTableStubBuilder.Has(linkedTable, key); 2464514f5e3Sopenharmony_ci } 2474514f5e3Sopenharmony_ci *result = BooleanToTaggedBooleanPtr(res); 2484514f5e3Sopenharmony_ci Jump(exit); 2494514f5e3Sopenharmony_ci} 2504514f5e3Sopenharmony_ci 2514514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSMap>::Has(Variable *result, Label *exit, Label *slowPath); 2524514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSSet>::Has(Variable *result, Label *exit, Label *slowPath); 2534514f5e3Sopenharmony_ci 2544514f5e3Sopenharmony_citemplate <typename CollectionType> 2554514f5e3Sopenharmony_civoid BuiltinsCollectionStubBuilder<CollectionType>::Get(Variable *result, Label *exit, Label *slowPath) 2564514f5e3Sopenharmony_ci{ 2574514f5e3Sopenharmony_ci auto env = GetEnvironment(); 2584514f5e3Sopenharmony_ci Label thisCollectionObj(env); 2594514f5e3Sopenharmony_ci // check target obj 2604514f5e3Sopenharmony_ci CheckCollectionObj(&thisCollectionObj, slowPath); 2614514f5e3Sopenharmony_ci 2624514f5e3Sopenharmony_ci Bind(&thisCollectionObj); 2634514f5e3Sopenharmony_ci GateRef key = GetCallArg0(numArgs_); 2644514f5e3Sopenharmony_ci GateRef linkedTable = GetLinked(); 2654514f5e3Sopenharmony_ci static_assert(std::is_same_v<CollectionType, JSMap>); 2664514f5e3Sopenharmony_ci LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> linkedHashTableStubBuilder(this, glue_); 2674514f5e3Sopenharmony_ci *result = linkedHashTableStubBuilder.Get(linkedTable, key); 2684514f5e3Sopenharmony_ci Jump(exit); 2694514f5e3Sopenharmony_ci} 2704514f5e3Sopenharmony_ci 2714514f5e3Sopenharmony_citemplate void BuiltinsCollectionStubBuilder<JSMap>::Get(Variable *result, Label *exit, Label *slowPath); 2724514f5e3Sopenharmony_ci 2734514f5e3Sopenharmony_ci} // namespace panda::ecmascript::kungfu 274