mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
!788 Add typedArray and array extensions
Merge pull request !788 from 王犇/master
This commit is contained in:
commit
c5ac3e084f
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -141,4 +141,97 @@ double ArrayHelper::GetArrayLength(JSThread *thread, const JSHandle<JSTaggedValu
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, 0);
|
||||
return len.GetNumber();
|
||||
}
|
||||
|
||||
JSTaggedValue ArrayHelper::FlattenIntoArray(JSThread *thread, const JSHandle<JSObject> &newArrayHandle,
|
||||
const JSHandle<JSTaggedValue> &thisObjVal, const FlattenArgs &args,
|
||||
const JSHandle<JSTaggedValue> &mapperFunctionHandle,
|
||||
const JSHandle<JSTaggedValue> &thisArg)
|
||||
{
|
||||
// 1. Assert: Type(target) is Object.
|
||||
// 2. Assert: Type(source) is Object.
|
||||
// 3. Assert: If mapperFunction is present, then ! IsCallable(mapperFunction) is true,
|
||||
// thisArg is present, and depth is 1.
|
||||
ASSERT(mapperFunctionHandle->IsUndefined() || mapperFunctionHandle->IsCallable() ||
|
||||
(!thisArg->IsUndefined() && args.depth == 1));
|
||||
InternalCallParams *arguments = thread->GetInternalCallParams();
|
||||
// 4. Let targetIndex be start.
|
||||
// 5. Let sourceIndex be +0!.
|
||||
FlattenArgs tempArgs;
|
||||
tempArgs.start = args.start;
|
||||
double sourceIndex = 0.0;
|
||||
JSMutableHandle<JSTaggedValue> p(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> element(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> targetIndexHandle(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> sourceIndexHandle(thread, JSTaggedValue::Undefined());
|
||||
JSHandle<EcmaString> sourceIndexStr;
|
||||
// 6. Repeat, while (sourceIndex) < sourceLen,
|
||||
// a. Let P be ! ToString(sourceIndex).
|
||||
// b. Let exists be ? HasProperty(source, P).
|
||||
// c. If exists is true, then
|
||||
// i. Let element be ? Get(source, P).
|
||||
// ii. If mapperFunction is present, then
|
||||
// 1. Set element to ? Call(mapperFunction, thisArg, « element, sourceIndex, source »).
|
||||
// iii. Let shouldFlatten be false.
|
||||
// iv. If depth > 0, then
|
||||
// 1. Set shouldFlatten to ? IsArray(element).
|
||||
// v. If shouldFlatten is true, then
|
||||
// 1. If depth is +∞, let newDepth be +∞.
|
||||
// 2. Else, let newDepth be depth - 1.
|
||||
// 3. Let elementLen be ? LengthOfArrayLike(element).
|
||||
// 4. Set targetIndex to ? FlattenIntoArray(target, element, elementLen, targetIndex, newDepth).
|
||||
// vi. Else,
|
||||
// 1. If targetIndex ≥ 2^53 - 1, throw a TypeError exception.
|
||||
// 2. Perform ? CreateDataPropertyOrThrow(target, ! ToString(!(targetIndex)), element).
|
||||
// 3. Set targetIndex to targetIndex + 1.
|
||||
// d. Set sourceIndex to sourceIndex + 1!.
|
||||
while (sourceIndex < args.sourceLen) {
|
||||
sourceIndexHandle.Update(JSTaggedValue(sourceIndex));
|
||||
sourceIndexStr = JSTaggedValue::ToString(thread, sourceIndexHandle);
|
||||
p.Update(sourceIndexStr.GetTaggedValue());
|
||||
bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, p);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
if (exists) {
|
||||
element.Update(JSArray::FastGetPropertyByValue(thread, thisObjVal, p).GetTaggedValue());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
if (!mapperFunctionHandle->IsUndefined()) {
|
||||
arguments->MakeArgv(element, p, thisObjVal);
|
||||
JSTaggedValue obj = JSFunction::Call(thread, mapperFunctionHandle, thisArg,
|
||||
3, arguments->GetArgv()); // 3: three args
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
element.Update(obj);
|
||||
}
|
||||
bool shouldFlatten = false;
|
||||
if (args.depth > 0) {
|
||||
shouldFlatten = element->IsArray(thread);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
}
|
||||
if (shouldFlatten) {
|
||||
tempArgs.depth = args.depth > POSITIVE_INFINITY ? POSITIVE_INFINITY : args.depth - 1;
|
||||
tempArgs.sourceLen = ArrayHelper::GetLength(thread, element);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSTaggedValue TargetIndexObj = FlattenIntoArray(thread, newArrayHandle, element, tempArgs,
|
||||
thread->GlobalConstants()->GetHandledUndefined(),
|
||||
thread->GlobalConstants()->GetHandledUndefined());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
targetIndexHandle.Update(TargetIndexObj);
|
||||
JSTaggedNumber targetIndexTemp = JSTaggedValue::ToNumber(thread, targetIndexHandle);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
tempArgs.start = base::NumberHelper::TruncateDouble(targetIndexTemp.GetNumber());
|
||||
} else {
|
||||
if (tempArgs.start > base::MAX_SAFE_INTEGER) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
|
||||
}
|
||||
sourceIndexHandle.Update(JSTaggedValue(tempArgs.start));
|
||||
sourceIndexStr = JSTaggedValue::ToString(thread, sourceIndexHandle);
|
||||
targetIndexHandle.Update(sourceIndexStr.GetTaggedValue());
|
||||
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, targetIndexHandle, element);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
tempArgs.start++;
|
||||
}
|
||||
}
|
||||
sourceIndex++;
|
||||
}
|
||||
// 7. Return targetIndex.
|
||||
return BuiltinsBase::GetTaggedDouble(tempArgs.start);
|
||||
}
|
||||
} // namespace panda::ecmascript::base
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -22,6 +22,11 @@
|
||||
#include "ecmascript/base/builtins_base.h"
|
||||
|
||||
namespace panda::ecmascript::base {
|
||||
struct FlattenArgs {
|
||||
double sourceLen = 0;
|
||||
double start = 0;
|
||||
double depth = 0;
|
||||
};
|
||||
class ArrayHelper {
|
||||
public:
|
||||
static bool IsConcatSpreadable(JSThread *thread, const JSHandle<JSTaggedValue> &obj);
|
||||
@ -29,6 +34,10 @@ public:
|
||||
const JSHandle<JSTaggedValue> &valueX, const JSHandle<JSTaggedValue> &valueY);
|
||||
static double GetLength(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle);
|
||||
static double GetArrayLength(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle);
|
||||
static JSTaggedValue FlattenIntoArray(JSThread *thread, const JSHandle<JSObject> &newArrayHandle,
|
||||
const JSHandle<JSTaggedValue> &thisObjVal, const FlattenArgs &args,
|
||||
const JSHandle<JSTaggedValue> &mapperFunctionHandle,
|
||||
const JSHandle<JSTaggedValue> &thisArg);
|
||||
};
|
||||
} // namespace panda::ecmascript::base
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -54,8 +54,12 @@ DataViewType TypedArrayHelper::GetType(const JSHandle<JSObject> &obj)
|
||||
return DataViewType::UINT32;
|
||||
case JSType::JS_FLOAT32_ARRAY:
|
||||
return DataViewType::FLOAT32;
|
||||
default:
|
||||
case JSType::JS_FLOAT64_ARRAY:
|
||||
return DataViewType::FLOAT64;
|
||||
case JSType::JS_BIGINT64_ARRAY:
|
||||
return DataViewType::BIGINT64;
|
||||
default:
|
||||
return DataViewType::BIGUINT64;
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +110,13 @@ DataViewType TypedArrayHelper::GetTypeFromName(JSThread *thread, const JSHandle<
|
||||
if (JSTaggedValue::SameValue(typeName, globalConst->GetHandledFloat32ArrayString())) {
|
||||
return DataViewType::FLOAT32;
|
||||
}
|
||||
return DataViewType::FLOAT64;
|
||||
if (JSTaggedValue::SameValue(typeName, globalConst->GetHandledFloat64ArrayString())) {
|
||||
return DataViewType::FLOAT64;
|
||||
}
|
||||
if (JSTaggedValue::SameValue(typeName, globalConst->GetHandledBigInt64ArrayString())) {
|
||||
return DataViewType::BIGINT64;
|
||||
}
|
||||
return DataViewType::BIGUINT64;
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> TypedArrayHelper::GetConstructor(JSThread *thread, const JSHandle<JSTaggedValue> &obj)
|
||||
@ -130,8 +140,12 @@ JSHandle<JSTaggedValue> TypedArrayHelper::GetConstructor(JSThread *thread, const
|
||||
return env->GetUint32ArrayFunction();
|
||||
case JSType::JS_FLOAT32_ARRAY:
|
||||
return env->GetFloat32ArrayFunction();
|
||||
default:
|
||||
case JSType::JS_FLOAT64_ARRAY:
|
||||
return env->GetFloat64ArrayFunction();
|
||||
case JSType::JS_BIGINT64_ARRAY:
|
||||
return env->GetBigInt64ArrayFunction();
|
||||
default:
|
||||
return env->GetBigUint64ArrayFunction();
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,7 +177,13 @@ JSHandle<JSFunction> TypedArrayHelper::GetConstructorFromName(JSThread *thread,
|
||||
if (JSTaggedValue::SameValue(typeName, globalConst->GetHandledFloat32ArrayString())) {
|
||||
return JSHandle<JSFunction>(env->GetFloat32ArrayFunction());
|
||||
}
|
||||
return JSHandle<JSFunction>(env->GetFloat64ArrayFunction());
|
||||
if (JSTaggedValue::SameValue(typeName, globalConst->GetHandledFloat64ArrayString())) {
|
||||
return JSHandle<JSFunction>(env->GetFloat64ArrayFunction());
|
||||
}
|
||||
if (JSTaggedValue::SameValue(typeName, globalConst->GetHandledBigInt64ArrayString())) {
|
||||
return JSHandle<JSFunction>(env->GetBigInt64ArrayFunction());
|
||||
}
|
||||
return JSHandle<JSFunction>(env->GetBigUint64ArrayFunction());
|
||||
}
|
||||
|
||||
int32_t TypedArrayHelper::GetSizeFromName(JSThread *thread, const JSHandle<JSTaggedValue> &typeName)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -204,12 +204,13 @@ JSTaggedValue TypedArrayHelper::CreateFromTypedArray(EcmaRuntimeCallInfo *argv,
|
||||
// 16. If IsSharedArrayBuffer(srcData) is false, then
|
||||
// a. Let bufferConstructor be ? SpeciesConstructor(srcData, %ArrayBuffer%).
|
||||
|
||||
JSTaggedValue data;
|
||||
JSHandle<JSTaggedValue> data;
|
||||
// 18. If elementType is the same as srcType, then
|
||||
// a. Let data be ? CloneArrayBuffer(srcData, srcByteOffset, byteLength, bufferConstructor).
|
||||
if (elementType == srcType) {
|
||||
data =
|
||||
JSTaggedValue tmp =
|
||||
BuiltinsArrayBuffer::CloneArrayBuffer(thread, srcData, srcByteOffset, globalConst->GetHandledUndefined());
|
||||
data = JSHandle<JSTaggedValue>(thread, tmp);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
} else {
|
||||
// 19. Else,
|
||||
@ -217,12 +218,19 @@ JSTaggedValue TypedArrayHelper::CreateFromTypedArray(EcmaRuntimeCallInfo *argv,
|
||||
JSHandle<JSTaggedValue> bufferConstructor =
|
||||
JSObject::SpeciesConstructor(thread, JSHandle<JSObject>(srcData), env->GetArrayBufferFunction());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
data = BuiltinsArrayBuffer::AllocateArrayBuffer(thread, bufferConstructor, byteLength);
|
||||
JSTaggedValue tmp = BuiltinsArrayBuffer::AllocateArrayBuffer(thread, bufferConstructor, byteLength);
|
||||
data = JSHandle<JSTaggedValue>(thread, tmp);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// b. If IsDetachedBuffer(srcData) is true, throw a TypeError exception.
|
||||
if (BuiltinsArrayBuffer::IsDetachedBuffer(srcData.GetTaggedValue())) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "The srcData is detached buffer.", JSTaggedValue::Exception());
|
||||
}
|
||||
ContentType objContentType = JSHandle<JSTypedArray>::Cast(obj)->GetContentType();
|
||||
ContentType srcArrayContentType = JSHandle<JSTypedArray>::Cast(srcArray)->GetContentType();
|
||||
if (srcArrayContentType != objContentType) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "srcArrayContentType is not equal objContentType.",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
// d. Let srcByteIndex be srcByteOffset.
|
||||
// e. Let targetByteIndex be 0.
|
||||
int32_t srcByteIndex = srcByteOffset;
|
||||
@ -233,11 +241,12 @@ JSTaggedValue TypedArrayHelper::CreateFromTypedArray(EcmaRuntimeCallInfo *argv,
|
||||
for (int32_t count = elementLength; count > 0; count--) {
|
||||
// i. Let value be GetValueFromBuffer(srcData, srcByteIndex, srcType, true, Unordered).
|
||||
JSTaggedValue taggedData =
|
||||
BuiltinsArrayBuffer::GetValueFromBuffer(srcData.GetTaggedValue(), srcByteIndex, srcType, true);
|
||||
BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcData.GetTaggedValue(), srcByteIndex, srcType, true);
|
||||
value.Update(taggedData);
|
||||
JSTaggedNumber numVal = JSTaggedValue::ToNumber(thread, value);
|
||||
// ii. Perform SetValueInBuffer(data, targetByteIndex, elementType, value, true, Unordered).
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(data, targetByteIndex, elementType, numVal, true);
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(thread, data.GetTaggedValue(),
|
||||
targetByteIndex, elementType, value, true);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// iii. Set srcByteIndex to srcByteIndex + srcElementSize.
|
||||
// iv. Set targetByteIndex to targetByteIndex + elementSize.
|
||||
// v. Set count to count - 1.
|
||||
@ -249,10 +258,11 @@ JSTaggedValue TypedArrayHelper::CreateFromTypedArray(EcmaRuntimeCallInfo *argv,
|
||||
// 20. Set O’s [[ByteLength]] internal slot to byteLength.
|
||||
// 21. Set O’s [[ByteOffset]] internal slot to 0.
|
||||
// 22. Set O’s [[ArrayLength]] internal slot to elementLength.
|
||||
JSTypedArray::Cast(*obj)->SetViewedArrayBuffer(thread, data);
|
||||
JSTypedArray::Cast(*obj)->SetByteLength(thread, JSTaggedValue(byteLength));
|
||||
JSTypedArray::Cast(*obj)->SetByteOffset(thread, JSTaggedValue(0));
|
||||
JSTypedArray::Cast(*obj)->SetArrayLength(thread, JSTaggedValue(elementLength));
|
||||
JSTypedArray *jsTypedArray = JSTypedArray::Cast(*obj);
|
||||
jsTypedArray->SetViewedArrayBuffer(thread, data);
|
||||
jsTypedArray->SetByteLength(thread, JSTaggedValue(byteLength));
|
||||
jsTypedArray->SetByteOffset(thread, JSTaggedValue(0));
|
||||
jsTypedArray->SetArrayLength(thread, JSTaggedValue(elementLength));
|
||||
// 23. Return O.
|
||||
return obj.GetTaggedValue();
|
||||
}
|
||||
@ -319,10 +329,11 @@ JSTaggedValue TypedArrayHelper::CreateFromArrayBuffer(EcmaRuntimeCallInfo *argv,
|
||||
// 14. Set O.[[ByteLength]] to newByteLength.
|
||||
// 15. Set O.[[ByteOffset]] to offset.
|
||||
// 16. Set O.[[ArrayLength]] to newByteLength / elementSize.
|
||||
JSTypedArray::Cast(*obj)->SetViewedArrayBuffer(thread, buffer);
|
||||
JSTypedArray::Cast(*obj)->SetByteLength(thread, JSTaggedValue(newByteLength));
|
||||
JSTypedArray::Cast(*obj)->SetByteOffset(thread, JSTaggedValue(offset));
|
||||
JSTypedArray::Cast(*obj)->SetArrayLength(thread, JSTaggedValue(newByteLength / elementSize));
|
||||
JSTypedArray *jsTypedArray = JSTypedArray::Cast(*obj);
|
||||
jsTypedArray->SetViewedArrayBuffer(thread, buffer);
|
||||
jsTypedArray->SetByteLength(thread, JSTaggedValue(newByteLength));
|
||||
jsTypedArray->SetByteOffset(thread, JSTaggedValue(offset));
|
||||
jsTypedArray->SetArrayLength(thread, JSTaggedValue(newByteLength / elementSize));
|
||||
// 17. Return O.
|
||||
return obj.GetTaggedValue();
|
||||
}
|
||||
@ -341,14 +352,24 @@ JSHandle<JSObject> TypedArrayHelper::AllocateTypedArray(ObjectFactory *factory,
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSHandle<JSObject>(thread, JSTaggedValue::Exception()));
|
||||
// 3. Assert: obj.[[ViewedArrayBuffer]] is undefined.
|
||||
// 4. Set obj.[[TypedArrayName]] to constructorName.
|
||||
|
||||
// 5. If constructorName is "BigInt64Array" or "BigUint64Array", set obj.[[ContentType]] to BigInt.
|
||||
// 6. Otherwise, set obj.[[ContentType]] to Number.
|
||||
JSTypedArray *jsTypedArray = JSTypedArray::Cast(*obj);
|
||||
if (JSTaggedValue::SameValue(constructorName, thread->GlobalConstants()->GetHandledBigInt64ArrayString()) ||
|
||||
JSTaggedValue::SameValue(constructorName, thread->GlobalConstants()->GetHandledBigUint64ArrayString())) {
|
||||
jsTypedArray->SetContentType(ContentType::BigInt);
|
||||
} else {
|
||||
jsTypedArray->SetContentType(ContentType::Number);
|
||||
}
|
||||
// 7. If length is not present, then
|
||||
// a. Set obj.[[ByteLength]] to 0.
|
||||
// b. Set obj.[[ByteOffset]] to 0.
|
||||
// c. Set obj.[[ArrayLength]] to 0.
|
||||
JSTypedArray::Cast(*obj)->SetTypedArrayName(thread, constructorName);
|
||||
JSTypedArray::Cast(*obj)->SetByteLength(thread, JSTaggedValue(0));
|
||||
JSTypedArray::Cast(*obj)->SetByteOffset(thread, JSTaggedValue(0));
|
||||
JSTypedArray::Cast(*obj)->SetArrayLength(thread, JSTaggedValue(0));
|
||||
jsTypedArray->SetTypedArrayName(thread, constructorName);
|
||||
jsTypedArray->SetByteLength(thread, JSTaggedValue(0));
|
||||
jsTypedArray->SetByteOffset(thread, JSTaggedValue(0));
|
||||
jsTypedArray->SetArrayLength(thread, JSTaggedValue(0));
|
||||
// 9. Return obj.
|
||||
return obj;
|
||||
} // namespace panda::ecmascript::base
|
||||
@ -401,14 +422,21 @@ JSHandle<JSObject> TypedArrayHelper::AllocateTypedArrayBuffer(JSThread *thread,
|
||||
JSHandle<JSTaggedValue> constructor = env->GetArrayBufferFunction();
|
||||
JSTaggedValue data = BuiltinsArrayBuffer::AllocateArrayBuffer(thread, constructor, byteLength);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, exception);
|
||||
JSTypedArray *jsTypedArray = JSTypedArray::Cast(*obj);
|
||||
if (JSTaggedValue::SameValue(constructorName, thread->GlobalConstants()->GetHandledBigInt64ArrayString()) ||
|
||||
JSTaggedValue::SameValue(constructorName, thread->GlobalConstants()->GetHandledBigUint64ArrayString())) {
|
||||
jsTypedArray->SetContentType(ContentType::BigInt);
|
||||
} else {
|
||||
jsTypedArray->SetContentType(ContentType::Number);
|
||||
}
|
||||
// 8. Set O.[[ViewedArrayBuffer]] to data.
|
||||
// 9. Set O.[[ByteLength]] to byteLength.
|
||||
// 10. Set O.[[ByteOffset]] to 0.
|
||||
// 11. Set O.[[ArrayLength]] to length.
|
||||
JSTypedArray::Cast(*obj)->SetViewedArrayBuffer(thread, data);
|
||||
JSTypedArray::Cast(*obj)->SetByteLength(thread, JSTaggedValue(byteLength));
|
||||
JSTypedArray::Cast(*obj)->SetByteOffset(thread, JSTaggedValue(0));
|
||||
JSTypedArray::Cast(*obj)->SetArrayLength(thread, JSTaggedValue(length));
|
||||
jsTypedArray->SetViewedArrayBuffer(thread, data);
|
||||
jsTypedArray->SetByteLength(thread, JSTaggedValue(byteLength));
|
||||
jsTypedArray->SetByteOffset(thread, JSTaggedValue(0));
|
||||
jsTypedArray->SetArrayLength(thread, JSTaggedValue(length));
|
||||
// 12. Return O.
|
||||
return obj;
|
||||
}
|
||||
@ -425,7 +453,16 @@ JSHandle<JSObject> TypedArrayHelper::TypedArraySpeciesCreate(JSThread *thread, c
|
||||
JSHandle<JSTaggedValue> thisConstructor = JSObject::SpeciesConstructor(thread, obj, defaultConstructor);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSHandle<JSObject>(thread, JSTaggedValue::Exception()));
|
||||
// 4. Let result be ? TypedArrayCreate(constructor, argumentList).
|
||||
return TypedArrayHelper::TypedArrayCreate(thread, thisConstructor, argc, argv);
|
||||
JSHandle<JSObject> result = TypedArrayHelper::TypedArrayCreate(thread, thisConstructor, argc, argv);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSHandle<JSObject>(thread, JSTaggedValue::Exception()));
|
||||
// 5. If result.[[ContentType]] ≠ exemplar.[[ContentType]], throw a TypeError exception.
|
||||
ContentType objContentType = JSHandle<JSTypedArray>::Cast(obj)->GetContentType();
|
||||
ContentType resultContentType = JSHandle<JSTypedArray>::Cast(result)->GetContentType();
|
||||
if (objContentType != resultContentType) {
|
||||
JSHandle<JSObject> exception(thread, JSTaggedValue::Exception());
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "resultContentType is not equal objContentType.", exception);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// es11 22.2.4.6 TypedArrayCreate ( constructor, argumentList )
|
||||
@ -482,8 +519,8 @@ int32_t TypedArrayHelper::SortCompare(JSThread *thread, const JSHandle<JSTaggedV
|
||||
const JSHandle<JSTaggedValue> &secondValue)
|
||||
{
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
// 1. Assert: Both Type(x) and Type(y) is Number.
|
||||
ASSERT(firstValue->IsNumber() && secondValue->IsNumber());
|
||||
// 1. Assert: Both Type(x) and Type(y) are Number or both are BigInt.
|
||||
ASSERT((firstValue->IsNumber() && secondValue->IsNumber()) || (firstValue->IsBigInt() && secondValue->IsBigInt()));
|
||||
// 2. If the argument comparefn is not undefined, then
|
||||
// a. Let v be Call(comparefn, undefined, «x, y»).
|
||||
// b. ReturnIfAbrupt(v).
|
||||
@ -509,41 +546,51 @@ int32_t TypedArrayHelper::SortCompare(JSThread *thread, const JSHandle<JSTaggedV
|
||||
}
|
||||
return value;
|
||||
}
|
||||
// 3. If x and y are both NaN, return +0.
|
||||
if (NumberHelper::IsNaN(firstValue.GetTaggedValue())) {
|
||||
if (NumberHelper::IsNaN(secondValue.GetTaggedValue())) {
|
||||
return +0;
|
||||
if (firstValue->IsNumber()) {
|
||||
// 3. If x and y are both NaN, return +0.
|
||||
if (NumberHelper::IsNaN(firstValue.GetTaggedValue())) {
|
||||
if (NumberHelper::IsNaN(secondValue.GetTaggedValue())) {
|
||||
return +0;
|
||||
}
|
||||
// 4. If x is NaN, return 1.
|
||||
return 1;
|
||||
}
|
||||
// 5. If y is NaN, return -1.
|
||||
if (NumberHelper::IsNaN(secondValue.GetTaggedValue())) {
|
||||
return -1;
|
||||
}
|
||||
ComparisonResult compareResult = JSTaggedValue::Compare(thread, firstValue, secondValue);
|
||||
// 6. If x < y, return -1.
|
||||
// 7. If x > y, return 1.
|
||||
// 8. If x is -0 and y is +0, return -1.
|
||||
// 9. If x is +0 and y is -0, return 1.
|
||||
// 10. Return +0.
|
||||
if (compareResult == ComparisonResult::LESS) {
|
||||
return -1;
|
||||
}
|
||||
if (compareResult == ComparisonResult::GREAT) {
|
||||
return 1;
|
||||
}
|
||||
JSTaggedNumber xNumber = JSTaggedValue::ToNumber(thread, firstValue);
|
||||
JSTaggedNumber yNumber = JSTaggedValue::ToNumber(thread, secondValue);
|
||||
double eZeroTemp = -0.0;
|
||||
auto eZero = JSTaggedNumber(eZeroTemp);
|
||||
double pZeroTemp = +0.0;
|
||||
auto pZero = JSTaggedNumber(pZeroTemp);
|
||||
if (JSTaggedNumber::SameValue(xNumber, eZero) && JSTaggedNumber::SameValue(yNumber, pZero)) {
|
||||
return -1;
|
||||
}
|
||||
if (JSTaggedNumber::SameValue(xNumber, pZero) && JSTaggedNumber::SameValue(yNumber, eZero)) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
ComparisonResult compareResult = JSTaggedValue::Compare(thread, firstValue, secondValue);
|
||||
if (compareResult == ComparisonResult::LESS) {
|
||||
return -1;
|
||||
}
|
||||
if (compareResult == ComparisonResult::GREAT) {
|
||||
return 1;
|
||||
}
|
||||
// 4. If x is NaN, return 1.
|
||||
return 1;
|
||||
}
|
||||
// 5. If y is NaN, return -1.
|
||||
if (NumberHelper::IsNaN(secondValue.GetTaggedValue())) {
|
||||
return -1;
|
||||
}
|
||||
ComparisonResult compareResult = JSTaggedValue::Compare(thread, firstValue, secondValue);
|
||||
// 6. If x < y, return -1.
|
||||
// 7. If x > y, return 1.
|
||||
// 8. If x is -0 and y is +0, return -1.
|
||||
// 9. If x is +0 and y is -0, return 1.
|
||||
// 10. Return +0.
|
||||
if (compareResult == ComparisonResult::LESS) {
|
||||
return -1;
|
||||
}
|
||||
if (compareResult == ComparisonResult::GREAT) {
|
||||
return 1;
|
||||
}
|
||||
JSTaggedNumber xNumber = JSTaggedValue::ToNumber(thread, firstValue);
|
||||
JSTaggedNumber yNumber = JSTaggedValue::ToNumber(thread, secondValue);
|
||||
double eZeroTemp = -0.0;
|
||||
auto eZero = JSTaggedNumber(eZeroTemp);
|
||||
double pZeroTemp = +0.0;
|
||||
auto pZero = JSTaggedNumber(pZeroTemp);
|
||||
if (JSTaggedNumber::SameValue(xNumber, eZero) && JSTaggedNumber::SameValue(yNumber, pZero)) {
|
||||
return -1;
|
||||
}
|
||||
if (JSTaggedNumber::SameValue(xNumber, pZero) && JSTaggedNumber::SameValue(yNumber, eZero)) {
|
||||
return 1;
|
||||
}
|
||||
return +0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -23,7 +23,6 @@
|
||||
|
||||
namespace panda::ecmascript::base {
|
||||
enum ElementSize : uint8_t { ONE = 1, TWO = 2, FOUR = 4, EIGHT = 8 };
|
||||
|
||||
class TypedArrayHelper {
|
||||
public:
|
||||
static JSTaggedValue TypedArrayConstructor(EcmaRuntimeCallInfo *argv,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -1711,6 +1711,9 @@ void Builtins::InitializeArray(const JSHandle<GlobalEnv> &env, const JSHandle<JS
|
||||
FunctionLength::ZERO);
|
||||
SetFunction(env, arrFuncPrototype, "unshift", BuiltinsArray::Unshift, FunctionLength::ONE);
|
||||
SetFunction(env, arrFuncPrototype, "values", BuiltinsArray::Values, FunctionLength::ZERO);
|
||||
SetFunction(env, arrFuncPrototype, "includes", BuiltinsArray::Includes, FunctionLength::ONE);
|
||||
SetFunction(env, arrFuncPrototype, "flat", BuiltinsArray::Flat, FunctionLength::ZERO);
|
||||
SetFunction(env, arrFuncPrototype, "flatMap", BuiltinsArray::FlatMap, FunctionLength::ONE);
|
||||
|
||||
// %ArrayPrototype% [ @@iterator ]
|
||||
JSHandle<JSTaggedValue> values(factory_->NewFromCanBeCompressString("values"));
|
||||
@ -1795,6 +1798,7 @@ void Builtins::InitializeTypedArray(const JSHandle<GlobalEnv> &env, const JSHand
|
||||
SetFunction(env, typedArrFuncPrototype, thread_->GlobalConstants()->GetHandledToLocaleStringString(),
|
||||
BuiltinsTypedArray::ToLocaleString, FunctionLength::ZERO);
|
||||
SetFunction(env, typedArrFuncPrototype, "values", BuiltinsTypedArray::Values, FunctionLength::ZERO);
|
||||
SetFunction(env, typedArrFuncPrototype, "includes", BuiltinsTypedArray::Includes, FunctionLength::ONE);
|
||||
|
||||
JSHandle<JSTaggedValue> bufferGetter =
|
||||
CreateGetter(env, BuiltinsTypedArray::GetBuffer, "buffer", FunctionLength::ZERO);
|
||||
@ -1867,6 +1871,8 @@ void Builtins::InitializeTypedArray(const JSHandle<GlobalEnv> &env, const JSHand
|
||||
InitializeUint32Array(env, typedArrFuncInstanceDynclass);
|
||||
InitializeFloat32Array(env, typedArrFuncInstanceDynclass);
|
||||
InitializeFloat64Array(env, typedArrFuncInstanceDynclass);
|
||||
InitializeBigInt64Array(env, typedArrFuncInstanceDynclass);
|
||||
InitializeBigUint64Array(env, typedArrFuncInstanceDynclass);
|
||||
}
|
||||
|
||||
void Builtins::InitializeInt8Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncDynclass) const
|
||||
@ -2088,6 +2094,54 @@ void Builtins::InitializeFloat64Array(const JSHandle<GlobalEnv> &env, const JSHa
|
||||
env->SetFloat64ArrayFunction(thread_, float64ArrayFunction);
|
||||
}
|
||||
|
||||
void Builtins::InitializeBigInt64Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncDynclass) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
// BigInt64Array.prototype
|
||||
JSHandle<JSObject> bigInt64ArrFuncPrototype = factory_->NewJSObject(objFuncDynclass);
|
||||
JSHandle<JSTaggedValue> bigInt64ArrFuncPrototypeValue(bigInt64ArrFuncPrototype);
|
||||
|
||||
// BigInt64Array.prototype_or_dynclass
|
||||
JSHandle<JSHClass> bigInt64ArrFuncInstanceDynclass = factory_->NewEcmaDynClass(
|
||||
panda::ecmascript::JSTypedArray::SIZE, JSType::JS_BIGINT64_ARRAY, bigInt64ArrFuncPrototypeValue);
|
||||
|
||||
// BigInt64Array = new Function()
|
||||
JSHandle<JSFunction> bigInt64ArrayFunction = factory_->NewSpecificTypedArrayFunction(
|
||||
env, reinterpret_cast<void *>(BuiltinsTypedArray::BigInt64ArrayConstructor));
|
||||
InitializeCtor(env, bigInt64ArrFuncPrototype, bigInt64ArrayFunction, "BigInt64Array", FunctionLength::THREE);
|
||||
|
||||
bigInt64ArrayFunction->SetProtoOrDynClass(thread_, bigInt64ArrFuncInstanceDynclass.GetTaggedValue());
|
||||
|
||||
const int bytesPerElement = 8;
|
||||
SetConstant(bigInt64ArrFuncPrototype, "BYTES_PER_ELEMENT", JSTaggedValue(bytesPerElement));
|
||||
SetConstant(JSHandle<JSObject>(bigInt64ArrayFunction), "BYTES_PER_ELEMENT", JSTaggedValue(bytesPerElement));
|
||||
env->SetBigInt64ArrayFunction(thread_, bigInt64ArrayFunction);
|
||||
}
|
||||
|
||||
void Builtins::InitializeBigUint64Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncDynclass) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
// BigUint64Array.prototype
|
||||
JSHandle<JSObject> bigUint64ArrFuncPrototype = factory_->NewJSObject(objFuncDynclass);
|
||||
JSHandle<JSTaggedValue> bigUint64ArrFuncPrototypeValue(bigUint64ArrFuncPrototype);
|
||||
|
||||
// BigUint64Array.prototype_or_dynclass
|
||||
JSHandle<JSHClass> bigUint64ArrFuncInstanceDynclass = factory_->NewEcmaDynClass(
|
||||
panda::ecmascript::JSTypedArray::SIZE, JSType::JS_BIGUINT64_ARRAY, bigUint64ArrFuncPrototypeValue);
|
||||
|
||||
// BigUint64Array = new Function()
|
||||
JSHandle<JSFunction> bigUint64ArrayFunction = factory_->NewSpecificTypedArrayFunction(
|
||||
env, reinterpret_cast<void *>(BuiltinsTypedArray::BigUint64ArrayConstructor));
|
||||
InitializeCtor(env, bigUint64ArrFuncPrototype, bigUint64ArrayFunction, "BigUint64Array", FunctionLength::THREE);
|
||||
|
||||
bigUint64ArrayFunction->SetProtoOrDynClass(thread_, bigUint64ArrFuncInstanceDynclass.GetTaggedValue());
|
||||
|
||||
const int bytesPerElement = 8;
|
||||
SetConstant(bigUint64ArrFuncPrototype, "BYTES_PER_ELEMENT", JSTaggedValue(bytesPerElement));
|
||||
SetConstant(JSHandle<JSObject>(bigUint64ArrayFunction), "BYTES_PER_ELEMENT", JSTaggedValue(bytesPerElement));
|
||||
env->SetBigUint64ArrayFunction(thread_, bigUint64ArrayFunction);
|
||||
}
|
||||
|
||||
void Builtins::InitializeArrayBuffer(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncDynclass) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -98,6 +98,10 @@ private:
|
||||
|
||||
void InitializeFloat64Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncDynclass) const;
|
||||
|
||||
void InitializeBigInt64Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncDynclass) const;
|
||||
|
||||
void InitializeBigUint64Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncDynclass) const;
|
||||
|
||||
void InitializeAllTypeError(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncDynclass) const;
|
||||
|
||||
void InitializeAllTypeErrorWithRealm(const JSHandle<GlobalEnv> &realm) const;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -736,9 +736,13 @@ JSTaggedValue BuiltinsArray::Fill(EcmaRuntimeCallInfo *argv)
|
||||
|
||||
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
|
||||
if (thisHandle->IsTypedArray()) {
|
||||
JSTaggedNumber number = JSTaggedValue::ToNumber(thread, value);
|
||||
ContentType contentType = JSHandle<JSTypedArray>::Cast(thisHandle)->GetContentType();
|
||||
if (contentType == ContentType::BigInt) {
|
||||
value = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToBigInt(thread, value));
|
||||
} else {
|
||||
value = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToNumber(thread, value));
|
||||
}
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
value = JSHandle<JSTaggedValue>(thread, JSTaggedValue(number.GetNumber()));
|
||||
}
|
||||
|
||||
// 3. Let len be ToLength(Get(O, "length")).
|
||||
@ -2636,4 +2640,161 @@ JSTaggedValue BuiltinsArray::Unscopables(EcmaRuntimeCallInfo *argv)
|
||||
|
||||
return unscopableList.GetTaggedValue();
|
||||
}
|
||||
|
||||
// es12 23.1.3.10
|
||||
JSTaggedValue BuiltinsArray::Flat(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Array, Values);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
|
||||
// 1. Let O be ? ToObject(this value).
|
||||
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
|
||||
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
array_size_t argc = argv->GetArgsNumber();
|
||||
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
|
||||
|
||||
// 2. Let sourceLen be ? LengthOfArrayLike(O).
|
||||
double sourceLen = ArrayHelper::GetLength(thread, thisObjVal);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
// 3. Let depthNum be 1.
|
||||
double depthNum = 1;
|
||||
|
||||
// 4. If depth is not undefined, then
|
||||
// a. Set depthNum to ? ToIntegerOrInfinity(depth).
|
||||
// b. If depthNum < 0, set depthNum to 0.
|
||||
if (argc > 0) {
|
||||
JSHandle<JSTaggedValue> msg1 = GetCallArg(argv, 0);
|
||||
JSTaggedNumber fromIndexTemp = JSTaggedValue::ToNumber(thread, msg1);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
depthNum = base::NumberHelper::TruncateDouble(fromIndexTemp.GetNumber());
|
||||
depthNum = depthNum < 0 ? 0 : depthNum;
|
||||
}
|
||||
|
||||
// 5. Let A be ? ArraySpeciesCreate(O, 0).
|
||||
uint32_t arrayLen = 0;
|
||||
JSTaggedValue newArray = JSArray::ArraySpeciesCreate(thread, thisObjHandle, JSTaggedNumber(arrayLen));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
base::FlattenArgs args = { sourceLen, 0, depthNum };
|
||||
JSHandle<JSObject> newArrayHandle(thread, newArray);
|
||||
// 6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, depthNum).
|
||||
ArrayHelper::FlattenIntoArray(thread, newArrayHandle, thisObjVal, args,
|
||||
thread->GlobalConstants()->GetHandledUndefined(),
|
||||
thread->GlobalConstants()->GetHandledUndefined());
|
||||
|
||||
// 7. Return A.
|
||||
return newArrayHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
// es12 23.1.3.11
|
||||
JSTaggedValue BuiltinsArray::FlatMap(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Array, Values);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
|
||||
// 1. Let O be ? ToObject(this value).
|
||||
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
|
||||
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
|
||||
|
||||
// 2. Let sourceLen be ? LengthOfArrayLike(O).
|
||||
double sourceLen = ArrayHelper::GetLength(thread, thisObjVal);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
// 3. If ! IsCallable(mapperFunction) is false, throw a TypeError exception.
|
||||
JSHandle<JSTaggedValue> mapperFunctionHandle = GetCallArg(argv, 0);
|
||||
if (!mapperFunctionHandle->IsCallable()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "the mapperFunction is not callable.", JSTaggedValue::Exception());
|
||||
}
|
||||
// 4. Let A be ? ArraySpeciesCreate(O, 0).
|
||||
uint32_t arrayLen = 0;
|
||||
JSTaggedValue newArray = JSArray::ArraySpeciesCreate(thread, thisObjHandle, JSTaggedNumber(arrayLen));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
base::FlattenArgs args = { sourceLen, 0, 1 };
|
||||
JSHandle<JSObject> newArrayHandle(thread, newArray);
|
||||
// 5. Perform ? FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, thisArg).
|
||||
ArrayHelper::FlattenIntoArray(thread, newArrayHandle, thisObjVal, args,
|
||||
mapperFunctionHandle, GetCallArg(argv, 1));
|
||||
|
||||
// 6. Return A.
|
||||
return newArrayHandle.GetTaggedValue();
|
||||
}
|
||||
|
||||
// 23.1.3.13 Array.prototype.includes ( searchElement [ , fromIndex ] )
|
||||
JSTaggedValue BuiltinsArray::Includes(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
BUILTINS_API_TRACE(argv->GetThread(), Array, Includes);
|
||||
JSThread *thread = argv->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
// 1. Let O be ? ToObject(this value).
|
||||
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
|
||||
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
array_size_t argc = argv->GetArgsNumber();
|
||||
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
|
||||
JSHandle<JSTaggedValue> searchElement = GetCallArg(argv, 0);
|
||||
|
||||
// 2. Let len be ? LengthOfArrayLike(O).
|
||||
double len = ArrayHelper::GetLength(thread, thisObjVal);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// 3. If len is 0, return false.
|
||||
if (len == 0) {
|
||||
return GetTaggedBoolean(false);
|
||||
}
|
||||
// 4. Let n be ? ToIntegerOrInfinity(fromIndex).
|
||||
// 5. Assert: If fromIndex is undefined, then n is 0.
|
||||
double fromIndex = 0;
|
||||
if (argc > 1) {
|
||||
JSHandle<JSTaggedValue> msg1 = GetCallArg(argv, 1);
|
||||
JSTaggedNumber fromIndexTemp = JSTaggedValue::ToNumber(thread, msg1);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
fromIndex = base::NumberHelper::TruncateDouble(fromIndexTemp.GetNumber());
|
||||
}
|
||||
|
||||
// 6. If n is +∞, return false.
|
||||
// 7. Else if n is -∞, set n to 0.
|
||||
if (fromIndex >= len) {
|
||||
return GetTaggedBoolean(false);
|
||||
} else if (fromIndex < -len) {
|
||||
fromIndex = 0;
|
||||
}
|
||||
// 8. If n ≥ 0, then
|
||||
// a. Let k be n.
|
||||
// 9. Else,
|
||||
// a. Let k be len + n.
|
||||
// b. If k < 0, let k be 0.
|
||||
double from = (fromIndex >= 0) ? fromIndex : ((len + fromIndex) >= 0 ? len + fromIndex : 0);
|
||||
|
||||
// 10. Repeat, while k < len,
|
||||
// a. Let elementK be ? Get(O, ! ToString(!(k))).
|
||||
// b. If SameValueZero(searchElement, elementK) is true, return true.
|
||||
// c. Set k to k + 1.
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> kValueHandle(thread, JSTaggedValue::Undefined());
|
||||
JSHandle<EcmaString> fromStr;
|
||||
while (from < len) {
|
||||
JSHandle<JSTaggedValue> handledFrom(thread, JSTaggedValue(from));
|
||||
fromStr = JSTaggedValue::ToString(thread, handledFrom);
|
||||
key.Update(fromStr.GetTaggedValue());
|
||||
kValueHandle.Update(JSArray::FastGetPropertyByValue(thread, thisObjVal, key).GetTaggedValue());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
if (JSTaggedValue::SameValueZero(searchElement.GetTaggedValue(), kValueHandle.GetTaggedValue())) {
|
||||
return GetTaggedBoolean(true);
|
||||
}
|
||||
from++;
|
||||
}
|
||||
// 11. Return false.
|
||||
return GetTaggedBoolean(false);
|
||||
}
|
||||
} // namespace panda::ecmascript::builtins
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -94,6 +94,12 @@ public:
|
||||
static JSTaggedValue Values(EcmaRuntimeCallInfo *argv);
|
||||
// 22.1.3.31
|
||||
static JSTaggedValue Unscopables(EcmaRuntimeCallInfo *argv);
|
||||
// es12 23.1.3.13
|
||||
static JSTaggedValue Includes(EcmaRuntimeCallInfo *argv);
|
||||
// es12 23.1.3.10
|
||||
static JSTaggedValue Flat(EcmaRuntimeCallInfo *argv);
|
||||
// es12 23.1.3.11
|
||||
static JSTaggedValue FlatMap(EcmaRuntimeCallInfo *argv);
|
||||
};
|
||||
} // namespace panda::ecmascript::builtins
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -19,6 +19,7 @@
|
||||
|
||||
#include "ecmascript/base/builtins_base.h"
|
||||
#include "ecmascript/base/number_helper.h"
|
||||
#include "ecmascript/builtins/builtins_bigint.h"
|
||||
#include "ecmascript/ecma_macros.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
@ -306,8 +307,8 @@ JSTaggedValue BuiltinsArrayBuffer::CloneArrayBuffer(JSThread *thread, const JSHa
|
||||
|
||||
// 24.1.1.5
|
||||
// NOLINTNEXTLINE(readability-function-size)
|
||||
JSTaggedValue BuiltinsArrayBuffer::GetValueFromBuffer(JSTaggedValue arrBuf, uint32_t byteIndex, DataViewType type,
|
||||
bool littleEndian)
|
||||
JSTaggedValue BuiltinsArrayBuffer::GetValueFromBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteIndex,
|
||||
DataViewType type, bool littleEndian)
|
||||
{
|
||||
JSArrayBuffer *jsArrayBuffer = JSArrayBuffer::Cast(arrBuf.GetTaggedObject());
|
||||
JSTaggedValue data = jsArrayBuffer->GetArrayBufferData();
|
||||
@ -336,6 +337,10 @@ JSTaggedValue BuiltinsArrayBuffer::GetValueFromBuffer(JSTaggedValue arrBuf, uint
|
||||
return GetValueFromBufferForFloat<float, UnionType32, NumberSize::FLOAT32>(block, byteIndex, littleEndian);
|
||||
case DataViewType::FLOAT64:
|
||||
return GetValueFromBufferForFloat<double, UnionType64, NumberSize::FLOAT64>(block, byteIndex, littleEndian);
|
||||
case DataViewType::BIGINT64:
|
||||
return GetValueFromBufferForBigInt(thread, block, byteIndex);
|
||||
case DataViewType::BIGUINT64:
|
||||
return GetValueFromBufferForBigUint(thread, block, byteIndex);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -344,14 +349,30 @@ JSTaggedValue BuiltinsArrayBuffer::GetValueFromBuffer(JSTaggedValue arrBuf, uint
|
||||
}
|
||||
|
||||
// 24.1.1.6
|
||||
JSTaggedValue BuiltinsArrayBuffer::SetValueInBuffer(JSTaggedValue arrBuf, uint32_t byteIndex, DataViewType type,
|
||||
JSTaggedNumber value, bool littleEndian)
|
||||
JSTaggedValue BuiltinsArrayBuffer::SetValueInBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteIndex,
|
||||
DataViewType type, const JSHandle<JSTaggedValue> &value,
|
||||
bool littleEndian)
|
||||
{
|
||||
JSArrayBuffer *jsArrayBuffer = JSArrayBuffer::Cast(arrBuf.GetTaggedObject());
|
||||
JSTaggedValue data = jsArrayBuffer->GetArrayBufferData();
|
||||
void *pointer = JSNativePointer::Cast(data.GetTaggedObject())->GetExternalPointer();
|
||||
auto *block = reinterpret_cast<uint8_t *>(pointer);
|
||||
double val = value.GetNumber();
|
||||
if (IsBigIntElementType(type)) {
|
||||
switch (type) {
|
||||
case DataViewType::BIGINT64:
|
||||
SetValueInBufferForBigInt(thread, value, block, byteIndex, false);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
break;
|
||||
case DataViewType::BIGUINT64:
|
||||
SetValueInBufferForBigInt(thread, value, block, byteIndex, true);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
double val = value.GetTaggedValue().GetNumber();
|
||||
switch (type) {
|
||||
case DataViewType::UINT8:
|
||||
SetValueInBufferForByte<uint8_t>(val, block, byteIndex);
|
||||
@ -386,11 +407,27 @@ JSTaggedValue BuiltinsArrayBuffer::SetValueInBuffer(JSTaggedValue arrBuf, uint32
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
|
||||
// es12 25.1.2.7 IsBigIntElementType ( type )
|
||||
bool BuiltinsArrayBuffer::IsBigIntElementType(DataViewType type)
|
||||
{
|
||||
if (type == DataViewType::BIGINT64 || type == DataViewType::BIGUINT64) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void BuiltinsArrayBuffer::SetTypeData(uint8_t *block, T value, uint32_t index)
|
||||
{
|
||||
uint32_t sizeCount = sizeof(T);
|
||||
auto *res = reinterpret_cast<uint8_t *>(&value);
|
||||
uint32_t sizeCount = 0;
|
||||
uint8_t *res = nullptr;
|
||||
if constexpr (std::is_same_v<T, uint32_t*>) {
|
||||
sizeCount = sizeof(uint32_t) * 2; // 2:Array occupies 8 bytes
|
||||
res = reinterpret_cast<uint8_t *>(value);
|
||||
} else {
|
||||
sizeCount = sizeof(T);
|
||||
res = reinterpret_cast<uint8_t *>(&value);
|
||||
}
|
||||
for (uint32_t i = 0; i < sizeCount; i++) {
|
||||
*(block + index + i) = *(res + i); // NOLINT
|
||||
}
|
||||
@ -486,6 +523,34 @@ JSTaggedValue BuiltinsArrayBuffer::GetValueFromBufferForFloat(uint8_t *block, ui
|
||||
return GetTaggedDouble(unionValue.value);
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsArrayBuffer::GetValueFromBufferForBigInt(JSThread *thread, uint8_t *block, uint32_t byteIndex)
|
||||
{
|
||||
uint32_t *pTmp = reinterpret_cast<uint32_t *>(block + byteIndex);
|
||||
JSHandle<BigInt> valBigInt = BigInt::CreateBigint(thread, 2); // 2:Create a bigint of 2 elements
|
||||
BigInt::SetDigit(thread, valBigInt, 0, *pTmp);
|
||||
uint32_t tmp = *(pTmp + 1);
|
||||
if (tmp >> BITS_THIRTY_ONE) {
|
||||
valBigInt->SetSign(true);
|
||||
}
|
||||
if ((*pTmp == 0) && (tmp >> BITS_THIRTY_ONE)) {
|
||||
BigInt::SetDigit(thread, valBigInt, 1, tmp);
|
||||
} else {
|
||||
BigInt::SetDigit(thread, valBigInt, 1, tmp & ~(1 << BITS_THIRTY_ONE));
|
||||
}
|
||||
BigIntHelper::RightTruncate(thread, valBigInt);
|
||||
return valBigInt.GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsArrayBuffer::GetValueFromBufferForBigUint(JSThread *thread, uint8_t *block, uint32_t byteIndex)
|
||||
{
|
||||
uint32_t *pTmp = reinterpret_cast<uint32_t *>(block + byteIndex);
|
||||
JSHandle<BigInt> valBigInt = BigInt::CreateBigint(thread, 2); // 2:2 elements
|
||||
BigInt::SetDigit(thread, valBigInt, 0, *pTmp);
|
||||
BigInt::SetDigit(thread, valBigInt, 1, *(pTmp + 1));
|
||||
BigIntHelper::RightTruncate(thread, valBigInt);
|
||||
return valBigInt.GetTaggedValue();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void BuiltinsArrayBuffer::SetValueInBufferForByte(double val, uint8_t *block, uint32_t byteIndex)
|
||||
{
|
||||
@ -565,4 +630,27 @@ void BuiltinsArrayBuffer::SetValueInBufferForFloat(double val, uint8_t *block, u
|
||||
}
|
||||
SetTypeData(block, data, byteIndex);
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsArrayBuffer::SetValueInBufferForBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &val,
|
||||
uint8_t *block, uint32_t byteIndex, bool isUint)
|
||||
{
|
||||
JSHandle<BigInt> valBigintHandle;
|
||||
if (isUint) {
|
||||
valBigintHandle = JSHandle<BigInt>(thread, val->ToBigUint64(thread, val));
|
||||
} else {
|
||||
valBigintHandle = JSHandle<BigInt>(thread, val->ToBigInt64(thread, val));
|
||||
}
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
uint32_t valLength = valBigintHandle->GetLength();
|
||||
uint32_t varBuffer[2] = {0}; // 2:2 elements with 8 bits
|
||||
for (uint32_t i = 0; i < valLength; i++) {
|
||||
varBuffer[i] = valBigintHandle->GetDigit(i);
|
||||
}
|
||||
if (!isUint) {
|
||||
bool sign = valBigintHandle->GetSign();
|
||||
varBuffer[1] = sign ? (varBuffer[1] |= 1 << BITS_THIRTY_ONE) : varBuffer[1];
|
||||
}
|
||||
SetTypeData(block, varBuffer, byteIndex);
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
} // namespace panda::ecmascript::builtins
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -26,6 +26,7 @@ static constexpr uint32_t BITS_EIGHT = 8;
|
||||
static constexpr uint32_t BITS_TWENTY_FOUR = 24;
|
||||
static constexpr uint32_t BITS_FORTY = 40;
|
||||
static constexpr uint32_t BITS_FIFTY_SIX = 56;
|
||||
static constexpr uint32_t BITS_THIRTY_ONE = 31;
|
||||
using DataViewType = ecmascript::DataViewType;
|
||||
union UnionType32 {
|
||||
uint32_t uValue;
|
||||
@ -37,7 +38,9 @@ union UnionType64 {
|
||||
};
|
||||
class BuiltinsArrayBuffer : public base::BuiltinsBase {
|
||||
public:
|
||||
enum NumberSize : uint8_t { UINT16 = 2, INT16 = 2, UINT32 = 4, INT32 = 4, FLOAT32 = 4, FLOAT64 = 8 };
|
||||
enum NumberSize : uint8_t {
|
||||
UINT16 = 2, INT16 = 2, UINT32 = 4, INT32 = 4, FLOAT32 = 4, FLOAT64 = 8, BIGINT64 = 8, BIGUINT64 = 8
|
||||
};
|
||||
|
||||
// 24.1.2.1 ArrayBuffer(length)
|
||||
static JSTaggedValue ArrayBufferConstructor(EcmaRuntimeCallInfo *argv);
|
||||
@ -52,17 +55,19 @@ public:
|
||||
// 24.1.1.2 IsDetachedBuffer(arrayBuffer)
|
||||
static bool IsDetachedBuffer(JSTaggedValue arrayBuffer);
|
||||
// 24.1.1.5 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isLittleEndian )
|
||||
static JSTaggedValue GetValueFromBuffer(JSTaggedValue arrBuf, uint32_t byteIndex, DataViewType type,
|
||||
bool littleEndian);
|
||||
static JSTaggedValue GetValueFromBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteIndex,
|
||||
DataViewType type, bool littleEndian);
|
||||
// 24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isLittleEndian )
|
||||
static JSTaggedValue SetValueInBuffer(JSTaggedValue arrBuf, uint32_t byteIndex, DataViewType type,
|
||||
JSTaggedNumber value, bool littleEndian);
|
||||
static JSTaggedValue SetValueInBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteIndex,
|
||||
DataViewType type, const JSHandle<JSTaggedValue> &value, bool littleEndian);
|
||||
// 24.1.1.4 CloneArrayBuffer( srcBuffer, srcByteOffset [, cloneConstructor] )
|
||||
static JSTaggedValue CloneArrayBuffer(JSThread *thread, const JSHandle<JSTaggedValue> &srcBuffer,
|
||||
uint32_t srcByteOffset, JSHandle<JSTaggedValue> constructor);
|
||||
// 24.1.1.1 AllocateArrayBuffer(constructor, byteLength)
|
||||
static JSTaggedValue AllocateArrayBuffer(JSThread *thread, const JSHandle<JSTaggedValue> &newTarget,
|
||||
double byteLength);
|
||||
// es12 25.1.2.7 IsBigIntElementType ( type )
|
||||
static bool IsBigIntElementType(DataViewType type);
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
@ -79,6 +84,10 @@ private:
|
||||
template<typename T, typename UnionType, NumberSize size>
|
||||
static JSTaggedValue GetValueFromBufferForFloat(uint8_t *block, uint32_t byteIndex, bool littleEndian);
|
||||
|
||||
static JSTaggedValue GetValueFromBufferForBigInt(JSThread *thread, uint8_t *block, uint32_t byteIndex);
|
||||
|
||||
static JSTaggedValue GetValueFromBufferForBigUint(JSThread *thread, uint8_t *block, uint32_t byteIndex);
|
||||
|
||||
template<typename T>
|
||||
static void SetValueInBufferForByte(double val, uint8_t *block, uint32_t byteIndex);
|
||||
|
||||
@ -89,6 +98,9 @@ private:
|
||||
|
||||
template<typename T>
|
||||
static void SetValueInBufferForFloat(double val, uint8_t *block, uint32_t byteIndex, bool littleEndian);
|
||||
|
||||
static JSTaggedValue SetValueInBufferForBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &val, uint8_t *block,
|
||||
uint32_t byteIndex, bool isUint);
|
||||
};
|
||||
} // namespace panda::ecmascript::builtins
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -350,7 +350,7 @@ JSTaggedValue BuiltinsDataView::GetViewValue(JSThread *thread, const JSHandle<JS
|
||||
// 14. Let bufferIndex be getIndex + viewOffset.
|
||||
uint32_t bufferIndex = index + offset;
|
||||
// 15. Return GetValueFromBuffer(buffer, bufferIndex, type, isLittleEndian).
|
||||
return BuiltinsArrayBuffer::GetValueFromBuffer(buffer, bufferIndex, type, isLittleEndian);
|
||||
return BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, bufferIndex, type, isLittleEndian);
|
||||
}
|
||||
|
||||
// 24.2.1.2
|
||||
@ -376,7 +376,7 @@ JSTaggedValue BuiltinsDataView::SetViewValue(JSThread *thread, const JSHandle<JS
|
||||
if (index < 0) {
|
||||
THROW_RANGE_ERROR_AND_RETURN(thread, "getIndex < 0", JSTaggedValue::Exception());
|
||||
}
|
||||
JSTaggedNumber numVal = JSTaggedValue::ToNumber(thread, value);
|
||||
JSHandle<JSTaggedValue> numValueHandle = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToNumber(thread, value));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
// 7. Let isLittleEndian be ToBoolean(isLittleEndian).
|
||||
bool isLittleEndian = false;
|
||||
@ -405,7 +405,7 @@ JSTaggedValue BuiltinsDataView::SetViewValue(JSThread *thread, const JSHandle<JS
|
||||
// 14. Let bufferIndex be getIndex + viewOffset.
|
||||
uint32_t bufferIndex = index + offset;
|
||||
// 15. Return SetValueFromBuffer(buffer, bufferIndex, type, value, isLittleEndian).
|
||||
return BuiltinsArrayBuffer::SetValueInBuffer(buffer, bufferIndex, type, numVal, isLittleEndian);
|
||||
return BuiltinsArrayBuffer::SetValueInBuffer(thread, buffer, bufferIndex, type, numValueHandle, isLittleEndian);
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsDataView::GetTypedValue(EcmaRuntimeCallInfo *argv, DataViewType type)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -111,6 +111,20 @@ JSTaggedValue BuiltinsTypedArray::Float64ArrayConstructor(EcmaRuntimeCallInfo *a
|
||||
return TypedArrayHelper::TypedArrayConstructor(argv, thread->GlobalConstants()->GetHandledFloat64ArrayString());
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsTypedArray::BigInt64ArrayConstructor(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
JSThread *thread = argv->GetThread();
|
||||
return TypedArrayHelper::TypedArrayConstructor(argv, thread->GlobalConstants()->GetHandledBigInt64ArrayString());
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsTypedArray::BigUint64ArrayConstructor(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
JSThread *thread = argv->GetThread();
|
||||
return TypedArrayHelper::TypedArrayConstructor(argv, thread->GlobalConstants()->GetHandledBigUint64ArrayString());
|
||||
}
|
||||
|
||||
// 22.2.2.1 %TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
|
||||
JSTaggedValue BuiltinsTypedArray::From(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
@ -996,26 +1010,34 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv)
|
||||
int32_t limit = targetByteIndex + targetElementSize * srcLen;
|
||||
// 24. Repeat, while targetByteIndex < limit
|
||||
// a. Let Pk be ToString(k).
|
||||
// b. Let kNumber be ToNumber(Get(src, Pk)).
|
||||
// c. ReturnIfAbrupt(kNumber).
|
||||
// b. If target.[[ContentType]] is BigInt, set value to ? ToBigInt(value).
|
||||
// c. Otherwise, set value to ? ToNumber(value).
|
||||
// d. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError exception.
|
||||
// e. Perform SetValueInBuffer(targetBuffer, targetByteIndex, targetType, kNumber).
|
||||
// f. Set k to k + 1.
|
||||
// g. Set targetByteIndex to targetByteIndex + targetElementSize.
|
||||
JSMutableHandle<JSTaggedValue> tKey(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> kNumberHandle(thread, JSTaggedValue::Undefined());
|
||||
while (targetByteIndex < limit) {
|
||||
tKey.Update(JSTaggedValue(k));
|
||||
JSHandle<JSTaggedValue> kKey(JSTaggedValue::ToString(thread, tKey));
|
||||
JSHandle<JSTaggedValue> kValue =
|
||||
JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>::Cast(src), kKey).GetValue();
|
||||
JSTaggedNumber kNumber = JSTaggedValue::ToNumber(thread, kValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
if (BuiltinsArrayBuffer::IsDetachedBuffer(targetBuffer.GetTaggedValue())) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "The targetBuffer of This value is detached buffer.",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(targetBuffer.GetTaggedValue(), targetByteIndex, targetType, kNumber,
|
||||
true);
|
||||
ContentType contentType = JSHandle<JSTypedArray>::Cast(target)->GetContentType();
|
||||
if (contentType == ContentType::BigInt) {
|
||||
kNumberHandle.Update(JSTaggedValue::ToBigInt(thread, kValue));
|
||||
} else {
|
||||
kNumberHandle.Update(JSTaggedValue::ToNumber(thread, kValue));
|
||||
}
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(thread, targetBuffer.GetTaggedValue(), targetByteIndex,
|
||||
targetType, kNumberHandle, true);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
k++;
|
||||
targetByteIndex = targetByteIndex + targetElementSize;
|
||||
}
|
||||
@ -1028,10 +1050,19 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv)
|
||||
// 12. Let srcBuffer be the value of typedArray’s [[ViewedArrayBuffer]] internal slot.
|
||||
// 13. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception.
|
||||
JSTaggedValue srcBuffer = JSTypedArray::Cast(*typedArray)->GetViewedArrayBuffer();
|
||||
JSHandle<JSTaggedValue> srcBufferHandle = JSHandle<JSTaggedValue>(thread, srcBuffer);
|
||||
if (BuiltinsArrayBuffer::IsDetachedBuffer(srcBuffer)) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "The ArrayBuffer of typedArray is detached buffer.",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
|
||||
ContentType objContentType = JSHandle<JSTypedArray>::Cast(target)->GetContentType();
|
||||
ContentType argArrayContentType = JSHandle<JSTypedArray>::Cast(argArray)->GetContentType();
|
||||
if (argArrayContentType != objContentType) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread,
|
||||
"argArrayContentType is not equal objContentType.",
|
||||
JSTaggedValue::Exception());
|
||||
}
|
||||
// 18. Let srcName be the String value of typedArray’s [[TypedArrayName]] internal slot.
|
||||
// 19. Let srcType be the String value of the Element Type value in Table 49 for srcName .
|
||||
// 20. Let srcElementSize be the Number value of the Element Size value specified in Table 49 for srcName.
|
||||
@ -1055,10 +1086,11 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv)
|
||||
// d. Let srcByteIndex be 0.
|
||||
// 25. Else, let srcByteIndex be srcByteOffset.
|
||||
int32_t srcByteIndex;
|
||||
if (JSTaggedValue::SameValue(srcBuffer, targetBuffer.GetTaggedValue())) {
|
||||
if (JSTaggedValue::SameValue(srcBufferHandle.GetTaggedValue(), targetBuffer.GetTaggedValue())) {
|
||||
srcBuffer =
|
||||
BuiltinsArrayBuffer::CloneArrayBuffer(thread, targetBuffer, srcByteOffset, env->GetArrayBufferFunction());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
srcBufferHandle = JSHandle<JSTaggedValue>(thread, srcBuffer);
|
||||
srcByteIndex = 0;
|
||||
} else {
|
||||
srcByteIndex = srcByteOffset;
|
||||
@ -1076,11 +1108,13 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv)
|
||||
JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
|
||||
if (srcType != targetType) {
|
||||
while (targetByteIndex < limit) {
|
||||
JSTaggedValue taggedData = BuiltinsArrayBuffer::GetValueFromBuffer(srcBuffer, srcByteIndex, srcType, true);
|
||||
JSTaggedValue taggedData =
|
||||
BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcBufferHandle.GetTaggedValue(),
|
||||
srcByteIndex, srcType, true);
|
||||
value.Update(taggedData);
|
||||
JSTaggedNumber kNumber = JSTaggedValue::ToNumber(thread, value);
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(targetBuffer.GetTaggedValue(), targetByteIndex, targetType, kNumber,
|
||||
true);
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(thread, targetBuffer.GetTaggedValue(), targetByteIndex,
|
||||
targetType, value, true);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
srcByteIndex = srcByteIndex + srcElementSize;
|
||||
targetByteIndex = targetByteIndex + targetElementSize;
|
||||
}
|
||||
@ -1095,11 +1129,12 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv)
|
||||
// iv. Set targetByteIndex to targetByteIndex + 1.
|
||||
while (targetByteIndex < limit) {
|
||||
JSTaggedValue taggedData =
|
||||
BuiltinsArrayBuffer::GetValueFromBuffer(srcBuffer, srcByteIndex, DataViewType::UINT8, true);
|
||||
BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcBufferHandle.GetTaggedValue(), srcByteIndex,
|
||||
DataViewType::UINT8, true);
|
||||
value.Update(taggedData);
|
||||
JSTaggedNumber kNumber = JSTaggedValue::ToNumber(thread, value);
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(targetBuffer.GetTaggedValue(), targetByteIndex, DataViewType::UINT8,
|
||||
kNumber, true);
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(thread, targetBuffer.GetTaggedValue(), targetByteIndex,
|
||||
DataViewType::UINT8, value, true);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
srcByteIndex = srcByteIndex + 1;
|
||||
targetByteIndex = targetByteIndex + 1;
|
||||
}
|
||||
@ -1225,12 +1260,12 @@ JSTaggedValue BuiltinsTypedArray::Slice(EcmaRuntimeCallInfo *argv)
|
||||
// iv. Increase targetByteIndex by 1.
|
||||
JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
|
||||
for (int32_t targetByteIndex = 0; targetByteIndex < count * elementSize; srcByteIndex++, targetByteIndex++) {
|
||||
JSTaggedValue taggedData = BuiltinsArrayBuffer::GetValueFromBuffer(srcBuffer.GetTaggedValue(), srcByteIndex,
|
||||
DataViewType::UINT8, true);
|
||||
JSTaggedValue taggedData = BuiltinsArrayBuffer::GetValueFromBuffer(thread, srcBuffer.GetTaggedValue(),
|
||||
srcByteIndex, DataViewType::UINT8,
|
||||
true);
|
||||
value.Update(taggedData);
|
||||
JSTaggedNumber kNumber = JSTaggedValue::ToNumber(thread, value);
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(targetBuffer.GetTaggedValue(), targetByteIndex, DataViewType::UINT8,
|
||||
kNumber, true);
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(thread, targetBuffer.GetTaggedValue(), targetByteIndex,
|
||||
DataViewType::UINT8, value, true);
|
||||
}
|
||||
}
|
||||
// 23. Return A.
|
||||
@ -1436,4 +1471,14 @@ JSTaggedValue BuiltinsTypedArray::ToStringTag(EcmaRuntimeCallInfo *argv)
|
||||
// 6. Return name.
|
||||
return name;
|
||||
}
|
||||
|
||||
// es12 23.2.3.13
|
||||
JSTaggedValue BuiltinsTypedArray::Includes(EcmaRuntimeCallInfo *argv)
|
||||
{
|
||||
ASSERT(argv);
|
||||
if (!GetThis(argv)->IsTypedArray()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(argv->GetThread(), "This is not a TypedArray.", JSTaggedValue::Exception());
|
||||
}
|
||||
return BuiltinsArray::Includes(argv);
|
||||
}
|
||||
} // namespace panda::ecmascript::builtins
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -33,6 +33,8 @@ public:
|
||||
static JSTaggedValue Uint32ArrayConstructor(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Float32ArrayConstructor(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue Float64ArrayConstructor(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue BigInt64ArrayConstructor(EcmaRuntimeCallInfo *argv);
|
||||
static JSTaggedValue BigUint64ArrayConstructor(EcmaRuntimeCallInfo *argv);
|
||||
|
||||
// 22.2.1.2.1
|
||||
static JSTaggedValue AllocateTypedArray(EcmaRuntimeCallInfo *argv);
|
||||
@ -103,6 +105,8 @@ public:
|
||||
static JSTaggedValue Values(EcmaRuntimeCallInfo *argv);
|
||||
// 22.2.3.31
|
||||
static JSTaggedValue ToStringTag(EcmaRuntimeCallInfo *argv);
|
||||
// es12 23.2.3.13
|
||||
static JSTaggedValue Includes(EcmaRuntimeCallInfo *argv);
|
||||
};
|
||||
} // namespace panda::ecmascript::builtins
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -234,6 +234,10 @@ CString *HeapSnapShot::GenerateNodeName(JSThread *thread, TaggedObject *entry)
|
||||
return GetString("Float32 Array");
|
||||
case JSType::JS_FLOAT64_ARRAY:
|
||||
return GetString("Float64 Array");
|
||||
case JSType::JS_BIGINT64_ARRAY:
|
||||
return GetString("BigInt64 Array");
|
||||
case JSType::JS_BIGUINT64_ARRAY:
|
||||
return GetString("BigUint64 Array");
|
||||
case JSType::JS_ARGUMENTS:
|
||||
return GetString("Arguments");
|
||||
case JSType::BIGINT:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -166,6 +166,10 @@ CString JSHClass::DumpJSType(JSType type)
|
||||
return "Float32 Array";
|
||||
case JSType::JS_FLOAT64_ARRAY:
|
||||
return "Float64 Array";
|
||||
case JSType::JS_BIGINT64_ARRAY:
|
||||
return "BigInt64 Array";
|
||||
case JSType::JS_BIGUINT64_ARRAY:
|
||||
return "BigUint64 Array";
|
||||
case JSType::JS_ARGUMENTS:
|
||||
return "Arguments";
|
||||
case JSType::JS_PROXY:
|
||||
@ -483,6 +487,8 @@ static void DumpObject(JSThread *thread, TaggedObject *obj, std::ostream &os)
|
||||
case JSType::JS_UINT32_ARRAY:
|
||||
case JSType::JS_FLOAT32_ARRAY:
|
||||
case JSType::JS_FLOAT64_ARRAY:
|
||||
case JSType::JS_BIGINT64_ARRAY:
|
||||
case JSType::JS_BIGUINT64_ARRAY:
|
||||
JSTypedArray::Cast(obj)->Dump(thread, os);
|
||||
break;
|
||||
case JSType::BIGINT:
|
||||
@ -2655,6 +2661,8 @@ static void DumpObject(JSThread *thread, TaggedObject *obj,
|
||||
case JSType::JS_UINT32_ARRAY:
|
||||
case JSType::JS_FLOAT32_ARRAY:
|
||||
case JSType::JS_FLOAT64_ARRAY:
|
||||
case JSType::JS_BIGINT64_ARRAY:
|
||||
case JSType::JS_BIGUINT64_ARRAY:
|
||||
JSTypedArray::Cast(obj)->DumpForSnapshot(thread, vec);
|
||||
return;
|
||||
case JSType::BIGINT:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -51,6 +51,8 @@ class JSThread;
|
||||
V(JSTaggedValue, Uint32ArrayFunction, UINT32_ARRAY_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, Float32ArrayFunction, FLOAT32_ARRAY_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, Float64ArrayFunction, FLOAT64_ARRAY_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, BigInt64ArrayFunction, BIGINT64_ARRAY_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, BigUint64ArrayFunction, BIGUINT64_ARRAY_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, ArrayBufferFunction, ARRAY_BUFFER_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, ArrayProtoValuesFunction, ARRAY_PROTO_VALUES_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, DataViewFunction, DATA_VIEW_FUNCTION_INDEX) \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -255,6 +255,8 @@ void GlobalEnvConstants::InitGlobalConstant(JSThread *thread)
|
||||
SetConstant(ConstantIndex::UINT32_ARRAY_STRING_INDEX, factory->NewFromCanBeCompressString("Uint32Array"));
|
||||
SetConstant(ConstantIndex::FLOAT32_ARRAY_STRING_INDEX, factory->NewFromCanBeCompressString("Float32Array"));
|
||||
SetConstant(ConstantIndex::FLOAT64_ARRAY_STRING_INDEX, factory->NewFromCanBeCompressString("Float64Array"));
|
||||
SetConstant(ConstantIndex::BIGINT64_ARRAY_STRING_INDEX, factory->NewFromCanBeCompressString("BigInt64Array"));
|
||||
SetConstant(ConstantIndex::BIGUINT64_ARRAY_STRING_INDEX, factory->NewFromCanBeCompressString("BigUint64Array"));
|
||||
SetConstant(ConstantIndex::ASYNC_FUNCTION_STRING_INDEX, factory->NewFromCanBeCompressString("AsyncFunction"));
|
||||
SetConstant(ConstantIndex::PROMISE_RESOLVE_STRING_INDEX, factory->NewFromCanBeCompressString("resolve"));
|
||||
SetConstant(ConstantIndex::ID_STRING_INDEX, factory->NewFromCanBeCompressString("id"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -162,6 +162,8 @@ class JSThread;
|
||||
V(JSTaggedValue, Uint32ArrayString, UINT32_ARRAY_STRING_INDEX, Uint32Array) \
|
||||
V(JSTaggedValue, Float32ArrayString, FLOAT32_ARRAY_STRING_INDEX, Float32Array) \
|
||||
V(JSTaggedValue, Float64ArrayString, FLOAT64_ARRAY_STRING_INDEX, Float64Array) \
|
||||
V(JSTaggedValue, BigInt64ArrayString, BIGINT64_ARRAY_STRING_INDEX, BigInt64Array) \
|
||||
V(JSTaggedValue, BigUint64ArrayString, BIGUINT64_ARRAY_STRING_INDEX, BigUint64Array) \
|
||||
V(JSTaggedValue, AsyncFunctionString, ASYNC_FUNCTION_STRING_INDEX, AsyncFunction) \
|
||||
V(JSTaggedValue, PromiseResolveString, PROMISE_RESOLVE_STRING_INDEX, resolve) \
|
||||
V(JSTaggedValue, IdString, ID_STRING_INDEX, id) \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -19,7 +19,9 @@
|
||||
#include "ecmascript/js_object.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
enum class DataViewType : uint8_t { FLOAT32 = 0, FLOAT64, INT8, INT16, INT32, UINT8, UINT16, UINT32, UINT8_CLAMPED };
|
||||
enum class DataViewType : uint8_t {
|
||||
BIGINT64 = 0, BIGUINT64, FLOAT32, FLOAT64, INT8, INT16, INT32, UINT8, UINT16, UINT32, UINT8_CLAMPED
|
||||
};
|
||||
class JSDataView : public JSObject {
|
||||
public:
|
||||
CAST_CHECK(JSDataView, IsDataView);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -133,7 +133,9 @@ class ProtoChangeDetails;
|
||||
JS_INT32_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_UINT32_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_FLOAT32_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_FLOAT64_ARRAY, /* JS_TYPED_ARRAY_END ///////////////////////////////////////////////////////////// */ \
|
||||
JS_FLOAT64_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_BIGINT64_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_BIGUINT64_ARRAY, /* JS_TYPED_ARRAY_END ///////////////////////////////////////////////////////////// */ \
|
||||
JS_PRIMITIVE_REF, /* number\boolean\string. SPECIAL indexed objects end, DON'T CHANGE HERE ////////-PADDING */ \
|
||||
JS_MODULE_NAMESPACE, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_GLOBAL_OBJECT, /* JS_OBJECT_END/////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
@ -205,7 +207,7 @@ class ProtoChangeDetails;
|
||||
JS_RECORD_END = COMPLETION_RECORD, /* ///////////////////////////////////////////////////////-PADDING */ \
|
||||
\
|
||||
JS_TYPED_ARRAY_BEGIN = JS_TYPED_ARRAY, /* /////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_TYPED_ARRAY_END = JS_FLOAT64_ARRAY, /* /////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_TYPED_ARRAY_END = JS_BIGUINT64_ARRAY, /* ///////////////////////////////////////////////////////-PADDING */ \
|
||||
\
|
||||
MODULE_RECORD_BEGIN = MODULE_RECORD, /* ///////////////////////////////////////////////////////////-PADDING */ \
|
||||
MODULE_RECORD_END = SOURCE_TEXT_MODULE_RECORD /* //////////////////////////////////////////////////-PADDING */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -287,6 +287,10 @@ bool JSSerializer::WriteTaggedObject(const JSHandle<JSTaggedValue> &value)
|
||||
return WriteJSTypedArray(value, SerializationUID::JS_FLOAT32_ARRAY);
|
||||
case JSType::JS_FLOAT64_ARRAY:
|
||||
return WriteJSTypedArray(value, SerializationUID::JS_FLOAT64_ARRAY);
|
||||
case JSType::JS_BIGINT64_ARRAY:
|
||||
return WriteJSTypedArray(value, SerializationUID::JS_BIGINT64_ARRAY);
|
||||
case JSType::JS_BIGUINT64_ARRAY:
|
||||
return WriteJSTypedArray(value, SerializationUID::JS_BIGUINT64_ARRAY);
|
||||
case JSType::JS_ARRAY_BUFFER:
|
||||
return WriteJSArrayBuffer(value);
|
||||
case JSType::STRING:
|
||||
@ -566,6 +570,12 @@ bool JSSerializer::WriteJSTypedArray(const JSHandle<JSTaggedValue> &value, Seria
|
||||
bufferSize_ = oldSize;
|
||||
return false;
|
||||
}
|
||||
// Write ACCESSORS(ContentType)
|
||||
ContentType contentType = typedArray->GetContentType();
|
||||
if (!WriteRawData(&contentType, sizeof(ContentType))) {
|
||||
bufferSize_ = oldSize;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -879,6 +889,10 @@ JSHandle<JSTaggedValue> JSDeserializer::DeserializeJSTaggedValue()
|
||||
return ReadJSTypedArray(SerializationUID::JS_FLOAT32_ARRAY);
|
||||
case SerializationUID::JS_FLOAT64_ARRAY:
|
||||
return ReadJSTypedArray(SerializationUID::JS_FLOAT64_ARRAY);
|
||||
case SerializationUID::JS_BIGINT64_ARRAY:
|
||||
return ReadJSTypedArray(SerializationUID::JS_BIGINT64_ARRAY);
|
||||
case SerializationUID::JS_BIGUINT64_ARRAY:
|
||||
return ReadJSTypedArray(SerializationUID::JS_BIGUINT64_ARRAY);
|
||||
case SerializationUID::NATIVE_FUNCTION_POINTER:
|
||||
return ReadNativeFunctionPointer();
|
||||
case SerializationUID::JS_ARRAY_BUFFER:
|
||||
@ -1145,6 +1159,14 @@ JSHandle<JSTaggedValue> JSDeserializer::ReadJSTypedArray(SerializationUID uid)
|
||||
target = env->GetFloat64ArrayFunction();
|
||||
break;
|
||||
}
|
||||
case SerializationUID::JS_BIGINT64_ARRAY: {
|
||||
target = env->GetBigInt64ArrayFunction();
|
||||
break;
|
||||
}
|
||||
case SerializationUID::JS_BIGUINT64_ARRAY: {
|
||||
target = env->GetBigUint64ArrayFunction();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -1186,6 +1208,12 @@ JSHandle<JSTaggedValue> JSDeserializer::ReadJSTypedArray(SerializationUID uid)
|
||||
return JSHandle<JSTaggedValue>();
|
||||
}
|
||||
typedArray->SetArrayLength(thread_, arrayLength);
|
||||
|
||||
ContentType *contentType = reinterpret_cast<ContentType*>(GetBuffer(sizeof(ContentType)));
|
||||
if (contentType == nullptr) {
|
||||
return JSHandle<JSTaggedValue>();
|
||||
}
|
||||
typedArray->SetContentType(*contentType);
|
||||
return objTag;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -64,6 +64,8 @@ enum class SerializationUID : uint8_t {
|
||||
JS_INT32_ARRAY,
|
||||
JS_FLOAT32_ARRAY,
|
||||
JS_FLOAT64_ARRAY,
|
||||
JS_BIGINT64_ARRAY,
|
||||
JS_BIGUINT64_ARRAY,
|
||||
// TypedArray end
|
||||
// Support tagged object id reference end
|
||||
// Error UIDs
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -637,6 +637,10 @@ bool JSTaggedValue::DeleteProperty(JSThread *thread, const JSHandle<JSTaggedValu
|
||||
return ModuleNamespace::DeleteProperty(thread, obj, key);
|
||||
}
|
||||
|
||||
if (obj->IsTypedArray()) {
|
||||
return JSTypedArray::DeleteProperty(thread, obj, JSTypedArray::ToPropKey(thread, key));
|
||||
}
|
||||
|
||||
if (obj->IsSpecialContainer()) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "Can not delete property in Container Object", false);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -246,6 +246,30 @@ bool JSTypedArray::SetProperty(JSThread *thread, const JSHandle<JSTaggedValue> &
|
||||
return JSObject::SetProperty(thread, typedarray, key, value, receiver, mayThrow);
|
||||
}
|
||||
|
||||
// s12 10.4.5.6 [[Delete]] ( P )
|
||||
bool JSTypedArray::DeleteProperty(JSThread *thread, const JSHandle<JSTaggedValue> &typedarray,
|
||||
const JSHandle<JSTaggedValue> &key)
|
||||
{
|
||||
// 1. Assert: IsPropertyKey(P) is true.
|
||||
// 2. Assert: O is an Integer-Indexed exotic object.
|
||||
ASSERT(JSTaggedValue::IsPropertyKey(key));
|
||||
// 3. If Type(P) is String, then
|
||||
// a. Let numericIndex be CanonicalNumericIndexString(P).
|
||||
// b. If numericIndex is not undefined, then
|
||||
// i. If IsValidIntegerIndex(O, numericIndex) is false, return true; else return false.
|
||||
if (key->IsString()) {
|
||||
JSTaggedValue numericIndex = JSTaggedValue::CanonicalNumericIndexString(thread, key);
|
||||
if (!numericIndex.IsUndefined()) {
|
||||
if (!IsValidIntegerIndex(thread, typedarray, numericIndex)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 4. Return ? OrdinaryDelete(O, P).
|
||||
return JSObject::DeleteProperty(thread, JSHandle<JSObject>(typedarray), key);
|
||||
}
|
||||
|
||||
// 9.4.5.6 [[OwnPropertyKeys]] ( )
|
||||
JSHandle<TaggedArray> JSTypedArray::OwnPropertyKeys(JSThread *thread, const JSHandle<JSTaggedValue> &typedarray)
|
||||
{
|
||||
@ -349,10 +373,40 @@ OperationResult JSTypedArray::IntegerIndexedElementGet(JSThread *thread, const J
|
||||
// 13. Let elementType be the String value of the Element Type value in Table 49 for arrayTypeName.
|
||||
DataViewType elementType = TypedArrayHelper::GetType(typedarrayObj);
|
||||
// 14. Return GetValueFromBuffer(buffer, indexedPosition, elementType).
|
||||
JSTaggedValue result = BuiltinsArrayBuffer::GetValueFromBuffer(buffer, byteIndex, elementType, true);
|
||||
JSTaggedValue result = BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, byteIndex, elementType, true);
|
||||
return OperationResult(thread, result, PropertyMetaData(true));
|
||||
}
|
||||
|
||||
// s12 10.4.5.9 IsValidIntegerIndex ( O, index )
|
||||
bool JSTypedArray::IsValidIntegerIndex(JSThread *thread, const JSHandle<JSTaggedValue> &typedArray,
|
||||
JSTaggedValue &index)
|
||||
{
|
||||
// 1. Assert: O is an Integer-Indexed exotic object.
|
||||
// 2. If IsDetachedBuffer(O.[[ViewedArrayBuffer]]) is true, return false.
|
||||
JSHandle<JSObject> typedarrayObj(typedArray);
|
||||
JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer();
|
||||
if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) {
|
||||
return false;
|
||||
}
|
||||
// 3. If ! IsIntegralNumber(index) is false, return false.
|
||||
if (!index.IsInteger()) {
|
||||
return false;
|
||||
}
|
||||
// 4. If index is -0𝔽, return false.
|
||||
double val = index.GetNumber();
|
||||
if (val == 0 && std::signbit(val)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t arrLen = TypedArrayHelper::GetArrayLength(thread, typedarrayObj);
|
||||
// 5. If ℝ(index) < 0 or ℝ(index) ≥ O.[[ArrayLength]], return false.
|
||||
if (val < 0 || val >= arrLen) {
|
||||
return false;
|
||||
}
|
||||
// 6. Return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool JSTypedArray::FastCopyElementToArray(JSThread *thread, const JSHandle<JSTaggedValue> &typedArray,
|
||||
JSHandle<TaggedArray> &array)
|
||||
@ -385,7 +439,7 @@ bool JSTypedArray::FastCopyElementToArray(JSThread *thread, const JSHandle<JSTag
|
||||
// 12. Let indexedPosition = (index × elementSize) + offset.
|
||||
int32_t byteIndex = index * elementSize + offset;
|
||||
// 14. Return GetValueFromBuffer(buffer, indexedPosition, elementType).
|
||||
JSTaggedValue result = BuiltinsArrayBuffer::GetValueFromBuffer(buffer, byteIndex, elementType, true);
|
||||
JSTaggedValue result = BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, byteIndex, elementType, true);
|
||||
array->Set(thread, index, result);
|
||||
}
|
||||
return true;
|
||||
@ -422,7 +476,7 @@ OperationResult JSTypedArray::FastElementGet(JSThread *thread, const JSHandle<JS
|
||||
// 13. Let elementType be the String value of the Element Type value in Table 49 for arrayTypeName.
|
||||
DataViewType elementType = TypedArrayHelper::GetType(typedarrayObj);
|
||||
// 14. Return GetValueFromBuffer(buffer, indexedPosition, elementType).
|
||||
JSTaggedValue result = BuiltinsArrayBuffer::GetValueFromBuffer(buffer, byteIndex, elementType, true);
|
||||
JSTaggedValue result = BuiltinsArrayBuffer::GetValueFromBuffer(thread, buffer, byteIndex, elementType, true);
|
||||
return OperationResult(thread, result, PropertyMetaData(true));
|
||||
}
|
||||
|
||||
@ -435,54 +489,37 @@ bool JSTypedArray::IntegerIndexedElementSet(JSThread *thread, const JSHandle<JST
|
||||
// 2. Assert: O is an Object that has [[ViewedArrayBuffer]], [[ArrayLength]], [[ByteOffset]], and
|
||||
// [[TypedArrayName]] internal slots.
|
||||
ASSERT(typedarray->IsTypedArray());
|
||||
// 3. Let numValue be ToNumber(value).
|
||||
JSTaggedNumber numVal = JSTaggedValue::ToNumber(thread, value);
|
||||
// 3. If O.[[ContentType]] is BigInt, let numValue be ? ToBigInt(value).
|
||||
JSHandle<JSTaggedValue> numValueHandle;
|
||||
ContentType contentType = JSHandle<JSTypedArray>::Cast(typedarray)->GetContentType();
|
||||
if (contentType == ContentType::BigInt) {
|
||||
numValueHandle = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToBigInt(thread, value));
|
||||
} else {
|
||||
numValueHandle = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToNumber(thread, value));
|
||||
}
|
||||
// 4. ReturnIfAbrupt(numValue).
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
|
||||
|
||||
// 5. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot.
|
||||
JSHandle<JSObject> typedarrayObj(typedarray);
|
||||
JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer();
|
||||
// 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||
if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) {
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", false);
|
||||
}
|
||||
// 7. If IsInteger(index) is false, return false
|
||||
if (!index.IsInteger()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 8. If index = −0, return false.
|
||||
// 9. Let length be the value of O’s [[ArrayLength]] internal slot.
|
||||
// 10. If index < 0 or index ≥ length, return false.
|
||||
JSHandle<JSTaggedValue> indexHandle(thread, index);
|
||||
JSTaggedNumber indexNumber = JSTaggedValue::ToNumber(thread, indexHandle);
|
||||
double tNegZero = -0.0;
|
||||
auto eZero = JSTaggedNumber(tNegZero);
|
||||
JSHandle<JSTaggedValue> zero(thread, JSTaggedValue(0));
|
||||
if (JSTaggedNumber::SameValue(indexNumber, eZero)) {
|
||||
return false;
|
||||
// 5. If ! IsValidIntegerIndex(O, index) is true, then
|
||||
if (IsValidIntegerIndex(thread, typedarray, index)) {
|
||||
// 6. Let offset be the value of O’s [[ByteOffset]] internal slot.
|
||||
int32_t offset = TypedArrayHelper::GetByteOffset(thread, typedarrayObj);
|
||||
// 7. Let arrayTypeName be the String value of O’s [[TypedArrayName]] internal slot.
|
||||
// 8. Let elementSize be the Number value of the Element Size value specified in Table 49 for
|
||||
// arrayTypeName.
|
||||
int32_t elementSize = TypedArrayHelper::GetElementSize(typedarrayObj);
|
||||
// 9. Let indexedPosition = (index × elementSize) + offset.
|
||||
int32_t k = JSTaggedValue::ToInteger(thread, indexHandle).ToInt32();
|
||||
int32_t byteIndex = k * elementSize + offset;
|
||||
// 10. Let elementType be the String value of the Element Type value in Table 49 for arrayTypeName.
|
||||
DataViewType elementType = TypedArrayHelper::GetType(typedarrayObj);
|
||||
// 11. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(thread, buffer, byteIndex, elementType, numValueHandle, true);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
|
||||
}
|
||||
int32_t arrLen = TypedArrayHelper::GetArrayLength(thread, typedarrayObj);
|
||||
JSHandle<JSTaggedValue> arrLenHandle(thread, JSTaggedValue(arrLen));
|
||||
if (JSTaggedValue::Less(thread, indexHandle, zero) || !JSTaggedValue::Less(thread, indexHandle, arrLenHandle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 11. Let offset be the value of O’s [[ByteOffset]] internal slot.
|
||||
int32_t offset = TypedArrayHelper::GetByteOffset(thread, typedarrayObj);
|
||||
// 12. Let arrayTypeName be the String value of O’s [[TypedArrayName]] internal slot.
|
||||
// 13. Let elementSize be the Number value of the Element Size value specified in Table 49 for
|
||||
// arrayTypeName.
|
||||
int32_t elementSize = TypedArrayHelper::GetElementSize(typedarrayObj);
|
||||
// 14. Let indexedPosition = (index × elementSize) + offset.
|
||||
int32_t k = JSTaggedValue::ToInteger(thread, indexHandle).ToInt32();
|
||||
int32_t byteIndex = k * elementSize + offset;
|
||||
// 15. Let elementType be the String value of the Element Type value in Table 49 for arrayTypeName.
|
||||
DataViewType elementType = TypedArrayHelper::GetType(typedarrayObj);
|
||||
// 16. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(buffer, byteIndex, elementType, numVal, true);
|
||||
// 17. Return true.
|
||||
return true;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -20,6 +20,7 @@
|
||||
#include "js_object.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
enum class ContentType : uint8_t { None = 1, Number, BigInt };
|
||||
class JSTypedArray : public JSObject {
|
||||
public:
|
||||
static JSTypedArray *Cast(ObjectHeader *object)
|
||||
@ -69,6 +70,9 @@ public:
|
||||
static bool SetProperty(JSThread *thread, const JSHandle<JSTaggedValue> &typedarray,
|
||||
const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value,
|
||||
const JSHandle<JSTaggedValue> &receiver, bool mayThrow = false);
|
||||
// s12 10.4.5.6 [[Delete]] ( P )
|
||||
static bool DeleteProperty(JSThread *thread, const JSHandle<JSTaggedValue> &typedarray,
|
||||
const JSHandle<JSTaggedValue> &key);
|
||||
// 9.4.5.6 [[OwnPropertyKeys]] ( )
|
||||
static JSHandle<TaggedArray> OwnPropertyKeys(JSThread *thread, const JSHandle<JSTaggedValue> &typedarray);
|
||||
// 9.4.5.7 IntegerIndexedObjectCreate (prototype, internalSlotsList)
|
||||
@ -81,18 +85,20 @@ public:
|
||||
// 9.4.5.9 IntegerIndexedElementSet ( O, index, value )
|
||||
static bool IntegerIndexedElementSet(JSThread *thread, const JSHandle<JSTaggedValue> &typedarray,
|
||||
JSTaggedValue index, const JSHandle<JSTaggedValue> &value);
|
||||
|
||||
// s12 10.4.5.9 IsValidIntegerIndex ( O, index )
|
||||
static bool IsValidIntegerIndex(JSThread *thread, const JSHandle<JSTaggedValue> &typedArray,
|
||||
JSTaggedValue &index);
|
||||
static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE;
|
||||
ACCESSORS(ViewedArrayBuffer, VIEWED_ARRAY_BUFFER_OFFSET, TYPED_ARRAY_NAME_OFFSET)
|
||||
ACCESSORS(TypedArrayName, TYPED_ARRAY_NAME_OFFSET, BYTE_LENGTH_OFFSET)
|
||||
ACCESSORS(ByteLength, BYTE_LENGTH_OFFSET, BYTE_OFFSET_OFFSET)
|
||||
ACCESSORS(ByteOffset, BYTE_OFFSET_OFFSET, ARRAY_LENGTH_OFFSET)
|
||||
ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, SIZE)
|
||||
|
||||
ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, CONTENT_TYPE_OFFSET)
|
||||
ACCESSORS_PRIMITIVE_FIELD(ContentType, ContentType, CONTENT_TYPE_OFFSET, LAST_OFFSET)
|
||||
DEFINE_ALIGN_SIZE(LAST_OFFSET);
|
||||
static const uint32_t MAX_TYPED_ARRAY_INDEX = MAX_ELEMENT_INDEX;
|
||||
DECL_DUMP()
|
||||
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE)
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, CONTENT_TYPE_OFFSET)
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_JS_TYPED_ARRAY_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -194,6 +194,8 @@ void ObjectXRay::VisitObjectBody(TaggedObject *object, JSHClass *klass, const Ec
|
||||
case JSType::JS_UINT32_ARRAY:
|
||||
case JSType::JS_FLOAT32_ARRAY:
|
||||
case JSType::JS_FLOAT64_ARRAY:
|
||||
case JSType::JS_BIGINT64_ARRAY:
|
||||
case JSType::JS_BIGUINT64_ARRAY:
|
||||
JSTypedArray::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::JS_PRIMITIVE_REF:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -341,7 +341,11 @@ JSHandle<TaggedArray> ObjectFactory::CloneProperties(const JSHandle<TaggedArray>
|
||||
return EmptyArray();
|
||||
}
|
||||
NewObjectHook();
|
||||
JSHandle<TaggedArray> newArray = NewTaggedArray(newLength);
|
||||
auto klass = old->GetClass();
|
||||
size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
|
||||
auto header = heap_->AllocateYoungOrHugeObject(klass, size);
|
||||
JSHandle<TaggedArray> newArray(thread_, header);
|
||||
newArray->SetLength(newLength);
|
||||
|
||||
for (uint32_t i = 0; i < newLength; i++) {
|
||||
JSTaggedValue value = old->Get(i);
|
||||
@ -719,11 +723,14 @@ JSHandle<JSObject> ObjectFactory::NewJSObjectByConstructor(const JSHandle<JSFunc
|
||||
case JSType::JS_UINT32_ARRAY:
|
||||
case JSType::JS_FLOAT32_ARRAY:
|
||||
case JSType::JS_FLOAT64_ARRAY:
|
||||
case JSType::JS_BIGINT64_ARRAY:
|
||||
case JSType::JS_BIGUINT64_ARRAY:
|
||||
JSTypedArray::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined());
|
||||
JSTypedArray::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined());
|
||||
JSTypedArray::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0));
|
||||
JSTypedArray::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0));
|
||||
JSTypedArray::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0));
|
||||
JSTypedArray::Cast(*obj)->SetContentType(ContentType::None);
|
||||
break;
|
||||
case JSType::JS_REG_EXP:
|
||||
JSRegExp::Cast(*obj)->SetByteCodeBuffer(thread_, JSTaggedValue::Undefined());
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -261,6 +261,9 @@ namespace panda::ecmascript {
|
||||
V(Array, ToString) \
|
||||
V(Array, Unshift) \
|
||||
V(Array, Values) \
|
||||
V(Array, Includes) \
|
||||
V(Array, Flat) \
|
||||
V(Array, FlatMap) \
|
||||
V(ArrayBuffer, Constructor) \
|
||||
V(ArrayBuffer, Slice) \
|
||||
V(ArrayBuffer, GetValueFromBuffer) \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-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
|
||||
@ -471,6 +471,7 @@ public:
|
||||
JSTaggedValue byteLength = resJSInt8Array->GetByteLength();
|
||||
JSTaggedValue byteOffset = resJSInt8Array->GetByteOffset();
|
||||
JSTaggedValue arrayLength = resJSInt8Array->GetArrayLength();
|
||||
ContentType contentType = resJSInt8Array->GetContentType();
|
||||
JSHandle<JSTaggedValue> viewedArrayBuffer(thread, resJSInt8Array->GetViewedArrayBuffer());
|
||||
|
||||
EXPECT_TRUE(typedArrayName->IsString());
|
||||
@ -479,6 +480,7 @@ public:
|
||||
EXPECT_TRUE(byteLength.GetInt() == originTypedArray->GetByteLength().GetInt()) << "Not Same ByteLength";
|
||||
EXPECT_TRUE(byteOffset.GetInt() == originTypedArray->GetByteOffset().GetInt()) << "Not Same ByteOffset";
|
||||
EXPECT_TRUE(arrayLength.GetInt() == originTypedArray->GetArrayLength().GetInt()) << "Not Same ArrayLength";
|
||||
EXPECT_TRUE(contentType == originTypedArray->GetContentType()) << "Not Same ContentType";
|
||||
|
||||
// check arrayBuffer
|
||||
JSHandle<JSArrayBuffer> resJSArrayBuffer(viewedArrayBuffer);
|
||||
@ -951,8 +953,12 @@ HWTEST_F_L0(JSSerializerTest, SerializeJSArrayBuffer)
|
||||
thread->GetEcmaVM()->GetFactory()->NewJSArrayBufferData(jsArrayBuffer, byteLength);
|
||||
jsArrayBuffer->SetArrayBufferByteLength(byteLength);
|
||||
JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(jsArrayBuffer);
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(obj.GetTaggedValue(), 1, DataViewType::UINT8, JSTaggedNumber(7), true);
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(obj.GetTaggedValue(), 3, DataViewType::UINT8, JSTaggedNumber(17), true);
|
||||
JSHandle<JSTaggedValue> number(thread, JSTaggedValue(7));
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(thread, obj.GetTaggedValue(), 1, DataViewType::UINT8,
|
||||
number, true);
|
||||
number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(17));
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(thread, obj.GetTaggedValue(), 3, DataViewType::UINT8, // 3:index
|
||||
number, true);
|
||||
|
||||
JSSerializer *serializer = new JSSerializer(thread);
|
||||
bool success = serializer->SerializeJSTaggedValue(JSHandle<JSTaggedValue>::Cast(jsArrayBuffer));
|
||||
@ -1046,9 +1052,13 @@ JSArrayBuffer *CreateTestJSArrayBuffer(JSThread *thread)
|
||||
jsArrayBuffer->SetArrayBufferByteLength(byteLength);
|
||||
JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(jsArrayBuffer);
|
||||
// 7 : test case
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(obj.GetTaggedValue(), 1, DataViewType::UINT8, JSTaggedNumber(7), true);
|
||||
JSHandle<JSTaggedValue> number(thread, JSTaggedValue(7));
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(thread, obj.GetTaggedValue(), 1, DataViewType::UINT8,
|
||||
number, true);
|
||||
// 3, 17 : test case
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(obj.GetTaggedValue(), 3, DataViewType::UINT8, JSTaggedNumber(17), true);
|
||||
number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(17));
|
||||
BuiltinsArrayBuffer::SetValueInBuffer(thread, obj.GetTaggedValue(), 3, DataViewType::UINT8, // 3:index
|
||||
number, true);
|
||||
return *jsArrayBuffer;
|
||||
}
|
||||
|
||||
@ -1068,6 +1078,7 @@ HWTEST_F_L0(JSSerializerTest, SerializeJSTypedArray)
|
||||
int8Array->SetByteOffset(thread, JSTaggedValue(byteOffset));
|
||||
int8Array->SetTypedArrayName(thread, thread->GlobalConstants()->GetInt8ArrayString());
|
||||
int8Array->SetArrayLength(thread, JSTaggedValue(arrayLength));
|
||||
int8Array->SetContentType(ContentType::Number);
|
||||
JSSerializer *serializer = new JSSerializer(thread);
|
||||
bool success = serializer->SerializeJSTaggedValue(JSHandle<JSTaggedValue>::Cast(int8Array));
|
||||
EXPECT_TRUE(success);
|
||||
|
Loading…
Reference in New Issue
Block a user