/* * Copyright (c) 2024 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_bitvector.h" #include "ecmascript/containers/containers_errors.h" #include "ecmascript/js_api/js_api_bitvector.h" namespace panda::ecmascript::containers { JSTaggedValue ContainersBitVector::BitVectorConstructor(EcmaRuntimeCallInfo* argv) { ASSERT(argv); JSThread* thread = argv->GetThread(); BUILTINS_API_TRACE(thread, BitVector, 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 BitVector's constructor cannot be directly invoked."); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } JSHandle constructor = GetConstructor(argv); ASSERT(constructor->IsJSSharedFunction() && constructor.GetTaggedValue().IsInSharedHeap()); JSHandle obj = JSHandle(factory->NewJSObjectByConstructor(JSHandle(constructor), newTarget)); ASSERT(obj.GetTaggedValue().IsInSharedHeap()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); JSHandle length = GetCallArg(argv, 0); if (!length->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, length); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"length\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } auto* newBitSetVector = new std::vector>(); if (!length->IsZero()) { int32_t capacity = std::max(0, (length->GetInt() / JSAPIBitVector::BIT_SET_LENGTH) + 1); std::bitset initBitSet; newBitSetVector->resize(capacity, initBitSet); } JSHandle pointer = factory->NewSJSNativePointer(newBitSetVector, ContainersBitVector::FreeBitsetVectorPointer, newBitSetVector); obj->SetNativePointer(thread, pointer); obj->SetLength(std::max(0, length->GetInt())); return obj.GetTaggedValue(); } JSTaggedValue ContainersBitVector::Push(EcmaRuntimeCallInfo* argv) { BUILTINS_API_TRACE(argv->GetThread(), BitVector, Push); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The push method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value = GetCallArg(argv, 0); return GetTaggedBoolean(JSAPIBitVector::Push(thread, JSHandle::Cast(self), value)); } JSTaggedValue ContainersBitVector::Pop(EcmaRuntimeCallInfo* argv) { BUILTINS_API_TRACE(argv->GetThread(), BitVector, Pop); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The pop method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } return JSHandle::Cast(self)->Pop(thread, JSHandle::Cast(self)); } JSTaggedValue ContainersBitVector::Has(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, Has); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR, "The has method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value = GetCallArg(argv, 0); JSHandle startIndex = GetCallArg(argv, 1); JSHandle endIndex = GetCallArg(argv, 2); // 2 means the third arg if (!startIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, startIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"fromIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } if (!endIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, endIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"toIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } bool isHas = JSHandle::Cast(self)->Has( thread, JSHandle::Cast(self), value, startIndex, endIndex); return GetTaggedBoolean(isHas); } JSTaggedValue ContainersBitVector::SetBitsByRange(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, SetBitsByRange); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR, "The setBitsByRange method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value = GetCallArg(argv, 0); JSHandle startIndex = GetCallArg(argv, 1); JSHandle endIndex = GetCallArg(argv, 2); // 2 means the third arg if (!startIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, startIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"fromIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } if (!endIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, endIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"toIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } JSHandle::Cast(self)->SetBitsByRange( thread, JSHandle::Cast(self), value, startIndex, endIndex); return JSTaggedValue::Undefined(); } JSTaggedValue ContainersBitVector::GetBitsByRange(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, GetBitsByRange); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR, "The getBitsByRange method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle startIndex = GetCallArg(argv, 0); JSHandle endIndex = GetCallArg(argv, 1); if (!startIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, startIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"fromIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } if (!endIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, endIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"toIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } return JSHandle::Cast(self)->GetBitsByRange( thread, JSHandle::Cast(self), startIndex, endIndex); } JSTaggedValue ContainersBitVector::Resize(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, Resize); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR, "The resize method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle size = GetCallArg(argv, 0); if (!size->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, size); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"size\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } JSHandle::Cast(self)->Resize( thread, JSHandle::Cast(self), JSTaggedValue::ToUint32(thread, size)); return JSTaggedValue::Undefined(); } JSTaggedValue ContainersBitVector::SetAllBits(EcmaRuntimeCallInfo* argv) { BUILTINS_API_TRACE(argv->GetThread(), BitVector, SetAllBits); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR, "The setAllBits method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value = GetCallArg(argv, 0); JSHandle::Cast(self)->SetAllBits(thread, JSHandle::Cast(self), value); return JSTaggedValue::Undefined(); } JSTaggedValue ContainersBitVector::GetBitCountByRange(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, GetBitCountByRange); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR, "The getBitCountByRange method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value = GetCallArg(argv, 0); JSHandle startIndex = GetCallArg(argv, 1); JSHandle endIndex = GetCallArg(argv, 2); // 2 means the third arg if (!startIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, startIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"fromIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } if (!endIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, endIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"toIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } return JSHandle::Cast(self)->GetBitCountByRange( thread, JSHandle::Cast(self), value, startIndex, endIndex); } JSTaggedValue ContainersBitVector::GetIndexOf(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, GetIndexOf); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR, "The getIndexOf method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value = GetCallArg(argv, 0); JSHandle startIndex = GetCallArg(argv, 1); JSHandle endIndex = GetCallArg(argv, 2); // 2 means the third arg if (!startIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, startIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"fromIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } if (!endIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, endIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"toIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } return JSTaggedValue( JSAPIBitVector::GetIndexOf(thread, JSHandle::Cast(self), value, startIndex, endIndex)); } JSTaggedValue ContainersBitVector::GetLastIndexOf(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, GetLastIndexOf); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR, "The getLastIndexOf method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle value = GetCallArg(argv, 0); JSHandle startIndex = GetCallArg(argv, 1); JSHandle endIndex = GetCallArg(argv, 2); // 2 means the third arg if (!startIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, startIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"fromIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } if (!endIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, endIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"toIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } return JSTaggedValue( JSAPIBitVector::GetLastIndexOf(thread, JSHandle::Cast(self), value, startIndex, endIndex)); } JSTaggedValue ContainersBitVector::FlipBitByIndex(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, FlipBitByIndex); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR, "The flipBitByIndex 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); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"index\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } JSAPIBitVector::FlipBitByIndex( thread, JSHandle::Cast(self), JSTaggedValue::ToUint32(thread, value)); return JSTaggedValue::Undefined(); } JSTaggedValue ContainersBitVector::FlipBitsByRange(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, FlipBitsByRange); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR, "The flipBitsByRange method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSHandle startIndex = GetCallArg(argv, 0); JSHandle endIndex = GetCallArg(argv, 1); if (!startIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, startIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"fromIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } if (!endIndex->IsInteger()) { JSHandle result = JSTaggedValue::ToString(thread, endIndex); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); CString errorMsg = "The type of \"toIndex\" must be integer. Received value is: " + ConvertToString(thread, *result); JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } JSHandle::Cast(self)->FlipBitsByRange( thread, JSHandle::Cast(self), startIndex, endIndex); return JSTaggedValue::Undefined(); } JSTaggedValue ContainersBitVector::GetSize(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, GetSize); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } 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()); } JSTaggedValue ContainersBitVector::GetIteratorObj(EcmaRuntimeCallInfo* argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), BitVector, GetIteratorObj); JSThread* thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle self = GetThis(argv); if (!self->IsJSAPIBitVector()) { if (self->IsJSProxy() && JSHandle::Cast(self)->GetTarget(thread).IsJSAPIBitVector()) { self = JSHandle(thread, JSHandle::Cast(self)->GetTarget(thread)); } else { JSTaggedValue error = ContainerError::BusinessError( thread, ErrorFlag::BIND_ERROR, "The Symbol.iterator method cannot be bound"); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception()); } } JSTaggedValue values = JSAPIBitVector::GetIteratorObj(thread, JSHandle::Cast(self)); return values; } void ContainersBitVector::FreeBitsetVectorPointer([[maybe_unused]] void *env, void *pointer, [[maybe_unused]] void *data) { if (pointer == nullptr) { return; } auto bitsetVector = reinterpret_cast> *>(pointer); delete bitsetVector; } } // namespace panda::ecmascript::containers