====================test.js========= for (let v0 = 1; v0 < 100; v0++) { const v2 = [1000]; const v4 = new BigUint64Array(v0); try { v4.set(v2); print(v4[0]) } catch (e6) {print(e6)} Object.defineProperty(v2, 10, {writable: true,value: 10}); } ==================================== Run args: ./jsc -f test.js --useConcurrentJIT=0 --jitPolicyScale=0 JSC should throw an exception "TypeError: Invalid argument type in ToBigInt operation", but it didn't actually. This bug exists even when jitPolicyScale=1. This bug may be related to runtime/JSGenericTypedArrayViewInlines.h setFromArrayLike ``` if constexpr (TypedArrayStorageType != TypeBigInt64 || TypedArrayStorageType != TypeBigUint64) { if (JSArray* array = jsDynamicCast<JSArray*>(object); LIKELY(array && isJSArray(array))) { if (safeLength == length && (safeLength + objectOffset) <= array->length() && array->isIteratorProtocolFastAndNonObservable()) { IndexingType indexingType = array->indexingType() & IndexingShapeMask; if (indexingType == Int32Shape) { copyFromInt32ShapeArray(offset, array, objectOffset, safeLength); return true; } if (indexingType == DoubleShape) { copyFromDoubleShapeArray(offset, array, objectOffset, safeLength); return true; } } } } ``` In copyFromInt32ShapeArray does not assert even when typeValue == TypeBigInt64 becuase '||' in `ASSERT(Adaptor::typeValue != TypeBigInt64 || Adaptor::typeValue != TypeBigUint64)` , should this be a '&&'? ``` template<typename Adaptor> void JSGenericTypedArrayView<Adaptor>::copyFromInt32ShapeArray(size_t offset, JSArray* array, size_t objectOffset, size_t length) { ASSERT(canAccessRangeQuickly(offset, length)); ASSERT((array->indexingType() & IndexingShapeMask) == Int32Shape); ASSERT(Adaptor::typeValue != TypeBigInt64 || Adaptor::typeValue != TypeBigUint64); ASSERT((length + objectOffset) <= array->length()); ASSERT(array->isIteratorProtocolFastAndNonObservable()); // If the destination is uint32_t or int32_t, we can use copyElements. // 1. int32_t -> uint32_t conversion does not change any bit representation. So we can simply copy them. // 2. Hole is represented as JSEmpty in Int32Shape, which lower 32bits is zero. And we expect 0 for undefined, thus this copying simply works. if constexpr (Adaptor::typeValue == TypeUint8 || Adaptor::typeValue == TypeInt8) { WTF::copyElements(bitwise_cast<uint8_t*>(typedVector() + offset), bitwise_cast<const uint64_t*>(array->butterfly()->contiguous().data() + objectOffset), length); return; } if constexpr (Adaptor::typeValue == TypeUint16 || Adaptor::typeValue == TypeInt16) { WTF::copyElements(bitwise_cast<uint16_t*>(typedVector() + offset), bitwise_cast<const uint64_t*>(array->butterfly()->contiguous().data() + objectOffset), length); return; } if constexpr (Adaptor::typeValue == TypeUint32 || Adaptor::typeValue == TypeInt32) { WTF::copyElements(bitwise_cast<uint32_t*>(typedVector() + offset), bitwise_cast<const uint64_t*>(array->butterfly()->contiguous().data() + objectOffset), length); return; } for (size_t i = 0; i < length; ++i) { JSValue value = array->butterfly()->contiguous().at(array, static_cast<unsigned>(i + objectOffset)).get(); if (LIKELY(!!value)) setIndexQuicklyToNativeValue(offset + i, Adaptor::toNativeFromInt32(value.asInt32())); else setIndexQuicklyToNativeValue(offset + i, Adaptor::toNativeFromUndefined()); } } ``` In copyFromInt32ShapeArray, when Adaptor::typeValue == TypeBigUint64, Int32 can not be convert to BigUint64 directly, it should throw an exception which is similar to `toNativeFromValue`.
<rdar://problem/117816146>
Pull request: https://github.com/WebKit/WebKit/pull/19868
Committed 270133@main (0e5745978de8): <https://commits.webkit.org/270133@main> Reviewed commits have been landed. Closing PR #19868 and removing active labels.