• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ecmascript/containers/containers_lightweightset.h"
17 
18 #include "ecmascript/containers/containers_errors.h"
19 #include "ecmascript/ecma_vm.h"
20 #include "ecmascript/js_api/js_api_lightweightset.h"
21 #include "ecmascript/js_api/js_api_lightweightset_iterator.h"
22 #include "ecmascript/js_array.h"
23 #include "ecmascript/object_factory.h"
24 #include "ecmascript/tagged_array-inl.h"
25 
26 namespace panda::ecmascript::containers {
LightWeightSetConstructor(EcmaRuntimeCallInfo * argv)27 JSTaggedValue ContainersLightWeightSet::LightWeightSetConstructor(EcmaRuntimeCallInfo *argv)
28 {
29     ASSERT(argv != nullptr);
30     JSThread *thread = argv->GetThread();
31     BUILTINS_API_TRACE(thread, LightWeightSet, Constructor);
32     [[maybe_unused]] EcmaHandleScope handleScope(thread);
33     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
34     JSHandle<JSTaggedValue> newTarget = GetNewTarget(argv);
35     if (newTarget->IsUndefined()) {
36         JSTaggedValue error =
37             ContainerError::BusinessError(thread, ErrorFlag::IS_NULL_ERROR,
38                                           "The LightWeightSet's constructor cannot be directly invoked");
39         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
40     }
41     JSHandle<JSTaggedValue> constructor = GetConstructor(argv);
42     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), newTarget);
43     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
44     JSHandle<JSAPILightWeightSet> lightweightSet = JSHandle<JSAPILightWeightSet>::Cast(obj);
45 
46     JSHandle<TaggedArray> hashes =
47         JSAPILightWeightSet::CreateSlot(thread, JSAPILightWeightSet::DEFAULT_CAPACITY_LENGTH);
48     JSHandle<TaggedArray> values =
49         JSAPILightWeightSet::CreateSlot(thread, JSAPILightWeightSet::DEFAULT_CAPACITY_LENGTH);
50     lightweightSet->SetHashes(thread, hashes);
51     lightweightSet->SetValues(thread, values);
52     return obj.GetTaggedValue();
53 }
54 
Add(EcmaRuntimeCallInfo * argv)55 JSTaggedValue ContainersLightWeightSet::Add(EcmaRuntimeCallInfo *argv)
56 {
57     ASSERT(argv != nullptr);
58     JSThread *thread = argv->GetThread();
59     BUILTINS_API_TRACE(thread, LightWeightSet, Add);
60     [[maybe_unused]] EcmaHandleScope handleScope(thread);
61     JSHandle<JSTaggedValue> self = GetThis(argv);
62     if (!self->IsJSAPILightWeightSet()) {
63         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
64             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
65         } else {
66             JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR,
67                                                                 "The add method cannot be bound");
68             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
69         }
70     }
71     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
72     bool flag = JSAPILightWeightSet::Add(thread, JSHandle<JSAPILightWeightSet>::Cast(self), value);
73     return JSTaggedValue(flag);
74 }
75 
AddAll(EcmaRuntimeCallInfo * argv)76 JSTaggedValue ContainersLightWeightSet::AddAll(EcmaRuntimeCallInfo *argv)
77 {
78     ASSERT(argv != nullptr);
79     JSThread *thread = argv->GetThread();
80     BUILTINS_API_TRACE(thread, LightWeightSet, AddAll);
81     [[maybe_unused]] EcmaHandleScope handleScope(thread);
82     JSHandle<JSTaggedValue> self = GetThis(argv);
83     if (!self->IsJSAPILightWeightSet()) {
84         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
85             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
86         } else {
87             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
88                                                                 "The addAll method cannot be bound");
89             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
90         }
91     }
92 
93     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
94     if (!value->IsJSAPILightWeightSet()) {
95         if (value->IsJSProxy() && JSHandle<JSProxy>::Cast(value)->GetTarget().IsJSAPILightWeightSet()) {
96             value = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(value)->GetTarget());
97         } else {
98             JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value.GetTaggedValue());
99             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
100             CString errorMsg =
101                 "The type of \"set\" must be LightWeightSet. Received value is: " + ConvertToString(*result);
102             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
103             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
104         }
105     }
106 
107     return JSTaggedValue(JSAPILightWeightSet::AddAll(thread, JSHandle<JSAPILightWeightSet>::Cast(self), value));
108 }
109 
IsEmpty(EcmaRuntimeCallInfo * argv)110 JSTaggedValue ContainersLightWeightSet::IsEmpty(EcmaRuntimeCallInfo *argv)
111 {
112     ASSERT(argv != nullptr);
113     JSThread *thread = argv->GetThread();
114     BUILTINS_API_TRACE(thread, LightWeightSet, IsEmpty);
115     [[maybe_unused]] EcmaHandleScope handleScope(thread);
116     JSHandle<JSTaggedValue> self = GetThis(argv);
117     if (!self->IsJSAPILightWeightSet()) {
118         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
119             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
120         } else {
121             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
122                                                                 "The isEmpty method cannot be bound");
123             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
124         }
125     }
126     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
127     return JSTaggedValue(set->IsEmpty());
128 }
129 
GetValueAt(EcmaRuntimeCallInfo * argv)130 JSTaggedValue ContainersLightWeightSet::GetValueAt(EcmaRuntimeCallInfo *argv)
131 {
132     ASSERT(argv != nullptr);
133     JSThread *thread = argv->GetThread();
134     BUILTINS_API_TRACE(thread, LightWeightSet, GetValueAt);
135     [[maybe_unused]] EcmaHandleScope handleScope(thread);
136     JSHandle<JSTaggedValue> self = GetThis(argv);
137     if (!self->IsJSAPILightWeightSet()) {
138         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
139             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
140         } else {
141             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
142                                                                 "The getValueAt method cannot be bound");
143             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
144         }
145     }
146     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
147     if (!value->IsInteger()) {
148         JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value.GetTaggedValue());
149         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
150         CString errorMsg =
151             "The type of \"index\" must be number. Received value is: " + ConvertToString(*result);
152         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
153         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
154     }
155     int32_t index = value->GetInt();
156     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
157     return set->GetValueAt(index);
158 }
159 
HasAll(EcmaRuntimeCallInfo * argv)160 JSTaggedValue ContainersLightWeightSet::HasAll(EcmaRuntimeCallInfo *argv)
161 {
162     ASSERT(argv != nullptr);
163     JSThread *thread = argv->GetThread();
164     BUILTINS_API_TRACE(thread, LightWeightSet, HasAll);
165     [[maybe_unused]] EcmaHandleScope handleScope(thread);
166     JSHandle<JSTaggedValue> self = GetThis(argv);
167     if (!self->IsJSAPILightWeightSet()) {
168         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
169             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
170         } else {
171             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
172                                                                 "The hasAll method cannot be bound");
173             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
174         }
175     }
176     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
177     if (!value->IsJSAPILightWeightSet()) {
178         if (value->IsJSProxy() && JSHandle<JSProxy>::Cast(value)->GetTarget().IsJSAPILightWeightSet()) {
179             value = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(value)->GetTarget());
180         } else {
181             JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value.GetTaggedValue());
182             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
183             CString errorMsg =
184                 "The type of \"set\" must be LightWeightSet. Received value is: " + ConvertToString(*result);
185             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
186             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
187         }
188     }
189     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
190     return JSTaggedValue(set->HasAll(value));
191 }
192 
Has(EcmaRuntimeCallInfo * argv)193 JSTaggedValue ContainersLightWeightSet::Has(EcmaRuntimeCallInfo *argv)
194 {
195     ASSERT(argv != nullptr);
196     JSThread *thread = argv->GetThread();
197     BUILTINS_API_TRACE(thread, LightWeightSet, Has);
198     [[maybe_unused]] EcmaHandleScope handleScope(thread);
199     JSHandle<JSTaggedValue> self = GetThis(argv);
200     if (!self->IsJSAPILightWeightSet()) {
201         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
202             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
203         } else {
204             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
205                                                                 "The has method cannot be bound");
206             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
207         }
208     }
209     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
210     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
211     return JSTaggedValue(set->Has(value));
212 }
213 
HasHash(EcmaRuntimeCallInfo * argv)214 JSTaggedValue ContainersLightWeightSet::HasHash(EcmaRuntimeCallInfo *argv)
215 {
216     ASSERT(argv != nullptr);
217     JSThread *thread = argv->GetThread();
218     BUILTINS_API_TRACE(thread, LightWeightSet, HasHash);
219     [[maybe_unused]] EcmaHandleScope handleScope(thread);
220     JSHandle<JSTaggedValue> self = GetThis(argv);
221     if (!self->IsJSAPILightWeightSet()) {
222         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
223             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
224         } else {
225             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
226                                                                 "The hasHash method cannot be bound");
227             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
228         }
229     }
230     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
231     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
232     return JSTaggedValue(set->HasHash(value));
233 }
234 
Equal(EcmaRuntimeCallInfo * argv)235 JSTaggedValue ContainersLightWeightSet::Equal(EcmaRuntimeCallInfo *argv)
236 {
237     ASSERT(argv != nullptr);
238     JSThread *thread = argv->GetThread();
239     BUILTINS_API_TRACE(thread, LightWeightSet, Equal);
240     [[maybe_unused]] EcmaHandleScope handleScope(thread);
241     JSHandle<JSTaggedValue> self = GetThis(argv);
242     if (!self->IsJSAPILightWeightSet()) {
243         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
244             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
245         } else {
246             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
247                                                                 "The equal method cannot be bound");
248             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
249         }
250     }
251     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
252     return JSTaggedValue(JSAPILightWeightSet::Equal(thread, JSHandle<JSAPILightWeightSet>::Cast(self), value));
253 }
254 
IncreaseCapacityTo(EcmaRuntimeCallInfo * argv)255 JSTaggedValue ContainersLightWeightSet::IncreaseCapacityTo(EcmaRuntimeCallInfo *argv)
256 {
257     ASSERT(argv != nullptr);
258     JSThread *thread = argv->GetThread();
259     BUILTINS_API_TRACE(thread, LightWeightSet, IncreaseCapacityTo);
260     [[maybe_unused]] EcmaHandleScope handleScope(thread);
261     JSHandle<JSTaggedValue> self = GetThis(argv);
262     if (!self->IsJSAPILightWeightSet()) {
263         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
264             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
265         } else {
266             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
267                                                                 "The increaseCapacityTo method cannot be bound");
268             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
269         }
270     }
271     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
272     if (!value->IsInteger()) {
273         JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value.GetTaggedValue());
274         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
275         CString errorMsg =
276             "The type of \"minimumCapacity\" must be number. Received value is: " + ConvertToString(*result);
277         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
278         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
279     }
280     int32_t minCapacity = value->GetInt();
281     JSAPILightWeightSet::IncreaseCapacityTo(thread, JSHandle<JSAPILightWeightSet>::Cast(self), minCapacity);
282     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
283     return JSTaggedValue::Undefined();
284 }
285 
GetIteratorObj(EcmaRuntimeCallInfo * argv)286 JSTaggedValue ContainersLightWeightSet::GetIteratorObj(EcmaRuntimeCallInfo *argv)
287 {
288     ASSERT(argv != nullptr);
289     JSThread *thread = argv->GetThread();
290     BUILTINS_API_TRACE(thread, LightWeightSet, GetIteratorObj);
291     [[maybe_unused]] EcmaHandleScope handleScope(thread);
292     JSHandle<JSTaggedValue> self = GetThis(argv);
293     if (!self->IsJSAPILightWeightSet()) {
294         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
295             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
296         } else {
297             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
298                                                                 "The getIteratorObj method cannot be bound");
299             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
300         }
301     }
302     JSHandle<JSTaggedValue> iter =
303         JSAPILightWeightSet::GetIteratorObj(thread, JSHandle<JSAPILightWeightSet>::Cast(self), IterationKind::VALUE);
304     return iter.GetTaggedValue();
305 }
306 
Values(EcmaRuntimeCallInfo * argv)307 JSTaggedValue ContainersLightWeightSet::Values(EcmaRuntimeCallInfo *argv)
308 {
309     ASSERT(argv != nullptr);
310     JSThread *thread = argv->GetThread();
311     BUILTINS_API_TRACE(thread, LightWeightSet, Values);
312     [[maybe_unused]] EcmaHandleScope handleScope(thread);
313     JSHandle<JSTaggedValue> self = GetThis(argv);
314     if (!self->IsJSAPILightWeightSet()) {
315         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
316             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
317         } else {
318             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
319                                                                 "The values method cannot be bound");
320             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
321         }
322     }
323     JSHandle<JSTaggedValue> iter =
324         JSAPILightWeightSet::GetIteratorObj(thread, JSHandle<JSAPILightWeightSet>::Cast(self), IterationKind::VALUE);
325     return iter.GetTaggedValue();
326 }
327 
Entries(EcmaRuntimeCallInfo * argv)328 JSTaggedValue ContainersLightWeightSet::Entries(EcmaRuntimeCallInfo *argv)
329 {
330     ASSERT(argv != nullptr);
331     JSThread *thread = argv->GetThread();
332     BUILTINS_API_TRACE(thread, LightWeightSet, Entries);
333     [[maybe_unused]] EcmaHandleScope handleScope(thread);
334     JSHandle<JSTaggedValue> self = GetThis(argv);
335     if (!self->IsJSAPILightWeightSet()) {
336         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
337             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
338         } else {
339             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
340                                                                 "The entries method cannot be bound");
341             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
342         }
343     }
344     JSHandle<JSTaggedValue> iter =
345         JSAPILightWeightSet::GetIteratorObj(thread, JSHandle<JSAPILightWeightSet>::Cast(self),
346                                             IterationKind::KEY_AND_VALUE);
347     return iter.GetTaggedValue();
348 }
349 
ForEach(EcmaRuntimeCallInfo * argv)350 JSTaggedValue ContainersLightWeightSet::ForEach(EcmaRuntimeCallInfo *argv)
351 {
352     ASSERT(argv != nullptr);
353     JSThread *thread = argv->GetThread();
354     BUILTINS_API_TRACE(thread, LightWeightSet, ForEach);
355     [[maybe_unused]] EcmaHandleScope handleScope(thread);
356     JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
357     JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
358 
359     if (!thisHandle->IsJSAPILightWeightSet()) {
360         if (thisHandle->IsJSProxy() && JSHandle<JSProxy>::Cast(thisHandle)->GetTarget().IsJSAPILightWeightSet()) {
361             thisHandle = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(thisHandle)->GetTarget());
362         } else {
363             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
364                                                                 "The forEach method cannot be bound");
365             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
366         }
367     }
368 
369     if (!callbackFnHandle->IsCallable()) {
370         JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, callbackFnHandle.GetTaggedValue());
371         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
372         CString errorMsg =
373             "The type of \"callbackfn\" must be callable. Received value is: " + ConvertToString(*result);
374         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
375         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
376     }
377     JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
378     return JSAPILightWeightSet::ForEach(thread, thisHandle, callbackFnHandle, thisArgHandle);
379 }
380 
GetIndexOf(EcmaRuntimeCallInfo * argv)381 JSTaggedValue ContainersLightWeightSet::GetIndexOf(EcmaRuntimeCallInfo *argv)
382 {
383     ASSERT(argv != nullptr);
384     JSThread *thread = argv->GetThread();
385     BUILTINS_API_TRACE(thread, LightWeightSet, GetIndexOf);
386     [[maybe_unused]] EcmaHandleScope handleScope(thread);
387     JSHandle<JSTaggedValue> self = GetThis(argv);
388     if (!self->IsJSAPILightWeightSet()) {
389         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
390             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
391         } else {
392             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
393                                                                 "The getIndexOf method cannot be bound");
394             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
395         }
396     }
397     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
398     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
399     int32_t result = set->GetIndexOf(value);
400     return JSTaggedValue(result);
401 }
402 
Remove(EcmaRuntimeCallInfo * argv)403 JSTaggedValue ContainersLightWeightSet::Remove(EcmaRuntimeCallInfo *argv)
404 {
405     ASSERT(argv != nullptr);
406     JSThread *thread = argv->GetThread();
407     BUILTINS_API_TRACE(thread, LightWeightSet, Remove);
408     [[maybe_unused]] EcmaHandleScope handleScope(thread);
409     JSHandle<JSTaggedValue> self = GetThis(argv);
410     if (!self->IsJSAPILightWeightSet()) {
411         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
412             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
413         } else {
414             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
415                                                                 "The remove method cannot be bound");
416             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
417         }
418     }
419     JSHandle<JSTaggedValue> key(GetCallArg(argv, 0));
420     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
421     return set->Remove(thread, key);
422 }
423 
RemoveAt(EcmaRuntimeCallInfo * argv)424 JSTaggedValue ContainersLightWeightSet::RemoveAt(EcmaRuntimeCallInfo *argv)
425 {
426     ASSERT(argv != nullptr);
427     JSThread *thread = argv->GetThread();
428     BUILTINS_API_TRACE(thread, LightWeightSet, RemoveAt);
429     [[maybe_unused]] EcmaHandleScope handleScope(thread);
430     JSHandle<JSTaggedValue> self = GetThis(argv);
431     if (!self->IsJSAPILightWeightSet()) {
432         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
433             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
434         } else {
435             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
436                                                                 "The removeAt method cannot be bound");
437             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
438         }
439     }
440     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
441     if (!value->IsInteger()) {
442         JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value.GetTaggedValue());
443         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
444         CString errorMsg =
445             "The type of \"index\" must be number. Received value is: " + ConvertToString(*result);
446         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
447         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
448     }
449     int32_t index = value->GetInt();
450     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
451     return JSTaggedValue(set->RemoveAt(thread, index));
452 }
453 
Clear(EcmaRuntimeCallInfo * argv)454 JSTaggedValue ContainersLightWeightSet::Clear(EcmaRuntimeCallInfo *argv)
455 {
456     ASSERT(argv != nullptr);
457     JSThread *thread = argv->GetThread();
458     BUILTINS_API_TRACE(thread, LightWeightSet, Clear);
459     [[maybe_unused]] EcmaHandleScope handleScope(thread);
460     JSHandle<JSTaggedValue> self = GetThis(argv);
461     if (!self->IsJSAPILightWeightSet()) {
462         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
463             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
464         } else {
465             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
466                                                                 "The clear method cannot be bound");
467             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
468         }
469     }
470     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
471     set->Clear(thread);
472     return JSTaggedValue::True();
473 }
474 
ToString(EcmaRuntimeCallInfo * argv)475 JSTaggedValue ContainersLightWeightSet::ToString(EcmaRuntimeCallInfo *argv)
476 {
477     ASSERT(argv != nullptr);
478     JSThread *thread = argv->GetThread();
479     BUILTINS_API_TRACE(thread, LightWeightSet, ToString);
480     [[maybe_unused]] EcmaHandleScope handleScope(thread);
481     JSHandle<JSTaggedValue> self = GetThis(argv);
482     if (!self->IsJSAPILightWeightSet()) {
483         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
484             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
485         } else {
486             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
487                                                                 "The toString method cannot be bound");
488             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
489         }
490     }
491     JSTaggedValue value = JSAPILightWeightSet::ToString(thread, JSHandle<JSAPILightWeightSet>::Cast(self));
492     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
493     return value;
494 }
495 
ToArray(EcmaRuntimeCallInfo * argv)496 JSTaggedValue ContainersLightWeightSet::ToArray(EcmaRuntimeCallInfo *argv)
497 {
498     ASSERT(argv != nullptr);
499     JSThread *thread = argv->GetThread();
500     BUILTINS_API_TRACE(thread, LightWeightSet, ToArray);
501     [[maybe_unused]] EcmaHandleScope handleScope(thread);
502     JSHandle<JSTaggedValue> self = GetThis(argv);
503     if (!self->IsJSAPILightWeightSet()) {
504         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
505             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
506         } else {
507             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
508                                                                 "The toArray method cannot be bound");
509             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
510         }
511     }
512     JSHandle<JSAPILightWeightSet> lightweightset = JSHandle<JSAPILightWeightSet>::Cast(self);
513     auto factory = thread->GetEcmaVM()->GetFactory();
514     JSHandle<JSArray> array = factory->NewJSArray();
515 
516     uint32_t length = lightweightset->GetLength();
517     array->SetArrayLength(thread, length);
518 
519     JSHandle<TaggedArray> srcArray(thread, lightweightset->GetValues());
520     JSHandle<TaggedArray> dstElements = factory->NewAndCopyTaggedArray(srcArray, length, length);
521     array->SetElements(thread, dstElements);
522     return array.GetTaggedValue();
523 }
524 
GetSize(EcmaRuntimeCallInfo * argv)525 JSTaggedValue ContainersLightWeightSet::GetSize(EcmaRuntimeCallInfo *argv)
526 {
527     ASSERT(argv != nullptr);
528     JSThread *thread = argv->GetThread();
529     BUILTINS_API_TRACE(thread, LightWeightSet, GetSize);
530     [[maybe_unused]] EcmaHandleScope handleScope(thread);
531     JSHandle<JSTaggedValue> self = GetThis(argv);
532     if (!self->IsJSAPILightWeightSet()) {
533         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
534             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
535         } else {
536             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
537                                                                 "The getSize method cannot be bound");
538             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
539         }
540     }
541     return JSTaggedValue(JSHandle<JSAPILightWeightSet>::Cast(self)->GetSize());
542 }
543 } // namespace panda::ecmascript::containers
544