!788 Add typedArray and array extensions

Merge pull request !788 from 王犇/master
This commit is contained in:
openharmony_ci 2022-03-24 08:26:01 +00:00 committed by Gitee
commit c5ac3e084f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
30 changed files with 851 additions and 187 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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 Os [[ByteLength]] internal slot to byteLength.
// 21. Set Os [[ByteOffset]] internal slot to 0.
// 22. Set Os [[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;
}

View File

@ -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,

View File

@ -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_);

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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 typedArrays [[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 typedArrays [[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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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) \

View File

@ -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"));

View File

@ -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) \

View File

@ -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);

View File

@ -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 */

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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 Os [[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 Os [[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 Os [[ByteOffset]] internal slot.
int32_t offset = TypedArrayHelper::GetByteOffset(thread, typedarrayObj);
// 7. Let arrayTypeName be the String value of Os [[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 Os [[ByteOffset]] internal slot.
int32_t offset = TypedArrayHelper::GetByteOffset(thread, typedarrayObj);
// 12. Let arrayTypeName be the String value of Os [[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

View File

@ -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

View File

@ -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:

View File

@ -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());

View File

@ -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) \

View File

@ -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);