diff options
author | 2023-01-04 03:30:15 -0800 | |
---|---|---|
committer | 2023-01-04 03:30:15 -0800 | |
commit | 4a328609b96609dbeb8dc98e19aa2f52d2e5eaab (patch) | |
tree | 36d16a77ab44f3b324e3508b6a3e9f4daecf9df2 /src/bun.js/bindings/JSBuffer.cpp | |
parent | 021331f154123f9fb39ac47d5c98f5a9e1095ea4 (diff) | |
download | bun-4a328609b96609dbeb8dc98e19aa2f52d2e5eaab.tar.gz bun-4a328609b96609dbeb8dc98e19aa2f52d2e5eaab.tar.zst bun-4a328609b96609dbeb8dc98e19aa2f52d2e5eaab.zip |
10x faster `new Buffer` (#1717)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js/bindings/JSBuffer.cpp')
-rw-r--r-- | src/bun.js/bindings/JSBuffer.cpp | 454 |
1 files changed, 244 insertions, 210 deletions
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)); } |