• 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             CString errorMsg =
100                 "The type of \"set\" must be LightWeightSet. Received value is: " + ConvertToString(*result);
101             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
102             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
103         }
104     }
105 
106     return JSTaggedValue(JSAPILightWeightSet::AddAll(thread, JSHandle<JSAPILightWeightSet>::Cast(self), value));
107 }
108 
IsEmpty(EcmaRuntimeCallInfo * argv)109 JSTaggedValue ContainersLightWeightSet::IsEmpty(EcmaRuntimeCallInfo *argv)
110 {
111     ASSERT(argv != nullptr);
112     JSThread *thread = argv->GetThread();
113     BUILTINS_API_TRACE(thread, LightWeightSet, IsEmpty);
114     [[maybe_unused]] EcmaHandleScope handleScope(thread);
115     JSHandle<JSTaggedValue> self = GetThis(argv);
116     if (!self->IsJSAPILightWeightSet()) {
117         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
118             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
119         } else {
120             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
121                                                                 "The isEmpty method cannot be bound");
122             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
123         }
124     }
125     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
126     return JSTaggedValue(set->IsEmpty());
127 }
128 
GetValueAt(EcmaRuntimeCallInfo * argv)129 JSTaggedValue ContainersLightWeightSet::GetValueAt(EcmaRuntimeCallInfo *argv)
130 {
131     ASSERT(argv != nullptr);
132     JSThread *thread = argv->GetThread();
133     BUILTINS_API_TRACE(thread, LightWeightSet, GetValueAt);
134     [[maybe_unused]] EcmaHandleScope handleScope(thread);
135     JSHandle<JSTaggedValue> self = GetThis(argv);
136     if (!self->IsJSAPILightWeightSet()) {
137         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
138             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
139         } else {
140             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
141                                                                 "The getValueAt method cannot be bound");;
142             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
143         }
144     }
145     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
146     if (!value->IsInteger()) {
147         JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value.GetTaggedValue());
148         CString errorMsg =
149             "The type of \"index\" must be number. Received value is: " + ConvertToString(*result);
150         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
151         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
152     }
153     int32_t index = value->GetInt();
154     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
155     return set->GetValueAt(index);
156 }
157 
HasAll(EcmaRuntimeCallInfo * argv)158 JSTaggedValue ContainersLightWeightSet::HasAll(EcmaRuntimeCallInfo *argv)
159 {
160     ASSERT(argv != nullptr);
161     JSThread *thread = argv->GetThread();
162     BUILTINS_API_TRACE(thread, LightWeightSet, HasAll);
163     [[maybe_unused]] EcmaHandleScope handleScope(thread);
164     JSHandle<JSTaggedValue> self = GetThis(argv);
165     if (!self->IsJSAPILightWeightSet()) {
166         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
167             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
168         } else {
169             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
170                                                                 "The hasAll method cannot be bound");
171             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
172         }
173     }
174     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
175     if (!value->IsJSAPILightWeightSet()) {
176         if (value->IsJSProxy() && JSHandle<JSProxy>::Cast(value)->GetTarget().IsJSAPILightWeightSet()) {
177             value = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(value)->GetTarget());
178         } else {
179             JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value.GetTaggedValue());
180             CString errorMsg =
181                 "The type of \"set\" must be LightWeightSet. Received value is: " + ConvertToString(*result);
182             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
183             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
184         }
185     }
186     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
187     return JSTaggedValue(set->HasAll(value));
188 }
189 
Has(EcmaRuntimeCallInfo * argv)190 JSTaggedValue ContainersLightWeightSet::Has(EcmaRuntimeCallInfo *argv)
191 {
192     ASSERT(argv != nullptr);
193     JSThread *thread = argv->GetThread();
194     BUILTINS_API_TRACE(thread, LightWeightSet, Has);
195     [[maybe_unused]] EcmaHandleScope handleScope(thread);
196     JSHandle<JSTaggedValue> self = GetThis(argv);
197     if (!self->IsJSAPILightWeightSet()) {
198         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
199             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
200         } else {
201             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
202                                                                 "The has method cannot be bound");
203             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
204         }
205     }
206     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
207     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
208     return JSTaggedValue(set->Has(value));
209 }
210 
HasHash(EcmaRuntimeCallInfo * argv)211 JSTaggedValue ContainersLightWeightSet::HasHash(EcmaRuntimeCallInfo *argv)
212 {
213     ASSERT(argv != nullptr);
214     JSThread *thread = argv->GetThread();
215     BUILTINS_API_TRACE(thread, LightWeightSet, HasHash);
216     [[maybe_unused]] EcmaHandleScope handleScope(thread);
217     JSHandle<JSTaggedValue> self = GetThis(argv);
218     if (!self->IsJSAPILightWeightSet()) {
219         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
220             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
221         } else {
222             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
223                                                                 "The hasHash method cannot be bound");
224             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
225         }
226     }
227     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
228     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
229     return JSTaggedValue(set->HasHash(value));
230 }
231 
Equal(EcmaRuntimeCallInfo * argv)232 JSTaggedValue ContainersLightWeightSet::Equal(EcmaRuntimeCallInfo *argv)
233 {
234     ASSERT(argv != nullptr);
235     JSThread *thread = argv->GetThread();
236     BUILTINS_API_TRACE(thread, LightWeightSet, Equal);
237     [[maybe_unused]] EcmaHandleScope handleScope(thread);
238     JSHandle<JSTaggedValue> self = GetThis(argv);
239     if (!self->IsJSAPILightWeightSet()) {
240         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
241             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
242         } else {
243             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
244                                                                 "The equal method cannot be bound");
245             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
246         }
247     }
248     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
249     return JSTaggedValue(JSAPILightWeightSet::Equal(thread, JSHandle<JSAPILightWeightSet>::Cast(self), value));
250 }
251 
IncreaseCapacityTo(EcmaRuntimeCallInfo * argv)252 JSTaggedValue ContainersLightWeightSet::IncreaseCapacityTo(EcmaRuntimeCallInfo *argv)
253 {
254     ASSERT(argv != nullptr);
255     JSThread *thread = argv->GetThread();
256     BUILTINS_API_TRACE(thread, LightWeightSet, IncreaseCapacityTo);
257     [[maybe_unused]] EcmaHandleScope handleScope(thread);
258     JSHandle<JSTaggedValue> self = GetThis(argv);
259     if (!self->IsJSAPILightWeightSet()) {
260         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
261             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
262         } else {
263             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
264                                                                 "The increaseCapacityTo method cannot be bound");
265             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
266         }
267     }
268     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
269     if (!value->IsInteger()) {
270         JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value.GetTaggedValue());
271         CString errorMsg =
272             "The type of \"minimumCapacity\" must be number. Received value is: " + ConvertToString(*result);
273         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
274         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
275     }
276     int32_t minCapacity = value->GetInt();
277     JSAPILightWeightSet::IncreaseCapacityTo(thread, JSHandle<JSAPILightWeightSet>::Cast(self), minCapacity);
278     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False());
279     return JSTaggedValue::Undefined();
280 }
281 
GetIteratorObj(EcmaRuntimeCallInfo * argv)282 JSTaggedValue ContainersLightWeightSet::GetIteratorObj(EcmaRuntimeCallInfo *argv)
283 {
284     ASSERT(argv != nullptr);
285     JSThread *thread = argv->GetThread();
286     BUILTINS_API_TRACE(thread, LightWeightSet, GetIteratorObj);
287     [[maybe_unused]] EcmaHandleScope handleScope(thread);
288     JSHandle<JSTaggedValue> self = GetThis(argv);
289     if (!self->IsJSAPILightWeightSet()) {
290         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
291             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
292         } else {
293             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
294                                                                 "The getIteratorObj method cannot be bound");
295             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
296         }
297     }
298     JSHandle<JSTaggedValue> iter =
299         JSAPILightWeightSet::GetIteratorObj(thread, JSHandle<JSAPILightWeightSet>::Cast(self), IterationKind::VALUE);
300     return iter.GetTaggedValue();
301 }
302 
Values(EcmaRuntimeCallInfo * argv)303 JSTaggedValue ContainersLightWeightSet::Values(EcmaRuntimeCallInfo *argv)
304 {
305     ASSERT(argv != nullptr);
306     JSThread *thread = argv->GetThread();
307     BUILTINS_API_TRACE(thread, LightWeightSet, Values);
308     [[maybe_unused]] EcmaHandleScope handleScope(thread);
309     JSHandle<JSTaggedValue> self = GetThis(argv);
310     if (!self->IsJSAPILightWeightSet()) {
311         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
312             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
313         } else {
314             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
315                                                                 "The values method cannot be bound");
316             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
317         }
318     }
319     JSHandle<JSTaggedValue> iter =
320         JSAPILightWeightSet::GetIteratorObj(thread, JSHandle<JSAPILightWeightSet>::Cast(self), IterationKind::VALUE);
321     return iter.GetTaggedValue();
322 }
323 
Entries(EcmaRuntimeCallInfo * argv)324 JSTaggedValue ContainersLightWeightSet::Entries(EcmaRuntimeCallInfo *argv)
325 {
326     ASSERT(argv != nullptr);
327     JSThread *thread = argv->GetThread();
328     BUILTINS_API_TRACE(thread, LightWeightSet, Entries);
329     [[maybe_unused]] EcmaHandleScope handleScope(thread);
330     JSHandle<JSTaggedValue> self = GetThis(argv);
331     if (!self->IsJSAPILightWeightSet()) {
332         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
333             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
334         } else {
335             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
336                                                                 "The entries method cannot be bound");
337             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
338         }
339     }
340     JSHandle<JSTaggedValue> iter =
341         JSAPILightWeightSet::GetIteratorObj(thread, JSHandle<JSAPILightWeightSet>::Cast(self),
342                                             IterationKind::KEY_AND_VALUE);
343     return iter.GetTaggedValue();
344 }
345 
ForEach(EcmaRuntimeCallInfo * argv)346 JSTaggedValue ContainersLightWeightSet::ForEach(EcmaRuntimeCallInfo *argv)
347 {
348     ASSERT(argv != nullptr);
349     JSThread *thread = argv->GetThread();
350     BUILTINS_API_TRACE(thread, LightWeightSet, ForEach);
351     [[maybe_unused]] EcmaHandleScope handleScope(thread);
352     JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
353     JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
354 
355     if (!thisHandle->IsJSAPILightWeightSet()) {
356         if (thisHandle->IsJSProxy() && JSHandle<JSProxy>::Cast(thisHandle)->GetTarget().IsJSAPILightWeightSet()) {
357             thisHandle = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(thisHandle)->GetTarget());
358         } else {
359             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
360                                                                 "The forEach method cannot be bound");
361             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
362         }
363     }
364 
365     if (!callbackFnHandle->IsCallable()) {
366         JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, callbackFnHandle.GetTaggedValue());
367         CString errorMsg =
368             "The type of \"callbackfn\" must be callable. Received value is: " + ConvertToString(*result);
369         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
370         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
371     }
372     JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
373     return JSAPILightWeightSet::ForEach(thread, thisHandle, callbackFnHandle, thisArgHandle);
374 }
375 
GetIndexOf(EcmaRuntimeCallInfo * argv)376 JSTaggedValue ContainersLightWeightSet::GetIndexOf(EcmaRuntimeCallInfo *argv)
377 {
378     ASSERT(argv != nullptr);
379     JSThread *thread = argv->GetThread();
380     BUILTINS_API_TRACE(thread, LightWeightSet, GetIndexOf);
381     [[maybe_unused]] EcmaHandleScope handleScope(thread);
382     JSHandle<JSTaggedValue> self = GetThis(argv);
383     if (!self->IsJSAPILightWeightSet()) {
384         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
385             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
386         } else {
387             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
388                                                                 "The getIndexOf method cannot be bound");
389             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
390         }
391     }
392     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
393     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
394     int32_t result = set->GetIndexOf(value);
395     return JSTaggedValue(result);
396 }
397 
Remove(EcmaRuntimeCallInfo * argv)398 JSTaggedValue ContainersLightWeightSet::Remove(EcmaRuntimeCallInfo *argv)
399 {
400     ASSERT(argv != nullptr);
401     JSThread *thread = argv->GetThread();
402     BUILTINS_API_TRACE(thread, LightWeightSet, Remove);
403     [[maybe_unused]] EcmaHandleScope handleScope(thread);
404     JSHandle<JSTaggedValue> self = GetThis(argv);
405     if (!self->IsJSAPILightWeightSet()) {
406         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
407             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
408         } else {
409             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
410                                                                 "The remove method cannot be bound");
411             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
412         }
413     }
414     JSHandle<JSTaggedValue> key(GetCallArg(argv, 0));
415     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
416     return set->Remove(thread, key);
417 }
418 
RemoveAt(EcmaRuntimeCallInfo * argv)419 JSTaggedValue ContainersLightWeightSet::RemoveAt(EcmaRuntimeCallInfo *argv)
420 {
421     ASSERT(argv != nullptr);
422     JSThread *thread = argv->GetThread();
423     BUILTINS_API_TRACE(thread, LightWeightSet, RemoveAt);
424     [[maybe_unused]] EcmaHandleScope handleScope(thread);
425     JSHandle<JSTaggedValue> self = GetThis(argv);
426     if (!self->IsJSAPILightWeightSet()) {
427         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
428             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
429         } else {
430             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
431                                                                 "The removeAt method cannot be bound");
432             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
433         }
434     }
435     JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
436     if (!value->IsInteger()) {
437         JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value.GetTaggedValue());
438         CString errorMsg =
439             "The type of \"index\" must be number. Received value is: " + ConvertToString(*result);
440         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
441         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
442     }
443     int32_t index = value->GetInt();
444     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
445     return JSTaggedValue(set->RemoveAt(thread, index));
446 }
447 
Clear(EcmaRuntimeCallInfo * argv)448 JSTaggedValue ContainersLightWeightSet::Clear(EcmaRuntimeCallInfo *argv)
449 {
450     ASSERT(argv != nullptr);
451     JSThread *thread = argv->GetThread();
452     BUILTINS_API_TRACE(thread, LightWeightSet, Clear);
453     [[maybe_unused]] EcmaHandleScope handleScope(thread);
454     JSHandle<JSTaggedValue> self = GetThis(argv);
455     if (!self->IsJSAPILightWeightSet()) {
456         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
457             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
458         } else {
459             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
460                                                                 "The clear method cannot be bound");
461             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
462         }
463     }
464     JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject());
465     set->Clear(thread);
466     return JSTaggedValue::True();
467 }
468 
ToString(EcmaRuntimeCallInfo * argv)469 JSTaggedValue ContainersLightWeightSet::ToString(EcmaRuntimeCallInfo *argv)
470 {
471     ASSERT(argv != nullptr);
472     JSThread *thread = argv->GetThread();
473     BUILTINS_API_TRACE(thread, LightWeightSet, ToString);
474     [[maybe_unused]] EcmaHandleScope handleScope(thread);
475     JSHandle<JSTaggedValue> self = GetThis(argv);
476     if (!self->IsJSAPILightWeightSet()) {
477         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
478             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
479         } else {
480             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
481                                                                 "The toString method cannot be bound");
482             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
483         }
484     }
485     JSTaggedValue value = JSAPILightWeightSet::ToString(thread, JSHandle<JSAPILightWeightSet>::Cast(self));
486     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
487     return value;
488 }
489 
ToArray(EcmaRuntimeCallInfo * argv)490 JSTaggedValue ContainersLightWeightSet::ToArray(EcmaRuntimeCallInfo *argv)
491 {
492     ASSERT(argv != nullptr);
493     JSThread *thread = argv->GetThread();
494     BUILTINS_API_TRACE(thread, LightWeightSet, ToArray);
495     [[maybe_unused]] EcmaHandleScope handleScope(thread);
496     JSHandle<JSTaggedValue> self = GetThis(argv);
497     if (!self->IsJSAPILightWeightSet()) {
498         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
499             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
500         } else {
501             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
502                                                                 "The toArray method cannot be bound");
503             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
504         }
505     }
506     JSHandle<JSAPILightWeightSet> lightweightset = JSHandle<JSAPILightWeightSet>::Cast(self);
507     auto factory = thread->GetEcmaVM()->GetFactory();
508     JSHandle<JSArray> array = factory->NewJSArray();
509 
510     uint32_t length = lightweightset->GetLength();
511     array->SetArrayLength(thread, length);
512 
513     JSHandle<TaggedArray> srcArray(thread, lightweightset->GetValues());
514     JSHandle<TaggedArray> dstElements = factory->NewAndCopyTaggedArray(srcArray, length, length);
515     array->SetElements(thread, dstElements);
516     return array.GetTaggedValue();
517 }
518 
GetSize(EcmaRuntimeCallInfo * argv)519 JSTaggedValue ContainersLightWeightSet::GetSize(EcmaRuntimeCallInfo *argv)
520 {
521     ASSERT(argv != nullptr);
522     JSThread *thread = argv->GetThread();
523     BUILTINS_API_TRACE(thread, LightWeightSet, GetSize);
524     [[maybe_unused]] EcmaHandleScope handleScope(thread);
525     JSHandle<JSTaggedValue> self = GetThis(argv);
526     if (!self->IsJSAPILightWeightSet()) {
527         if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPILightWeightSet()) {
528             self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
529         } else {
530             JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
531                                                                 "The getSize method cannot be bound");
532             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
533         }
534     }
535     return JSTaggedValue(JSHandle<JSAPILightWeightSet>::Cast(self)->GetSize());
536 }
537 } // namespace panda::ecmascript::containers