From 10ed353cd3b055c5c6da21e1a299939d80d22981 Mon Sep 17 00:00:00 2001 From: wangrx Date: Tue, 19 Mar 2024 17:47:35 +0800 Subject: [PATCH] Fix mjsunit/es6/typedarray-fill.js --- ecmascript/builtins/builtins_array.cpp | 2 +- ecmascript/builtins/builtins_arraybuffer.cpp | 6 +- ecmascript/builtins/builtins_typedarray.cpp | 110 ++++++++++++++++++- 3 files changed, 113 insertions(+), 5 deletions(-) diff --git a/ecmascript/builtins/builtins_array.cpp b/ecmascript/builtins/builtins_array.cpp index 4992971f6..69232e4e1 100644 --- a/ecmascript/builtins/builtins_array.cpp +++ b/ecmascript/builtins/builtins_array.cpp @@ -774,7 +774,7 @@ JSTaggedValue BuiltinsArray::Fill(EcmaRuntimeCallInfo *argv) } // 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_arraybuffer.cpp b/ecmascript/builtins/builtins_arraybuffer.cpp index 2fee49c75..c36871e73 100644 --- a/ecmascript/builtins/builtins_arraybuffer.cpp +++ b/ecmascript/builtins/builtins_arraybuffer.cpp @@ -786,7 +786,11 @@ void BuiltinsArrayBuffer::FastSetValueInBufferForUint8Clamped(uint8_t *byteBegin } else { val = val >= UINT8_MAX ? UINT8_MAX : val; constexpr double HALF = 0.5; - val = val == HALF ? 0 : std::round(val); + if (std::fmod(std::floor(val), 2) == 0) { + val = (val - std::floor(val)) <= HALF ? std::floor(val) : std::round(val); + } else { + val = val == HALF ? 0 : std::round(val); + } res = static_cast(val); } FastSetTypeData(byteBeginOffset, byteEndOffset, res); diff --git a/ecmascript/builtins/builtins_typedarray.cpp b/ecmascript/builtins/builtins_typedarray.cpp index cd13f0dd0..3edc30c36 100644 --- a/ecmascript/builtins/builtins_typedarray.cpp +++ b/ecmascript/builtins/builtins_typedarray.cpp @@ -571,10 +571,114 @@ JSTaggedValue BuiltinsTypedArray::Fill(EcmaRuntimeCallInfo *argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), TypedArray, Fill); - 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 thisObjVal = GetThis(argv); + if (!thisObjVal->IsTypedArray()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "This is not a TypedArray.", JSTaggedValue::Exception()); } - return BuiltinsArray::Fill(argv); + + JSTaggedValue buffer = JSHandle::Cast(thisObjVal)->GetViewedArrayBufferOrByteArray(); + if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { + THROW_TYPE_ERROR_AND_RETURN(thread, "The targetBuffer of This value is detached buffer.", + JSTaggedValue::Exception()); + } + + // 1. Let O be ToObject(this value). + JSHandle thisObjHandle = JSTaggedValue::ToObject(thread, thisObjVal); + + if (thisObjVal->IsJSArray()) { + bool isDictionary = thisObjHandle->GetJSHClass()->IsDictionaryElement(); + if (isDictionary) { + uint32_t length = JSArray::Cast(*thisObjHandle)->GetLength(); + uint32_t size = thisObjHandle->GetNumberOfElements(); + if (length - size > JSObject::MAX_GAP) { + JSObject::TryOptimizeAsFastElements(thread, thisObjHandle); + } + } + } + + // 2. ReturnIfAbrupt(O). + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + JSHandle value = GetCallArg(argv, 0); + if (thisObjVal->IsTypedArray()) { + ContentType contentType = JSHandle::Cast(thisObjVal)->GetContentType(); + if (contentType == ContentType::BigInt) { + value = JSHandle(thread, JSTaggedValue::ToBigInt(thread, value)); + } else { + value = JSHandle(thread, JSTaggedValue::ToNumber(thread, value)); + } + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + } + + // 3. Let len be ToLength(Get(O, "length")). + int64_t len = JSHandle::Cast(thisObjHandle)->GetArrayLength(); + // 4. ReturnIfAbrupt(len). + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 5. Let relativeStart be ToInteger(start). + JSHandle startArg = GetCallArg(argv, 1); + JSTaggedNumber argStartTemp = JSTaggedValue::ToInteger(thread, startArg); + // 6. ReturnIfAbrupt(relativeStart). + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + double argStart = argStartTemp.GetNumber(); + // 7. If relativeStart < 0, let k be max((len + relativeStart),0); else let k be min(relativeStart, len). + int64_t start = 0; + if (argStart < 0) { + double tempStart = argStart + len; + start = tempStart > 0 ? tempStart : 0; + } else { + start = argStart < len ? argStart : len; + } + + // 8. If end is undefined, let relativeEnd be len; else let relativeEnd be ToInteger(end). + double argEnd = len; + JSHandle endArg = GetCallArg(argv, INDEX_TWO); + if (!endArg->IsUndefined()) { + JSTaggedNumber argEndTemp = JSTaggedValue::ToInteger(thread, endArg); + // 9. ReturnIfAbrupt(relativeEnd). + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + argEnd = argEndTemp.GetNumber(); + } + + // 10. If relativeEnd < 0, let final be max((len + relativeEnd),0); else let final be min(relativeEnd, len). + int64_t end = len; + if (argEnd < 0) { + double tempEnd = argEnd + len; + end = tempEnd > 0 ? tempEnd : 0; + } else { + end = argEnd < len ? argEnd : len; + } + // 11. Repeat, while k < final + // a. Let Pk be ToString(k). + // b. Let setStatus be Set(O, Pk, value, true). + // c. ReturnIfAbrupt(setStatus). + // d. Increase k by 1. + + if (thisObjVal->IsStableJSArray(thread) && !startArg->IsJSObject() && !endArg->IsJSObject()) { + return JSStableArray::Fill(thread, thisObjHandle, value, start, end, len); + } + + if (thisObjVal->IsTypedArray()) { + bool result = JSTypedArray::FastTypedArrayFill(thread, thisObjVal, value, start, end); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (result) { + return thisObjHandle.GetTaggedValue(); + } + } + + int64_t k = start; + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + while (k < end) { + key.Update(JSTaggedValue(k)); + JSArray::FastSetPropertyByValue(thread, thisObjVal, key, value); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + k++; + } + + // 12. Return O. + return thisObjHandle.GetTaggedValue(); } // 22.2.3.9 %TypedArray%.prototype.filter ( callbackfn [ , thisArg ] ) -- Gitee