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