diff options
19 files changed, 480 insertions, 520 deletions
diff --git a/bench/snippets/buffer-create.mjs b/bench/snippets/buffer-create.mjs index 87e16fe59..a83eddefb 100644 --- a/bench/snippets/buffer-create.mjs +++ b/bench/snippets/buffer-create.mjs @@ -1,32 +1,29 @@ import { bench, run } from "mitata"; +const N = parseInt(process.argv.slice(2).at(0) || "10", 10); + bench("new Buffer(0)", () => { return new Buffer(0); }); -const buffer = new ArrayBuffer(10); -bench("new DataView(buffer)", () => { - return new DataView(buffer); -}); - -bench("Buffer.alloc(10)", () => { - return Buffer.alloc(10); +bench(`new Buffer(${N})`, () => { + return new Buffer(N); }); -bench("Buffer.allocUnsafe(10)", () => { - return Buffer.allocUnsafe(10); +bench(`Buffer.alloc(${N})`, () => { + return Buffer.alloc(N); }); -bench("Buffer.allocUnsafe(1024)", () => { - return Buffer.allocUnsafe(1024); +bench(`Buffer.allocUnsafe(${N})`, () => { + return Buffer.allocUnsafe(N); }); -bench("new Uint8Array(0)", () => { - return new Uint8Array(0); +bench("Buffer.allocUnsafe(24_000)", () => { + return Buffer.allocUnsafe(24_000); }); -bench("new Uint8Array(10)", () => { - return new Uint8Array(10); +bench("Buffer.alloc(24_000)", () => { + return Buffer.alloc(24_000); }); await run(); diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp index 29774f3c5..ebaec3def 100644 --- a/src/bun.js/bindings/JSBuffer.cpp +++ b/src/bun.js/bindings/JSBuffer.cpp @@ -22,6 +22,12 @@ #include "JavaScriptCore/FunctionPrototype.h" #include "JavaScriptCore/HeapAnalyzer.h" +#include <JavaScriptCore/JSFunction.h> +#include <JavaScriptCore/InternalFunction.h> +#include <JavaScriptCore/LazyClassStructure.h> +#include <JavaScriptCore/LazyClassStructureInlines.h> +#include <JavaScriptCore/FunctionPrototype.h> + #include "JavaScriptCore/JSDestructibleObjectHeapCellType.h" #include "JavaScriptCore/SlotVisitorMacros.h" #include "JavaScriptCore/SubspaceInlines.h" @@ -40,9 +46,18 @@ #include "JSMediaSource.h" #endif +#include <JavaScriptCore/DOMJITAbstractHeap.h> +#include "DOMJITIDLConvert.h" +#include "DOMJITIDLType.h" +#include "DOMJITIDLTypeFilter.h" +#include "DOMJITHelpers.h" +#include <JavaScriptCore/DFGAbstractHeap.h> + // #include "JavaScriptCore/JSTypedArrayViewPrototype.h" #include "JavaScriptCore/JSArrayBufferViewInlines.h" +JSC_DECLARE_HOST_FUNCTION(constructJSBuffer); + static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_alloc); static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_allocUnsafe); static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_allocUnsafeSlow); @@ -67,6 +82,39 @@ static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_swap64); static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_toString); static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_write); +static JSUint8Array* allocBuffer(JSC::JSGlobalObject* lexicalGlobalObject, unsigned int byteLength) +{ + JSC::VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + + auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto* subclassStructure = globalObject->JSBufferSubclassStructure(); + + auto* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, byteLength); + if (UNLIKELY(!uint8Array)) { + throwOutOfMemoryError(lexicalGlobalObject, throwScope); + return nullptr; + } + + return uint8Array; +} +static JSUint8Array* allocBufferUnsafe(JSC::JSGlobalObject* lexicalGlobalObject, unsigned int byteLength) +{ + JSC::VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + + auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto* subclassStructure = globalObject->JSBufferSubclassStructure(); + + auto* uint8Array = JSC::JSUint8Array::createUninitialized(lexicalGlobalObject, subclassStructure, byteLength); + if (UNLIKELY(!uint8Array)) { + throwOutOfMemoryError(lexicalGlobalObject, throwScope); + return nullptr; + } + + return uint8Array; +} + bool JSBuffer__isBuffer(JSC::JSGlobalObject* lexicalGlobalObject, JSC::EncodedJSValue value) { JSC::VM& vm = lexicalGlobalObject->vm(); @@ -76,7 +124,7 @@ bool JSBuffer__isBuffer(JSC::JSGlobalObject* lexicalGlobalObject, JSC::EncodedJS if (!jsBuffer) return false; - return !!jsBuffer->getIfPropertyExists(lexicalGlobalObject, clientData->builtinNames().dataViewPrivateName()); + return jsBuffer->hasProperty(lexicalGlobalObject, clientData->builtinNames().dataViewPrivateName()); } // Normalize val to be an integer in the range of [1, -1] since @@ -100,7 +148,7 @@ static int normalizeCompareVal(int val, size_t a_length, size_t b_length) namespace WebCore { using namespace JSC; -template<> class IDLOperation<JSBuffer> { +template<> class IDLOperation<JSArrayBufferView> { public: using ClassParameter = JSC::JSUint8Array*; using Operation = JSC::EncodedJSValue(JSC::JSGlobalObject*, JSC::CallFrame*, ClassParameter); @@ -132,19 +180,20 @@ JSC::EncodedJSValue JSBuffer__bufferFromPointerAndLengthAndDeinit(JSC::JSGlobalO JSC::JSUint8Array* uint8Array = nullptr; + auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto* subclassStructure = globalObject->JSBufferSubclassStructure(); + if (LIKELY(length > 0)) { auto buffer = ArrayBuffer::createFromBytes(ptr, length, createSharedTask<void(void*)>([=](void* p) { if (bytesDeallocator) bytesDeallocator(p, ctx); })); - uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), WTFMove(buffer), 0, length); + uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(buffer), 0, length); } else { - uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), 0); + uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, 0); } - toBuffer(lexicalGlobalObject, uint8Array); - return JSC::JSValue::encode(uint8Array); } @@ -162,21 +211,15 @@ static inline JSC::JSUint8Array* JSBuffer__bufferFromLengthAsArray(JSC::JSGlobal JSC::JSUint8Array* uint8Array = nullptr; - if (LIKELY(length > 0)) { - - auto arrayBuffer = JSC::ArrayBuffer::tryCreateUninitialized(length, 1); - if (UNLIKELY(!arrayBuffer)) { - throwOutOfMemoryError(lexicalGlobalObject, throwScope); - return nullptr; - } + auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto* subclassStructure = globalObject->JSBufferSubclassStructure(); - uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), WTFMove(arrayBuffer), 0, length); + if (LIKELY(length > 0)) { + uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, length); } else { - uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), 0); + uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, 0); } - toBuffer(lexicalGlobalObject, uint8Array); - RELEASE_AND_RETURN(throwScope, uint8Array); } @@ -196,7 +239,7 @@ static inline JSC::EncodedJSValue jsBufferConstructorFunction_allocUnsafeBody(JS return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); auto length = callFrame->uncheckedArgument(0).toInt32(lexicalGlobalObject); - RELEASE_AND_RETURN(throwScope, JSBuffer__bufferFromLength(lexicalGlobalObject, length)); + RELEASE_AND_RETURN(throwScope, JSValue::encode(allocBufferUnsafe(lexicalGlobalObject, length))); } EncodedJSValue JSBuffer__bufferFromPointerAndLength(JSC::JSGlobalObject* lexicalGlobalObject, const unsigned char* ptr, unsigned int length) @@ -204,16 +247,17 @@ EncodedJSValue JSBuffer__bufferFromPointerAndLength(JSC::JSGlobalObject* lexical JSC::JSUint8Array* uint8Array; + auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto* subclassStructure = globalObject->JSBufferSubclassStructure(); + if (LIKELY(length > 0)) { auto buffer = ArrayBuffer::create(ptr, length); - uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), WTFMove(buffer), 0, length); + uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(buffer), 0, length); } else { - uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), 0); + uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, 0); } - toBuffer(lexicalGlobalObject, uint8Array); - return JSC::JSValue::encode(uint8Array); } @@ -334,8 +378,10 @@ static inline JSC::EncodedJSValue jsBufferConstructorFunction_allocBody(JSC::JSG return JSValue::encode(jsUndefined()); } - auto uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), WTFMove(arrayBuffer), 0, length); - toBuffer(lexicalGlobalObject, uint8Array); + auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto* subclassStructure = globalObject->JSBufferSubclassStructure(); + + auto uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(arrayBuffer), 0, length); RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(uint8Array)); } @@ -610,7 +656,7 @@ static inline JSC::EncodedJSValue jsBufferConstructorFunction_toBufferBody(JSC:: class JSBufferPrototype : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; - static JSBufferPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + static JSBufferPrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure) { JSBufferPrototype* ptr = new (NotNull, JSC::allocateCell<JSBufferPrototype>(vm)) JSBufferPrototype(vm, globalObject, structure); ptr->finishCreation(vm, globalObject); @@ -638,7 +684,7 @@ private: }; STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSBufferPrototype, JSBufferPrototype::Base); -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_compareBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_compareBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); @@ -720,7 +766,7 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_compareBody(JSC::JSG RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(JSC::jsNumber(normalizeCompareVal(result, sourceLength, targetLength)))); } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_copyBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_copyBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); @@ -793,7 +839,7 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_copyBody(JSC::JSGlob return JSValue::encode(jsNumber(actualLength)); } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_equalsBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_equalsBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); @@ -828,7 +874,7 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_equalsBody(JSC::JSGl RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(JSC::jsBoolean(normalizeCompareVal(result, a_length, b_length) == 0))); } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_fillBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_fillBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); @@ -949,7 +995,7 @@ static int64_t lastIndexOf(const uint8_t* thisPtr, int64_t thisLength, const uin return -1; } -static int64_t indexOf(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis, bool last) +static int64_t indexOf(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis, bool last) { auto& vm = JSC::getVM(lexicalGlobalObject); auto scope = DECLARE_THROW_SCOPE(vm); @@ -1050,38 +1096,38 @@ static int64_t indexOf(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* return -1; } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_includesBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_includesBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto index = indexOf(lexicalGlobalObject, callFrame, castedThis, false); return JSC::JSValue::encode(jsBoolean(index != -1)); } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_indexOfBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_indexOfBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto index = indexOf(lexicalGlobalObject, callFrame, castedThis, false); return JSC::JSValue::encode(jsNumber(index)); } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_lastIndexOfBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_lastIndexOfBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto index = indexOf(lexicalGlobalObject, callFrame, castedThis, true); return JSC::JSValue::encode(jsNumber(index)); } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap16Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap16Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); return JSC::JSValue::encode(jsUndefined()); } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap32Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap32Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); return JSC::JSValue::encode(jsUndefined()); } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap64Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap64Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); return JSC::JSValue::encode(jsUndefined()); } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); uint32_t offset = 0; @@ -1188,7 +1234,7 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JS RELEASE_AND_RETURN(scope, JSC::JSValue::encode(retValue)); } -static inline JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBuffer>::ClassParameter castedThis) +static inline JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); uint32_t offset = 0; @@ -1296,7 +1342,43 @@ JSC_DEFINE_HOST_FUNCTION(jsBufferConstructorFunction_toBuffer, (JSGlobalObject * return jsBufferConstructorFunction_toBufferBody(lexicalGlobalObject, callFrame); } -using JSBufferConstructor = JSDOMConstructor<JSBuffer>; +class JSBufferConstructor final : public JSC::InternalFunction { +public: + using Base = JSC::InternalFunction; + static constexpr unsigned StructureFlags = Base::StructureFlags; + + ~JSBufferConstructor() = default; + + static void destroy(JSC::JSCell* cell) + { + static_cast<JSBufferConstructor*>(cell)->JSBufferConstructor::~JSBufferConstructor(); + } + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject) + { + JSValue prototype = globalObject->m_typedArrayUint8.constructorInitializedOnMainThread(globalObject); + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(prototype.asCell()->type(), StructureFlags), info()); + } + + DECLARE_INFO; + + static JSBufferConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSObject* prototype) + { + JSBufferConstructor* constructor = new (NotNull, JSC::allocateCell<JSBufferConstructor>(vm)) JSBufferConstructor(vm, globalObject, structure); + constructor->finishCreation(vm, globalObject, prototype); + return constructor; + } + +private: + JSBufferConstructor(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure) + : Base(vm, structure, constructJSBuffer, constructJSBuffer) + + { + } + + void finishCreation(JSC::VM&, JSGlobalObject*, JSC::JSObject* prototype); + +} JSC_DEFINE_HOST_FUNCTION(jsBufferConstructorFunction_isEncoding, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { @@ -1321,122 +1403,106 @@ JSC_DEFINE_HOST_FUNCTION(jsBufferConstructorFunction_concat, (JSGlobalObject * l return jsBufferConstructorFunction_concatBody(lexicalGlobalObject, callFrame); } -/* Hash table for constructor */ -static const HashTableValue JSBufferConstructorTableValues[] = { - { "alloc"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_alloc, 3 } }, - { "allocUnsafe"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafe, 1 } }, - { "allocUnsafeSlow"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafeSlow, 1 } }, - { "byteLength"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_byteLength, 2 } }, - { "compare"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_compare, 2 } }, - { "concat"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_concat, 2 } }, - { "from"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferConstructorFromCodeGenerator, 1 } }, - { "isBuffer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_isBuffer, 1 } }, - { "toBuffer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_toBuffer, 1 } }, - { "isEncoding"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_isEncoding, 1 } }, -}; +extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(jsBufferConstructorAllocWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int size)); +extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(jsBufferConstructorAllocUnsafeWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int size)); +extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(jsBufferConstructorAllocUnsafeSlowWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int size)); -template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSBufferConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int byteLength)) { - VM& vm = lexicalGlobalObject->vm(); - auto throwScope = DECLARE_THROW_SCOPE(vm); - UNUSED_PARAM(throwScope); - size_t argsCount = std::min<size_t>(3, callFrame->argumentCount()); - if (argsCount == 0) { - RELEASE_AND_RETURN(throwScope, (constructBufferEmpty(lexicalGlobalObject, callFrame))); - } - JSValue distinguishingArg = callFrame->uncheckedArgument(0); - if (distinguishingArg.isNumber()) { - RELEASE_AND_RETURN(throwScope, (constructBufferFromLength(lexicalGlobalObject, callFrame))); - } else if (distinguishingArg.isString()) { - RELEASE_AND_RETURN(throwScope, (constructBufferFromStringAndEncoding(lexicalGlobalObject, callFrame))); - } - - JSC::JSObject* constructor = lexicalGlobalObject->m_typedArrayUint8.constructor(lexicalGlobalObject); - - MarkedArgumentBuffer args; - for (size_t i = 0; i < argsCount; ++i) - args.append(callFrame->uncheckedArgument(i)); - - JSC::JSObject* object = JSC::construct(lexicalGlobalObject, constructor, callFrame->newTarget(), args, "Failed to construct 'Buffer' object"_s); - if (!object) { - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - auto value = JSC::JSValue(object); - - toBuffer(lexicalGlobalObject, JSC::jsCast<JSC::JSUint8Array*>(value)); - - RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(value)); + VM& vm = JSC::getVM(lexicalGlobalObject); + IGNORE_WARNINGS_BEGIN("frame-address") + CallFrame* callFrame = DECLARE_CALL_FRAME(vm); + IGNORE_WARNINGS_END + JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); + return allocBuffer(lexicalGlobalObject, byteLength); } -JSC_ANNOTATE_HOST_FUNCTION(JSBufferConstructorConstruct, JSBufferConstructor::construct); -template<> const ClassInfo JSBufferConstructor::s_info = { "Buffer"_s, nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSBufferConstructor) }; - -template<> JSValue JSBufferConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int byteLength)) { - UNUSED_PARAM(vm); - return globalObject.functionPrototype(); + VM& vm = JSC::getVM(lexicalGlobalObject); + IGNORE_WARNINGS_BEGIN("frame-address") + CallFrame* callFrame = DECLARE_CALL_FRAME(vm); + IGNORE_WARNINGS_END + JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); + return allocBufferUnsafe(lexicalGlobalObject, byteLength); } -template<> void JSBufferConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeSlowWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int byteLength)) { - putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); - JSString* nameString = jsNontrivialString(vm, "Buffer"_s); - m_originalName.set(vm, this, nameString); - putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); - putDirect(vm, vm.propertyNames->prototype, JSBuffer::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); - reifyStaticProperties(vm, JSBufferConstructor::info(), JSBufferConstructorTableValues, *this); + VM& vm = JSC::getVM(lexicalGlobalObject); + IGNORE_WARNINGS_BEGIN("frame-address") + CallFrame* callFrame = DECLARE_CALL_FRAME(vm); + IGNORE_WARNINGS_END + JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); + return allocBufferUnsafe(lexicalGlobalObject, byteLength); } -const ClassInfo JSBuffer::s_info = { "Buffer"_s, JSC::getUint8ArrayClassInfo(), nullptr, nullptr, CREATE_METHOD_TABLE(JSBuffer) }; +JSC_ANNOTATE_HOST_FUNCTION(JSBufferConstructorConstruct, JSBufferConstructor::construct); + +const ClassInfo JSBufferConstructor::s_info = { "Buffer"_s, nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSBufferConstructor) }; + +class JSBuffer : public JSC::JSNonFinalObject { + + DECLARE_INFO; + + static constexpr JSC::JSTypeRange typeRange = { Uint8ArrayType, Uint8ArrayType }; +}; + +const ClassInfo JSBuffer::s_info = { + "Buffer"_s, + JSC::getUint8ArrayClassInfo(), + nullptr, + nullptr, + CREATE_METHOD_TABLE(JSBuffer) +}; JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_compare, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_compareBody>(*lexicalGlobalObject, *callFrame, "compare"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_compareBody>(*lexicalGlobalObject, *callFrame, "compare"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_copy, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_copyBody>(*lexicalGlobalObject, *callFrame, "copy"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_copyBody>(*lexicalGlobalObject, *callFrame, "copy"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_equals, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_equalsBody>(*lexicalGlobalObject, *callFrame, "equals"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_equalsBody>(*lexicalGlobalObject, *callFrame, "equals"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_fill, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_fillBody>(*lexicalGlobalObject, *callFrame, "fill"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_fillBody>(*lexicalGlobalObject, *callFrame, "fill"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_includes, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_includesBody>(*lexicalGlobalObject, *callFrame, "includes"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_includesBody>(*lexicalGlobalObject, *callFrame, "includes"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_indexOf, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_indexOfBody>(*lexicalGlobalObject, *callFrame, "indexOf"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_indexOfBody>(*lexicalGlobalObject, *callFrame, "indexOf"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_lastIndexOf, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_lastIndexOfBody>(*lexicalGlobalObject, *callFrame, "lastIndexOf"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_lastIndexOfBody>(*lexicalGlobalObject, *callFrame, "lastIndexOf"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_swap16, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_swap16Body>(*lexicalGlobalObject, *callFrame, "swap16"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_swap16Body>(*lexicalGlobalObject, *callFrame, "swap16"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_swap32, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_swap32Body>(*lexicalGlobalObject, *callFrame, "swap32"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_swap32Body>(*lexicalGlobalObject, *callFrame, "swap32"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_swap64, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_swap64Body>(*lexicalGlobalObject, *callFrame, "swap64"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_swap64Body>(*lexicalGlobalObject, *callFrame, "swap64"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_toString, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_toStringBody>(*lexicalGlobalObject, *callFrame, "toString"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_toStringBody>(*lexicalGlobalObject, *callFrame, "toString"); } JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_write, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { - return IDLOperation<JSBuffer>::call<jsBufferPrototypeFunction_writeBody>(*lexicalGlobalObject, *callFrame, "write"); + return IDLOperation<JSArrayBufferView>::call<jsBufferPrototypeFunction_writeBody>(*lexicalGlobalObject, *callFrame, "write"); } /* */ @@ -1542,136 +1608,104 @@ void JSBufferPrototype::finishCreation(VM& vm, JSC::JSGlobalObject* globalThis) { Base::finishCreation(vm); JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); - this->setPrototypeDirect(vm, globalThis->m_typedArrayUint8.prototype(globalThis)); auto clientData = WebCore::clientData(vm); - this->putDirect(vm, clientData->builtinNames().dataViewPublicName(), JSC::jsUndefined(), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly); - this->putDirect(vm, clientData->builtinNames().dataViewPrivateName(), JSC::JSValue(true), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly); + this->putDirect(vm, clientData->builtinNames().dataViewPrivateName(), JSC::jsUndefined(), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); reifyStaticProperties(vm, JSBuffer::info(), JSBufferPrototypeTableValues, *this); } const ClassInfo JSBufferPrototype::s_info = { "Buffer"_s, nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(JSBufferPrototype) }; -JSObject* JSBuffer::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) -{ - return JSBufferPrototype::create(vm, &globalObject, JSBufferPrototype::createStructure(vm, &globalObject, globalObject.m_typedArrayUint8.prototype(&globalObject))); -} +static const JSC::DOMJIT::Signature DOMJITSignaturejsBufferConstructorAllocUnsafe(jsBufferConstructorAllocUnsafeWithoutTypeChecks, + JSBufferConstructor::info(), + JSC::DOMJIT::Effect::forWriteKinds(JSC::DFG::AbstractHeapKind::Heap), + JSC::SpecUint8Array, JSC::SpecInt32Only); +static const JSC::DOMJIT::Signature DOMJITSignaturejsBufferConstructorAllocUnsafeSlow(jsBufferConstructorAllocUnsafeSlowWithoutTypeChecks, + JSBufferConstructor::info(), + JSC::DOMJIT::Effect::forWriteKinds(JSC::DFG::AbstractHeapKind::Heap), + JSC::SpecUint8Array, JSC::SpecInt32Only); -JSObject* JSBuffer::prototype(VM& vm, JSDOMGlobalObject& globalObject) -{ - return getDOMPrototype<JSBuffer>(vm, globalObject); -} - -JSValue JSBuffer::getConstructor(VM& vm, const JSGlobalObject* globalObject) -{ - return getDOMConstructor<JSBufferConstructor, DOMConstructorID::Buffer>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); -} +/* Hash table for constructor */ +static const HashTableValue JSBufferConstructorTableValues[] = { + { "alloc"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferConstructorAllocCodeGenerator, 1 } }, + // { "alloc"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction), NoIntrinsic, { HashTableValue::DOMJITFunctionType, jsBufferConstructorFunction_alloc, &DOMJITSignaturejsBufferConstructorAlloc } }, + { "allocUnsafe"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafe, 1 } }, + // { "allocUnsafe"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction), NoIntrinsic, { HashTableValue::DOMJITFunctionType, jsBufferConstructorFunction_allocUnsafe, &DOMJITSignaturejsBufferConstructorAllocUnsafe } }, + { "allocUnsafeSlow"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafeSlow, 1 } }, + // { "allocUnsafeSlow"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction), NoIntrinsic, { HashTableValue::DOMJITFunctionType, jsBufferConstructorFunction_allocUnsafeSlow, &DOMJITSignaturejsBufferConstructorAllocUnsafeSlow } }, + { "byteLength"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_byteLength, 2 } }, + { "compare"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_compare, 2 } }, + { "concat"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_concat, 2 } }, + { "from"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferConstructorFromCodeGenerator, 1 } }, + { "isBuffer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_isBuffer, 1 } }, + { "toBuffer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_toBuffer, 1 } }, + { "isEncoding"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_isEncoding, 1 } }, +}; -void JSBuffer::destroy(JSC::JSCell* cell) +void JSBufferConstructor::finishCreation(VM& vm, JSGlobalObject* globalObject, JSC::JSObject* prototype) { - JSBuffer* thisObject = static_cast<JSBuffer*>(cell); - thisObject->JSBuffer::~JSBuffer(); + Base::finishCreation(vm, 3, "Buffer"_s, PropertyAdditionMode::WithoutStructureTransition); + reifyStaticProperties(vm, JSBufferConstructor::info(), JSBufferConstructorTableValues, *this); + putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); + prototype->putDirect(vm, vm.propertyNames->speciesSymbol, this, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); } -JSBuffer::JSBuffer(Structure* structure, JSDOMGlobalObject& globalObject, Ref<Buffer>&& impl) - : JSDOMWrapper<Buffer>(structure, globalObject, WTFMove(impl)) +JSC::Structure* createBufferStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) { + return JSBuffer::createStructure(vm, globalObject, prototype); } -void JSBuffer::finishCreation(VM& vm) +JSC::JSObject* createBufferPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject) { - Base::finishCreation(vm); - ASSERT(inherits(info())); - - // static_assert(!std::is_base_of<ActiveDOMObject, DOMURL>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); + return JSBufferPrototype::create(vm, globalObject, JSBufferPrototype::createStructure(vm, globalObject, globalObject->m_typedArrayUint8.prototype(globalObject))); } - -JSC::GCClient::IsoSubspace* JSBuffer::subspaceForImpl(JSC::VM& vm) +JSC::JSObject* createBufferConstructor(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSObject* bufferPrototype) { - return WebCore::subspaceForImpl<JSBuffer, UseCustomHeapCellType::No>( + return JSBufferConstructor::create( vm, - [](auto& spaces) { return spaces.m_clientSubspaceForBuffer.get(); }, - [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForBuffer = WTFMove(space); }, - [](auto& spaces) { return spaces.m_subspaceForBuffer.get(); }, - [](auto& spaces, auto&& space) { spaces.m_subspaceForBuffer = WTFMove(space); }); + globalObject, + JSBufferConstructor::createStructure(vm, globalObject), + bufferPrototype); } -// template<typename Visitor> -// void JSBuffer::visitChildrenImpl(JSCell* cell, Visitor& visitor) -// { -// auto* thisObject = jsCast<Buffer*>(cell); -// ASSERT_GC_OBJECT_INHERITS(thisObject, info()); -// Base::visitChildren(thisObject, visitor); -// } - -// DEFINE_VISIT_CHILDREN(JSBuffer); - -// template<typename Visitor> -// void JSBuffer::visitOutputConstraints(JSCell* cell, Visitor& visitor) -// { -// auto* thisObject = jsCast<Buffer*>(cell); -// ASSERT_GC_OBJECT_INHERITS(thisObject, info()); -// Base::visitOutputConstraints(thisObject, visitor); -// } - -// template void JSBuffer::visitOutputConstraints(JSCell*, AbstractSlotVisitor&); -// template void JSBuffer::visitOutputConstraints(JSCell*, SlotVisitor&); -// void JSBuffer::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) -// { -// auto* thisObject = jsCast<Buffer*>(cell); -// analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); -// // if (thisObject->scriptExecutionContext()) -// // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); -// Base::analyzeHeap(cell, analyzer); -// } - -JSBufferOwner::~JSBufferOwner() -{ -} - -bool JSBufferOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) -{ - UNUSED_PARAM(handle); - UNUSED_PARAM(visitor); - UNUSED_PARAM(reason); - return false; -} +} // namespace WebCore -void JSBufferOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +void toBuffer(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSUint8Array* uint8Array) { - auto* jsBuffer = static_cast<JSBuffer*>(handle.slot()->asCell()); - auto& world = *static_cast<DOMWrapperWorld*>(context); - uncacheWrapper(world, &jsBuffer->wrapped(), jsBuffer); + JSC::VM& vm = lexicalGlobalObject->vm(); + auto clientData = WebCore::clientData(vm); + JSC::JSObject* object = JSC::JSValue(uint8Array).getObject(); } -JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<Buffer>&& impl) +JSC_DEFINE_HOST_FUNCTION(constructJSBuffer, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) { + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + size_t argsCount = std::min<size_t>(3, callFrame->argumentCount()); + if (argsCount == 0) { + RELEASE_AND_RETURN(throwScope, (constructBufferEmpty(lexicalGlobalObject, callFrame))); + } + JSValue distinguishingArg = callFrame->uncheckedArgument(0); + if (distinguishingArg.isNumber()) { + RELEASE_AND_RETURN(throwScope, JSBuffer__bufferFromLength(lexicalGlobalObject, distinguishingArg.toInt32(lexicalGlobalObject))); + } else if (distinguishingArg.isString()) { + RELEASE_AND_RETURN(throwScope, (constructBufferFromStringAndEncoding(lexicalGlobalObject, callFrame))); + } - return createWrapper<Buffer>(globalObject, WTFMove(impl)); -} - -JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, Buffer& impl) -{ - return wrap(lexicalGlobalObject, globalObject, impl); -} + JSC::JSObject* constructor = lexicalGlobalObject->m_typedArrayUint8.constructor(lexicalGlobalObject); -Buffer* JSBuffer::toWrapped(JSC::VM& vm, JSC::JSValue value) -{ - if (auto* wrapper = jsDynamicCast<JSBuffer*>(value)) - return &wrapper->wrapped(); - return nullptr; -} + MarkedArgumentBuffer args; + for (size_t i = 0; i < argsCount; ++i) + args.append(callFrame->uncheckedArgument(i)); -} // namespace WebCore + JSC::JSObject* object = JSC::construct(lexicalGlobalObject, constructor, callFrame->newTarget(), args, "Failed to construct 'Buffer' object"_s); + if (!object) { + return JSC::JSValue::encode(JSC::jsUndefined()); + } -void toBuffer(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSUint8Array* uint8Array) -{ - JSC::VM& vm = lexicalGlobalObject->vm(); - auto clientData = WebCore::clientData(vm); - JSC::JSObject* object = JSC::JSValue(uint8Array).getObject(); + auto value = JSC::JSValue(object); - object->setPrototypeDirect(vm, WebCore::JSBuffer::prototype(vm, *JSC::jsCast<WebCore::JSDOMGlobalObject*>(lexicalGlobalObject))); + toBuffer(lexicalGlobalObject, JSC::jsCast<JSC::JSUint8Array*>(value)); - auto* dataView = JSC::JSDataView::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeDataView, false), uint8Array->possiblySharedBuffer(), uint8Array->byteOffset(), uint8Array->length()); - // putDirectWithTransition doesn't work here - object->putDirectWithoutTransition(vm, clientData->builtinNames().dataViewPublicName(), dataView, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly); + RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(value)); } diff --git a/src/bun.js/bindings/JSBuffer.h b/src/bun.js/bindings/JSBuffer.h index 50593c885..9c1bf44ca 100644 --- a/src/bun.js/bindings/JSBuffer.h +++ b/src/bun.js/bindings/JSBuffer.h @@ -22,7 +22,7 @@ #include "root.h" -#include "JSDOMWrapper.h" +#include <JavaScriptCore/JSGlobalObject.h> #include "wtf/NeverDestroyed.h" #include "BufferEncodingType.h" @@ -30,81 +30,14 @@ extern "C" bool JSBuffer__isBuffer(JSC::JSGlobalObject*, JSC::EncodedJSValue); void toBuffer(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSUint8Array* uint8Array); +JSC::JSValue makeBuffer(JSC::JSGlobalObject* lexicalGlobalObject, unsigned int byteLength); +JSC::JSValue makeBufferUnsafe(JSC::JSGlobalObject* lexicalGlobalObject, unsigned int byteLength); namespace WebCore { JSC::EncodedJSValue constructSlowBuffer(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC::JSObject* createBufferPrototype(JSC::VM&, JSC::JSGlobalObject*); +JSC::Structure* createBufferStructure(JSC::VM&, JSC::JSGlobalObject*, JSC::JSValue prototype); +JSC::JSObject* createBufferConstructor(JSC::VM&, JSC::JSGlobalObject*, JSC::JSObject* bufferPrototype); -class WEBCORE_EXPORT JSBuffer final : public JSDOMWrapper<Buffer> { -public: - using Base = JSDOMWrapper<Buffer>; - - static JSBuffer* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<Buffer>&& impl) - { - JSBuffer* ptr = new (NotNull, JSC::allocateCell<JSBuffer>(globalObject->vm())) JSBuffer(structure, *globalObject, WTFMove(impl)); - ptr->finishCreation(globalObject->vm()); - return ptr; - } - - static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); - static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); - static Buffer* toWrapped(JSC::VM&, JSC::JSValue); - static void destroy(JSC::JSCell*); - - using Adaptor = JSC::JSUint8Array::Adaptor; - - DECLARE_INFO; - - static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) - { - return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSC::JSType::Uint8ArrayType), StructureFlags), info(), JSC::MayHaveIndexedAccessors); - } - - static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); - template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) - { - if constexpr (mode == JSC::SubspaceAccess::Concurrently) - return nullptr; - return subspaceForImpl(vm); - } - static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); - // DECLARE_VISIT_CHILDREN; - // template<typename Visitor> void visitAdditionalChildren(Visitor&); - // template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&); - // static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); - -protected: - JSBuffer(JSC::Structure*, JSDOMGlobalObject&, Ref<Buffer>&&); - - void finishCreation(JSC::VM&); -}; - -class JSBufferOwner final : public JSC::WeakHandleOwner { -public: - ~JSBufferOwner() final; - bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; - void finalize(JSC::Handle<JSC::Unknown>, void* context) final; -}; - -inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, Buffer*) -{ - static NeverDestroyed<JSBufferOwner> owner; - return &owner.get(); -} - -inline void* wrapperKey(Buffer* wrappableObject) -{ - return wrappableObject; -} - -WEBCORE_EXPORT JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, Buffer&); -inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, Buffer* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } -JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<Buffer>&&); -inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<Buffer>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } - -template<> struct JSDOMWrapperConverterTraits<Buffer> { - using WrapperClass = JSBuffer; - using ToWrappedReturnType = Buffer*; -}; - -} // namespace WebCore +}
\ No newline at end of file diff --git a/src/bun.js/bindings/JSBufferList.cpp b/src/bun.js/bindings/JSBufferList.cpp index a615dfe73..d30ec0aa0 100644 --- a/src/bun.js/bindings/JSBufferList.cpp +++ b/src/bun.js/bindings/JSBufferList.cpp @@ -38,8 +38,8 @@ JSC::JSValue JSBufferList::concat(JSC::VM& vm, JSC::JSGlobalObject* lexicalGloba JSC::JSUint8Array* uint8Array = nullptr; if (length() == 0) { // Buffer.alloc(0) - uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), 0); - toBuffer(lexicalGlobalObject, uint8Array); + uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject)->JSBufferSubclassStructure(), 0); + RELEASE_AND_RETURN(throwScope, uint8Array); } // Buffer.allocUnsafe(n >>> 0) @@ -47,8 +47,7 @@ JSC::JSValue JSBufferList::concat(JSC::VM& vm, JSC::JSGlobalObject* lexicalGloba if (UNLIKELY(!arrayBuffer)) { return throwOutOfMemoryError(lexicalGlobalObject, throwScope); } - uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), WTFMove(arrayBuffer), 0, n); - toBuffer(lexicalGlobalObject, uint8Array); + uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject)->JSBufferSubclassStructure(), WTFMove(arrayBuffer), 0, n); size_t i = 0; for (auto iter = m_deque.begin(); iter != m_deque.end(); ++iter) { @@ -78,7 +77,7 @@ JSC::JSValue JSBufferList::join(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalO const bool needSeq = seq->length() != 0; const auto end = m_deque.end(); JSRopeString::RopeBuilder<RecordOverflow> ropeBuilder(vm); - for (auto iter = m_deque.begin(); ;) { + for (auto iter = m_deque.begin();;) { auto str = iter->get().toString(lexicalGlobalObject); if (!ropeBuilder.append(str)) return throwOutOfMemoryError(lexicalGlobalObject, throwScope); @@ -135,8 +134,8 @@ JSC::JSValue JSBufferList::_getBuffer(JSC::VM& vm, JSC::JSGlobalObject* lexicalG JSC::JSUint8Array* uint8Array = nullptr; if (n == 0) { // Buffer.alloc(0) - uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), 0); - toBuffer(lexicalGlobalObject, uint8Array); + uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject)->JSBufferSubclassStructure(), 0); + RELEASE_AND_RETURN(throwScope, uint8Array); } // Buffer.allocUnsafe(n >>> 0) @@ -144,8 +143,7 @@ JSC::JSValue JSBufferList::_getBuffer(JSC::VM& vm, JSC::JSGlobalObject* lexicalG if (UNLIKELY(!arrayBuffer)) { return throwTypeError(lexicalGlobalObject, throwScope); } - uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), WTFMove(arrayBuffer), 0, n); - toBuffer(lexicalGlobalObject, uint8Array); + uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject)->JSBufferSubclassStructure(), WTFMove(arrayBuffer), 0, n); size_t offset = 0; for (auto iter = m_deque.begin(); iter != m_deque.end() && n > 0; ++iter) { @@ -165,8 +163,7 @@ JSC::JSValue JSBufferList::_getBuffer(JSC::VM& vm, JSC::JSGlobalObject* lexicalG return throwOutOfMemoryError(lexicalGlobalObject, throwScope); } JSC::JSUint8Array* newArray = JSC::JSUint8Array::create( - lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, false), WTFMove(arrayBuffer), 0, length - n); - toBuffer(lexicalGlobalObject, newArray); + lexicalGlobalObject, reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject)->JSBufferSubclassStructure(), WTFMove(arrayBuffer), 0, length - n); memcpy(newArray->typedVector(), array->typedVector() + n, length - n); iter->set(vm, this, newArray); diff --git a/src/bun.js/bindings/JSDOMConvertBufferSource+JSBuffer.h b/src/bun.js/bindings/JSDOMConvertBufferSource+JSBuffer.h index 76d05e1b1..88664ff25 100644 --- a/src/bun.js/bindings/JSDOMConvertBufferSource+JSBuffer.h +++ b/src/bun.js/bindings/JSDOMConvertBufferSource+JSBuffer.h @@ -8,24 +8,4 @@ namespace WebCore { -struct IDLJSBuffer : IDLTypedArray<WebCore::JSBuffer> { -}; - -template<> struct JSConverter<IDLJSBuffer> { - static constexpr bool needsState = true; - static constexpr bool needsGlobalObject = true; - - template<typename U> - static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) - { - return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); - } - - template<typename U> - static JSC::JSValue convertNewlyCreated(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, U&& value) - { - return convert(lexicalGlobalObject, globalObject, std::forward<U>(value)); - } -}; - }
\ No newline at end of file diff --git a/src/bun.js/bindings/JSStringDecoder.cpp b/src/bun.js/bindings/JSStringDecoder.cpp index a2872b994..66f9cb654 100644 --- a/src/bun.js/bindings/JSStringDecoder.cpp +++ b/src/bun.js/bindings/JSStringDecoder.cpp @@ -364,8 +364,8 @@ static JSC_DEFINE_CUSTOM_GETTER(jsStringDecoder_lastChar, (JSGlobalObject * lexi auto throwScope = DECLARE_THROW_SCOPE(vm); JSStringDecoder* thisObject = jsCast<JSStringDecoder*>(JSValue::decode(thisValue)); auto buffer = ArrayBuffer::createFromBytes(thisObject->m_lastChar, 4, nullptr); - JSC::JSUint8Array* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->typedArrayStructure(JSC::TypeUint8, true), WTFMove(buffer), 0, 4); - toBuffer(lexicalGlobalObject, uint8Array); + auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + JSC::JSUint8Array* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, globalObject->JSBufferSubclassStructure(), WTFMove(buffer), 0, 4); RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(uint8Array)); } static JSC_DEFINE_CUSTOM_GETTER(jsStringDecoder_lastNeed, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index d8593a9fa..1a9a1dc1b 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -127,7 +127,6 @@ using SourceOrigin = JSC::SourceOrigin; using JSObject = JSC::JSObject; using JSNonFinalObject = JSC::JSNonFinalObject; namespace JSCastingHelpers = JSC::JSCastingHelpers; -using JSBuffer = WebCore::JSBuffer; #include <dlfcn.h> #include "IDLTypes.h" @@ -574,6 +573,15 @@ JSC_DEFINE_CUSTOM_GETTER(JSCloseEvent_getter, WebCore::JSCloseEvent::getConstructor(JSC::getVM(lexicalGlobalObject), thisObject)); } +JSC_DEFINE_CUSTOM_GETTER(JSBuffer_getter, + (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, + JSC::PropertyName)) +{ + Zig::GlobalObject* thisObject = JSC::jsCast<Zig::GlobalObject*>(lexicalGlobalObject); + return JSC::JSValue::encode( + thisObject->JSBufferConstructor()); +} + GENERATED_CONSTRUCTOR_GETTER(JSTextDecoder); GENERATED_CONSTRUCTOR_SETTER(JSTextDecoder); @@ -589,9 +597,6 @@ GENERATED_CONSTRUCTOR_SETTER(JSBlob); WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSMessageEvent); WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSMessageEvent); -WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSBuffer); -WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSBuffer); - WEBCORE_GENERATED_CONSTRUCTOR_GETTER(JSWebSocket); WEBCORE_GENERATED_CONSTRUCTOR_SETTER(JSWebSocket); @@ -2419,6 +2424,15 @@ void GlobalObject::finishCreation(VM& vm) init.set(JSModuleNamespaceObject::createStructure(init.vm, init.owner, init.owner->objectPrototype())); }); + m_JSBufferSubclassStructure.initLater( + [](const Initializer<Structure>& init) { + auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(init.owner); + auto clientData = WebCore::clientData(init.vm); + + auto* baseStructure = globalObject->typedArrayStructure(JSC::TypeUint8, false); + JSC::Structure* subclassStructure = JSC::InternalFunction::createSubclassStructure(globalObject, globalObject->JSBufferConstructor(), baseStructure); + init.set(subclassStructure); + }); m_performMicrotaskFunction.initLater( [](const Initializer<JSFunction>& init) { init.set(JSFunction::create(init.vm, init.owner, 4, "performMicrotask"_s, jsFunctionPerformMicrotask, ImplementationVisibility::Public)); @@ -2596,6 +2610,16 @@ void GlobalObject::finishCreation(VM& vm) init.setConstructor(constructor); }); + m_JSBufferClassStructure.initLater( + [](LazyClassStructure::Initializer& init) { + 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); + init.setStructure(structure); + init.setConstructor(constructor); + }); + m_JSHTTPSResponseSinkClassStructure.initLater( [](LazyClassStructure::Initializer& init) { auto* prototype = createJSSinkPrototype(init.vm, init.global, WebCore::SinkID::HTTPSResponseSink); @@ -3087,7 +3111,9 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm) putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "CloseEvent"_s), JSC::CustomGetterSetter::create(vm, JSCloseEvent_getter, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly); - PUT_WEBCORE_GENERATED_CONSTRUCTOR("Buffer"_s, JSBuffer); + putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "Buffer"_s), JSC::CustomGetterSetter::create(vm, JSBuffer_getter, nullptr), + JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly); + PUT_WEBCORE_GENERATED_CONSTRUCTOR("TextEncoder"_s, JSTextEncoder); PUT_WEBCORE_GENERATED_CONSTRUCTOR("MessageEvent"_s, JSMessageEvent); PUT_WEBCORE_GENERATED_CONSTRUCTOR("WebSocket"_s, JSWebSocket); @@ -3405,6 +3431,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor) thisObject->m_JSReadableStateClassStructure.visit(visitor); thisObject->m_JSStringDecoderClassStructure.visit(visitor); thisObject->m_NapiClassStructure.visit(visitor); + thisObject->m_JSBufferClassStructure.visit(visitor); thisObject->m_pendingVirtualModuleResultStructure.visit(visitor); thisObject->m_performMicrotaskFunction.visit(visitor); @@ -3424,6 +3451,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor) thisObject->m_JSHTTPResponseController.visit(visitor); thisObject->m_callSiteStructure.visit(visitor); thisObject->m_emitReadableNextTickFunction.visit(visitor); + thisObject->m_JSBufferSubclassStructure.visit(visitor); for (auto& barrier : thisObject->m_thenables) { visitor.append(barrier); diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index 7335c9d97..f07c108dd 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -197,6 +197,11 @@ public: JSC::JSValue FileSinkPrototype() { return m_JSFileSinkClassStructure.prototypeInitializedOnMainThread(this); } JSC::JSValue JSReadableFileSinkControllerPrototype() { return m_JSFileSinkControllerPrototype.getInitializedOnMainThread(this); } + JSC::Structure* JSBufferStructure() { return m_JSBufferClassStructure.getInitializedOnMainThread(this); } + JSC::JSObject* JSBufferConstructor() { return m_JSBufferClassStructure.constructorInitializedOnMainThread(this); } + JSC::JSValue JSBufferPrototype() { return m_JSBufferClassStructure.prototypeInitializedOnMainThread(this); } + JSC::Structure* JSBufferSubclassStructure() { return m_JSBufferSubclassStructure.getInitializedOnMainThread(this); } + JSC::Structure* ArrayBufferSinkStructure() { return m_JSArrayBufferSinkClassStructure.getInitializedOnMainThread(this); } JSC::JSObject* ArrayBufferSink() { return m_JSArrayBufferSinkClassStructure.constructorInitializedOnMainThread(this); } JSC::JSValue ArrayBufferSinkPrototype() { return m_JSArrayBufferSinkClassStructure.prototypeInitializedOnMainThread(this); } @@ -462,6 +467,7 @@ private: LazyClassStructure m_JSStringDecoderClassStructure; LazyClassStructure m_NapiClassStructure; LazyClassStructure m_callSiteStructure; + LazyClassStructure m_JSBufferClassStructure; /** * WARNING: You must update visitChildrenImpl() if you add a new field. @@ -490,6 +496,7 @@ private: LazyProperty<JSGlobalObject, JSObject> m_processObject; LazyProperty<JSGlobalObject, JSObject> m_subtleCryptoObject; LazyProperty<JSGlobalObject, Structure> m_JSHTTPResponseController; + LazyProperty<JSGlobalObject, JSC::Structure> m_JSBufferSubclassStructure; DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock); void* m_bunVM; diff --git a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h index 5c7acd18a..aa0eb99a8 100644 --- a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h +++ b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h @@ -16,7 +16,6 @@ public: DOMClientIsoSubspaces() = default; /* --- bun --- */ - std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBuffer; std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBufferList; std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFFIFunction; std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNapiClass; diff --git a/src/bun.js/bindings/webcore/DOMConstructors.h b/src/bun.js/bindings/webcore/DOMConstructors.h index dc38fedcd..37c5d9220 100644 --- a/src/bun.js/bindings/webcore/DOMConstructors.h +++ b/src/bun.js/bindings/webcore/DOMConstructors.h @@ -855,13 +855,12 @@ enum class DOMConstructorID : uint16_t { XSLTProcessor, // --bun-- - Buffer, EventEmitter, }; static constexpr unsigned numberOfDOMConstructorsBase = 846; -static constexpr unsigned bunExtraConstructors = 2; +static constexpr unsigned bunExtraConstructors = 1; static constexpr unsigned numberOfDOMConstructors = numberOfDOMConstructorsBase + bunExtraConstructors; diff --git a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h index d15866b7b..3adfa0f44 100644 --- a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h +++ b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h @@ -16,7 +16,6 @@ class DOMIsoSubspaces { public: DOMIsoSubspaces() = default; /*-- BUN --*/ - std::unique_ptr<IsoSubspace> m_subspaceForBuffer; std::unique_ptr<IsoSubspace> m_subspaceForBufferList; std::unique_ptr<IsoSubspace> m_subspaceForFFIFunction; std::unique_ptr<IsoSubspace> m_subspaceForNapiClass; diff --git a/src/bun.js/builtins/cpp/JSBufferConstructorBuiltins.cpp b/src/bun.js/builtins/cpp/JSBufferConstructorBuiltins.cpp index ed14b6699..dd03c2a77 100644 --- a/src/bun.js/builtins/cpp/JSBufferConstructorBuiltins.cpp +++ b/src/bun.js/builtins/cpp/JSBufferConstructorBuiltins.cpp @@ -48,10 +48,26 @@ namespace WebCore { +const JSC::ConstructAbility s_jsBufferConstructorAllocCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_jsBufferConstructorAllocCodeConstructorKind = JSC::ConstructorKind::None; +const JSC::ImplementationVisibility s_jsBufferConstructorAllocCodeImplementationVisibility = JSC::ImplementationVisibility::Public; +const int s_jsBufferConstructorAllocCodeLength = 185; +static const JSC::Intrinsic s_jsBufferConstructorAllocCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_jsBufferConstructorAllocCode = + "(function (n) {\n" \ + " \"use strict\";\n" \ + " if (typeof n !== \"number\" || n < 0) {\n" \ + " @throwRangeError(\"n must be a positive integer less than 2^32\");\n" \ + " }\n" \ + " \n" \ + " return new this(n);\n" \ + "})\n" \ +; + const JSC::ConstructAbility s_jsBufferConstructorFromCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferConstructorFromCodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferConstructorFromCodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferConstructorFromCodeLength = 1033; +const int s_jsBufferConstructorFromCodeLength = 1035; static const JSC::Intrinsic s_jsBufferConstructorFromCodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferConstructorFromCode = "(function (items) {\n" \ @@ -92,7 +108,7 @@ const char* const s_jsBufferConstructorFromCode = " //\n" \ " //\n" \ " //\n" \ - " return this.toBuffer(@Uint8Array.from(arrayLike));\n" \ + " return new this(@Uint8Array.from(arrayLike).buffer);\n" \ "})\n" \ ; diff --git a/src/bun.js/builtins/cpp/JSBufferConstructorBuiltins.h b/src/bun.js/builtins/cpp/JSBufferConstructorBuiltins.h index f9181b402..05058bba3 100644 --- a/src/bun.js/builtins/cpp/JSBufferConstructorBuiltins.h +++ b/src/bun.js/builtins/cpp/JSBufferConstructorBuiltins.h @@ -47,6 +47,11 @@ class FunctionExecutable; namespace WebCore { /* JSBufferConstructor */ +extern const char* const s_jsBufferConstructorAllocCode; +extern const int s_jsBufferConstructorAllocCodeLength; +extern const JSC::ConstructAbility s_jsBufferConstructorAllocCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferConstructorAllocCodeConstructorKind; +extern const JSC::ImplementationVisibility s_jsBufferConstructorAllocCodeImplementationVisibility; extern const char* const s_jsBufferConstructorFromCode; extern const int s_jsBufferConstructorFromCodeLength; extern const JSC::ConstructAbility s_jsBufferConstructorFromCodeConstructAbility; @@ -54,14 +59,18 @@ extern const JSC::ConstructorKind s_jsBufferConstructorFromCodeConstructorKind; extern const JSC::ImplementationVisibility s_jsBufferConstructorFromCodeImplementationVisibility; #define WEBCORE_FOREACH_JSBUFFERCONSTRUCTOR_BUILTIN_DATA(macro) \ + macro(alloc, jsBufferConstructorAlloc, 1) \ macro(from, jsBufferConstructorFrom, 1) \ +#define WEBCORE_BUILTIN_JSBUFFERCONSTRUCTOR_ALLOC 1 #define WEBCORE_BUILTIN_JSBUFFERCONSTRUCTOR_FROM 1 #define WEBCORE_FOREACH_JSBUFFERCONSTRUCTOR_BUILTIN_CODE(macro) \ + macro(jsBufferConstructorAllocCode, alloc, ASCIILiteral(), s_jsBufferConstructorAllocCodeLength) \ macro(jsBufferConstructorFromCode, from, ASCIILiteral(), s_jsBufferConstructorFromCodeLength) \ #define WEBCORE_FOREACH_JSBUFFERCONSTRUCTOR_BUILTIN_FUNCTION_NAME(macro) \ + macro(alloc) \ macro(from) \ #define DECLARE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \ diff --git a/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp b/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp index cd8b072d4..dbb9e13c1 100644 --- a/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp +++ b/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp @@ -51,240 +51,240 @@ namespace WebCore { const JSC::ConstructAbility s_jsBufferPrototypeSetBigUint64CodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeSetBigUint64CodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeSetBigUint64CodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeSetBigUint64CodeLength = 107; +const int s_jsBufferPrototypeSetBigUint64CodeLength = 174; static const JSC::Intrinsic s_jsBufferPrototypeSetBigUint64CodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeSetBigUint64Code = "(function (offset, value, le) {\n" \ " \"use strict\";\n" \ - " return this.dataView.setBigUint64(offset, value, le);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setBigUint64(offset, value, le);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadInt8CodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadInt8CodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadInt8CodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadInt8CodeLength = 80; +const int s_jsBufferPrototypeReadInt8CodeLength = 147; static const JSC::Intrinsic s_jsBufferPrototypeReadInt8CodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadInt8Code = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getInt8(offset);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getInt8(offset);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadUInt8CodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadUInt8CodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadUInt8CodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadUInt8CodeLength = 81; +const int s_jsBufferPrototypeReadUInt8CodeLength = 148; static const JSC::Intrinsic s_jsBufferPrototypeReadUInt8CodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadUInt8Code = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getUint8(offset);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getUint8(offset);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadInt16LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadInt16LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadInt16LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadInt16LECodeLength = 87; +const int s_jsBufferPrototypeReadInt16LECodeLength = 154; static const JSC::Intrinsic s_jsBufferPrototypeReadInt16LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadInt16LECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getInt16(offset, true);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getInt16(offset, true);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadInt16BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadInt16BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadInt16BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadInt16BECodeLength = 88; +const int s_jsBufferPrototypeReadInt16BECodeLength = 155; static const JSC::Intrinsic s_jsBufferPrototypeReadInt16BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadInt16BECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getInt16(offset, false);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getInt16(offset, false);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadUInt16LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadUInt16LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadUInt16LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadUInt16LECodeLength = 88; +const int s_jsBufferPrototypeReadUInt16LECodeLength = 155; static const JSC::Intrinsic s_jsBufferPrototypeReadUInt16LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadUInt16LECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getUint16(offset, true);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getUint16(offset, true);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadUInt16BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadUInt16BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadUInt16BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadUInt16BECodeLength = 89; +const int s_jsBufferPrototypeReadUInt16BECodeLength = 156; static const JSC::Intrinsic s_jsBufferPrototypeReadUInt16BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadUInt16BECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getUint16(offset, false);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getUint16(offset, false);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadInt32LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadInt32LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadInt32LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadInt32LECodeLength = 87; +const int s_jsBufferPrototypeReadInt32LECodeLength = 154; static const JSC::Intrinsic s_jsBufferPrototypeReadInt32LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadInt32LECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getInt32(offset, true);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getInt32(offset, true);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadInt32BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadInt32BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadInt32BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadInt32BECodeLength = 88; +const int s_jsBufferPrototypeReadInt32BECodeLength = 155; static const JSC::Intrinsic s_jsBufferPrototypeReadInt32BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadInt32BECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getInt32(offset, false);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getInt32(offset, false);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadUInt32LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadUInt32LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadUInt32LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadUInt32LECodeLength = 88; +const int s_jsBufferPrototypeReadUInt32LECodeLength = 155; static const JSC::Intrinsic s_jsBufferPrototypeReadUInt32LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadUInt32LECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getUint32(offset, true);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getUint32(offset, true);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadUInt32BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadUInt32BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadUInt32BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadUInt32BECodeLength = 89; +const int s_jsBufferPrototypeReadUInt32BECodeLength = 156; static const JSC::Intrinsic s_jsBufferPrototypeReadUInt32BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadUInt32BECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getUint32(offset, false);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getUint32(offset, false);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadFloatLECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadFloatLECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadFloatLECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadFloatLECodeLength = 89; +const int s_jsBufferPrototypeReadFloatLECodeLength = 156; static const JSC::Intrinsic s_jsBufferPrototypeReadFloatLECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadFloatLECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getFloat32(offset, true);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getFloat32(offset, true);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadFloatBECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadFloatBECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadFloatBECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadFloatBECodeLength = 90; +const int s_jsBufferPrototypeReadFloatBECodeLength = 157; static const JSC::Intrinsic s_jsBufferPrototypeReadFloatBECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadFloatBECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getFloat32(offset, false);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getFloat32(offset, false);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadDoubleLECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadDoubleLECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadDoubleLECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadDoubleLECodeLength = 89; +const int s_jsBufferPrototypeReadDoubleLECodeLength = 156; static const JSC::Intrinsic s_jsBufferPrototypeReadDoubleLECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadDoubleLECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getFloat64(offset, true);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getFloat64(offset, true);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadDoubleBECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadDoubleBECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadDoubleBECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadDoubleBECodeLength = 90; +const int s_jsBufferPrototypeReadDoubleBECodeLength = 157; static const JSC::Intrinsic s_jsBufferPrototypeReadDoubleBECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadDoubleBECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getFloat64(offset, false);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getFloat64(offset, false);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadBigInt64LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadBigInt64LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadBigInt64LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadBigInt64LECodeLength = 90; +const int s_jsBufferPrototypeReadBigInt64LECodeLength = 157; static const JSC::Intrinsic s_jsBufferPrototypeReadBigInt64LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadBigInt64LECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getBigInt64(offset, true);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getBigInt64(offset, true);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadBigInt64BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadBigInt64BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadBigInt64BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadBigInt64BECodeLength = 91; +const int s_jsBufferPrototypeReadBigInt64BECodeLength = 158; static const JSC::Intrinsic s_jsBufferPrototypeReadBigInt64BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadBigInt64BECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getBigInt64(offset, false);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getBigInt64(offset, false);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadBigUInt64LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadBigUInt64LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadBigUInt64LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadBigUInt64LECodeLength = 91; +const int s_jsBufferPrototypeReadBigUInt64LECodeLength = 158; static const JSC::Intrinsic s_jsBufferPrototypeReadBigUInt64LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadBigUInt64LECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getBigUint64(offset, true);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getBigUint64(offset, true);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeReadBigUInt64BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeReadBigUInt64BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeReadBigUInt64BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeReadBigUInt64BECodeLength = 92; +const int s_jsBufferPrototypeReadBigUInt64BECodeLength = 159; static const JSC::Intrinsic s_jsBufferPrototypeReadBigUInt64BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeReadBigUInt64BECode = "(function (offset) {\n" \ " \"use strict\";\n" \ - " return this.dataView.getBigUint64(offset, false);\n" \ + " return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getBigUint64(offset, false);\n" \ "})\n" \ ; const JSC::ConstructAbility s_jsBufferPrototypeWriteInt8CodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteInt8CodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteInt8CodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteInt8CodeLength = 108; +const int s_jsBufferPrototypeWriteInt8CodeLength = 175; static const JSC::Intrinsic s_jsBufferPrototypeWriteInt8CodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteInt8Code = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setInt8(offset, value);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setInt8(offset, value);\n" \ " return offset + 1;\n" \ "})\n" \ ; @@ -292,12 +292,12 @@ const char* const s_jsBufferPrototypeWriteInt8Code = const JSC::ConstructAbility s_jsBufferPrototypeWriteUInt8CodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteUInt8CodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteUInt8CodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteUInt8CodeLength = 109; +const int s_jsBufferPrototypeWriteUInt8CodeLength = 176; static const JSC::Intrinsic s_jsBufferPrototypeWriteUInt8CodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteUInt8Code = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setUint8(offset, value);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setUint8(offset, value);\n" \ " return offset + 1;\n" \ "})\n" \ ; @@ -305,12 +305,12 @@ const char* const s_jsBufferPrototypeWriteUInt8Code = const JSC::ConstructAbility s_jsBufferPrototypeWriteInt16LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteInt16LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteInt16LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteInt16LECodeLength = 115; +const int s_jsBufferPrototypeWriteInt16LECodeLength = 182; static const JSC::Intrinsic s_jsBufferPrototypeWriteInt16LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteInt16LECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setInt16(offset, value, true);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setInt16(offset, value, true);\n" \ " return offset + 2;\n" \ "})\n" \ ; @@ -318,12 +318,12 @@ const char* const s_jsBufferPrototypeWriteInt16LECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteInt16BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteInt16BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteInt16BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteInt16BECodeLength = 116; +const int s_jsBufferPrototypeWriteInt16BECodeLength = 183; static const JSC::Intrinsic s_jsBufferPrototypeWriteInt16BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteInt16BECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setInt16(offset, value, false);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setInt16(offset, value, false);\n" \ " return offset + 2;\n" \ "})\n" \ ; @@ -331,12 +331,12 @@ const char* const s_jsBufferPrototypeWriteInt16BECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteUInt16LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteUInt16LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteUInt16LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteUInt16LECodeLength = 116; +const int s_jsBufferPrototypeWriteUInt16LECodeLength = 183; static const JSC::Intrinsic s_jsBufferPrototypeWriteUInt16LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteUInt16LECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setUint16(offset, value, true);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setUint16(offset, value, true);\n" \ " return offset + 2;\n" \ "})\n" \ ; @@ -344,12 +344,12 @@ const char* const s_jsBufferPrototypeWriteUInt16LECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteUInt16BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteUInt16BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteUInt16BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteUInt16BECodeLength = 117; +const int s_jsBufferPrototypeWriteUInt16BECodeLength = 184; static const JSC::Intrinsic s_jsBufferPrototypeWriteUInt16BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteUInt16BECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setUint16(offset, value, false);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setUint16(offset, value, false);\n" \ " return offset + 2;\n" \ "})\n" \ ; @@ -357,12 +357,12 @@ const char* const s_jsBufferPrototypeWriteUInt16BECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteInt32LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteInt32LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteInt32LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteInt32LECodeLength = 115; +const int s_jsBufferPrototypeWriteInt32LECodeLength = 182; static const JSC::Intrinsic s_jsBufferPrototypeWriteInt32LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteInt32LECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setInt32(offset, value, true);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setInt32(offset, value, true);\n" \ " return offset + 4;\n" \ "})\n" \ ; @@ -370,12 +370,12 @@ const char* const s_jsBufferPrototypeWriteInt32LECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteInt32BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteInt32BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteInt32BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteInt32BECodeLength = 116; +const int s_jsBufferPrototypeWriteInt32BECodeLength = 183; static const JSC::Intrinsic s_jsBufferPrototypeWriteInt32BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteInt32BECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setInt32(offset, value, false);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setInt32(offset, value, false);\n" \ " return offset + 4;\n" \ "})\n" \ ; @@ -383,12 +383,12 @@ const char* const s_jsBufferPrototypeWriteInt32BECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteUInt32LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteUInt32LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteUInt32LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteUInt32LECodeLength = 116; +const int s_jsBufferPrototypeWriteUInt32LECodeLength = 183; static const JSC::Intrinsic s_jsBufferPrototypeWriteUInt32LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteUInt32LECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setUint32(offset, value, true);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setUint32(offset, value, true);\n" \ " return offset + 4;\n" \ "})\n" \ ; @@ -396,12 +396,12 @@ const char* const s_jsBufferPrototypeWriteUInt32LECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteUInt32BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteUInt32BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteUInt32BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteUInt32BECodeLength = 117; +const int s_jsBufferPrototypeWriteUInt32BECodeLength = 184; static const JSC::Intrinsic s_jsBufferPrototypeWriteUInt32BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteUInt32BECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setUint32(offset, value, false);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setUint32(offset, value, false);\n" \ " return offset + 4;\n" \ "})\n" \ ; @@ -409,12 +409,12 @@ const char* const s_jsBufferPrototypeWriteUInt32BECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteFloatLECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteFloatLECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteFloatLECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteFloatLECodeLength = 117; +const int s_jsBufferPrototypeWriteFloatLECodeLength = 184; static const JSC::Intrinsic s_jsBufferPrototypeWriteFloatLECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteFloatLECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setFloat32(offset, value, true);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setFloat32(offset, value, true);\n" \ " return offset + 4;\n" \ "})\n" \ ; @@ -422,12 +422,12 @@ const char* const s_jsBufferPrototypeWriteFloatLECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteFloatBECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteFloatBECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteFloatBECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteFloatBECodeLength = 118; +const int s_jsBufferPrototypeWriteFloatBECodeLength = 185; static const JSC::Intrinsic s_jsBufferPrototypeWriteFloatBECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteFloatBECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setFloat32(offset, value, false);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setFloat32(offset, value, false);\n" \ " return offset + 4;\n" \ "})\n" \ ; @@ -435,12 +435,12 @@ const char* const s_jsBufferPrototypeWriteFloatBECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteDoubleLECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteDoubleLECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteDoubleLECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteDoubleLECodeLength = 117; +const int s_jsBufferPrototypeWriteDoubleLECodeLength = 184; static const JSC::Intrinsic s_jsBufferPrototypeWriteDoubleLECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteDoubleLECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setFloat64(offset, value, true);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setFloat64(offset, value, true);\n" \ " return offset + 8;\n" \ "})\n" \ ; @@ -448,12 +448,12 @@ const char* const s_jsBufferPrototypeWriteDoubleLECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteDoubleBECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteDoubleBECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteDoubleBECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteDoubleBECodeLength = 118; +const int s_jsBufferPrototypeWriteDoubleBECodeLength = 185; static const JSC::Intrinsic s_jsBufferPrototypeWriteDoubleBECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteDoubleBECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setFloat64(offset, value, false);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setFloat64(offset, value, false);\n" \ " return offset + 8;\n" \ "})\n" \ ; @@ -461,12 +461,12 @@ const char* const s_jsBufferPrototypeWriteDoubleBECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteBigInt64LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteBigInt64LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteBigInt64LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteBigInt64LECodeLength = 118; +const int s_jsBufferPrototypeWriteBigInt64LECodeLength = 185; static const JSC::Intrinsic s_jsBufferPrototypeWriteBigInt64LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteBigInt64LECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setBigInt64(offset, value, true);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setBigInt64(offset, value, true);\n" \ " return offset + 8;\n" \ "})\n" \ ; @@ -474,12 +474,12 @@ const char* const s_jsBufferPrototypeWriteBigInt64LECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteBigInt64BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteBigInt64BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteBigInt64BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteBigInt64BECodeLength = 119; +const int s_jsBufferPrototypeWriteBigInt64BECodeLength = 186; static const JSC::Intrinsic s_jsBufferPrototypeWriteBigInt64BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteBigInt64BECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setBigInt64(offset, value, false);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setBigInt64(offset, value, false);\n" \ " return offset + 8;\n" \ "})\n" \ ; @@ -487,12 +487,12 @@ const char* const s_jsBufferPrototypeWriteBigInt64BECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteBigUInt64LECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteBigUInt64LECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteBigUInt64LECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteBigUInt64LECodeLength = 119; +const int s_jsBufferPrototypeWriteBigUInt64LECodeLength = 186; static const JSC::Intrinsic s_jsBufferPrototypeWriteBigUInt64LECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteBigUInt64LECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setBigUint64(offset, value, true);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setBigUint64(offset, value, true);\n" \ " return offset + 8;\n" \ "})\n" \ ; @@ -500,12 +500,12 @@ const char* const s_jsBufferPrototypeWriteBigUInt64LECode = const JSC::ConstructAbility s_jsBufferPrototypeWriteBigUInt64BECodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeWriteBigUInt64BECodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeWriteBigUInt64BECodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeWriteBigUInt64BECodeLength = 120; +const int s_jsBufferPrototypeWriteBigUInt64BECodeLength = 187; static const JSC::Intrinsic s_jsBufferPrototypeWriteBigUInt64BECodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeWriteBigUInt64BECode = "(function (value, offset) {\n" \ " \"use strict\";\n" \ - " this.dataView.setBigUint64(offset, value, false);\n" \ + " (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setBigUint64(offset, value, false);\n" \ " return offset + 8;\n" \ "})\n" \ ; diff --git a/src/bun.js/builtins/js/JSBufferConstructor.js b/src/bun.js/builtins/js/JSBufferConstructor.js index bfb122034..48342fe26 100644 --- a/src/bun.js/builtins/js/JSBufferConstructor.js +++ b/src/bun.js/builtins/js/JSBufferConstructor.js @@ -25,6 +25,14 @@ // ^ that comment is required or the builtins generator will have a fit. +function alloc(n) { + "use strict"; + if (typeof n !== "number" || n < 0) { + @throwRangeError("n must be a positive integer less than 2^32"); + } + + return new this(n); +} function from(items) { "use strict"; @@ -64,5 +72,5 @@ function from(items) { // Don't pass the second argument because Node's Buffer.from doesn't accept // a function and Uint8Array.from requires it if it exists // That means we cannot use @tailCallFowrardArguments here, sadly - return this.toBuffer(@Uint8Array.from(arrayLike)); + return new this(@Uint8Array.from(arrayLike).buffer); } diff --git a/src/bun.js/builtins/js/JSBufferPrototype.js b/src/bun.js/builtins/js/JSBufferPrototype.js index 689dc2dde..ef3332d88 100644 --- a/src/bun.js/builtins/js/JSBufferPrototype.js +++ b/src/bun.js/builtins/js/JSBufferPrototype.js @@ -31,176 +31,176 @@ function setBigUint64(offset, value, le) { "use strict"; - return this.dataView.setBigUint64(offset, value, le); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setBigUint64(offset, value, le); } function readInt8(offset) { "use strict"; - return this.dataView.getInt8(offset); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getInt8(offset); } function readUInt8(offset) { "use strict"; - return this.dataView.getUint8(offset); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getUint8(offset); } function readInt16LE(offset) { "use strict"; - return this.dataView.getInt16(offset, true); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getInt16(offset, true); } function readInt16BE(offset) { "use strict"; - return this.dataView.getInt16(offset, false); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getInt16(offset, false); } function readUInt16LE(offset) { "use strict"; - return this.dataView.getUint16(offset, true); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getUint16(offset, true); } function readUInt16BE(offset) { "use strict"; - return this.dataView.getUint16(offset, false); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getUint16(offset, false); } function readInt32LE(offset) { "use strict"; - return this.dataView.getInt32(offset, true); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getInt32(offset, true); } function readInt32BE(offset) { "use strict"; - return this.dataView.getInt32(offset, false); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getInt32(offset, false); } function readUInt32LE(offset) { "use strict"; - return this.dataView.getUint32(offset, true); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getUint32(offset, true); } function readUInt32BE(offset) { "use strict"; - return this.dataView.getUint32(offset, false); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getUint32(offset, false); } function readFloatLE(offset) { "use strict"; - return this.dataView.getFloat32(offset, true); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getFloat32(offset, true); } function readFloatBE(offset) { "use strict"; - return this.dataView.getFloat32(offset, false); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getFloat32(offset, false); } function readDoubleLE(offset) { "use strict"; - return this.dataView.getFloat64(offset, true); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getFloat64(offset, true); } function readDoubleBE(offset) { "use strict"; - return this.dataView.getFloat64(offset, false); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getFloat64(offset, false); } function readBigInt64LE(offset) { "use strict"; - return this.dataView.getBigInt64(offset, true); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getBigInt64(offset, true); } function readBigInt64BE(offset) { "use strict"; - return this.dataView.getBigInt64(offset, false); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getBigInt64(offset, false); } function readBigUInt64LE(offset) { "use strict"; - return this.dataView.getBigUint64(offset, true); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getBigUint64(offset, true); } function readBigUInt64BE(offset) { "use strict"; - return this.dataView.getBigUint64(offset, false); + return (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).getBigUint64(offset, false); } function writeInt8(value, offset) { "use strict"; - this.dataView.setInt8(offset, value); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setInt8(offset, value); return offset + 1; } function writeUInt8(value, offset) { "use strict"; - this.dataView.setUint8(offset, value); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setUint8(offset, value); return offset + 1; } function writeInt16LE(value, offset) { "use strict"; - this.dataView.setInt16(offset, value, true); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setInt16(offset, value, true); return offset + 2; } function writeInt16BE(value, offset) { "use strict"; - this.dataView.setInt16(offset, value, false); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setInt16(offset, value, false); return offset + 2; } function writeUInt16LE(value, offset) { "use strict"; - this.dataView.setUint16(offset, value, true); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setUint16(offset, value, true); return offset + 2; } function writeUInt16BE(value, offset) { "use strict"; - this.dataView.setUint16(offset, value, false); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setUint16(offset, value, false); return offset + 2; } function writeInt32LE(value, offset) { "use strict"; - this.dataView.setInt32(offset, value, true); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setInt32(offset, value, true); return offset + 4; } function writeInt32BE(value, offset) { "use strict"; - this.dataView.setInt32(offset, value, false); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setInt32(offset, value, false); return offset + 4; } function writeUInt32LE(value, offset) { "use strict"; - this.dataView.setUint32(offset, value, true); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setUint32(offset, value, true); return offset + 4; } function writeUInt32BE(value, offset) { "use strict"; - this.dataView.setUint32(offset, value, false); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setUint32(offset, value, false); return offset + 4; } function writeFloatLE(value, offset) { "use strict"; - this.dataView.setFloat32(offset, value, true); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setFloat32(offset, value, true); return offset + 4; } function writeFloatBE(value, offset) { "use strict"; - this.dataView.setFloat32(offset, value, false); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setFloat32(offset, value, false); return offset + 4; } function writeDoubleLE(value, offset) { "use strict"; - this.dataView.setFloat64(offset, value, true); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setFloat64(offset, value, true); return offset + 8; } function writeDoubleBE(value, offset) { "use strict"; - this.dataView.setFloat64(offset, value, false); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setFloat64(offset, value, false); return offset + 8; } function writeBigInt64LE(value, offset) { "use strict"; - this.dataView.setBigInt64(offset, value, true); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setBigInt64(offset, value, true); return offset + 8; } function writeBigInt64BE(value, offset) { "use strict"; - this.dataView.setBigInt64(offset, value, false); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setBigInt64(offset, value, false); return offset + 8; } function writeBigUInt64LE(value, offset) { "use strict"; - this.dataView.setBigUint64(offset, value, true); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setBigUint64(offset, value, true); return offset + 8; } function writeBigUInt64BE(value, offset) { "use strict"; - this.dataView.setBigUint64(offset, value, false); + (this.@dataView ||= new DataView(this.buffer, this.byteOffset, this.byteLength)).setBigUint64(offset, value, false); return offset + 8; } diff --git a/src/bun.js/modules/BufferModule.h b/src/bun.js/modules/BufferModule.h index c6e3aa651..afc00ffd1 100644 --- a/src/bun.js/modules/BufferModule.h +++ b/src/bun.js/modules/BufferModule.h @@ -14,16 +14,14 @@ inline void generateBufferSourceCode(JSC::JSGlobalObject *lexicalGlobalObject, reinterpret_cast<GlobalObject *>(lexicalGlobalObject); exportNames.append(JSC::Identifier::fromString(vm, "Buffer"_s)); - exportValues.append(WebCore::JSBuffer::getConstructor(vm, globalObject)); + exportValues.append(globalObject->JSBufferConstructor()); auto *slowBuffer = JSC::JSFunction::create( vm, globalObject, 0, "SlowBuffer"_s, WebCore::constructSlowBuffer, ImplementationVisibility::Public, NoIntrinsic, WebCore::constructSlowBuffer); slowBuffer->putDirect( - vm, vm.propertyNames->prototype, - WebCore::JSBuffer::prototype( - vm, *jsCast<JSDOMGlobalObject *>(lexicalGlobalObject)), + vm, vm.propertyNames->prototype, globalObject->JSBufferPrototype(), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); exportNames.append(JSC::Identifier::fromString(vm, "SlowBuffer"_s)); diff --git a/test/bun.js/buffer.test.js b/test/bun.js/buffer.test.js index b8771d5b4..3e14ead81 100644 --- a/test/bun.js/buffer.test.js +++ b/test/bun.js/buffer.test.js @@ -82,56 +82,12 @@ it("Buffer.isBuffer", () => { gc(); expect(Buffer.isBuffer(a)).toBe(false); gc(); - Buffer.toBuffer(a); + a = new Buffer(a.buffer); gc(); expect(Buffer.isBuffer(a)).toBe(true); gc(); -}); - -it("Buffer.toBuffer throws", () => { - const checks = [ - [], - {}, - "foo", - new Uint16Array(), - new DataView(new Uint8Array(14).buffer), - ]; - for (let i = 0; i < checks.length; i++) { - try { - Buffer.toBuffer(checks[i]); - expect(false).toBe(true); - } catch (exception) { - expect(exception.message).toBe("Expected Uint8Array"); - } - } - expect(true).toBe(true); -}); - -it("Buffer.toBuffer works", () => { - var array = new Uint8Array(20); - expect(array instanceof Buffer).toBe(false); - var buf = Buffer.toBuffer(array); - expect(array instanceof Buffer).toBe(true); - // if this fails or infinitely loops, it means there is a memory issue with the JSC::Structure object - expect(Object.keys(buf).length > 0).toBe(true); - - expect(buf.write("hello world ")).toBe(12); - gc(); - expect(buf.toString("utf8", 0, "hello world ".length)).toBe("hello world "); - gc(); - expect(buf.toString("base64url", 0, "hello world ".length)).toBe( - btoa("hello world "), - ); - gc(); - - expect(buf instanceof Uint8Array).toBe(true); - expect(buf instanceof Buffer).toBe(true); - expect(buf.slice() instanceof Uint8Array).toBe(true); - expect(buf.slice(0, 1) instanceof Buffer).toBe(true); - expect(buf.slice(0, 1) instanceof Uint8Array).toBe(true); - expect(buf.slice(0, 1) instanceof Buffer).toBe(true); - expect(new Buffer(buf) instanceof Buffer).toBe(true); - expect(new Buffer(buf.buffer) instanceof Buffer).toBe(true); + expect(a instanceof Buffer).toBe(true); + expect(a instanceof Uint8Array).toBe(true); }); it("writeInt", () => { @@ -195,8 +151,8 @@ it("Buffer.equals", () => { a[2] = 1; var b = new Uint8Array(10); b[2] = 1; - Buffer.toBuffer(a); - Buffer.toBuffer(b); + a = new Buffer(a.buffer); + b = new Buffer(b.buffer); expect(a.equals(b)).toBe(true); b[2] = 0; expect(a.equals(b)).toBe(false); @@ -207,8 +163,8 @@ it("Buffer.compare", () => { a[2] = 1; var b = new Uint8Array(10); b[2] = 1; - Buffer.toBuffer(a); - Buffer.toBuffer(b); + a = new Buffer(a.buffer); + b = new Buffer(b.buffer); expect(a.compare(b)).toBe(0); b[2] = 0; expect(a.compare(b)).toBe(1); @@ -283,12 +239,12 @@ it("Buffer.compare", () => { it("Buffer.copy", () => { var array1 = new Uint8Array(128); array1.fill(100); - Buffer.toBuffer(array1); + array1 = new Buffer(array1.buffer); var array2 = new Uint8Array(128); array2.fill(200); - Buffer.toBuffer(array2); + array2 = new Buffer(array2.buffer); var array3 = new Uint8Array(128); - Buffer.toBuffer(array3); + array3 = new Buffer(array3.buffer); gc(); expect(array1.copy(array2)).toBe(128); expect(array1.join("")).toBe(array2.join("")); diff --git a/test/bun.js/node-stream-uint8array.test.ts b/test/bun.js/node-stream-uint8array.test.ts index 4bd1c4bcf..ec2e95d34 100644 --- a/test/bun.js/node-stream-uint8array.test.ts +++ b/test/bun.js/node-stream-uint8array.test.ts @@ -9,7 +9,7 @@ describe("Writable", () => { let called; function logCall(fn, id) { - return function() { + return function () { called[id] = (called[id] || 0) + 1; return fn.apply(this, arguments); }; @@ -36,7 +36,7 @@ describe("Writable", () => { writable.write(ABC); writable.end(DEF); - expect(called).toEqual([ 2 ]); + expect(called).toEqual([2]); }); it("should pass in Uint8Array in object mode", () => { @@ -52,7 +52,7 @@ describe("Writable", () => { }); writable.end(ABC); - expect(called).toEqual([ 1 ]); + expect(called).toEqual([1]); }); it("should handle multiple writes carried out via writev()", () => { @@ -77,14 +77,14 @@ describe("Writable", () => { writable.write(DEF); writable.end(GHI); callback(); - expect(called).toEqual([ 1, 1 ]); + expect(called).toEqual([1, 1]); }); }); describe("Readable", () => { it("should perform simple operations", () => { const readable = new Readable({ - read() {} + read() {}, }); readable.push(DEF); @@ -92,12 +92,12 @@ describe("Readable", () => { const buf = readable.read(); expect(buf instanceof Buffer).toBe(true); - expect([ ...buf ]).toEqual([ ...ABC, ...DEF ]); + expect([...buf]).toEqual([...ABC, ...DEF]); }); it("should work with setEncoding()", () => { const readable = new Readable({ - read() {} + read() {}, }); readable.setEncoding("utf8"); |