!7091 【bug】Exception in obtaining length for TypeArray.reduce and Array.prototype.reduce

Merge pull request !7091 from liujia178/mjsunit_typedarray_reduce
This commit is contained in:
openharmony_ci 2024-07-20 22:18:31 +00:00 committed by Gitee
commit 5158e8f248
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
7 changed files with 108 additions and 14 deletions

View File

@ -1598,7 +1598,6 @@ JSTaggedValue BuiltinsArray::Reduce(EcmaRuntimeCallInfo *argv)
JSThread *thread = argv->GetThread();
[[maybe_unused]] EcmaHandleScope handleScope(thread);
uint32_t argc = argv->GetArgsNumber();
// 1. Let O be ToObject(this value).
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
@ -1607,9 +1606,23 @@ JSTaggedValue BuiltinsArray::Reduce(EcmaRuntimeCallInfo *argv)
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
// 3. Let len be ToLength(Get(O, "length")).
int64_t len = ArrayHelper::GetLength(thread, thisObjVal);
int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
// 4. ReturnIfAbrupt(len).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return ReduceInner(argv, len);
}
JSTaggedValue BuiltinsArray::ReduceInner(EcmaRuntimeCallInfo *argv, int64_t len)
{
ASSERT(argv);
JSThread *thread = argv->GetThread();
uint32_t argc = argv->GetArgsNumber();
// 1. Let O be ToObject(this value).
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
// 2. ReturnIfAbrupt(O).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
// 5. If IsCallable(callbackfn) is false, throw a TypeError exception.
JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
@ -1671,6 +1684,25 @@ JSTaggedValue BuiltinsArray::ReduceRight(EcmaRuntimeCallInfo *argv)
BUILTINS_API_TRACE(argv->GetThread(), Array, ReduceRight);
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);
// 2. ReturnIfAbrupt(O).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
// 3. Let len be ToLength(Get(O, "length")).
int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
// 4. ReturnIfAbrupt(len).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return ReduceRightInner(argv, len);
}
JSTaggedValue BuiltinsArray::ReduceRightInner(EcmaRuntimeCallInfo *argv, int64_t len)
{
ASSERT(argv);
JSThread *thread = argv->GetThread();
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
uint32_t argc = argv->GetArgsNumber();
@ -1682,11 +1714,6 @@ JSTaggedValue BuiltinsArray::ReduceRight(EcmaRuntimeCallInfo *argv)
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
// 3. Let len be ToLength(Get(O, "length")).
int64_t len = ArrayHelper::GetLength(thread, thisObjVal);
// 4. ReturnIfAbrupt(len).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
// 5. If IsCallable(callbackfn) is false, throw a TypeError exception.
JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
if (!callbackFnHandle->IsCallable()) {

View File

@ -239,6 +239,10 @@ public:
static JSTaggedValue MapUnStableJSArray(JSThread *thread, JSHandle<JSTaggedValue> &thisArgHandle,
JSHandle<JSTaggedValue> &thisObjVal, int64_t k, int64_t len, JSHandle<JSObject> newArrayHandle,
JSHandle<JSTaggedValue> &callbackFnHandle);
static JSTaggedValue ReduceInner(EcmaRuntimeCallInfo *argv, int64_t len);
static JSTaggedValue ReduceRightInner(EcmaRuntimeCallInfo *argv, int64_t len);
private:
#define BUILTIN_ARRAY_FUNCTION_ENTRY(name, method, length, id) \
base::BuiltinFunctionEntry::Create(name, BuiltinsArray::method, length, kungfu::BuiltinsStubCSigns::id),

View File

@ -1098,10 +1098,23 @@ JSTaggedValue BuiltinsTypedArray::Reduce(EcmaRuntimeCallInfo *argv)
{
ASSERT(argv);
BUILTINS_API_TRACE(argv->GetThread(), TypedArray, Reduce);
if (!GetThis(argv)->IsTypedArray()) {
THROW_TYPE_ERROR_AND_RETURN(argv->GetThread(), "This is not a TypedArray.", JSTaggedValue::Exception());
JSThread *thread = argv->GetThread();
[[maybe_unused]] EcmaHandleScope handleScope(thread);
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
if (!thisHandle->IsTypedArray()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "This is not a TypedArray.", JSTaggedValue::Exception());
}
return BuiltinsArray::Reduce(argv);
BuiltinsArrayBuffer::IsDetachedBuffer(thread, JSHandle<JSTypedArray>::Cast(thisHandle));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
int64_t len = JSHandle<JSTypedArray>::Cast(thisObjVal)->GetArrayLength();
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return BuiltinsArray::ReduceInner(argv, len);
}
// 22.2.3.20
@ -1109,10 +1122,23 @@ JSTaggedValue BuiltinsTypedArray::ReduceRight(EcmaRuntimeCallInfo *argv)
{
ASSERT(argv);
BUILTINS_API_TRACE(argv->GetThread(), TypedArray, ReduceRight);
if (!GetThis(argv)->IsTypedArray()) {
THROW_TYPE_ERROR_AND_RETURN(argv->GetThread(), "This is not a TypedArray.", JSTaggedValue::Exception());
JSThread *thread = argv->GetThread();
[[maybe_unused]] EcmaHandleScope handleScope(thread);
JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
if (!thisHandle->IsTypedArray()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "This is not a TypedArray.", JSTaggedValue::Exception());
}
return BuiltinsArray::ReduceRight(argv);
BuiltinsArrayBuffer::IsDetachedBuffer(thread, JSHandle<JSTypedArray>::Cast(thisHandle));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
int64_t len = JSHandle<JSTypedArray>::Cast(thisObjVal)->GetArrayLength();
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return BuiltinsArray::ReduceRightInner(argv, len);
}
// 22.2.3.21

View File

@ -1015,6 +1015,7 @@ void BuiltinsTypedArrayStubBuilder::ReduceRight(GateRef glue, GateRef thisValue,
Label callbackFnHandleCallable(env);
Label noTypeError(env);
Label typedArray(env);
Label notDetached(env);
BRANCH(IsEcmaObject(thisValue), &ecmaObj, slowPath);
Bind(&ecmaObj);
@ -1022,6 +1023,9 @@ void BuiltinsTypedArrayStubBuilder::ReduceRight(GateRef glue, GateRef thisValue,
Bind(&typedArray);
BRANCH(HasConstructor(thisValue), slowPath, &defaultConstr);
Bind(&defaultConstr);
GateRef buffer = GetViewedArrayBuffer(thisValue);
BRANCH(IsDetachedBuffer(buffer), slowPath, &notDetached);
Bind(&notDetached);
GateRef thisLen = GetArrayLength(thisValue);
BRANCH(Int64GreaterThanOrEqual(numArgs, IntPtr(1)), &atLeastOneArg, slowPath);
Bind(&atLeastOneArg);
@ -1119,6 +1123,7 @@ void BuiltinsTypedArrayStubBuilder::Reduce(GateRef glue, GateRef thisValue, Gate
Label callbackFnHandleCallable(env);
Label noTypeError(env);
Label typedArray(env);
Label notDetached(env);
BRANCH(IsEcmaObject(thisValue), &ecmaObj, slowPath);
Bind(&ecmaObj);
@ -1126,6 +1131,9 @@ void BuiltinsTypedArrayStubBuilder::Reduce(GateRef glue, GateRef thisValue, Gate
Bind(&typedArray);
BRANCH(HasConstructor(thisValue), slowPath, &defaultConstr);
Bind(&defaultConstr);
GateRef buffer = GetViewedArrayBuffer(thisValue);
BRANCH(IsDetachedBuffer(buffer), slowPath, &notDetached);
Bind(&notDetached);
GateRef thisLen = GetArrayLength(thisValue);
BRANCH(Int64GreaterThanOrEqual(numArgs, IntPtr(1)), &atLeastOneArg, slowPath);
Bind(&atLeastOneArg);

View File

@ -260,4 +260,10 @@ true
true
true
true
true
true
true
true
true
true
true

View File

@ -1055,3 +1055,27 @@ var arr_fill1 = new Uint8ClampedArray([0, 0, 0]).fill(2.50000);
arr_fill1.forEach((b)=> {
print(2 == b);
})
function sum(a, b) { return a + b; }
var arr_shadow_length = new Uint8Array([11, 22]);
Object.defineProperty(arr_shadow_length, 'length', {value: 1});
print(Array.prototype.reduce.call(arr_shadow_length, sum, 0) == 11);
print(Array.prototype.reduceRight.call(arr_shadow_length, sum, 0) == 11);
print(Uint8Array.prototype.reduce.length == 1);
print(Uint8Array.prototype.reduceRight.length == 1);
var arr_reduce = new Uint8Array([11, 22]);
ArkTools.arrayBufferDetach(arr_reduce.buffer);
try {
arr_reduce.reduce(sum, 0);
} catch (e) {
print(e instanceof TypeError);
}
var arr_reduceRight = new Uint8Array([11, 22]);
ArkTools.arrayBufferDetach(arr_reduceRight.buffer);
try {
arr_reduceRight.reduceRight(sum, 0);
} catch (e) {
print(e instanceof TypeError);
}

View File

@ -3014,7 +3014,6 @@
"mjsunit/es6/math-trunc.js",
"mjsunit/es6/promise-all.js",
"mjsunit/es6/array-species-delete.js",
"mjsunit/es6/typedarray-reduce.js",
"mjsunit/es6/math-log2-log10.js",
"mjsunit/es6/promise-lookup-getter-setter.js",
"mjsunit/es6/instanceof-proxies.js",