/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ecmascript/containers/containers_lightweightset.h" #include "ecmascript/containers/containers_errors.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/js_api/js_api_lightweightset.h" #include "ecmascript/js_api/js_api_lightweightset_iterator.h" #include "ecmascript/js_array.h" #include "ecmascript/object_factory.h" #include "ecmascript/tagged_array-inl.h" namespace panda::ecmascript::containers { JSTaggedValue ContainersLightWeightSet::LightWeightSetConstructor(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, Constructor); [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle newTarget = GetNewTarget(argv); if (newTarget->IsUndefined()) { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::IS_NULL_ERROR, "The LightWeightSet's constructor cannot be directly invoked"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } JSHandle constructor = GetConstructor(argv); JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(constructor), newTarget); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); JSHandle lightweightSet = JSHandle::Cast(obj); JSHandle hashes = JSAPILightWeightSet::CreateSlot(thread, JSAPILightWeightSet::DEFAULT_CAPACITY_LENGTH); JSHandle values = JSAPILightWeightSet::CreateSlot(thread, JSAPILightWeightSet::DEFAULT_CAPACITY_LENGTH); lightweightSet->SetHashes(thread, hashes); lightweightSet->SetValues(thread, values); return obj.GetTaggedValue(); } JSTaggedValue ContainersLightWeightSet::Add(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, Add); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR, "The add method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value(GetCallArg(argv, 0)); bool flag = JSAPILightWeightSet::Add(thread, JSHandle::Cast(self), value); return JSTaggedValue(flag); } JSTaggedValue ContainersLightWeightSet::AddAll(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, AddAll); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The addAll method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value(GetCallArg(argv, 0)); if (!value->IsJSAPILightWeightSet()) { if (value->IsJSProxy() && JSHandle::Cast(value)->GetTarget().IsJSAPILightWeightSet()) { value = JSHandle(thread, JSHandle::Cast(value)->GetTarget()); } else { JSHandle result = JSTaggedValue::ToString(thread, value.GetTaggedValue()); CString errorMsg = "The type of \"set\" must be LightWeightSet. Received value is: " + ConvertToString(*result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } return JSTaggedValue(JSAPILightWeightSet::AddAll(thread, JSHandle::Cast(self), value)); } JSTaggedValue ContainersLightWeightSet::IsEmpty(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, IsEmpty); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The isEmpty method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject()); return JSTaggedValue(set->IsEmpty()); } JSTaggedValue ContainersLightWeightSet::GetValueAt(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, GetValueAt); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The getValueAt method cannot be bound");; THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value(GetCallArg(argv, 0)); if (!value->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, value.GetTaggedValue()); CString errorMsg = "The type of \"index\" must be number. Received value is: " + ConvertToString(*result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } int32_t index = value->GetInt(); JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject()); return set->GetValueAt(index); } JSTaggedValue ContainersLightWeightSet::HasAll(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, HasAll); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The hasAll method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value(GetCallArg(argv, 0)); if (!value->IsJSAPILightWeightSet()) { if (value->IsJSProxy() && JSHandle::Cast(value)->GetTarget().IsJSAPILightWeightSet()) { value = JSHandle(thread, JSHandle::Cast(value)->GetTarget()); } else { JSHandle result = JSTaggedValue::ToString(thread, value.GetTaggedValue()); CString errorMsg = "The type of \"set\" must be LightWeightSet. Received value is: " + ConvertToString(*result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject()); return JSTaggedValue(set->HasAll(value)); } JSTaggedValue ContainersLightWeightSet::Has(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, Has); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The has method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value(GetCallArg(argv, 0)); JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject()); return JSTaggedValue(set->Has(value)); } JSTaggedValue ContainersLightWeightSet::HasHash(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, HasHash); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The hasHash method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value(GetCallArg(argv, 0)); JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject()); return JSTaggedValue(set->HasHash(value)); } JSTaggedValue ContainersLightWeightSet::Equal(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, Equal); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The equal method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value(GetCallArg(argv, 0)); return JSTaggedValue(JSAPILightWeightSet::Equal(thread, JSHandle::Cast(self), value)); } JSTaggedValue ContainersLightWeightSet::IncreaseCapacityTo(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, IncreaseCapacityTo); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The increaseCapacityTo method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value(GetCallArg(argv, 0)); if (!value->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, value.GetTaggedValue()); CString errorMsg = "The type of \"minimumCapacity\" must be number. Received value is: " + ConvertToString(*result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } int32_t minCapacity = value->GetInt(); JSAPILightWeightSet::IncreaseCapacityTo(thread, JSHandle::Cast(self), minCapacity); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::False()); return JSTaggedValue::Undefined(); } JSTaggedValue ContainersLightWeightSet::GetIteratorObj(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, GetIteratorObj); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The getIteratorObj method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle iter = JSAPILightWeightSet::GetIteratorObj(thread, JSHandle::Cast(self), IterationKind::VALUE); return iter.GetTaggedValue(); } JSTaggedValue ContainersLightWeightSet::Values(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, Values); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The values method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle iter = JSAPILightWeightSet::GetIteratorObj(thread, JSHandle::Cast(self), IterationKind::VALUE); return iter.GetTaggedValue(); } JSTaggedValue ContainersLightWeightSet::Entries(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, Entries); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The entries method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle iter = JSAPILightWeightSet::GetIteratorObj(thread, JSHandle::Cast(self), IterationKind::KEY_AND_VALUE); return iter.GetTaggedValue(); } JSTaggedValue ContainersLightWeightSet::ForEach(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, ForEach); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle thisHandle = GetThis(argv); JSHandle callbackFnHandle = GetCallArg(argv, 0); if (!thisHandle->IsJSAPILightWeightSet()) { if (thisHandle->IsJSProxy() && JSHandle::Cast(thisHandle)->GetTarget().IsJSAPILightWeightSet()) { thisHandle = JSHandle(thread, JSHandle::Cast(thisHandle)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The forEach method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } if (!callbackFnHandle->IsCallable()) { JSHandle result = JSTaggedValue::ToString(thread, callbackFnHandle.GetTaggedValue()); CString errorMsg = "The type of \"callbackfn\" must be callable. Received value is: " + ConvertToString(*result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } JSHandle thisArgHandle = GetCallArg(argv, 1); return JSAPILightWeightSet::ForEach(thread, thisHandle, callbackFnHandle, thisArgHandle); } JSTaggedValue ContainersLightWeightSet::GetIndexOf(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, GetIndexOf); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The getIndexOf method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value(GetCallArg(argv, 0)); JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject()); int32_t result = set->GetIndexOf(value); return JSTaggedValue(result); } JSTaggedValue ContainersLightWeightSet::Remove(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, Remove); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The remove method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle key(GetCallArg(argv, 0)); JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject()); return set->Remove(thread, key); } JSTaggedValue ContainersLightWeightSet::RemoveAt(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, RemoveAt); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The removeAt method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value(GetCallArg(argv, 0)); if (!value->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, value.GetTaggedValue()); CString errorMsg = "The type of \"index\" must be number. Received value is: " + ConvertToString(*result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } int32_t index = value->GetInt(); JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject()); return JSTaggedValue(set->RemoveAt(thread, index)); } JSTaggedValue ContainersLightWeightSet::Clear(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, Clear); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The clear method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSAPILightWeightSet *set = JSAPILightWeightSet::Cast(self->GetTaggedObject()); set->Clear(thread); return JSTaggedValue::True(); } JSTaggedValue ContainersLightWeightSet::ToString(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, ToString); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The toString method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSTaggedValue value = JSAPILightWeightSet::ToString(thread, JSHandle::Cast(self)); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return value; } JSTaggedValue ContainersLightWeightSet::ToArray(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, ToArray); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The toArray method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle lightweightset = JSHandle::Cast(self); auto factory = thread->GetEcmaVM()->GetFactory(); JSHandle array = factory->NewJSArray(); uint32_t length = lightweightset->GetLength(); array->SetArrayLength(thread, length); JSHandle srcArray(thread, lightweightset->GetValues()); JSHandle dstElements = factory->NewAndCopyTaggedArray(srcArray, length, length); array->SetElements(thread, dstElements); return array.GetTaggedValue(); } JSTaggedValue ContainersLightWeightSet::GetSize(EcmaRuntimeCallInfo *argv) { ASSERT(argv != nullptr); JSThread *thread = argv->GetThread(); BUILTINS_API_TRACE(thread, LightWeightSet, GetSize); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPILightWeightSet()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget().IsJSAPILightWeightSet()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget()); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The getSize method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } return JSTaggedValue(JSHandle::Cast(self)->GetSize()); } } // namespace panda::ecmascript::containers