node:buffer: fix test-buffer-resizable.js (#17350)

This commit is contained in:
Meghan Denny
2025-02-14 23:29:09 -08:00
committed by GitHub
parent 43367817a4
commit 600343fff7
9 changed files with 81 additions and 26 deletions

View File

@@ -2450,6 +2450,16 @@ EncodedJSValue constructBufferFromArrayBuffer(JSC::ThrowScope& throwScope, JSGlo
if (length > byteLength - offset) return Bun::ERR::BUFFER_OUT_OF_BOUNDS(throwScope, lexicalGlobalObject, "length"_s);
}
auto isResizableOrGrowableShared = jsBuffer->isResizableOrGrowableShared();
if (isResizableOrGrowableShared) {
auto* subclassStructure = globalObject->JSResizableOrGrowableSharedBufferSubclassStructure();
auto* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(buffer), offset, std::nullopt);
if (UNLIKELY(!uint8Array)) {
throwOutOfMemoryError(globalObject, throwScope);
return {};
}
RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(uint8Array));
}
auto* subclassStructure = globalObject->JSBufferSubclassStructure();
auto* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(buffer), offset, length);
if (UNLIKELY(!uint8Array)) {

View File

@@ -197,7 +197,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel
uint32_t length = cell.value.typed_array.length;
switch (type) {
case JSC::JSType::Int32ArrayType: {
JSC::JSInt32Array* array = JSC::JSInt32Array::createUninitialized(globalObject, globalObject->typedArrayStructure(TypedArrayType::TypeInt32, false), length);
JSC::JSInt32Array* array = JSC::JSInt32Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType<TypedArrayType::TypeInt32>(), length);
if (UNLIKELY(array == nullptr)) {
return {};
}
@@ -209,7 +209,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel
return array;
}
case JSC::JSType::Uint32ArrayType: {
JSC::JSUint32Array* array = JSC::JSUint32Array::createUninitialized(globalObject, globalObject->typedArrayStructure(TypedArrayType::TypeUint32, false), length);
JSC::JSUint32Array* array = JSC::JSUint32Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType<TypedArrayType::TypeUint32>(), length);
if (UNLIKELY(array == nullptr)) {
return {};
}
@@ -220,7 +220,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel
return array;
}
case JSC::JSType::Int16ArrayType: {
JSC::JSInt16Array* array = JSC::JSInt16Array::createUninitialized(globalObject, globalObject->typedArrayStructure(TypedArrayType::TypeInt16, false), length);
JSC::JSInt16Array* array = JSC::JSInt16Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType<TypedArrayType::TypeInt16>(), length);
if (UNLIKELY(array == nullptr)) {
return {};
}
@@ -232,7 +232,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel
return array;
}
case JSC::JSType::Uint16ArrayType: {
JSC::JSUint16Array* array = JSC::JSUint16Array::createUninitialized(globalObject, globalObject->typedArrayStructure(TypedArrayType::TypeUint16, false), length);
JSC::JSUint16Array* array = JSC::JSUint16Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType<TypedArrayType::TypeUint16>(), length);
if (UNLIKELY(array == nullptr)) {
return {};
}
@@ -243,7 +243,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel
return array;
}
case JSC::JSType::Float16ArrayType: {
JSC::JSFloat16Array* array = JSC::JSFloat16Array::createUninitialized(globalObject, globalObject->typedArrayStructure(TypedArrayType::TypeFloat16, false), length);
JSC::JSFloat16Array* array = JSC::JSFloat16Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType<TypedArrayType::TypeFloat16>(), length);
if (UNLIKELY(array == nullptr)) {
return {};
}
@@ -254,7 +254,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel
return array;
}
case JSC::JSType::Float32ArrayType: {
JSC::JSFloat32Array* array = JSC::JSFloat32Array::createUninitialized(globalObject, globalObject->typedArrayStructure(TypedArrayType::TypeFloat32, false), length);
JSC::JSFloat32Array* array = JSC::JSFloat32Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType<TypedArrayType::TypeFloat32>(), length);
if (UNLIKELY(array == nullptr)) {
return {};
}
@@ -265,7 +265,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel
return array;
}
case JSC::JSType::Float64ArrayType: {
JSC::JSFloat64Array* array = JSC::JSFloat64Array::createUninitialized(globalObject, globalObject->typedArrayStructure(TypedArrayType::TypeFloat64, false), length);
JSC::JSFloat64Array* array = JSC::JSFloat64Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType<TypedArrayType::TypeFloat64>(), length);
if (UNLIKELY(array == nullptr)) {
return {};
}

View File

@@ -15,9 +15,9 @@ extern "C" JSC::EncodedJSValue JSUint8Array__fromDefaultAllocator(JSC::JSGlobalO
mi_free(p);
}));
uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), WTFMove(buffer), 0, length);
uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructureWithTypedArrayType<JSC::TypeUint8>(), WTFMove(buffer), 0, length);
} else {
uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), 0);
uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructureWithTypedArrayType<JSC::TypeUint8>(), 0);
}
return JSC::JSValue::encode(uint8Array);

View File

@@ -1867,10 +1867,8 @@ extern "C" JSC__JSValue Bun__createUint8ArrayForCopy(JSC::JSGlobalObject* global
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSC::JSUint8Array* array = JSC::JSUint8Array::createUninitialized(
globalObject,
isBuffer ? reinterpret_cast<Zig::GlobalObject*>(globalObject)->JSBufferSubclassStructure() : globalObject->typedArrayStructure(TypeUint8, false),
len);
auto* subclassStructure = isBuffer ? reinterpret_cast<Zig::GlobalObject*>(globalObject)->JSBufferSubclassStructure() : globalObject->typedArrayStructureWithTypedArrayType<TypeUint8>();
JSC::JSUint8Array* array = JSC::JSUint8Array::createUninitialized(globalObject, subclassStructure, len);
if (UNLIKELY(!array)) {
JSC::throwOutOfMemoryError(globalObject, scope);
@@ -2940,8 +2938,14 @@ void GlobalObject::finishCreation(VM& vm)
m_JSBufferSubclassStructure.initLater(
[](const Initializer<Structure>& init) {
auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(init.owner);
auto* baseStructure = globalObject->typedArrayStructure(JSC::TypeUint8, false);
auto* baseStructure = globalObject->typedArrayStructureWithTypedArrayType<JSC::TypeUint8>();
JSC::Structure* subclassStructure = JSC::InternalFunction::createSubclassStructure(globalObject, globalObject->JSBufferConstructor(), baseStructure);
init.set(subclassStructure);
});
m_JSResizableOrGrowableSharedBufferSubclassStructure.initLater(
[](const Initializer<Structure>& init) {
auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(init.owner);
auto* baseStructure = globalObject->resizableOrGrowableSharedTypedArrayStructureWithTypedArrayType<JSC::TypeUint8>();
JSC::Structure* subclassStructure = JSC::InternalFunction::createSubclassStructure(globalObject, globalObject->JSBufferConstructor(), baseStructure);
init.set(subclassStructure);
});
@@ -3288,7 +3292,7 @@ void GlobalObject::finishCreation(VM& vm)
m_JSBufferClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
auto prototype = WebCore::createBufferPrototype(init.vm, init.global);
auto* prototype = WebCore::createBufferPrototype(init.vm, init.global);
auto* structure = WebCore::createBufferStructure(init.vm, init.global, JSValue(prototype));
auto* constructor = WebCore::createBufferConstructor(init.vm, init.global, jsCast<JSObject*>(prototype));
init.setPrototype(prototype);
@@ -3877,6 +3881,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_JSBufferClassStructure.visit(visitor);
thisObject->m_JSBufferListClassStructure.visit(visitor);
thisObject->m_JSBufferSubclassStructure.visit(visitor);
thisObject->m_JSResizableOrGrowableSharedBufferSubclassStructure.visit(visitor);
thisObject->m_JSCryptoKey.visit(visitor);
thisObject->m_lazyStackCustomGetterSetter.visit(visitor);
thisObject->m_JSDOMFileConstructor.visit(visitor);

View File

@@ -193,6 +193,7 @@ public:
JSC::JSObject* JSBufferConstructor() const { return m_JSBufferClassStructure.constructorInitializedOnMainThread(this); }
JSC::JSValue JSBufferPrototype() const { return m_JSBufferClassStructure.prototypeInitializedOnMainThread(this); }
JSC::Structure* JSBufferSubclassStructure() const { return m_JSBufferSubclassStructure.getInitializedOnMainThread(this); }
JSC::Structure* JSResizableOrGrowableSharedBufferSubclassStructure() const { return m_JSResizableOrGrowableSharedBufferSubclassStructure.getInitializedOnMainThread(this); }
JSC::Structure* JSCryptoKeyStructure() const { return m_JSCryptoKey.getInitializedOnMainThread(this); }
@@ -567,6 +568,7 @@ public:
LazyProperty<JSGlobalObject, JSObject> m_subtleCryptoObject;
LazyProperty<JSGlobalObject, Structure> m_JSHTTPResponseController;
LazyProperty<JSGlobalObject, Structure> m_JSBufferSubclassStructure;
LazyProperty<JSGlobalObject, Structure> m_JSResizableOrGrowableSharedBufferSubclassStructure;
LazyProperty<JSGlobalObject, JSWeakMap> m_vmModuleContextMap;
LazyProperty<JSGlobalObject, JSObject> m_lazyRequireCacheObject;
LazyProperty<JSGlobalObject, JSObject> m_lazyTestModuleObject;

View File

@@ -143,7 +143,7 @@ bool ReadableStreamDefaultController::enqueue(RefPtr<JSC::ArrayBuffer>&& buffer)
JSC::JSLockHolder lock(vm);
auto scope = DECLARE_CATCH_SCOPE(vm);
auto length = buffer->byteLength();
auto value = JSC::JSUint8Array::create(&lexicalGlobalObject, lexicalGlobalObject.typedArrayStructure(JSC::TypeUint8, true), WTFMove(buffer), 0, length);
auto value = JSC::JSUint8Array::create(&lexicalGlobalObject, lexicalGlobalObject.typedArrayStructureWithTypedArrayType<JSC::TypeUint8>(), WTFMove(buffer), 0, length);
EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException());
RETURN_IF_EXCEPTION(scope, false);

View File

@@ -1141,12 +1141,8 @@ void WebSocket::didReceiveBinaryData(const AtomString& eventName, const std::spa
context->postTask([name = eventName, buffer = WTFMove(arrayBuffer), protectedThis = Ref { *this }](ScriptExecutionContext& context) {
size_t length = buffer->byteLength();
auto* globalObject = context.jsGlobalObject();
JSUint8Array* uint8array = JSUint8Array::create(
globalObject,
reinterpret_cast<Zig::GlobalObject*>(globalObject)->JSBufferSubclassStructure(),
buffer.copyRef(),
0,
length);
auto* subclassStructure = reinterpret_cast<Zig::GlobalObject*>(globalObject)->JSBufferSubclassStructure();
JSUint8Array* uint8array = JSUint8Array::create(globalObject, subclassStructure, buffer.copyRef(), 0, length);
JSC::EnsureStillAliveScope ensureStillAlive(uint8array);
MessageEvent::Init init;
init.data = uint8array;

View File

@@ -1,3 +1,4 @@
#include "root.h"
#include "_NativeModule.h"
#include "ExceptionOr.h"
@@ -796,9 +797,8 @@ JSC_DEFINE_HOST_FUNCTION(functionSerialize,
if (asNodeBuffer) {
size_t byteLength = arrayBuffer->byteLength();
JSC::JSUint8Array* uint8Array = JSC::JSUint8Array::create(
lexicalGlobalObject, globalObject->JSBufferSubclassStructure(),
WTFMove(arrayBuffer), 0, byteLength);
auto* subclassStructure = globalObject->JSBufferSubclassStructure();
JSC::JSUint8Array* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(arrayBuffer), 0, byteLength);
return JSValue::encode(uint8Array);
}

View File

@@ -0,0 +1,42 @@
// Flags: --no-warnings
'use strict';
require('../common');
const { Buffer } = require('node:buffer');
const { strictEqual } = require('node:assert');
{
{
const ab = new ArrayBuffer(10, { maxByteLength: 20 });
const buffer = Buffer.from(ab, 1);
strictEqual(ab.byteLength, 10);
strictEqual(buffer.buffer.byteLength, 10);
strictEqual(buffer.byteLength, 9);
ab.resize(15);
strictEqual(ab.byteLength, 15);
strictEqual(buffer.buffer.byteLength, 15);
strictEqual(buffer.byteLength, 14);
ab.resize(5);
strictEqual(ab.byteLength, 5);
strictEqual(buffer.buffer.byteLength, 5);
strictEqual(buffer.byteLength, 4);
}
}
{
{
const ab = new ArrayBuffer(10, { maxByteLength: 20 });
const buffer = new Buffer(ab, 1);
strictEqual(ab.byteLength, 10);
strictEqual(buffer.buffer.byteLength, 10);
strictEqual(buffer.byteLength, 9);
ab.resize(15);
strictEqual(ab.byteLength, 15);
strictEqual(buffer.buffer.byteLength, 15);
strictEqual(buffer.byteLength, 14);
ab.resize(5);
strictEqual(ab.byteLength, 5);
strictEqual(buffer.buffer.byteLength, 5);
strictEqual(buffer.byteLength, 4);
}
}