Skip to content
Permalink
Browse files
ArrayBuffer species should be ignored when cloning a Typed Array
https://bugs.webkit.org/show_bug.cgi?id=240996

Reviewed by Yusuke Suzuki.

This patch implements the spec change of tc39/ecma262#2719:
Constructing one Typed Array from another used to require that we check @@species on the source buffer and create
a new ArrayBuffer using the species constructor's *prototype*...without actually calling the species constructor itself.
Happily, this ridiculous behavior turned out to be web-compatible to remove.

* JSTests/test262/expectations.yaml:
* Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewWithArguments):
(JSC::constructCustomArrayBufferIfNeeded): Deleted.

Canonical link: https://commits.webkit.org/251040@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294929 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
rkirsling committed May 27, 2022
1 parent 749c20e commit 5713e4188469d86c19f96e4364c90eb6d3319c70
Showing 2 changed files with 1 addition and 46 deletions.
@@ -1098,9 +1098,6 @@ test/built-ins/TypedArray/prototype/set/array-arg-targetbuffer-detached-on-get-s
test/built-ins/TypedArray/prototype/sort/sort-tonumber.js:
default: 'TypeError: Underlying ArrayBuffer has been detached from the view (Testing with Float64Array.)'
strict mode: 'TypeError: Underlying ArrayBuffer has been detached from the view (Testing with Float64Array.)'
test/built-ins/TypedArrayConstructors/ctors/no-species.js:
default: 'Test262Error: unreachable'
strict mode: 'Test262Error: unreachable'
test/harness/temporalHelpers-one-shift-time-zone.js:
default: "TypeError: undefined is not a constructor (evaluating 'new Temporal.PlainDateTime(2021, 3, 28, 1)')"
strict mode: "TypeError: undefined is not a constructor (evaluating 'new Temporal.PlainDateTime(2021, 3, 28, 1)')"
@@ -105,43 +105,6 @@ inline JSObject* constructGenericTypedArrayViewFromIterator(JSGlobalObject* glob
return result;
}

inline JSArrayBuffer* constructCustomArrayBufferIfNeeded(JSGlobalObject* globalObject, JSArrayBufferView* view)
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

JSArrayBuffer* source = view->possiblySharedJSBuffer(globalObject);
RETURN_IF_EXCEPTION(scope, nullptr);
if (source->isShared())
return nullptr;

std::optional<JSValue> species = arrayBufferSpeciesConstructor(globalObject, source, ArrayBufferSharingMode::Default);
RETURN_IF_EXCEPTION(scope, nullptr);
if (!species)
return nullptr;

if (!species->isConstructor()) {
throwTypeError(globalObject, scope, "species is not a constructor"_s);
return nullptr;
}

JSValue prototype = species->get(globalObject, vm.propertyNames->prototype);
RETURN_IF_EXCEPTION(scope, nullptr);

auto buffer = ArrayBuffer::tryCreate(source->impl()->byteLength(), 1);
if (!buffer) {
throwOutOfMemoryError(globalObject, scope);
return nullptr;
}

JSGlobalObject* functionGlobalObject = getFunctionRealm(globalObject, asObject(species.value()));
RETURN_IF_EXCEPTION(scope, nullptr);
auto result = JSArrayBuffer::create(vm, functionGlobalObject->arrayBufferStructure(ArrayBufferSharingMode::Default), WTFMove(buffer));
if (prototype.isObject())
result->setPrototypeDirect(vm, prototype);
return result;
}

template<typename ViewClass>
inline JSObject* constructGenericTypedArrayViewWithArguments(JSGlobalObject* globalObject, Structure* structure, EncodedJSValue firstArgument, size_t offset, std::optional<size_t> lengthOpt)
{
@@ -183,13 +146,10 @@ inline JSObject* constructGenericTypedArrayViewWithArguments(JSGlobalObject* glo

if (JSObject* object = jsDynamicCast<JSObject*>(firstValue)) {
size_t length;
JSArrayBuffer* customBuffer = nullptr;

if (isTypedView(object->classInfo()->typedArrayStorageType)) {
auto* view = jsCast<JSArrayBufferView*>(object);

customBuffer = constructCustomArrayBufferIfNeeded(globalObject, view);
RETURN_IF_EXCEPTION(scope, nullptr);
if (view->isDetached()) {
throwTypeError(globalObject, scope, "Underlying ArrayBuffer has been detached from the view"_s);
return nullptr;
@@ -236,9 +196,7 @@ inline JSObject* constructGenericTypedArrayViewWithArguments(JSGlobalObject* glo
}
}

ViewClass* result = customBuffer
? ViewClass::create(globalObject, structure, customBuffer->impl(), 0, length)
: ViewClass::createUninitialized(globalObject, structure, length);
ViewClass* result = ViewClass::createUninitialized(globalObject, structure, length);
EXCEPTION_ASSERT(!!scope.exception() == !result);
if (UNLIKELY(!result))
return nullptr;

0 comments on commit 5713e41

Please sign in to comment.