diff options
Diffstat (limited to 'src/bun.js/modules/BufferModule.h')
-rw-r--r-- | src/bun.js/modules/BufferModule.h | 141 |
1 files changed, 137 insertions, 4 deletions
diff --git a/src/bun.js/modules/BufferModule.h b/src/bun.js/modules/BufferModule.h index 42eab5173..6e6e39e9c 100644 --- a/src/bun.js/modules/BufferModule.h +++ b/src/bun.js/modules/BufferModule.h @@ -2,11 +2,127 @@ #include "../bindings/ZigGlobalObject.h" #include "JavaScriptCore/JSGlobalObject.h" #include "JavaScriptCore/ObjectConstructor.h" +#include "simdutf.h" namespace Zig { using namespace WebCore; using namespace JSC; +// TODO: Add DOMJIT fast path +JSC_DEFINE_HOST_FUNCTION(jsBufferConstructorFunction_isUtf8, + (JSC::JSGlobalObject * lexicalGlobalObject, + JSC::CallFrame *callframe)) { + auto throwScope = DECLARE_THROW_SCOPE(lexicalGlobalObject->vm()); + + auto buffer = callframe->argument(0); + auto *bufferView = JSC::jsDynamicCast<JSC::JSArrayBufferView *>(buffer); + const char *ptr = nullptr; + size_t byteLength = 0; + if (bufferView) { + if (UNLIKELY(bufferView->isDetached())) { + throwTypeError(lexicalGlobalObject, throwScope, + "ArrayBufferView is detached"_s); + return JSValue::encode({}); + } + + byteLength = bufferView->byteLength(); + + if (byteLength == 0) { + return JSValue::encode(jsBoolean(true)); + } + + ptr = reinterpret_cast<const char *>(bufferView->vector()); + } else if (auto *arrayBuffer = + JSC::jsDynamicCast<JSC::JSArrayBuffer *>(buffer)) { + auto *impl = arrayBuffer->impl(); + + if (!impl) { + return JSValue::encode(jsBoolean(true)); + } + + if (UNLIKELY(impl->isDetached())) { + throwTypeError(lexicalGlobalObject, throwScope, + "ArrayBuffer is detached"_s); + return JSValue::encode({}); + } + + byteLength = impl->byteLength(); + + if (byteLength == 0) { + return JSValue::encode(jsBoolean(true)); + } + + ptr = reinterpret_cast<const char *>(impl->data()); + } else { + throwVMError( + lexicalGlobalObject, throwScope, + createTypeError(lexicalGlobalObject, + "First argument must be an ArrayBufferView"_s)); + return JSValue::encode({}); + } + + RELEASE_AND_RETURN(throwScope, JSValue::encode(jsBoolean( + simdutf::validate_utf8(ptr, byteLength)))); +} + +// TODO: Add DOMJIT fast path +JSC_DEFINE_HOST_FUNCTION(jsBufferConstructorFunction_isAscii, + (JSC::JSGlobalObject * lexicalGlobalObject, + JSC::CallFrame *callframe)) { + auto throwScope = DECLARE_THROW_SCOPE(lexicalGlobalObject->vm()); + + auto buffer = callframe->argument(0); + auto *bufferView = JSC::jsDynamicCast<JSC::JSArrayBufferView *>(buffer); + const char *ptr = nullptr; + size_t byteLength = 0; + if (bufferView) { + + if (UNLIKELY(bufferView->isDetached())) { + throwTypeError(lexicalGlobalObject, throwScope, + "ArrayBufferView is detached"_s); + return JSValue::encode({}); + } + + byteLength = bufferView->byteLength(); + + if (byteLength == 0) { + return JSValue::encode(jsBoolean(true)); + } + + ptr = reinterpret_cast<const char *>(bufferView->vector()); + } else if (auto *arrayBuffer = + JSC::jsDynamicCast<JSC::JSArrayBuffer *>(buffer)) { + auto *impl = arrayBuffer->impl(); + if (UNLIKELY(impl->isDetached())) { + throwTypeError(lexicalGlobalObject, throwScope, + "ArrayBuffer is detached"_s); + return JSValue::encode({}); + } + + if (!impl) { + return JSValue::encode(jsBoolean(true)); + } + + byteLength = impl->byteLength(); + + if (byteLength == 0) { + return JSValue::encode(jsBoolean(true)); + } + + ptr = reinterpret_cast<const char *>(impl->data()); + } else { + throwVMError( + lexicalGlobalObject, throwScope, + createTypeError(lexicalGlobalObject, + "First argument must be an ArrayBufferView"_s)); + return JSValue::encode({}); + } + + RELEASE_AND_RETURN( + throwScope, + JSValue::encode(jsBoolean(simdutf::validate_ascii(ptr, byteLength)))); +} + JSC_DEFINE_HOST_FUNCTION(jsFunctionNotImplemented, (JSGlobalObject * globalObject, CallFrame *callFrame)) { @@ -29,10 +145,13 @@ inline void generateBufferSourceCode(JSC::JSGlobalObject *lexicalGlobalObject, JSC::JSObject *defaultObject = JSC::constructEmptyObject( globalObject, globalObject->objectPrototype(), 12); - defaultObject->putDirect(vm, - PropertyName(Identifier::fromUid( - vm.symbolRegistry().symbolForKey("CommonJS"_s))), - jsNumber(0), 0); + auto CommonJS = + Identifier::fromUid(vm.symbolRegistry().symbolForKey("CommonJS"_s)); + + defaultObject->putDirect(vm, PropertyName(CommonJS), jsNumber(0), 0); + + exportNames.append(CommonJS); + exportValues.append(jsNumber(0)); auto exportProperty = [&](JSC::Identifier name, JSC::JSValue value) { exportNames.append(name); @@ -103,6 +222,20 @@ inline void generateBufferSourceCode(JSC::JSGlobalObject *lexicalGlobalObject, exportProperty(JSC::Identifier::fromString(vm, "resolveObjectURL"_s), resolveObjectURL); + exportProperty(JSC::Identifier::fromString(vm, "isAscii"_s), + JSC::JSFunction::create(vm, globalObject, 1, "isAscii"_s, + jsBufferConstructorFunction_isAscii, + ImplementationVisibility::Public, + NoIntrinsic, + jsBufferConstructorFunction_isUtf8)); + + exportProperty(JSC::Identifier::fromString(vm, "isUtf8"_s), + JSC::JSFunction::create(vm, globalObject, 1, "isUtf8"_s, + jsBufferConstructorFunction_isUtf8, + ImplementationVisibility::Public, + NoIntrinsic, + jsBufferConstructorFunction_isUtf8)); + exportNames.append(vm.propertyNames->defaultKeyword); exportValues.append(defaultObject); } |