Add napi for map

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IA89HH?from=project-issue
Signed-off-by: liu-zelin <liuzelin8@huawei.com>
Change-Id: I2fd4251d2bb30d38f26f115dcedff72311b3c56a
This commit is contained in:
liu-zelin 2024-06-25 20:22:04 +08:00
parent 4cf33a8091
commit a25f68f442
3 changed files with 285 additions and 0 deletions

View File

@ -59,6 +59,7 @@ class ObjectRef;
class FunctionRef;
class NumberRef;
class MapIteratorRef;
class SendableMapIteratorRef;
class BooleanRef;
class NativePointerRef;
class JsiRuntimeCallInfo;
@ -517,6 +518,7 @@ public:
bool IsSharedTypedArray(const EcmaVM *vm);
bool IsSharedSet(const EcmaVM *vm);
bool IsSharedMap(const EcmaVM *vm);
bool IsSharedMapIterator(const EcmaVM *vm);
bool IsHeapObject();
void *GetNativePointerValue(const EcmaVM *vm, bool &isNativePointer);
bool IsDetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer);
@ -1270,10 +1272,36 @@ public:
int32_t GetSize();
int32_t GetTotalElements();
Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8);
Local<JSValueRef> GetKey(const EcmaVM *vm, int entry);
Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
static Local<MapRef> New(const EcmaVM *vm);
void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
void Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value);
bool Has(const EcmaVM *vm, Local<JSValueRef> key);
bool Has(const EcmaVM *vm, const char *utf8);
void Delete(const EcmaVM *vm, Local<JSValueRef> key);
void Clear(const EcmaVM *vm);
Local<MapIteratorRef> GetEntries(const EcmaVM *vm);
Local<MapIteratorRef> GetKeys(const EcmaVM *vm);
Local<MapIteratorRef> GetValues(const EcmaVM *vm);
};
class ECMA_PUBLIC_API SendableMapRef : public ObjectRef {
public:
static Local<SendableMapRef> New(const EcmaVM *vm);
uint32_t GetSize(const EcmaVM *vm);
Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8);
void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
void Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value);
bool Has(const EcmaVM *vm, Local<JSValueRef> key);
bool Has(const EcmaVM *vm, const char *utf8);
void Delete(const EcmaVM *vm, Local<JSValueRef> key);
void Clear(const EcmaVM *vm);
Local<SendableMapIteratorRef> GetEntries(const EcmaVM *vm);
Local<SendableMapIteratorRef> GetKeys(const EcmaVM *vm);
Local<SendableMapIteratorRef> GetValues(const EcmaVM *vm);
};
class ECMA_PUBLIC_API BufferRef : public ObjectRef {
@ -1334,6 +1362,12 @@ public:
static Local<MapIteratorRef> New(const EcmaVM *vm, Local<MapRef> map);
ecmascript::EcmaRuntimeCallInfo* GetEcmaRuntimeCallInfo(const EcmaVM *vm);
static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo* ecmaRuntimeCallInfo);
Local<JSValueRef> Next(const EcmaVM *vm);
};
class ECMA_PUBLIC_API SendableMapIteratorRef : public ObjectRef {
public:
Local<JSValueRef> Next(const EcmaVM *vm);
};
class ECMA_PUBLIC_API JSNApi {

View File

@ -1005,6 +1005,11 @@ bool JSValueRef::IsSharedMap([[maybe_unused]] const EcmaVM *vm)
return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedMap();
}
bool JSValueRef::IsSharedMapIterator([[maybe_unused]] const EcmaVM *vm)
{
return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedMapIterator();
}
bool JSValueRef::IsHeapObject()
{
return JSNApiHelper::ToJSTaggedValue(this).IsHeapObject();
@ -1214,6 +1219,17 @@ Local<JSValueRef> MapRef::Get(const EcmaVM *vm, Local<JSValueRef> key)
map->Get(thread, JSNApiHelper::ToJSTaggedValue(*key))));
}
Local<JSValueRef> MapRef::Get(const EcmaVM *vm, const char *utf8)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
auto result = JSHandle<JSTaggedValue>(thread, map->Get(thread, key.GetTaggedValue()));
return JSNApiHelper::ToLocal<JSValueRef>(result);
}
void MapRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value)
{
CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
@ -1222,6 +1238,52 @@ void MapRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> valu
JSMap::Set(thread, map, JSNApiHelper::ToJSHandle(key), JSNApiHelper::ToJSHandle(value));
}
void MapRef::Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value)
{
CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
JSMap::Set(thread, map, key, JSNApiHelper::ToJSHandle(value));
}
bool MapRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
bool result = map->Has(thread, JSNApiHelper::ToJSTaggedValue(*key));
return result;
}
bool MapRef::Has(const EcmaVM *vm, const char *utf8)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
bool result = map->Has(thread, key.GetTaggedValue());
return result;
}
void MapRef::Delete(const EcmaVM *vm, Local<JSValueRef> key)
{
CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
JSMap::Delete(thread, map, JSNApiHelper::ToJSHandle(key));
}
void MapRef::Clear(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
JSMap::Clear(thread, map);
}
Local<MapRef> MapRef::New(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
@ -1255,6 +1317,7 @@ int32_t MapRef::GetTotalElements()
Local<JSValueRef> MapRef::GetKey(const EcmaVM *vm, int entry)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(map, FATAL);
return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, map->GetKey(entry)));
@ -1263,11 +1326,178 @@ Local<JSValueRef> MapRef::GetKey(const EcmaVM *vm, int entry)
Local<JSValueRef> MapRef::GetValue(const EcmaVM *vm, int entry)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(map, FATAL);
return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, map->GetValue(entry)));
}
Local<MapIteratorRef> MapRef::GetEntries(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
JSHandle<JSTaggedValue> mapIter =
ecmascript::JSMapIterator::CreateMapIterator(thread, map, IterationKind::KEY_AND_VALUE);
return JSNApiHelper::ToLocal<MapIteratorRef>(mapIter);
}
Local<MapIteratorRef> MapRef::GetKeys(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
JSHandle<JSTaggedValue> mapIter = ecmascript::JSMapIterator::CreateMapIterator(thread, map, IterationKind::KEY);
return JSNApiHelper::ToLocal<MapIteratorRef>(mapIter);
}
Local<MapIteratorRef> MapRef::GetValues(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
JSHandle<JSTaggedValue> mapIter = ecmascript::JSMapIterator::CreateMapIterator(thread, map, IterationKind::VALUE);
return JSNApiHelper::ToLocal<MapIteratorRef>(mapIter);
}
// SendableMapRef
Local<SendableMapRef> SendableMapRef::New(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(thread);
ObjectFactory *factory = vm->GetFactory();
JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
JSHandle<JSTaggedValue> constructor = env->GetSBuiltininMapFunction();
ASSERT(constructor->IsJSSharedFunction() && constructor.GetTaggedValue().IsInSharedHeap());
JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor);
ASSERT(obj.GetTaggedValue().IsInSharedHeap());
JSHandle<ecmascript::JSSharedMap> sharedMap = JSHandle<ecmascript::JSSharedMap>::Cast(obj);
JSHandle<LinkedHashMap> linkedMap =
LinkedHashMap::Create(thread, LinkedHashMap::MIN_CAPACITY, ecmascript::MemSpaceKind::SHARED);
sharedMap->SetLinkedMap(thread, linkedMap);
JSHandle<JSTaggedValue> sharedMapTag = JSHandle<JSTaggedValue>::Cast(sharedMap);
return JSNApiHelper::ToLocal<SendableMapRef>(sharedMapTag);
}
Local<JSValueRef> SendableMapRef::Get(const EcmaVM *vm, Local<JSValueRef> key)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
return JSNApiHelper::ToLocal<JSValueRef>(
JSHandle<JSTaggedValue>(thread, map->Get(thread, JSNApiHelper::ToJSTaggedValue(*key))));
}
Local<JSValueRef> SendableMapRef::Get(const EcmaVM *vm, const char *utf8)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
auto result = JSHandle<JSTaggedValue>(thread, map->Get(thread, key.GetTaggedValue()));
return JSNApiHelper::ToLocal<JSValueRef>(result);
}
void SendableMapRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value)
{
CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
ecmascript::JSSharedMap::Set(thread, map, JSNApiHelper::ToJSHandle(key), JSNApiHelper::ToJSHandle(value));
}
void SendableMapRef::Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value)
{
CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
ecmascript::JSSharedMap::Set(thread, map, key, JSNApiHelper::ToJSHandle(value));
}
bool SendableMapRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
bool result = map->Has(thread, JSNApiHelper::ToJSTaggedValue(*key));
return result;
}
bool SendableMapRef::Has(const EcmaVM *vm, const char *utf8)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
bool result = map->Has(thread, key.GetTaggedValue());
return result;
}
void SendableMapRef::Delete(const EcmaVM *vm, Local<JSValueRef> key)
{
CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
ecmascript::JSSharedMap::Delete(thread, map, JSNApiHelper::ToJSHandle(key));
}
void SendableMapRef::Clear(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
ecmascript::JSSharedMap::Clear(thread, map);
}
uint32_t SendableMapRef::GetSize(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
return map->GetSize(thread);
}
Local<SendableMapIteratorRef> SendableMapRef::GetEntries(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
JSHandle<JSTaggedValue> sharedMapIter =
ecmascript::JSSharedMapIterator::CreateMapIterator(thread, map, IterationKind::KEY_AND_VALUE);
return JSNApiHelper::ToLocal<SendableMapIteratorRef>(sharedMapIter);
}
Local<SendableMapIteratorRef> SendableMapRef::GetKeys(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
JSHandle<JSTaggedValue> sharedMapIter =
ecmascript::JSSharedMapIterator::CreateMapIterator(thread, map, IterationKind::KEY);
return JSNApiHelper::ToLocal<SendableMapIteratorRef>(sharedMapIter);
}
Local<SendableMapIteratorRef> SendableMapRef::GetValues(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
JSHandle<JSTaggedValue> sharedMapIter =
ecmascript::JSSharedMapIterator::CreateMapIterator(thread, map, IterationKind::VALUE);
return JSNApiHelper::ToLocal<SendableMapIteratorRef>(sharedMapIter);
}
// ----------------------------------- MapIteratorRef ---------------------------------------
int32_t MapIteratorRef::GetIndex()
{
@ -1335,6 +1565,25 @@ Local<ArrayRef> MapIteratorRef::Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCa
return JSNApiHelper::ToLocal<ArrayRef>(iteratorVal);
}
Local<JSValueRef> MapIteratorRef::Next(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<JSTaggedValue> mapIter(JSNApiHelper::ToJSHandle(this));
auto result = JSMapIterator::NextInternal(thread, mapIter);
return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, result));
}
// SendableMapIteratorRef
Local<JSValueRef> SendableMapIteratorRef::Next(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<JSTaggedValue> sharedMapIter(JSNApiHelper::ToJSHandle(this));
auto result = ecmascript::JSSharedMapIterator::NextInternal(thread, sharedMapIter);
return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, result));
}
// ----------------------------------- SetIteratorRef ---------------------------------------
int32_t SetIteratorRef::GetIndex()
{

View File

@ -32,6 +32,7 @@
panda::Float32ArrayRef::*;
panda::Float64ArrayRef::*;
panda::MapIteratorRef::*;
panda::SendableMapIteratorRef::*;
panda::FunctionRef::*;
panda::GeneratorFunctionRef::*;
panda::GeneratorObjectRef::*;
@ -41,6 +42,7 @@
panda::IntegerRef::*;
panda::JSValueRef::*;
panda::MapRef::*;
panda::SendableMapRef::*;
panda::NativePointerRef::*;
panda::NumberFormatRef::*;
panda::NumberRef::*;