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