fix napi sendable

1. add ut
2. fix some interface bug

https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I9OLPG

Signed-off-by: wengchangcheng <wengchangcheng@huawei.com>
Change-Id: Ic26e5fe5fb39432a896b6a98a8e194006e623bf1
This commit is contained in:
wengchangcheng 2024-05-11 23:18:52 +08:00
parent 826791e286
commit cdba5d43ba
13 changed files with 134 additions and 35 deletions

View File

@ -426,7 +426,7 @@ JSHandle<JSHClass> TypedArrayHelper::GetNotOnHeapHclassFromType(
}
JSHandle<JSHClass> TypedArrayHelper::GetSharedNotOnHeapHclassFromType(
JSThread *thread, const JSHandle<JSTypedArray> &obj, const DataViewType arrayType)
JSThread *thread, const JSHandle<JSSharedTypedArray> &obj, const DataViewType arrayType)
{
JSHClass* objHclass = JSHandle<TaggedObject>(obj)->GetClass();
ASSERT_PRINT(objHclass->IsOnHeapFromBitField(), "must be on heap");

View File

@ -504,7 +504,7 @@ JSTaggedValue TypedArrayHelper::CreateSharedFromTypedArray(EcmaRuntimeCallInfo *
// 6. Let srcData be srcArray.[[ViewedArrayBuffer]].
JSTaggedValue buffer;
if (srcArray->IsSharedTypedArray()) {
buffer = JSTypedArray::GetSharedOffHeapBuffer(thread, srcObj);
buffer = JSSharedTypedArray::GetSharedOffHeapBuffer(thread, JSHandle<JSSharedTypedArray>(srcObj));
} else {
buffer = JSTypedArray::GetOffHeapBuffer(thread, srcObj);
}

View File

@ -21,6 +21,7 @@
#include "ecmascript/base/builtins_base.h"
#include "ecmascript/js_dataview.h"
#include "ecmascript/js_typed_array.h"
#include "ecmascript/shared_objects/js_shared_typed_array.h"
#include "ecmascript/builtins/builtins_shared_typedarray.h"
#include "ecmascript/builtins/builtins_typedarray.h"
@ -88,7 +89,7 @@ public:
inline static JSHandle<JSHClass> GetSharedOnHeapHclassFromType(
JSThread *thread, const JSHandle<JSTypedArray> &obj, const DataViewType arrayType);
inline static JSHandle<JSHClass> GetSharedNotOnHeapHclassFromType(
JSThread *thread, const JSHandle<JSTypedArray> &obj, const DataViewType arrayType);
JSThread *thread, const JSHandle<JSSharedTypedArray> &obj, const DataViewType arrayType);
inline static uint32_t GetSizeFromType(const DataViewType arrayType);
inline static bool IsAccessorHasChanged(const JSHandle<JSTaggedValue> &obj);
static int32_t SortCompare(JSThread *thread, const JSHandle<JSTaggedValue> &callbackfnHandle,

View File

@ -375,8 +375,8 @@ JSTaggedValue BuiltinsSharedTypedArray::GetBuffer(EcmaRuntimeCallInfo *argv)
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
}
// 4. Let buffer be the value of Os [[ViewedArrayBuffer]] internal slot.
JSHandle<JSTypedArray> typedArray = JSHandle<JSTypedArray>::Cast(thisHandle);
JSTaggedValue buffer = JSTypedArray::GetSharedOffHeapBuffer(thread, typedArray);
JSHandle<JSSharedTypedArray> typedArray = JSHandle<JSSharedTypedArray>::Cast(thisHandle);
JSTaggedValue buffer = JSSharedTypedArray::GetSharedOffHeapBuffer(thread, typedArray);
// 5. Return buffer.
return buffer;
}
@ -1623,7 +1623,7 @@ JSTaggedValue BuiltinsSharedTypedArray::Subarray(EcmaRuntimeCallInfo *argv)
ASSERT((static_cast<uint64_t>(srcByteOffset) + static_cast<uint64_t>(beginIndex) *
static_cast<uint64_t>(elementSize)) <= static_cast<uint64_t>(UINT32_MAX));
uint32_t beginByteOffset = srcByteOffset + beginIndex * elementSize;
JSTaggedValue buffer = JSTypedArray::GetSharedOffHeapBuffer(thread, thisObj);
JSTaggedValue buffer = JSSharedTypedArray::GetSharedOffHeapBuffer(thread, JSHandle<JSSharedTypedArray>(thisObj));
// 21. Let argumentsList be «buffer, beginByteOffset, newLength».
// 5. Let buffer be the value of Os [[ViewedArrayBuffer]] internal slot.
// 22. Return Construct(constructor, argumentsList).

View File

@ -776,7 +776,7 @@ JSTaggedValue JSTypedArray::GetOffHeapBuffer(JSThread *thread, JSHandle<JSTypedA
return arrayBuffer.GetTaggedValue();
}
JSTaggedValue JSTypedArray::GetSharedOffHeapBuffer(JSThread *thread, JSHandle<JSTypedArray> &typedArray)
JSTaggedValue JSSharedTypedArray::GetSharedOffHeapBuffer(JSThread *thread, JSHandle<JSSharedTypedArray> typedArray)
{
JSTaggedValue arrBuf = typedArray->GetViewedArrayBufferOrByteArray();
if (arrBuf.IsSendableArrayBuffer()) {

View File

@ -100,7 +100,6 @@ public:
// only use in TypeArray fast set property
static JSTaggedNumber NonEcmaObjectToNumber(JSThread *thread, const JSTaggedValue tagged);
static JSTaggedValue GetOffHeapBuffer(JSThread *thread, JSHandle<JSTypedArray> &typedArray);
static JSTaggedValue GetSharedOffHeapBuffer(JSThread *thread, JSHandle<JSTypedArray> &typedArray);
static bool FastTypedArrayFill(JSThread *thread, const JSHandle<JSTaggedValue> &typedArray,
const JSHandle<JSTaggedValue> &value, uint32_t start, uint32_t end);
static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE;

View File

@ -970,12 +970,19 @@ public:
void Detach(const EcmaVM *vm);
bool IsDetach();
};
static Local<ArrayBufferRef> NewSendable(const EcmaVM *vm, int32_t length);
class ECMA_PUBLIC_API SendableArrayBufferRef : public ObjectRef {
public:
static Local<SendableArrayBufferRef> New(const EcmaVM *vm, int32_t length);
static Local<SendableArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length,
const NativePointerCallback &deleter, void *data);
void SendableDetach(const EcmaVM *vm);
bool SendableIsDetach();
void *SendableGetBuffer();
int32_t ByteLength(const EcmaVM *vm);
void *GetBuffer();
void Detach(const EcmaVM *vm);
bool IsDetach();
};
class ECMA_PUBLIC_API DateRef : public ObjectRef {
@ -991,11 +998,14 @@ public:
uint32_t ByteOffset(const EcmaVM *vm);
uint32_t ArrayLength(const EcmaVM *vm);
Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
};
uint32_t SendableByteLength(const EcmaVM *vm);
uint32_t SendableByteOffset(const EcmaVM *vm);
uint32_t SendableArrayLength(const EcmaVM *vm);
Local<ArrayBufferRef> SendableGetArrayBuffer(const EcmaVM *vm);
class ECMA_PUBLIC_API SendableTypedArrayRef : public ObjectRef {
public:
uint32_t ByteLength(const EcmaVM *vm);
uint32_t ByteOffset(const EcmaVM *vm);
uint32_t ArrayLength(const EcmaVM *vm);
Local<SendableArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
};
class ECMA_PUBLIC_API ArrayRef : public ObjectRef {
@ -1007,6 +1017,14 @@ public:
static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index);
};
class ECMA_PUBLIC_API SendableArrayRef : public ObjectRef {
public:
static Local<SendableArrayRef> New(const EcmaVM *vm, uint32_t length = 0);
uint32_t Length(const EcmaVM *vm);
static bool SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value);
static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index);
};
class ECMA_PUBLIC_API Int8ArrayRef : public TypedArrayRef {
public:
static Local<Int8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);

View File

@ -964,7 +964,7 @@ bool JSValueRef::IsSharedArray()
bool JSValueRef::IsSharedTypedArray()
{
return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedTypedArray();
return JSNApiHelper::ToJSTaggedValue(this).IsSharedTypedArray();
}
bool JSValueRef::IsSharedSet()
@ -1394,8 +1394,7 @@ Local<BufferRef> BufferRef::New(
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSArrayBuffer> arrayBuffer =
factory->NewJSArrayBuffer(buffer, length, reinterpret_cast<ecmascript::NativePointerCallback>(deleter), data);
JSHandle<JSArrayBuffer> arrayBuffer = factory->NewJSArrayBuffer(buffer, length, deleter, data);
JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
JSHandle<JSFunction> current =
@ -2544,8 +2543,7 @@ Local<ArrayBufferRef> ArrayBufferRef::New(
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSArrayBuffer> arrayBuffer =
factory->NewJSArrayBuffer(buffer, length, reinterpret_cast<ecmascript::NativePointerCallback>(deleter), data);
JSHandle<JSArrayBuffer> arrayBuffer = factory->NewJSArrayBuffer(buffer, length, deleter, data);
return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
}
@ -2584,16 +2582,36 @@ bool ArrayBufferRef::IsDetach()
return arrayBuffer->IsDetach();
}
Local<ArrayBufferRef> ArrayBufferRef::NewSendable(const EcmaVM *vm, int32_t length)
Local<SendableArrayBufferRef> SendableArrayBufferRef::New(const EcmaVM *vm, int32_t length)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
ObjectFactory *factory = vm->GetFactory();
JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer = factory->NewJSSendableArrayBuffer(length);
return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
return JSNApiHelper::ToLocal<SendableArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
}
void ArrayBufferRef::SendableDetach(const EcmaVM *vm)
Local<SendableArrayBufferRef> SendableArrayBufferRef::New(
const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, void *data)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
ObjectFactory *factory = vm->GetFactory();
JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer =
factory->NewJSSendableArrayBuffer(buffer, length, deleter, data);
return JSNApiHelper::ToLocal<SendableArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
}
int32_t SendableArrayBufferRef::ByteLength([[maybe_unused]] const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(arrayBuffer, FATAL);
return arrayBuffer->GetArrayBufferByteLength();
}
void SendableArrayBufferRef::Detach(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
@ -2601,14 +2619,14 @@ void ArrayBufferRef::SendableDetach(const EcmaVM *vm)
arrayBuffer->Detach(thread);
}
bool ArrayBufferRef::SendableIsDetach()
bool SendableArrayBufferRef::IsDetach()
{
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false);
JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
return arrayBuffer->IsDetach();
}
void *ArrayBufferRef::SendableGetBuffer()
void *SendableArrayBufferRef::GetBuffer()
{
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
@ -2692,7 +2710,7 @@ Local<ArrayBufferRef> TypedArrayRef::GetArrayBuffer(const EcmaVM *vm)
return JSNApiHelper::ToLocal<ArrayBufferRef>(arrayBuffer);
}
uint32_t TypedArrayRef::SendableByteLength([[maybe_unused]] const EcmaVM *vm)
uint32_t SendableTypedArrayRef::ByteLength([[maybe_unused]] const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
JSHandle<ecmascript::JSSharedTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
@ -2700,7 +2718,7 @@ uint32_t TypedArrayRef::SendableByteLength([[maybe_unused]] const EcmaVM *vm)
return typedArray->GetByteLength();
}
uint32_t TypedArrayRef::SendableByteOffset([[maybe_unused]] const EcmaVM *vm)
uint32_t SendableTypedArrayRef::ByteOffset([[maybe_unused]] const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
JSHandle<ecmascript::JSSharedTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
@ -2708,7 +2726,7 @@ uint32_t TypedArrayRef::SendableByteOffset([[maybe_unused]] const EcmaVM *vm)
return typedArray->GetByteOffset();
}
uint32_t TypedArrayRef::SendableArrayLength([[maybe_unused]] const EcmaVM *vm)
uint32_t SendableTypedArrayRef::ArrayLength([[maybe_unused]] const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
JSHandle<ecmascript::JSSharedTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
@ -2716,14 +2734,15 @@ uint32_t TypedArrayRef::SendableArrayLength([[maybe_unused]] const EcmaVM *vm)
return typedArray->GetArrayLength();
}
Local<ArrayBufferRef> TypedArrayRef::SendableGetArrayBuffer(const EcmaVM *vm)
Local<SendableArrayBufferRef> SendableTypedArrayRef::GetArrayBuffer(const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(thread);
JSHandle<JSTypedArray> typeArray(JSNApiHelper::ToJSHandle(this));
JSHandle<ecmascript::JSSharedTypedArray> typeArray(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(typeArray, ERROR);
JSHandle<JSTaggedValue> arrayBuffer(thread, JSTypedArray::GetSharedOffHeapBuffer(thread, typeArray));
return JSNApiHelper::ToLocal<ArrayBufferRef>(arrayBuffer);
JSHandle<JSTaggedValue> arrayBuffer(thread,
ecmascript::JSSharedTypedArray::GetSharedOffHeapBuffer(thread, typeArray));
return JSNApiHelper::ToLocal<SendableArrayBufferRef>(arrayBuffer);
}
// ----------------------------------- FunctionRef --------------------------------------
@ -3212,6 +3231,41 @@ bool ArrayRef::SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t inde
return JSArray::FastSetPropertyByValue(thread, objectHandle, index, valueHandle);
}
// ----------------------------------- SendableArrayRef ----------------------------------------
Local<SendableArrayRef> SendableArrayRef::New(const EcmaVM *vm, uint32_t length)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSTaggedNumber arrayLen(length);
JSHandle<JSTaggedValue> array = ecmascript::JSSharedArray::ArrayCreate(thread, arrayLen);
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
return JSNApiHelper::ToLocal<SendableArrayRef>(array);
}
uint32_t SendableArrayRef::Length([[maybe_unused]] const EcmaVM *vm)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
return ecmascript::JSSharedArray::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetArrayLength();
}
Local<JSValueRef> SendableArrayRef::GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(obj);
JSHandle<JSTaggedValue> result = ecmascript::JSSharedArray::FastGetPropertyByValue(thread, object, index);
return JSNApiHelper::ToLocal<JSValueRef>(result);
}
bool SendableArrayRef::SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
JSHandle<JSTaggedValue> objectHandle = JSNApiHelper::ToJSHandle(obj);
JSHandle<JSTaggedValue> valueHandle = JSNApiHelper::ToJSHandle(value);
return ecmascript::JSSharedArray::FastSetPropertyByValue(thread, objectHandle, index, valueHandle);
}
// ---------------------------------- Error ---------------------------------------
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EXCEPTION_ERROR_NEW(name, type) \

View File

@ -321,7 +321,27 @@ JSHandle<JSSendableArrayBuffer> ObjectFactory::NewJSSendableArrayBuffer(int32_t
sendableArrayBuffer->SetArrayBufferByteLength(length);
if (length > 0) {
NewJSSendableArrayBufferData(sendableArrayBuffer, length);
sendableArrayBuffer->SetShared(true);
sendableArrayBuffer->SetShared(false);
}
return sendableArrayBuffer;
}
JSHandle<JSSendableArrayBuffer> ObjectFactory::NewJSSendableArrayBuffer(void *buffer, int32_t length,
const NativePointerCallback &deleter,
void *data)
{
JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
JSHandle<JSFunction> constructor(env->GetSBuiltininArrayBufferFunction());
JSHandle<JSSendableArrayBuffer> sendableArrayBuffer(NewJSObjectByConstructor(constructor));
length = buffer == nullptr ? 0 : length;
sendableArrayBuffer->SetArrayBufferByteLength(length);
if (length > 0) {
JSHandle<JSNativePointer> pointer = NewSJSNativePointer(buffer, deleter, data, false, length);
sendableArrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue());
sendableArrayBuffer->SetShared(false);
sendableArrayBuffer->SetWithNativeAreaAllocator(deleter == NativeAreaAllocator::FreeBufferFunc &&
data == vm_->GetNativeAreaAllocator());
}
return sendableArrayBuffer;
}

View File

@ -490,6 +490,8 @@ public:
void NewJSArrayBufferData(const JSHandle<JSArrayBuffer> &array, int32_t length);
void NewJSSendableArrayBufferData(const JSHandle<JSSendableArrayBuffer> &array, int32_t length);
JSHandle<JSSendableArrayBuffer> NewJSSendableArrayBuffer(int32_t length);
JSHandle<JSSendableArrayBuffer> NewJSSendableArrayBuffer(void *buffer, int32_t length,
const NativePointerCallback &deleter, void *data);
JSHandle<JSArrayBuffer> NewJSArrayBuffer(int32_t length);

View File

@ -39,6 +39,8 @@ public:
return static_cast<JSSharedTypedArray *>(object);
}
static JSTaggedValue GetSharedOffHeapBuffer(JSThread *thread, JSHandle<JSSharedTypedArray> typedArray);
static constexpr size_t MOD_RECORD_OFFSET = JSTypedArray::SIZE;
ACCESSORS_SYNCHRONIZED_PRIMITIVE_FIELD(ModRecord, uint32_t, MOD_RECORD_OFFSET, LAST_OFFSET)
DEFINE_ALIGN_SIZE(LAST_OFFSET);

View File

@ -17,8 +17,10 @@
panda::ecmascript::COMPILER_HELP_HEAD_MSG*;
panda::ArrayBufferRef::*;
panda::SendableArrayBufferRef::*;
panda::BufferRef::*;
panda::ArrayRef::*;
panda::SendableArrayRef::*;
panda::BigInt64ArrayRef::*;
panda::BigIntRef::*;
panda::BigUint64ArrayRef::*;
@ -50,6 +52,7 @@
panda::RegExpRef::*;
panda::SetIteratorRef::*;
panda::SetRef::*;
panda::SendableTypedArrayRef::*;
panda::SharedInt8ArrayRef::*;
panda::SharedUint8ArrayRef::*;
panda::SharedInt16ArrayRef::*;

View File

@ -152,7 +152,7 @@ template("host_moduletest_action") {
if (defined(invoker.is_merge_abc) && invoker.is_merge_abc) {
_is_merge_abc_ = true
}
_timeout_ = "200"
_timeout_ = "300"
if (defined(invoker.timeout)) {
_timeout_ = invoker.timeout
}