From 6172ed15c2871a415d73b411475db43a5b4d8bb6 Mon Sep 17 00:00:00 2001 From: mingyix <13926077+mingyix@user.noreply.gitee.com> Date: Mon, 18 Mar 2024 17:07:56 +0800 Subject: [PATCH] [fixbug][es6/typedarray-iteration.js]Typedarray shadowing length doesn't affect some, unlike Array.prototype.some. If IsDetachedBuffer expected typedError. --- ecmascript/builtins/builtins_array.cpp | 2 +- ecmascript/builtins/builtins_typedarray.cpp | 74 ++++++++++++++++++++- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/ecmascript/builtins/builtins_array.cpp b/ecmascript/builtins/builtins_array.cpp index f5c221e82..1b0a8fe5b 100644 --- a/ecmascript/builtins/builtins_array.cpp +++ b/ecmascript/builtins/builtins_array.cpp @@ -2199,7 +2199,7 @@ JSTaggedValue BuiltinsArray::Some(EcmaRuntimeCallInfo *argv) JSHandle 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); diff --git a/ecmascript/builtins/builtins_typedarray.cpp b/ecmascript/builtins/builtins_typedarray.cpp index ac43756a6..04e387b82 100644 --- a/ecmascript/builtins/builtins_typedarray.cpp +++ b/ecmascript/builtins/builtins_typedarray.cpp @@ -1552,11 +1552,79 @@ JSTaggedValue BuiltinsTypedArray::Slice(EcmaRuntimeCallInfo *argv) JSTaggedValue BuiltinsTypedArray::Some(EcmaRuntimeCallInfo *argv) { ASSERT(argv); - BUILTINS_API_TRACE(argv->GetThread(), TypedArray, Some); + JSThread *thread = argv->GetThread(); + BUILTINS_API_TRACE(thread, TypedArray, Some); if (!GetThis(argv)->IsTypedArray()) { - THROW_TYPE_ERROR_AND_RETURN(argv->GetThread(), "This is not a TypedArray.", JSTaggedValue::Exception()); + THROW_TYPE_ERROR_AND_RETURN(thread, "This is not a TypedArray.", JSTaggedValue::Exception()); + } + + // 1. Let O be ToObject(this value). + JSHandle thisHandle = GetThis(argv); + + JSHandle typedArray(thisHandle); + JSTaggedValue srcBuffer = typedArray->GetViewedArrayBufferOrByteArray(); + if (BuiltinsArrayBuffer::IsDetachedBuffer(srcBuffer)) { + THROW_TYPE_ERROR_AND_RETURN(thread, "The ArrayBuffer of typedArray is detached buffer.", + JSTaggedValue::Exception()); + } + + JSHandle thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle); + // 2. ReturnIfAbrupt(O). + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + JSHandle thisObjVal(thisObjHandle); + + // 3. Let len be ToLength(Get(O, "length")). + int64_t len = JSHandle::Cast(thisHandle)->GetArrayLength(); + // 4. ReturnIfAbrupt(len). + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 5. If IsCallable(callbackfn) is false, throw a TypeError exception. + JSHandle callbackFnHandle = GetCallArg(argv, 0); + if (!callbackFnHandle->IsCallable()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "the callbackfun is not callable.", JSTaggedValue::Exception()); } - return BuiltinsArray::Some(argv); + + // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. + JSHandle thisArgHandle = GetCallArg(argv, 1); + + // 7. Let k be 0. + // 8. Repeat, while k < len + // a. Let Pk be ToString(k). + // b. Let kPresent be HasProperty(O, Pk). + // c. ReturnIfAbrupt(kPresent). + // d. If kPresent is true, then + // i. Let kValue be Get(O, Pk). + // ii. ReturnIfAbrupt(kValue). + // iii. Let testResult be ToBoolean(Call(callbackfn, T, «kValue, k, and O»)). + // iv. ReturnIfAbrupt(testResult). + // v. If testResult is true, return true. + // e. Increase k by 1. + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + int64_t k = 0; + while (k < len) { + bool exists = (thisHandle->IsTypedArray() || JSTaggedValue::HasProperty(thread, thisObjVal, k)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (exists) { + key.Update(JSTaggedValue(k)); + JSHandle kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, key); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + const uint32_t argsLength = 3; // 3: «kValue, k, O» + JSHandle undefined = thread->GlobalConstants()->GetHandledUndefined(); + EcmaRuntimeCallInfo *info = + EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue()); + JSTaggedValue callResult = JSFunction::Call(info); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (callResult.ToBoolean()) { + return GetTaggedBoolean(true); + } + } + k++; + } + + // 9. Return false. + return GetTaggedBoolean(false); } // 22.2.3.25 -- Gitee