mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 04:00:37 +00:00
Optimize jsapi encodeInto
Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAL8WP Signed-off-by: hewei <hewei215@huawei.com> Change-Id: Ica2189d0f330f5ce6652e499a3d0506bca9013f8
This commit is contained in:
parent
dfc2b50b76
commit
1f49cf34ff
@ -435,4 +435,26 @@ HWTEST_F_L0(TypedArrayHelperTest, SortCompare)
|
||||
result = TypedArrayHelper::SortCompare(thread, callbackfnHandle, buffer, pZero, eZero);
|
||||
EXPECT_EQ(result, 1);
|
||||
}
|
||||
|
||||
HWTEST_F_L0(TypedArrayHelperTest, FastCreateTypedArray) {
|
||||
uint8_t first = static_cast<uint8_t>(DataViewType::BIGINT64);
|
||||
uint8_t last = static_cast<uint8_t>(DataViewType::UINT8_CLAMPED);
|
||||
for (uint8_t type = first; type <= last; ++type) {
|
||||
DataViewType arrayType = static_cast<DataViewType>(type);
|
||||
JSHandle<JSTaggedValue> constructorName = TypedArrayHelper::GetConstructorNameFromType(thread, arrayType);
|
||||
JSHandle<JSObject> arrayObj =
|
||||
TypedArrayHelper::FastCreateTypedArray(thread, constructorName, 0, arrayType);
|
||||
JSTypedArray *jsTypedArray = JSTypedArray::Cast(*arrayObj);
|
||||
if (arrayType == DataViewType::BIGINT64 ||
|
||||
arrayType == DataViewType::BIGUINT64) {
|
||||
EXPECT_EQ(jsTypedArray->GetContentType(), ContentType::BigInt);
|
||||
} else {
|
||||
EXPECT_EQ(jsTypedArray->GetContentType(), ContentType::Number);
|
||||
}
|
||||
EXPECT_EQ(jsTypedArray->GetTypedArrayName().GetRawData(), constructorName.GetTaggedValue().GetRawData());
|
||||
EXPECT_EQ(jsTypedArray->GetByteLength(), 0U);
|
||||
EXPECT_EQ(jsTypedArray->GetByteOffset(), 0U);
|
||||
EXPECT_EQ(jsTypedArray->GetArrayLength(), 0U);
|
||||
}
|
||||
}
|
||||
} // namespace panda::test
|
||||
|
@ -133,6 +133,56 @@ JSTaggedValue TypedArrayHelper::SharedTypedArrayConstructor(EcmaRuntimeCallInfo
|
||||
return TypedArrayHelper::CreateFromOrdinaryObject<TypedArrayKind::SHARED>(argv, obj, arrayType);
|
||||
}
|
||||
|
||||
// Fastpath for create a typedarray. Do not need to create an EcmaRuntimeCallInfo.
|
||||
JSHandle<JSObject> TypedArrayHelper::FastCreateTypedArray(JSThread *thread,
|
||||
const JSHandle<JSTaggedValue> &constructorName,
|
||||
uint32_t length,
|
||||
const DataViewType arrayType)
|
||||
{
|
||||
JSHandle<JSObject> exception(thread, JSTaggedValue::Exception());
|
||||
if (length > JSTypedArray::MAX_TYPED_ARRAY_INDEX) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "array length must less than 2^32 - 1", exception);
|
||||
}
|
||||
|
||||
// Create TypedArray
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<JSFunction> typedArrayFunc = TypedArrayHelper::GetConstructorFromType(thread, arrayType);
|
||||
JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(typedArrayFunc,
|
||||
JSHandle<JSTaggedValue>::Cast(typedArrayFunc));
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSHandle<JSObject>(thread, JSTaggedValue::Exception()));
|
||||
JSTypedArray::Cast(*obj)->SetTypedArrayName(thread, constructorName);
|
||||
|
||||
// Create ArrayBuffer
|
||||
uint32_t elementSize = TypedArrayHelper::GetSizeFromType(arrayType);
|
||||
uint32_t arrayLength = static_cast<uint32_t>(length);
|
||||
uint64_t byteLength = static_cast<uint64_t>(elementSize) * length;
|
||||
JSHandle<JSTaggedValue> data;
|
||||
|
||||
JSHandle<JSTaggedValue> constructor = thread->GetEcmaVM()->GetGlobalEnv()->GetArrayBufferFunction();
|
||||
data = JSHandle<JSTaggedValue>(thread,
|
||||
BuiltinsArrayBuffer::AllocateArrayBuffer(thread, constructor, byteLength));
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, exception);
|
||||
|
||||
// Assign ArrayBuffer to TypedArray
|
||||
JSTypedArray *jsTypedArray = JSTypedArray::Cast(*obj);
|
||||
if (arrayType == DataViewType::BIGINT64 ||
|
||||
arrayType == DataViewType::BIGUINT64) {
|
||||
jsTypedArray->SetContentType(ContentType::BigInt);
|
||||
} else {
|
||||
jsTypedArray->SetContentType(ContentType::Number);
|
||||
}
|
||||
// Set O.[[ViewedArrayBuffer]] to data.
|
||||
// Set O.[[ByteLength]] to byteLength.
|
||||
// Set O.[[ByteOffset]] to 0.
|
||||
// Set O.[[ArrayLength]] to length.
|
||||
jsTypedArray->SetViewedArrayBufferOrByteArray(thread, data);
|
||||
jsTypedArray->SetByteLength(byteLength);
|
||||
jsTypedArray->SetByteOffset(0);
|
||||
jsTypedArray->SetArrayLength(arrayLength);
|
||||
// Return O.
|
||||
return obj;
|
||||
}
|
||||
|
||||
template<>
|
||||
JSHandle<JSObject> TypedArrayHelper::AllocateTypedArrayBuffer<TypedArrayKind::NON_SHARED>(
|
||||
JSThread *thread, const JSHandle<JSObject> &obj, uint64_t length, const DataViewType arrayType)
|
||||
|
@ -45,6 +45,10 @@ public:
|
||||
static JSTaggedValue SharedTypedArrayConstructor(EcmaRuntimeCallInfo *argv,
|
||||
const JSHandle<JSTaggedValue> &constructorName,
|
||||
const DataViewType arrayType);
|
||||
static JSHandle<JSObject> FastCreateTypedArray(JSThread *thread,
|
||||
const JSHandle<JSTaggedValue> &constructorName,
|
||||
uint32_t length,
|
||||
const DataViewType arrayType);
|
||||
static JSHandle<JSObject> AllocateTypedArray(JSThread *thread,
|
||||
const JSHandle<JSTaggedValue> &constructorName,
|
||||
const JSHandle<JSTaggedValue> &newTarget,
|
||||
|
@ -63,6 +63,7 @@ class MapIteratorRef;
|
||||
class SendableMapIteratorRef;
|
||||
class BooleanRef;
|
||||
class NativePointerRef;
|
||||
class TypedArrayRef;
|
||||
class JsiRuntimeCallInfo;
|
||||
class RuntimeOption;
|
||||
namespace test {
|
||||
@ -868,6 +869,7 @@ public:
|
||||
int WriteUtf16(const EcmaVM *vm, char16_t *buffer, int length);
|
||||
int WriteLatin1(const EcmaVM *vm, char *buffer, int length);
|
||||
static Local<StringRef> GetNapiWrapperString(const EcmaVM *vm);
|
||||
Local<TypedArrayRef> EncodeIntoUint8Array(const EcmaVM *vm);
|
||||
};
|
||||
|
||||
class ECMA_PUBLIC_API PromiseRejectInfo {
|
||||
|
@ -47,6 +47,7 @@ namespace panda {
|
||||
using ecmascript::AccessorData;
|
||||
using ecmascript::BigInt;
|
||||
using ecmascript::ByteArray;
|
||||
using ecmascript::DataViewType;
|
||||
using ecmascript::ECMAObject;
|
||||
using ecmascript::EcmaRuntimeCallInfo;
|
||||
using ecmascript::EcmaString;
|
||||
@ -2168,6 +2169,30 @@ Local<StringRef> StringRef::GetNapiWrapperString(const EcmaVM *vm)
|
||||
return JSNApiHelper::ToLocal<StringRef>(napiWapperString);
|
||||
}
|
||||
|
||||
Local<TypedArrayRef> StringRef::EncodeIntoUint8Array(const EcmaVM *vm)
|
||||
{
|
||||
CROSS_THREAD_CHECK(vm);
|
||||
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
|
||||
JSHandle<JSTaggedValue> string = JSNApiHelper::ToJSHandle(this);
|
||||
uint32_t length = this->Utf8Length(vm, true);
|
||||
// 1 because Utf8Length adds 1 for the return value
|
||||
if (length <= 1) {
|
||||
return Undefined(vm);
|
||||
}
|
||||
|
||||
JSHandle<JSObject> obj =
|
||||
TypedArrayHelper::FastCreateTypedArray(thread, thread->GlobalConstants()->GetHandledUint8ArrayString(),
|
||||
length - 1, DataViewType::UINT8);
|
||||
JSHandle<JSObject> arrayBuffer(thread, JSTypedArray::Cast(*obj)->GetViewedArrayBufferOrByteArray());
|
||||
JSTaggedValue bufferData = JSHandle<JSArrayBuffer>::Cast(arrayBuffer)->GetArrayBufferData();
|
||||
void *buffer = JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
|
||||
|
||||
JSHandle<EcmaString> stringHandle = JSHandle<EcmaString>::Cast(string);
|
||||
EcmaStringAccessor(stringHandle).WriteToFlatUtf8(reinterpret_cast<uint8_t*>(buffer), length - 1, true);
|
||||
JSHandle<JSTaggedValue> typedArrayTag = JSHandle<JSTaggedValue>::Cast(obj);
|
||||
return JSNApiHelper::ToLocal<TypedArrayRef>(typedArrayTag);
|
||||
}
|
||||
|
||||
// ---------------------------------- PromiseRejectInfo ---------------------------------
|
||||
PromiseRejectInfo::PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason,
|
||||
PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data)
|
||||
|
@ -381,6 +381,30 @@ HWTEST_F_L0(JSNApiTests, StringUtf8_003)
|
||||
EXPECT_EQ(buffer2[2], 'b');
|
||||
}
|
||||
|
||||
HWTEST_F_L0(JSNApiTests, StringEncodeIntoUint8_001) {
|
||||
LocalScope scope(vm_);
|
||||
std::string test = "";
|
||||
|
||||
Local<StringRef> testString1 =
|
||||
StringRef::NewFromUtf8(vm_, test.c_str(), test.length());
|
||||
Local<TypedArrayRef> typedArray = testString1->EncodeIntoUint8Array(vm_);
|
||||
EXPECT_TRUE(typedArray->IsUndefined());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(JSNApiTests, StringEncodeIntoUint8_002) {
|
||||
LocalScope scope(vm_);
|
||||
std::string test = "abc123";
|
||||
char excepted[7] = {0x61, 0x62, 0x63, 0x31, 0x32, 0x33, 0};
|
||||
|
||||
Local<StringRef> testString1 =
|
||||
StringRef::NewFromUtf8(vm_, test.c_str(), test.length());
|
||||
Local<TypedArrayRef> typedArray = testString1->EncodeIntoUint8Array(vm_);
|
||||
|
||||
char *res = reinterpret_cast<char *>(typedArray->GetArrayBuffer(vm_)->GetBuffer(vm_));
|
||||
|
||||
ASSERT_STREQ(res, excepted);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: ffi_interface_api_007
|
||||
* @tc.name: StringLatin1_001
|
||||
|
Loading…
Reference in New Issue
Block a user