diff --git a/src/deps/uws.zig b/src/deps/uws.zig index b97555efce..ae0efef79c 100644 --- a/src/deps/uws.zig +++ b/src/deps/uws.zig @@ -7,7 +7,7 @@ pub const u_int32_t = c_uint; pub const u_int64_t = c_ulonglong; pub const LIBUS_LISTEN_DEFAULT: c_int = 0; pub const LIBUS_LISTEN_EXCLUSIVE_PORT: c_int = 1; -pub const us_socket_t = opaque {}; +pub const Socket = opaque {}; pub const us_timer_t = opaque {}; pub const us_socket_context_t = opaque {}; pub const Loop = opaque { @@ -90,22 +90,22 @@ extern fn us_socket_context_on_server_name(ssl: c_int, context: ?*us_socket_cont extern fn us_socket_context_get_native_handle(ssl: c_int, context: ?*us_socket_context_t) ?*anyopaque; extern fn us_create_socket_context(ssl: c_int, loop: ?*Loop, ext_size: c_int, options: us_socket_context_options_t) ?*us_socket_context_t; extern fn us_socket_context_free(ssl: c_int, context: ?*us_socket_context_t) void; -extern fn us_socket_context_on_open(ssl: c_int, context: ?*us_socket_context_t, on_open: ?fn (?*us_socket_t, c_int, [*c]u8, c_int) callconv(.C) ?*us_socket_t) void; -extern fn us_socket_context_on_close(ssl: c_int, context: ?*us_socket_context_t, on_close: ?fn (?*us_socket_t, c_int, ?*anyopaque) callconv(.C) ?*us_socket_t) void; -extern fn us_socket_context_on_data(ssl: c_int, context: ?*us_socket_context_t, on_data: ?fn (?*us_socket_t, [*c]u8, c_int) callconv(.C) ?*us_socket_t) void; -extern fn us_socket_context_on_writable(ssl: c_int, context: ?*us_socket_context_t, on_writable: ?fn (*us_socket_t) callconv(.C) ?*us_socket_t) void; -extern fn us_socket_context_on_timeout(ssl: c_int, context: ?*us_socket_context_t, on_timeout: ?fn (?*us_socket_t) callconv(.C) ?*us_socket_t) void; -extern fn us_socket_context_on_connect_error(ssl: c_int, context: ?*us_socket_context_t, on_connect_error: ?fn (?*us_socket_t, c_int) callconv(.C) ?*us_socket_t) void; -extern fn us_socket_context_on_end(ssl: c_int, context: ?*us_socket_context_t, on_end: ?fn (?*us_socket_t) callconv(.C) ?*us_socket_t) void; +extern fn us_socket_context_on_open(ssl: c_int, context: ?*us_socket_context_t, on_open: ?fn (?*Socket, c_int, [*c]u8, c_int) callconv(.C) ?*Socket) void; +extern fn us_socket_context_on_close(ssl: c_int, context: ?*us_socket_context_t, on_close: ?fn (?*Socket, c_int, ?*anyopaque) callconv(.C) ?*Socket) void; +extern fn us_socket_context_on_data(ssl: c_int, context: ?*us_socket_context_t, on_data: ?fn (?*Socket, [*c]u8, c_int) callconv(.C) ?*Socket) void; +extern fn us_socket_context_on_writable(ssl: c_int, context: ?*us_socket_context_t, on_writable: ?fn (*Socket) callconv(.C) ?*Socket) void; +extern fn us_socket_context_on_timeout(ssl: c_int, context: ?*us_socket_context_t, on_timeout: ?fn (?*Socket) callconv(.C) ?*Socket) void; +extern fn us_socket_context_on_connect_error(ssl: c_int, context: ?*us_socket_context_t, on_connect_error: ?fn (?*Socket, c_int) callconv(.C) ?*Socket) void; +extern fn us_socket_context_on_end(ssl: c_int, context: ?*us_socket_context_t, on_end: ?fn (?*Socket) callconv(.C) ?*Socket) void; extern fn us_socket_context_ext(ssl: c_int, context: ?*us_socket_context_t) ?*anyopaque; extern fn us_socket_context_listen(ssl: c_int, context: ?*us_socket_context_t, host: [*c]const u8, port: c_int, options: c_int, socket_ext_size: c_int) ?*listen_socket_t; -extern fn us_socket_context_connect(ssl: c_int, context: ?*us_socket_context_t, host: [*c]const u8, port: c_int, source_host: [*c]const u8, options: c_int, socket_ext_size: c_int) ?*us_socket_t; -extern fn us_socket_is_established(ssl: c_int, s: ?*us_socket_t) c_int; -extern fn us_socket_close_connecting(ssl: c_int, s: ?*us_socket_t) ?*us_socket_t; +extern fn us_socket_context_connect(ssl: c_int, context: ?*us_socket_context_t, host: [*c]const u8, port: c_int, source_host: [*c]const u8, options: c_int, socket_ext_size: c_int) ?*Socket; +extern fn us_socket_is_established(ssl: c_int, s: ?*Socket) c_int; +extern fn us_socket_close_connecting(ssl: c_int, s: ?*Socket) ?*Socket; extern fn us_socket_context_loop(ssl: c_int, context: ?*us_socket_context_t) ?*Loop; -extern fn us_socket_context_adopt_socket(ssl: c_int, context: ?*us_socket_context_t, s: ?*us_socket_t, ext_size: c_int) ?*us_socket_t; +extern fn us_socket_context_adopt_socket(ssl: c_int, context: ?*us_socket_context_t, s: ?*Socket, ext_size: c_int) ?*Socket; extern fn us_create_child_socket_context(ssl: c_int, context: ?*us_socket_context_t, context_ext_size: c_int) ?*us_socket_context_t; pub const Poll = opaque { @@ -182,19 +182,19 @@ pub const Poll = opaque { extern fn us_poll_resize(p: ?*Poll, loop: ?*Loop, ext_size: c_uint) ?*Poll; }; -extern fn us_socket_get_native_handle(ssl: c_int, s: ?*us_socket_t) ?*anyopaque; -extern fn us_socket_write(ssl: c_int, s: ?*us_socket_t, data: [*c]const u8, length: c_int, msg_more: c_int) c_int; -extern fn us_socket_timeout(ssl: c_int, s: ?*us_socket_t, seconds: c_uint) void; -extern fn us_socket_ext(ssl: c_int, s: ?*us_socket_t) ?*anyopaque; -extern fn us_socket_context(ssl: c_int, s: ?*us_socket_t) ?*us_socket_context_t; -extern fn us_socket_flush(ssl: c_int, s: ?*us_socket_t) void; -extern fn us_socket_shutdown(ssl: c_int, s: ?*us_socket_t) void; -extern fn us_socket_shutdown_read(ssl: c_int, s: ?*us_socket_t) void; -extern fn us_socket_is_shut_down(ssl: c_int, s: ?*us_socket_t) c_int; -extern fn us_socket_is_closed(ssl: c_int, s: ?*us_socket_t) c_int; -extern fn us_socket_close(ssl: c_int, s: ?*us_socket_t, code: c_int, reason: ?*anyopaque) ?*us_socket_t; -extern fn us_socket_local_port(ssl: c_int, s: ?*us_socket_t) c_int; -extern fn us_socket_remote_address(ssl: c_int, s: ?*us_socket_t, buf: [*c]u8, length: [*c]c_int) void; +extern fn us_socket_get_native_handle(ssl: c_int, s: ?*Socket) ?*anyopaque; +extern fn us_socket_write(ssl: c_int, s: ?*Socket, data: [*c]const u8, length: c_int, msg_more: c_int) c_int; +extern fn Socketimeout(ssl: c_int, s: ?*Socket, seconds: c_uint) void; +extern fn us_socket_ext(ssl: c_int, s: ?*Socket) ?*anyopaque; +extern fn us_socket_context(ssl: c_int, s: ?*Socket) ?*us_socket_context_t; +extern fn us_socket_flush(ssl: c_int, s: ?*Socket) void; +extern fn us_socket_shutdown(ssl: c_int, s: ?*Socket) void; +extern fn us_socket_shutdown_read(ssl: c_int, s: ?*Socket) void; +extern fn us_socket_is_shut_down(ssl: c_int, s: ?*Socket) c_int; +extern fn us_socket_is_closed(ssl: c_int, s: ?*Socket) c_int; +extern fn us_socket_close(ssl: c_int, s: ?*Socket, code: c_int, reason: ?*anyopaque) ?*Socket; +extern fn us_socket_local_port(ssl: c_int, s: ?*Socket) c_int; +extern fn us_socket_remote_address(ssl: c_int, s: ?*Socket, buf: [*c]u8, length: [*c]c_int) void; pub const uws_app_s = opaque {}; pub const uws_req_s = opaque {}; pub const uws_websocket_s = opaque {}; @@ -673,7 +673,7 @@ pub fn NewApp(comptime ssl: bool) type { // }; // const OnWritable = struct { - // pub fn handle(socket: *us_socket_t) callconv(.C) ?*us_socket_t { + // pub fn handle(socket: *Socket) callconv(.C) ?*Socket { // if (comptime UserDataType == void) { // @call(.{ .modifier = .always_inline }, handler, .{ // void{}, @@ -710,7 +710,7 @@ pub fn NewApp(comptime ssl: bool) type { }; } extern fn uws_res_prepare_for_sendfile(ssl: c_int, res: *uws_res) void; -extern fn uws_res_get_native_handle(ssl: c_int, res: *uws_res) *us_socket_t; +extern fn uws_res_get_native_handle(ssl: c_int, res: *uws_res) *Socket; extern fn uws_create_app(ssl: c_int, options: us_socket_context_options_t) *uws_app_t; extern fn uws_app_destroy(ssl: c_int, app: *uws_app_t) void; extern fn uws_app_get(ssl: c_int, app: *uws_app_t, pattern: [*c]const u8, handler: uws_method_handler, user_data: ?*anyopaque) void; diff --git a/src/javascript/jsc/api/bun.zig b/src/javascript/jsc/api/bun.zig index 906e0e53cd..bb0fa218b1 100644 --- a/src/javascript/jsc/api/bun.zig +++ b/src/javascript/jsc/api/bun.zig @@ -2375,7 +2375,7 @@ pub const FFI = struct { return JSC.toInvalidArguments("ptr to invalid memory, that would segfault Bun :(", .{}, globalThis.ref()); } - return JSC.JSValue.jsNumber(@bitCast(f64, @as(usize, addr))); + return JSC.JSValue.fromPtrAddress(addr); } const ValueOrError = union(enum) { diff --git a/src/javascript/jsc/api/ffi.zig b/src/javascript/jsc/api/ffi.zig index 820a0e3d57..864a5d889f 100644 --- a/src/javascript/jsc/api/ffi.zig +++ b/src/javascript/jsc/api/ffi.zig @@ -351,7 +351,7 @@ pub const FFI = struct { return ZigString.init("Failed to compile (nothing happend!)").toErrorInstance(global); }, .compiled => |compiled| { - var cb = Bun__CreateFFIFunction( + var cb = JSC.NewFunctionPtr( global, &ZigString.init(std.mem.span(function_name)), @intCast(u32, function.arg_types.items.len), @@ -443,7 +443,7 @@ pub const FFI = struct { return ZigString.init("Failed to compile (nothing happend!)").toErrorInstance(global); }, .compiled => |compiled| { - var cb = Bun__CreateFFIFunction( + var cb = JSC.NewFunctionPtr( global, &ZigString.init(std.mem.span(function_name)), @intCast(u32, function.arg_types.items.len), @@ -1434,10 +1434,3 @@ pub const FFI = struct { } }; }; - -extern fn Bun__CreateFFIFunction( - globalObject: *JSGlobalObject, - symbolName: *const ZigString, - argCount: u32, - functionPointer: *anyopaque, -) *anyopaque; diff --git a/src/javascript/jsc/bindings/BunBuiltinNames.h b/src/javascript/jsc/bindings/BunBuiltinNames.h index 5c90729f26..17408972a5 100644 --- a/src/javascript/jsc/bindings/BunBuiltinNames.h +++ b/src/javascript/jsc/bindings/BunBuiltinNames.h @@ -43,12 +43,12 @@ using namespace JSC; macro(associatedReadableByteStreamController) \ macro(autoAllocateChunkSize) \ macro(backingMap) \ - macro(bunNativeTag) \ macro(backingSet) \ macro(backpressure) \ macro(backpressureChangePromise) \ macro(basename) \ macro(body) \ + macro(bunNativeTag) \ macro(byobRequest) \ macro(cancel) \ macro(cancelAlgorithm) \ @@ -67,6 +67,7 @@ using namespace JSC; macro(controller) \ macro(cork) \ macro(createReadableStream) \ + macro(createNativeReadableStream) \ macro(createWritableStreamFromInternal) \ macro(cwd) \ macro(dataView) \ @@ -123,6 +124,7 @@ using namespace JSC; macro(makeGetterTypeError) \ macro(makeThisTypeError) \ macro(map) \ + macro(nativeReadableStreamPrototype) \ macro(nextTick) \ macro(normalize) \ macro(on) \ diff --git a/src/javascript/jsc/bindings/JSFFIFunction.cpp b/src/javascript/jsc/bindings/JSFFIFunction.cpp index 5c4ad3ed6c..2937fd3588 100644 --- a/src/javascript/jsc/bindings/JSFFIFunction.cpp +++ b/src/javascript/jsc/bindings/JSFFIFunction.cpp @@ -33,10 +33,15 @@ extern "C" Zig::JSFFIFunction* Bun__CreateFFIFunction(Zig::GlobalObject* globalObject, const ZigString* symbolName, unsigned argCount, Zig::FFIFunction functionPointer) { JSC::VM& vm = globalObject->vm(); - Zig::JSFFIFunction* function = Zig::JSFFIFunction::create(vm, globalObject, argCount, Zig::toStringCopy(*symbolName), functionPointer, JSC::NoIntrinsic); + Zig::JSFFIFunction* function = Zig::JSFFIFunction::create(vm, globalObject, argCount, symbolName != nullptr ? Zig::toStringCopy(*symbolName) : String(), functionPointer, JSC::NoIntrinsic); JSC::gcProtect(function); return function; } +extern "C" JSC::EncodedJSValue Bun__CreateFFIFunctionValue(Zig::GlobalObject* globalObject, const ZigString* symbolName, unsigned argCount, Zig::FFIFunction functionPointer); +extern "C" JSC::EncodedJSValue Bun__CreateFFIFunctionValue(Zig::GlobalObject* globalObject, const ZigString* symbolName, unsigned argCount, Zig::FFIFunction functionPointer) +{ + return JSC::JSValue::encode(JSC::JSValue(Bun__CreateFFIFunction(globalObject, symbolName, argCount, functionPointer))); +} namespace Zig { using namespace JSC; @@ -70,7 +75,7 @@ void JSFFIFunction::finishCreation(VM& vm, NativeExecutable* executable, unsigne JSFFIFunction* JSFFIFunction::create(VM& vm, Zig::GlobalObject* globalObject, unsigned length, const String& name, FFIFunction FFIFunction, Intrinsic intrinsic, NativeFunction nativeConstructor) { - NativeExecutable* executable = vm.getHostFunction(FFIFunction, intrinsic, nativeConstructor, nullptr, name); + NativeExecutable* executable = vm.getHostFunction(FFIFunction, intrinsic, FFIFunction, nullptr, name); Structure* structure = globalObject->FFIFunctionStructure(); JSFFIFunction* function = new (NotNull, allocateCell(vm)) JSFFIFunction(vm, executable, globalObject, structure, WTFMove(FFIFunction)); diff --git a/src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp b/src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp index 9386bcb1c2..1e91a4b73a 100644 --- a/src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp +++ b/src/javascript/jsc/bindings/ReadableByteStreamInternalsBuiltins.cpp @@ -436,7 +436,7 @@ const char* const s_readableByteStreamInternalsTransferBufferToCurrentRealmCode const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeConstructorKind = JSC::ConstructorKind::None; -const int s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeLength = 1423; +const int s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeLength = 1440; static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCode = "(function (controller, chunk)\n" \ @@ -446,30 +446,28 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerEnque " const stream = @getByIdDirectPrivate(controller, \"controlledReadableStream\");\n" \ " @assert(!@getByIdDirectPrivate(controller, \"closeRequested\"));\n" \ " @assert(@getByIdDirectPrivate(stream, \"state\") === @streamReadable);\n" \ - " const buffer = chunk.buffer;\n" \ " const byteOffset = chunk.byteOffset;\n" \ " const byteLength = chunk.byteLength;\n" \ - " const transferredBuffer = @transferBufferToCurrentRealm(buffer);\n" \ "\n" \ " if (@readableStreamHasDefaultReader(stream)) {\n" \ " if (!@getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readRequests\").length)\n" \ - " @readableByteStreamControllerEnqueueChunk(controller, transferredBuffer, byteOffset, byteLength);\n" \ + " @readableByteStreamControllerEnqueueChunk(controller, @transferBufferToCurrentRealm(chunk.buffer), byteOffset, byteLength);\n" \ " else {\n" \ " @assert(!@getByIdDirectPrivate(controller, \"queue\").content.length);\n" \ - " let transferredView = new @Uint8Array(transferredBuffer, byteOffset, byteLength);\n" \ + " const transferredView = chunk.constructor === @Uint8Array ? chunk : new @Uint8Array(chunk.buffer, byteOffset, byteLength);\n" \ " @readableStreamFulfillReadRequest(stream, transferredView, false);\n" \ " }\n" \ " return;\n" \ " }\n" \ "\n" \ " if (@readableStreamHasBYOBReader(stream)) {\n" \ - " @readableByteStreamControllerEnqueueChunk(controller, transferredBuffer, byteOffset, byteLength);\n" \ + " @readableByteStreamControllerEnqueueChunk(controller, @transferBufferToCurrentRealm(chunk.buffer), byteOffset, byteLength);\n" \ " @readableByteStreamControllerProcessPullDescriptors(controller);\n" \ " return;\n" \ " }\n" \ "\n" \ " @assert(!@isReadableStreamLocked(stream));\n" \ - " @readableByteStreamControllerEnqueueChunk(controller, transferredBuffer, byteOffset, byteLength);\n" \ + " @readableByteStreamControllerEnqueueChunk(controller, @transferBufferToCurrentRealm(chunk.buffer), byteOffset, byteLength);\n" \ "})\n" \ ; diff --git a/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp b/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp index 928e875be9..3aa51f5b2f 100644 --- a/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp +++ b/src/javascript/jsc/bindings/ReadableStreamBuiltins.cpp @@ -117,6 +117,89 @@ const char* const s_readableStreamInitializeReadableStreamCode = "})\n" \ ; +const JSC::ConstructAbility s_readableStreamCreateNativeReadableStreamCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +const JSC::ConstructorKind s_readableStreamCreateNativeReadableStreamCodeConstructorKind = JSC::ConstructorKind::None; +const int s_readableStreamCreateNativeReadableStreamCodeLength = 2522; +static const JSC::Intrinsic s_readableStreamCreateNativeReadableStreamCodeIntrinsic = JSC::NoIntrinsic; +const char* const s_readableStreamCreateNativeReadableStreamCode = + "(function (nativeTag, nativeID) {\n" \ + " var cached = @getByIdDirectPrivate(globalThis, \"nativeReadableStreamPrototype\");\n" \ + " if (!cached) {\n" \ + " cached = new @Map();\n" \ + " @putByIdDirectPrivate(globalThis, \"nativeReadableStreamPrototype\", cached);\n" \ + " }\n" \ + " var Prototype = cached.get(nativeID);\n" \ + " if (!Prototype) {\n" \ + " var [pull, start, cancel, setClose, deinit] = globalThis[Symbol.for(\"Bun.lazy\")](nativeID);\n" \ + " Prototype = class NativeReadableStreamSource {\n" \ + " constructor(tag) {\n" \ + " this.pull = this.pull_.bind(tag);\n" \ + " this.start = this.start_.bind(tag);\n" \ + " this.cancel = this.cancel_.bind(tag);\n" \ + " }\n" \ + "\n" \ + " pull;\n" \ + " start;\n" \ + " cancel;\n" \ + " \n" \ + " pull_(controller) {\n" \ + " var result;\n" \ + " try {\n" \ + " result = pull(this);\n" \ + " } catch (e) {\n" \ + " controller.error(e);\n" \ + " return;\n" \ + " }\n" \ + " \n" \ + " if (result === false) {\n" \ + " //\n" \ + " new @Promise((resolve, reject) => resolve(controller.close())).then(() => {}, () => {});\n" \ + " return;\n" \ + " }\n" \ + "\n" \ + " if (@isPromise(result)) {\n" \ + " result.then(controller.enqueue, controller.error);\n" \ + " } else {\n" \ + " controller.enqueue(result);\n" \ + " }\n" \ + " }\n" \ + "\n" \ + " start_(controller) {\n" \ + " setClose(this, controller.close);\n" \ + " const result = start(this, controller.enqueue, controller.error);\n" \ + " if (result === false) {\n" \ + " //\n" \ + " new @Promise((resolve, reject) => resolve(controller.close())).then(() => {}, () => {});\n" \ + " return;\n" \ + " }\n" \ + "\n" \ + "\n" \ + " if (@isPromise(result)) {\n" \ + " result.then(controller.enqueue, controller.error);\n" \ + " } else {\n" \ + " controller.enqueue(result);\n" \ + " }\n" \ + "\n" \ + " return result;\n" \ + " }\n" \ + "\n" \ + " cancel_(reason) {\n" \ + " cancel(this, reason);\n" \ + " }\n" \ + "\n" \ + " static registry = new FinalizationRegistry(deinit);\n" \ + " }\n" \ + " cached.set(nativeID, Prototype);\n" \ + " }\n" \ + " \n" \ + " var instance = new Prototype(nativeTag);\n" \ + " Prototype.registry.register(instance, nativeTag);\n" \ + " var stream = new @ReadableStream(instance);\n" \ + " @putByIdDirectPrivate(stream, \"bunNativeTag\", nativeID);\n" \ + " return stream;\n" \ + "})\n" \ +; + const JSC::ConstructAbility s_readableStreamCancelCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamCancelCodeConstructorKind = JSC::ConstructorKind::None; const int s_readableStreamCancelCodeLength = 324; diff --git a/src/javascript/jsc/bindings/ReadableStreamBuiltins.h b/src/javascript/jsc/bindings/ReadableStreamBuiltins.h index 356d47eb74..ccf3e9b7c7 100644 --- a/src/javascript/jsc/bindings/ReadableStreamBuiltins.h +++ b/src/javascript/jsc/bindings/ReadableStreamBuiltins.h @@ -51,6 +51,10 @@ extern const char* const s_readableStreamInitializeReadableStreamCode; extern const int s_readableStreamInitializeReadableStreamCodeLength; extern const JSC::ConstructAbility s_readableStreamInitializeReadableStreamCodeConstructAbility; extern const JSC::ConstructorKind s_readableStreamInitializeReadableStreamCodeConstructorKind; +extern const char* const s_readableStreamCreateNativeReadableStreamCode; +extern const int s_readableStreamCreateNativeReadableStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamCreateNativeReadableStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamCreateNativeReadableStreamCodeConstructorKind; extern const char* const s_readableStreamCancelCode; extern const int s_readableStreamCancelCodeLength; extern const JSC::ConstructAbility s_readableStreamCancelCodeConstructAbility; @@ -78,6 +82,7 @@ extern const JSC::ConstructorKind s_readableStreamLockedCodeConstructorKind; #define WEBCORE_FOREACH_READABLESTREAM_BUILTIN_DATA(macro) \ macro(initializeReadableStream, readableStreamInitializeReadableStream, 2) \ + macro(createNativeReadableStream, readableStreamCreateNativeReadableStream, 2) \ macro(cancel, readableStreamCancel, 1) \ macro(getReader, readableStreamGetReader, 1) \ macro(pipeThrough, readableStreamPipeThrough, 2) \ @@ -86,6 +91,7 @@ extern const JSC::ConstructorKind s_readableStreamLockedCodeConstructorKind; macro(locked, readableStreamLocked, 0) \ #define WEBCORE_BUILTIN_READABLESTREAM_INITIALIZEREADABLESTREAM 1 +#define WEBCORE_BUILTIN_READABLESTREAM_CREATENATIVEREADABLESTREAM 1 #define WEBCORE_BUILTIN_READABLESTREAM_CANCEL 1 #define WEBCORE_BUILTIN_READABLESTREAM_GETREADER 1 #define WEBCORE_BUILTIN_READABLESTREAM_PIPETHROUGH 1 @@ -95,6 +101,7 @@ extern const JSC::ConstructorKind s_readableStreamLockedCodeConstructorKind; #define WEBCORE_FOREACH_READABLESTREAM_BUILTIN_CODE(macro) \ macro(readableStreamInitializeReadableStreamCode, initializeReadableStream, ASCIILiteral(), s_readableStreamInitializeReadableStreamCodeLength) \ + macro(readableStreamCreateNativeReadableStreamCode, createNativeReadableStream, ASCIILiteral(), s_readableStreamCreateNativeReadableStreamCodeLength) \ macro(readableStreamCancelCode, cancel, ASCIILiteral(), s_readableStreamCancelCodeLength) \ macro(readableStreamGetReaderCode, getReader, ASCIILiteral(), s_readableStreamGetReaderCodeLength) \ macro(readableStreamPipeThroughCode, pipeThrough, ASCIILiteral(), s_readableStreamPipeThroughCodeLength) \ @@ -104,6 +111,7 @@ extern const JSC::ConstructorKind s_readableStreamLockedCodeConstructorKind; #define WEBCORE_FOREACH_READABLESTREAM_BUILTIN_FUNCTION_NAME(macro) \ macro(cancel) \ + macro(createNativeReadableStream) \ macro(getReader) \ macro(initializeReadableStream) \ macro(locked) \ diff --git a/src/javascript/jsc/bindings/StreamInternalsBuiltins.cpp b/src/javascript/jsc/bindings/StreamInternalsBuiltins.cpp index 1910dd83d4..41b6a45328 100644 --- a/src/javascript/jsc/bindings/StreamInternalsBuiltins.cpp +++ b/src/javascript/jsc/bindings/StreamInternalsBuiltins.cpp @@ -164,7 +164,7 @@ const char* const s_streamInternalsPromiseInvokeOrFallbackOrNoopCode = const JSC::ConstructAbility s_streamInternalsValidateAndNormalizeQueuingStrategyCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_streamInternalsValidateAndNormalizeQueuingStrategyCodeConstructorKind = JSC::ConstructorKind::None; -const int s_streamInternalsValidateAndNormalizeQueuingStrategyCodeLength = 486; +const int s_streamInternalsValidateAndNormalizeQueuingStrategyCodeLength = 430; static const JSC::Intrinsic s_streamInternalsValidateAndNormalizeQueuingStrategyCodeIntrinsic = JSC::NoIntrinsic; const char* const s_streamInternalsValidateAndNormalizeQueuingStrategyCode = "(function (size, highWaterMark)\n" \ @@ -174,15 +174,12 @@ const char* const s_streamInternalsValidateAndNormalizeQueuingStrategyCode = " if (size !== @undefined && typeof size !== \"function\")\n" \ " @throwTypeError(\"size parameter must be a function\");\n" \ "\n" \ - " const normalizedStrategy = {\n" \ - " size: size,\n" \ - " highWaterMark: @toNumber(highWaterMark)\n" \ - " };\n" \ + " const newHighWaterMark = @toNumber(highWaterMark);\n" \ "\n" \ - " if (@isNaN(normalizedStrategy.highWaterMark) || normalizedStrategy.highWaterMark < 0)\n" \ + " if (@isNaN(newHighWaterMark) || newHighWaterMark < 0)\n" \ " @throwRangeError(\"highWaterMark value is negative or not a number\");\n" \ "\n" \ - " return normalizedStrategy;\n" \ + " return { size: size, highWaterMark: newHighWaterMark };\n" \ "})\n" \ ; diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp index aa4dc3105c..61f94e3f84 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp +++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp @@ -97,7 +97,7 @@ #include "napi.h" #include "JSZigGlobalObjectBuiltins.h" #include "JSSQLStatement.h" -#include "bun-base64.h" +#include "ReadableStreamBuiltins.h" using JSGlobalObject = JSC::JSGlobalObject; using Exception = JSC::Exception; @@ -902,6 +902,27 @@ JSC: static NeverDestroyed sqliteString(MAKE_STATIC_STRING_IMPL("sqlite")); static NeverDestroyed noopString(MAKE_STATIC_STRING_IMPL("noop")); JSC::JSValue moduleName = callFrame->argument(0); + if (moduleName.isNumber()) { + switch (moduleName.toInt32(globalObject)) { + case 0: { + auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); + JSC::throwTypeError(globalObject, scope, "lazyLoad expects a string"_s); + scope.release(); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + case 1: { + return ByteBlob__JSReadableStreamSource__load(globalObject); + } + default: { + auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); + JSC::throwTypeError(globalObject, scope, "lazyLoad expects a string"_s); + scope.release(); + return JSC::JSValue::encode(JSC::JSValue {}); + } + } + } + auto string = moduleName.toWTFString(globalObject); if (string.isNull()) { auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); @@ -1181,6 +1202,24 @@ JSC_DEFINE_HOST_FUNCTION(isAbortSignal, (JSGlobalObject*, CallFrame* callFrame)) return JSValue::encode(jsBoolean(callFrame->uncheckedArgument(0).inherits())); } +extern "C" JSC__JSValue ZigGlobalObject__createNativeReadableStream(Zig::GlobalObject* globalObject, JSC__JSValue nativeID, JSC__JSValue nativeTag); +extern "C" JSC__JSValue ZigGlobalObject__createNativeReadableStream(Zig::GlobalObject* globalObject, JSC__JSValue nativeID, JSC__JSValue nativeTag) +{ + auto& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto clientData = WebCore::clientData(vm); + auto& builtinNames = WebCore::builtinNames(vm); + + auto function = globalObject->getDirect(vm, builtinNames.createNativeReadableStreamPrivateName()).getObject(); + JSC::MarkedArgumentBuffer arguments = JSC::MarkedArgumentBuffer(); + arguments.append(JSValue::decode(nativeID)); + arguments.append(JSValue::decode(nativeTag)); + + auto callData = JSC::getCallData(function); + return JSC::JSValue::encode(call(globalObject, function, callData, JSC::jsUndefined(), arguments)); +} + void GlobalObject::finishCreation(VM& vm) { Base::finishCreation(vm); @@ -1285,6 +1324,8 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm) extraStaticGlobals.releaseBuffer(); + putDirectBuiltinFunction(vm, this, builtinNames.createNativeReadableStreamPrivateName(), readableStreamCreateNativeReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); + putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "process"_s), JSC::CustomGetterSetter::create(vm, property_lazyProcessGetter, property_lazyProcessSetter), JSC::PropertyAttribute::CustomAccessor | 0); diff --git a/src/javascript/jsc/bindings/bindings.cpp b/src/javascript/jsc/bindings/bindings.cpp index dc43afd79d..1dda5c6be3 100644 --- a/src/javascript/jsc/bindings/bindings.cpp +++ b/src/javascript/jsc/bindings/bindings.cpp @@ -1427,116 +1427,6 @@ void JSC__SourceCode__fromString(JSC__SourceCode* arg0, const WTF__String* arg1, const JSC__SourceOrigin* arg2, WTF__String* arg3, unsigned char SourceType4) {} -#pragma mark - JSC::JSFunction - -// JSC__JSValue JSC__JSFunction__callWithArguments(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, -// JSC__JSValue* arg2, size_t arg3, -// JSC__Exception** arg4, const unsigned char* arg5) -// { -// auto args = makeArgs(arg2, arg3); -// return JSC::JSValue::encode(JSC::call(arg1, JSC::JSValue::decode(JSValue0), -// JSC::JSValue::decode(JSValue0), args, (const char*)arg5)); -// } -// JSC__JSValue JSC__JSFunction__callWithArgumentsAndThis(JSC__JSValue JSValue0, JSC__JSValue JSValue1, -// JSC__JSGlobalObject* arg2, -// JSC__JSValue* arg3, size_t arg4, -// JSC__Exception** arg5, -// const unsigned char* arg6) -// { -// auto args = makeArgs(arg3, arg4); -// return JSC::JSValue::encode(JSC::call(arg2, JSC::JSValue::decode(JSValue0), -// JSC::JSValue::decode(JSValue1), args, (const char*)arg6)); -// } -// JSC__JSValue JSC__JSFunction__callWithoutAnyArgumentsOrThis(JSC__JSValue JSValue0, -// JSC__JSGlobalObject* arg1, -// JSC__Exception** arg2, -// const unsigned char* arg3) -// { -// return JSC::JSValue::encode(JSC::call(arg1, JSC::JSValue::decode(JSValue0), -// JSC::JSValue::decode(JSValue0), JSC::ArgList(), -// (const char*)arg3)); -// } -// JSC__JSValue JSC__JSFunction__callWithThis(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, -// JSC__JSValue JSValue2, JSC__Exception** arg3, -// const unsigned char* arg4) -// { -// return JSC::JSValue::encode(JSC::call(arg1, JSC::JSValue::decode(JSValue0), -// JSC::JSValue::decode(JSValue2), JSC::ArgList(), -// (const char*)arg4)); -// } -// JSC__JSValue JSC__JSFunction__constructWithArguments(JSC__JSValue JSValue0, -// JSC__JSGlobalObject* arg1, JSC__JSValue* arg2, -// size_t arg3, JSC__Exception** arg4, -// const unsigned char* arg5) -// { -// auto args = makeArgs(arg2, arg3); -// return JSC::JSValue::encode( -// JSC::construct(arg1, JSC::JSValue::decode(JSValue0), args, (const char*)arg5)); -// } - -// JSC__JSValue JSC__JSFunction__constructWithArgumentsAndNewTarget( -// JSC__JSValue JSValue0, JSC__JSValue JSValue1, JSC__JSGlobalObject* arg2, JSC__JSValue* arg3, -// size_t arg4, JSC__Exception** arg5, const unsigned char* arg6) -// { -// auto args = makeArgs(arg3, arg4); -// return JSC::JSValue::encode(JSC::construct(arg2, JSC::JSValue::decode(JSValue0), -// JSC::JSValue::decode(JSValue0), args, -// (const char*)arg6)); -// } -// JSC__JSValue JSC__JSFunction__constructWithNewTarget(JSC__JSValue JSValue0, -// JSC__JSGlobalObject* arg1, -// JSC__JSValue JSValue2, JSC__Exception** arg3, -// const unsigned char* arg4) -// { -// return JSC::JSValue::encode(JSC::construct(arg1, JSC::JSValue::decode(JSValue0), -// JSC::JSValue::decode(JSValue2), JSC::ArgList(), -// (const char*)arg4)); -// } -// JSC__JSValue JSC__JSFunction__constructWithoutAnyArgumentsOrNewTarget(JSC__JSValue JSValue0, -// JSC__JSGlobalObject* arg1, -// JSC__Exception** arg2, -// const unsigned char* arg3) -// { -// return JSC::JSValue::encode( -// JSC::construct(arg1, JSC::JSValue::decode(JSValue0), JSC::ArgList(), (const char*)arg3)); -// } - -JSC__JSFunction* JSC__JSFunction__createFromNative(JSC__JSGlobalObject* arg0, uint16_t arg1, - const WTF__String* arg2, void* ctx, - NativeCallbackFunction callback) -{ - return JSC::JSNativeStdFunction::create( - reinterpret_cast(arg0->vm()), arg0, arg1, arg2 != nullptr ? *arg2 : WTF::String(), - [ctx, callback](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) - -> JSC::EncodedJSValue { return callback(ctx, globalObject, callFrame); }); -} -// JSC__JSFunction* JSC__JSFunction__createFromSourceCode( -// JSC__JSGlobalObject* arg0, -// const unsigned char* arg1, -// uint16_t arg2, -// JSC__JSValue arg3, -// uint16_t arg4, -// const JSC__SourceCode* source, -// JSC__SourceOrigin* origin, -// JSC__JSObject** exception -// ) { -// JSC::VM& vm = reinterpret_cast(arg0->vm()); -// JSC::Identifier functionName = JSC::Identifier::fromString(vm, arg2 && -// arg1 != nullptr ? WTF::StringImpl(static_cast(arg1), arg2) -// : vm->propertyNames->anonymous.impl()); - -// JSC::FunctionExecutable* function = -// JSC::FunctionExecutable::fromGlobalCode( -// functionName, -// arg0, -// source, -// exception, -// 0, -// nullptr, -// ); - -// } - bWTF__String JSC__JSFunction__displayName(JSC__JSFunction* arg0, JSC__VM* arg1) { auto wrap = Wrap(arg0->displayName(reinterpret_cast(arg1))); @@ -2662,27 +2552,6 @@ bJSC__CatchScope JSC__CatchScope__declare(JSC__VM* arg0, unsigned char* arg1, un } JSC__Exception* JSC__CatchScope__exception(JSC__CatchScope* arg0) { return arg0->exception(); } -#pragma mark - JSC::CallFrame - -JSC__JSValue JSC__CallFrame__argument(const JSC__CallFrame* arg0, uint16_t arg1) -{ - return JSC::JSValue::encode(arg0->argument(arg1)); -}; -size_t JSC__CallFrame__argumentsCount(const JSC__CallFrame* arg0) { return arg0->argumentCount(); } -JSC__JSObject* JSC__CallFrame__jsCallee(const JSC__CallFrame* arg0) { return arg0->jsCallee(); } -JSC__JSValue JSC__CallFrame__newTarget(const JSC__CallFrame* arg0) -{ - return JSC::JSValue::encode(arg0->newTarget()); -}; -JSC__JSValue JSC__CallFrame__thisValue(const JSC__CallFrame* arg0) -{ - return JSC::JSValue::encode(arg0->thisValue()); -} -JSC__JSValue JSC__CallFrame__uncheckedArgument(const JSC__CallFrame* arg0, uint16_t arg1) -{ - return JSC::JSValue::encode(arg0->uncheckedArgument(arg1)); -} - #pragma mark - JSC::Identifier void JSC__Identifier__deinit(const JSC__Identifier* arg0) diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig index cce3a40284..2e752304d3 100644 --- a/src/javascript/jsc/bindings/bindings.zig +++ b/src/javascript/jsc/bindings/bindings.zig @@ -1,4 +1,3 @@ -pub const Shimmer = @import("./shimmer.zig").Shimmer; const std = @import("std"); const bun = @import("../../../global.zig"); const string = bun.string; @@ -15,6 +14,7 @@ const ZigStackTrace = Exports.ZigStackTrace; const is_bindgen: bool = std.meta.globalOption("bindgen", bool) orelse false; const ArrayBuffer = @import("../base.zig").ArrayBuffer; const JSC = @import("../../../jsc.zig"); +const Shimmer = JSC.Shimmer; pub const JSObject = extern struct { pub const shim = Shimmer("JSC", "JSObject", @This()); bytes: shim.Bytes, @@ -1077,6 +1077,13 @@ pub const JSModuleRecord = extern struct { }; }; +pub fn Async(comptime ReturnType: type) type { + return struct { + promise: *?*JSPromise, + continuation: anyframe->ReturnType, + }; +} + pub const JSPromise = extern struct { pub const shim = Shimmer("JSC", "JSPromise", @This()); bytes: shim.Bytes, @@ -1425,8 +1432,6 @@ pub const JSFunction = extern struct { pub const name = "JSC::JSFunction"; pub const namespace = "JSC"; - pub const NativeFunctionCallback = fn (ctx: ?*anyopaque, global: [*c]JSGlobalObject, call_frame: [*c]CallFrame) callconv(.C) JSValue; - // pub fn createFromSourceCode( // global: *JSGlobalObject, // function_name: ?[*]const u8, @@ -1448,15 +1453,7 @@ pub const JSFunction = extern struct { // exception, // }); // } - pub fn createFromNative( - global: *JSGlobalObject, - argument_count: u16, - name_: ?*const String, - ctx: ?*anyopaque, - func: NativeFunctionCallback, - ) *JSFunction { - return cppFn("createFromNative", .{ global, argument_count, name_, ctx, func }); - } + pub fn getName(this: *JSFunction, vm: *VM) String { return cppFn("getName", .{ this, vm }); } @@ -1470,152 +1467,13 @@ pub const JSFunction = extern struct { // return cppFn("toString", .{ this, globalThis }); // } - pub fn callWithArgumentsAndThis( - function: JSValue, - thisValue: JSValue, - globalThis: *JSGlobalObject, - arguments_ptr: [*]JSValue, - arguments_len: usize, - exception: ReturnableException, - error_message: [*c]const u8, - ) JSValue { - return cppFn("callWithArgumentsAndThis", .{ - function, - thisValue, - globalThis, - arguments_ptr, - arguments_len, - exception, - error_message, - }); - } - - pub fn callWithArguments( - function: JSValue, - globalThis: *JSGlobalObject, - arguments_ptr: [*]JSValue, - arguments_len: usize, - exception: ReturnableException, - error_message: [*c]const u8, - ) JSValue { - return cppFn("callWithArguments", .{ - function, - globalThis, - arguments_ptr, - arguments_len, - exception, - error_message, - }); - } - - pub fn callWithThis( - function: JSValue, - globalThis: *JSGlobalObject, - thisValue: JSValue, - exception: ReturnableException, - error_message: [*c]const u8, - ) JSValue { - return cppFn("callWithThis", .{ - function, - globalThis, - thisValue, - exception, - error_message, - }); - } - - pub fn callWithoutAnyArgumentsOrThis( - function: JSValue, - globalThis: *JSGlobalObject, - exception: ReturnableException, - error_message: [*c]const u8, - ) JSValue { - return cppFn("callWithoutAnyArgumentsOrThis", .{ function, globalThis, exception, error_message }); - } - - pub fn constructWithArgumentsAndNewTarget( - function: JSValue, - newTarget: JSValue, - globalThis: *JSGlobalObject, - arguments_ptr: [*]JSValue, - arguments_len: usize, - exception: ReturnableException, - error_message: [*c]const u8, - ) JSValue { - return cppFn("constructWithArgumentsAndNewTarget", .{ - function, - newTarget, - globalThis, - arguments_ptr, - arguments_len, - exception, - error_message, - }); - } - - pub fn constructWithArguments( - function: JSValue, - globalThis: *JSGlobalObject, - arguments_ptr: [*]JSValue, - arguments_len: usize, - exception: ReturnableException, - error_message: [*c]const u8, - ) JSValue { - return cppFn("constructWithArguments", .{ - function, - globalThis, - arguments_ptr, - arguments_len, - exception, - error_message, - }); - } - - pub fn constructWithNewTarget( - function: JSValue, - globalThis: *JSGlobalObject, - newTarget: JSValue, - exception: ReturnableException, - error_message: [*c]const u8, - ) JSValue { - return cppFn("constructWithNewTarget", .{ - function, - globalThis, - newTarget, - exception, - error_message, - }); - } - - pub fn constructWithoutAnyArgumentsOrNewTarget( - function: JSValue, - globalThis: *JSGlobalObject, - exception: ReturnableException, - error_message: [*c]const u8, - ) JSValue { - return cppFn("constructWithoutAnyArgumentsOrNewTarget", .{ - function, - globalThis, - exception, - error_message, - }); - } - pub const Extern = [_][]const u8{ "fromString", // "createFromSourceCode", - "createFromNative", + "getName", "displayName", "calculatedDisplayName", - "callWithArgumentsAndThis", - "callWithArguments", - "callWithThis", - "callWithoutAnyArgumentsOrThis", - "constructWithArgumentsAndNewTarget", - "constructWithArguments", - "constructWithNewTarget", - "constructWithoutAnyArgumentsOrNewTarget", }; }; @@ -2306,6 +2164,20 @@ pub const JSValue = enum(u64) { return JSC.C.JSValueIsInstanceOfConstructor(global.ref(), this.asObjectRef(), constructor.asObjectRef(), null); } + pub fn call(this: JSValue, globalThis: *JSGlobalObject, args: []const JSC.JSValue) JSC.JSValue { + return callWithThis(this, globalThis, JSC.JSValue.zero, args); + } + + pub fn callWithThis(this: JSValue, globalThis: *JSGlobalObject, thisValue: JSC.JSValue, args: []const JSC.JSValue) JSC.JSValue { + return JSC.C.JSObjectCallAsFunctionReturnValue( + globalThis.ref(), + this.asObjectRef(), + thisValue.asObjectRef(), + args.len, + @ptrCast([*]const JSC.C.JSValueRef, args.ptr), + ); + } + pub fn jsType( this: JSValue, ) JSType { @@ -2842,6 +2714,18 @@ pub const JSValue = enum(u64) { }); } + pub fn asPtr(this: JSValue, comptime Pointer: type) *Pointer { + return @intToPtr(*Pointer, @bitCast(usize, this.asNumber())); + } + + pub fn fromPtrAddress(addr: anytype) JSValue { + return jsNumber(@bitCast(f64, @as(usize, addr))); + } + + pub fn fromPtr(addr: anytype) JSValue { + return fromPtrAddress(@ptrToInt(addr)); + } + pub fn toBoolean(this: JSValue) bool { return cppFn("toBoolean", .{ this, @@ -3228,59 +3112,35 @@ pub const CatchScope = extern struct { }; }; -pub const CallFrame = extern struct { - pub const shim = Shimmer("JSC", "CallFrame", @This()); - bytes: shim.Bytes, - const cppFn = shim.cppFn; +pub const CallFrame = opaque { + /// The value is generated in `make sizegen` + /// The value is 6. + /// On ARM64_32, the value is something else but it really doesn't matter for our case + /// However, I don't want this to subtly break amidst future upgrades to JavaScriptCore + const arguments_offset = 6; + const thisValue_offset = arguments_offset - 1; + const argumentsCount_offset = thisValue_offset - 1; + const alignment = std.meta.alignment([]const JSC.JSValue); - pub const include = "JavaScriptCore/CallFrame.h"; - pub const name = "JSC::CallFrame"; - pub const namespace = "JSC"; - - pub inline fn argumentsCount(call_frame: *const CallFrame) usize { - return cppFn("argumentsCount", .{ - call_frame, - }); - } - pub inline fn uncheckedArgument(call_frame: *const CallFrame, i: u16) JSValue { - return cppFn("uncheckedArgument", .{ call_frame, i }); - } - pub inline fn argument(call_frame: *const CallFrame, i: u16) JSValue { - return cppFn("argument", .{ - call_frame, - i, - }); - } - pub inline fn thisValue(call_frame: *const CallFrame) ?JSValue { - return cppFn("thisValue", .{ - call_frame, - }); + pub fn argumentsPtr(self: *const CallFrame) [*]const JSC.JSValue { + return @ptrCast([*]const JSC.JSValue, @alignCast(alignment, self)) + arguments_offset; } - pub inline fn setThisValue(call_frame: *CallFrame, new_this: JSValue) ?JSValue { - return cppFn("setThisValue", .{ - call_frame, - new_this, - }); - } - pub inline fn newTarget(call_frame: *const CallFrame) ?JSValue { - return cppFn("newTarget", .{ - call_frame, - }); + pub fn arguments(self: *const CallFrame) []const JSC.JSValue { + return self.argumentsPtr()[0..self.argumentsCount()]; } - pub inline fn setNewTarget(call_frame: *CallFrame, target: JSValue) ?JSValue { - return cppFn("setNewTarget", .{ - call_frame, - target, - }); + pub fn argument(self: *const CallFrame, comptime i: comptime_int) JSC.JSValue { + return self.argumentsPtr()[i]; } - pub inline fn jsCallee(call_frame: *const CallFrame) *JSObject { - return cppFn("jsCallee", .{ - call_frame, - }); + + pub fn this(self: *const CallFrame) JSC.JSValue { + return (@ptrCast([*]const JSC.JSValue, @alignCast(alignment, self)) + thisValue_offset)[0]; + } + + pub fn argumentsCount(self: *const CallFrame) usize { + return (@ptrCast([*]const usize, @alignCast(alignment, self)) + argumentsCount_offset)[0]; } - pub const Extern = [_][]const u8{ "argumentsCount", "uncheckedArgument", "argument", "thisValue", "newTarget", "jsCallee", "setNewTarget", "setThisValue" }; }; // pub const WellKnownSymbols = extern struct { @@ -3500,6 +3360,47 @@ pub const ExternalStringImpl = extern struct { }; }; +pub const JSArray = struct { + pub fn from(globalThis: *JSGlobalObject, arguments: []const JSC.JSValue) JSValue { + return JSC.JSValue.c(JSC.C.JSObjectMakeArray(globalThis.ref(), arguments.len, @ptrCast([*]const JSC.C.JSObjectRef, arguments.ptr), null)); + } +}; + +const private = struct { + pub extern fn Bun__CreateFFIFunction( + globalObject: *JSGlobalObject, + symbolName: ?*const ZigString, + argCount: u32, + functionPointer: *const anyopaque, + ) *anyopaque; + + pub extern fn Bun__CreateFFIFunctionValue( + globalObject: *JSGlobalObject, + symbolName: ?*const ZigString, + argCount: u32, + functionPointer: *const anyopaque, + ) JSValue; +}; +pub fn NewFunctionPtr( + globalObject: *JSGlobalObject, + symbolName: ?*const ZigString, + argCount: u32, + functionPointer: anytype, +) *anyopaque { + if (comptime JSC.is_bindgen) unreachable; + return private.Bun__CreateFFIFunction(globalObject, symbolName, argCount, @ptrCast(*const anyopaque, functionPointer)); +} + +pub fn NewFunction( + globalObject: *JSGlobalObject, + symbolName: ?*const ZigString, + argCount: u32, + functionPointer: anytype, +) JSValue { + if (comptime JSC.is_bindgen) unreachable; + return private.Bun__CreateFFIFunctionValue(globalObject, symbolName, argCount, @ptrCast(*const anyopaque, functionPointer)); +} + pub const ObjectPrototype = _JSCellStub("ObjectPrototype"); pub const FunctionPrototype = _JSCellStub("FunctionPrototype"); pub const ArrayPrototype = _JSCellStub("ArrayPrototype"); diff --git a/src/javascript/jsc/bindings/builtins/js/ReadableStream.js b/src/javascript/jsc/bindings/builtins/js/ReadableStream.js index 177bb75e9f..446d28bb3a 100644 --- a/src/javascript/jsc/bindings/builtins/js/ReadableStream.js +++ b/src/javascript/jsc/bindings/builtins/js/ReadableStream.js @@ -88,6 +88,84 @@ function initializeReadableStream(underlyingSource, strategy) return this; } +@globalPrivate +function createNativeReadableStream(nativeTag, nativeID) { + var cached = @getByIdDirectPrivate(globalThis, "nativeReadableStreamPrototype"); + if (!cached) { + cached = new @Map(); + @putByIdDirectPrivate(globalThis, "nativeReadableStreamPrototype", cached); + } + var Prototype = cached.get(nativeID); + if (!Prototype) { + var [pull, start, cancel, setClose, deinit] = globalThis[Symbol.for("Bun.lazy")](nativeID); + Prototype = class NativeReadableStreamSource { + constructor(tag) { + this.pull = this.pull_.bind(tag); + this.start = this.start_.bind(tag); + this.cancel = this.cancel_.bind(tag); + } + + pull; + start; + cancel; + + pull_(controller) { + var result; + try { + result = pull(this); + } catch (e) { + controller.error(e); + return; + } + + if (result === false) { + // close on next tick + new @Promise((resolve, reject) => resolve(controller.close())).then(() => {}, () => {}); + return; + } + + if (@isPromise(result)) { + result.then(controller.enqueue, controller.error); + } else { + controller.enqueue(result); + } + } + + start_(controller) { + setClose(this, controller.close); + const result = start(this, controller.enqueue, controller.error); + if (result === false) { + // close on next tick + new @Promise((resolve, reject) => resolve(controller.close())).then(() => {}, () => {}); + return; + } + + + if (@isPromise(result)) { + result.then(controller.enqueue, controller.error); + } else { + controller.enqueue(result); + } + + return result; + } + + cancel_(reason) { + cancel(this, reason); + } + + static registry = new FinalizationRegistry(deinit); + } + cached.set(nativeID, Prototype); + } + + var instance = new Prototype(nativeTag); + Prototype.registry.register(instance, nativeTag); + var stream = new @ReadableStream(instance); + @putByIdDirectPrivate(stream, "bunNativeTag", nativeID); + return stream; +} + function cancel(reason) { "use strict"; diff --git a/src/javascript/jsc/bindings/exports.zig b/src/javascript/jsc/bindings/exports.zig index e1b7d38b93..f346b9f197 100644 --- a/src/javascript/jsc/bindings/exports.zig +++ b/src/javascript/jsc/bindings/exports.zig @@ -177,9 +177,11 @@ pub const ZigErrorType = extern struct { pub const NodeReadableStream = JSC.Node.Readable.State; /// do not use this reference directly, use JSC.Node.Writable pub const NodeWritableStream = JSC.Node.Writable.State; - pub const NodePath = JSC.Node.Path; +// Web Streams +pub const BlobReadableStream = JSC.WebCore.ByteBlobLoader.Source.JSReadableStreamSource; + pub fn Errorable(comptime Type: type) type { return extern struct { result: Result, @@ -2503,6 +2505,7 @@ comptime { std.testing.refAllDecls(Bun.Timer); std.testing.refAllDecls(NodeWritableStream); std.testing.refAllDecls(NodePath); + std.testing.refAllDecls(BlobReadableStream); _ = ZigString__free; _ = ZigString__free_global; } diff --git a/src/javascript/jsc/bindings/headers-cpp.h b/src/javascript/jsc/bindings/headers-cpp.h index 8b5c3bfa4f..37fd0a7a99 100644 --- a/src/javascript/jsc/bindings/headers-cpp.h +++ b/src/javascript/jsc/bindings/headers-cpp.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1653281389 +//-- AUTOGENERATED FILE -- 1653376853 // clang-format off #pragma once @@ -176,14 +176,6 @@ extern "C" const size_t JSC__ThrowScope_object_align_ = alignof(JSC::ThrowScope) extern "C" const size_t JSC__CatchScope_object_size_ = sizeof(JSC::CatchScope); extern "C" const size_t JSC__CatchScope_object_align_ = alignof(JSC::CatchScope); -#ifndef INCLUDED_JavaScriptCore_CallFrame_h -#define INCLUDED_JavaScriptCore_CallFrame_h -#include "JavaScriptCore/CallFrame.h" -#endif - -extern "C" const size_t JSC__CallFrame_object_size_ = sizeof(JSC::CallFrame); -extern "C" const size_t JSC__CallFrame_object_align_ = alignof(JSC::CallFrame); - #ifndef INCLUDED_JavaScriptCore_Identifier_h #define INCLUDED_JavaScriptCore_Identifier_h #include "JavaScriptCore/Identifier.h" @@ -264,8 +256,8 @@ extern "C" const size_t Zig__ConsoleClient_object_align_ = alignof(Zig::ConsoleC extern "C" const size_t Bun__Timer_object_size_ = sizeof(Bun__Timer); extern "C" const size_t Bun__Timer_object_align_ = alignof(Bun__Timer); -const size_t sizes[32] = {sizeof(JSC::JSObject), sizeof(WebCore::DOMURL), sizeof(WebCore::FetchHeaders), sizeof(SystemError), sizeof(JSC::JSCell), sizeof(JSC::JSString), sizeof(Inspector::ScriptArguments), sizeof(JSC::JSModuleLoader), sizeof(JSC::JSModuleRecord), sizeof(JSC::JSPromise), sizeof(JSC::JSInternalPromise), sizeof(JSC::SourceOrigin), sizeof(JSC::SourceCode), sizeof(JSC::JSFunction), sizeof(JSC::JSGlobalObject), sizeof(WTF::URL), sizeof(WTF::String), sizeof(JSC::JSValue), sizeof(JSC::PropertyName), sizeof(JSC::Exception), sizeof(JSC::VM), sizeof(JSC::ThrowScope), sizeof(JSC::CatchScope), sizeof(JSC::CallFrame), sizeof(JSC::Identifier), sizeof(WTF::StringImpl), sizeof(WTF::ExternalStringImpl), sizeof(WTF::StringView), sizeof(Zig::GlobalObject), sizeof(Bun__Readable), sizeof(Bun__Writable), sizeof(Bun__Path)}; +const size_t sizes[31] = {sizeof(JSC::JSObject), sizeof(WebCore::DOMURL), sizeof(WebCore::FetchHeaders), sizeof(SystemError), sizeof(JSC::JSCell), sizeof(JSC::JSString), sizeof(Inspector::ScriptArguments), sizeof(JSC::JSModuleLoader), sizeof(JSC::JSModuleRecord), sizeof(JSC::JSPromise), sizeof(JSC::JSInternalPromise), sizeof(JSC::SourceOrigin), sizeof(JSC::SourceCode), sizeof(JSC::JSFunction), sizeof(JSC::JSGlobalObject), sizeof(WTF::URL), sizeof(WTF::String), sizeof(JSC::JSValue), sizeof(JSC::PropertyName), sizeof(JSC::Exception), sizeof(JSC::VM), sizeof(JSC::ThrowScope), sizeof(JSC::CatchScope), sizeof(JSC::Identifier), sizeof(WTF::StringImpl), sizeof(WTF::ExternalStringImpl), sizeof(WTF::StringView), sizeof(Zig::GlobalObject), sizeof(Bun__Readable), sizeof(Bun__Writable), sizeof(Bun__Path)}; -const char* names[32] = {"JSC__JSObject", "WebCore__DOMURL", "WebCore__FetchHeaders", "SystemError", "JSC__JSCell", "JSC__JSString", "Inspector__ScriptArguments", "JSC__JSModuleLoader", "JSC__JSModuleRecord", "JSC__JSPromise", "JSC__JSInternalPromise", "JSC__SourceOrigin", "JSC__SourceCode", "JSC__JSFunction", "JSC__JSGlobalObject", "WTF__URL", "WTF__String", "JSC__JSValue", "JSC__PropertyName", "JSC__Exception", "JSC__VM", "JSC__ThrowScope", "JSC__CatchScope", "JSC__CallFrame", "JSC__Identifier", "WTF__StringImpl", "WTF__ExternalStringImpl", "WTF__StringView", "Zig__GlobalObject", "Bun__Readable", "Bun__Writable", "Bun__Path"}; +const char* names[31] = {"JSC__JSObject", "WebCore__DOMURL", "WebCore__FetchHeaders", "SystemError", "JSC__JSCell", "JSC__JSString", "Inspector__ScriptArguments", "JSC__JSModuleLoader", "JSC__JSModuleRecord", "JSC__JSPromise", "JSC__JSInternalPromise", "JSC__SourceOrigin", "JSC__SourceCode", "JSC__JSFunction", "JSC__JSGlobalObject", "WTF__URL", "WTF__String", "JSC__JSValue", "JSC__PropertyName", "JSC__Exception", "JSC__VM", "JSC__ThrowScope", "JSC__CatchScope", "JSC__Identifier", "WTF__StringImpl", "WTF__ExternalStringImpl", "WTF__StringView", "Zig__GlobalObject", "Bun__Readable", "Bun__Writable", "Bun__Path"}; -const size_t aligns[32] = {alignof(JSC::JSObject), alignof(WebCore::DOMURL), alignof(WebCore::FetchHeaders), alignof(SystemError), alignof(JSC::JSCell), alignof(JSC::JSString), alignof(Inspector::ScriptArguments), alignof(JSC::JSModuleLoader), alignof(JSC::JSModuleRecord), alignof(JSC::JSPromise), alignof(JSC::JSInternalPromise), alignof(JSC::SourceOrigin), alignof(JSC::SourceCode), alignof(JSC::JSFunction), alignof(JSC::JSGlobalObject), alignof(WTF::URL), alignof(WTF::String), alignof(JSC::JSValue), alignof(JSC::PropertyName), alignof(JSC::Exception), alignof(JSC::VM), alignof(JSC::ThrowScope), alignof(JSC::CatchScope), alignof(JSC::CallFrame), alignof(JSC::Identifier), alignof(WTF::StringImpl), alignof(WTF::ExternalStringImpl), alignof(WTF::StringView), alignof(Zig::GlobalObject), alignof(Bun__Readable), alignof(Bun__Writable), alignof(Bun__Path)}; +const size_t aligns[31] = {alignof(JSC::JSObject), alignof(WebCore::DOMURL), alignof(WebCore::FetchHeaders), alignof(SystemError), alignof(JSC::JSCell), alignof(JSC::JSString), alignof(Inspector::ScriptArguments), alignof(JSC::JSModuleLoader), alignof(JSC::JSModuleRecord), alignof(JSC::JSPromise), alignof(JSC::JSInternalPromise), alignof(JSC::SourceOrigin), alignof(JSC::SourceCode), alignof(JSC::JSFunction), alignof(JSC::JSGlobalObject), alignof(WTF::URL), alignof(WTF::String), alignof(JSC::JSValue), alignof(JSC::PropertyName), alignof(JSC::Exception), alignof(JSC::VM), alignof(JSC::ThrowScope), alignof(JSC::CatchScope), alignof(JSC::Identifier), alignof(WTF::StringImpl), alignof(WTF::ExternalStringImpl), alignof(WTF::StringView), alignof(Zig::GlobalObject), alignof(Bun__Readable), alignof(Bun__Writable), alignof(Bun__Path)}; diff --git a/src/javascript/jsc/bindings/headers.h b/src/javascript/jsc/bindings/headers.h index ad00b46647..8adcfbb950 100644 --- a/src/javascript/jsc/bindings/headers.h +++ b/src/javascript/jsc/bindings/headers.h @@ -1,5 +1,5 @@ // clang-format: off -//-- AUTOGENERATED FILE -- 1653281389 +//-- AUTOGENERATED FILE -- 1653376853 #pragma once #include @@ -34,12 +34,10 @@ typedef void* JSClassRef; typedef char* bJSC__JSModuleRecord_buf; typedef struct bJSC__ThrowScope { unsigned char bytes[8]; } bJSC__ThrowScope; typedef char* bJSC__ThrowScope_buf; - typedef struct bJSC__CallFrame { unsigned char bytes[8]; } bJSC__CallFrame; - typedef char* bJSC__CallFrame_buf; - typedef struct bJSC__JSFunction { unsigned char bytes[32]; } bJSC__JSFunction; - typedef char* bJSC__JSFunction_buf; typedef struct bJSC__PropertyName { unsigned char bytes[8]; } bJSC__PropertyName; typedef char* bJSC__PropertyName_buf; + typedef struct bJSC__JSFunction { unsigned char bytes[32]; } bJSC__JSFunction; + typedef char* bJSC__JSFunction_buf; typedef struct bJSC__JSGlobalObject { unsigned char bytes[2312]; } bJSC__JSGlobalObject; typedef char* bJSC__JSGlobalObject_buf; typedef struct bJSC__JSCell { unsigned char bytes[8]; } bJSC__JSCell; @@ -104,9 +102,8 @@ typedef void* JSClassRef; typedef Bun__Readable Bun__Readable; typedef bJSC__JSInternalPromise JSC__JSInternalPromise; // JSC::JSInternalPromise typedef Bun__Writable Bun__Writable; - typedef struct JSC__MapIteratorPrototype JSC__MapIteratorPrototype; // JSC::MapIteratorPrototype typedef struct JSC__RegExpPrototype JSC__RegExpPrototype; // JSC::RegExpPrototype - typedef bJSC__CallFrame JSC__CallFrame; // JSC::CallFrame + typedef struct JSC__MapIteratorPrototype JSC__MapIteratorPrototype; // JSC::MapIteratorPrototype typedef struct WebCore__FetchHeaders WebCore__FetchHeaders; // WebCore::FetchHeaders typedef bWTF__StringView WTF__StringView; // WTF::StringView typedef bJSC__ThrowScope JSC__ThrowScope; // JSC::ThrowScope @@ -168,7 +165,6 @@ typedef void* JSClassRef; class SourceCode; class FunctionPrototype; class IteratorPrototype; - class CallFrame; class ObjectPrototype; } namespace WTF { @@ -232,7 +228,6 @@ typedef void* JSClassRef; using JSC__SourceCode = JSC::SourceCode; using JSC__FunctionPrototype = JSC::FunctionPrototype; using JSC__IteratorPrototype = JSC::IteratorPrototype; - using JSC__CallFrame = JSC::CallFrame; using JSC__ObjectPrototype = JSC::ObjectPrototype; using WTF__URL = WTF::URL; using WTF__StringImpl = WTF::StringImpl; @@ -368,15 +363,6 @@ CPP_DECL void JSC__SourceCode__fromString(JSC__SourceCode* arg0, const WTF__Stri #pragma mark - JSC::JSFunction CPP_DECL bWTF__String JSC__JSFunction__calculatedDisplayName(JSC__JSFunction* arg0, JSC__VM* arg1); -CPP_DECL JSC__JSValue JSC__JSFunction__callWithArguments(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, JSC__JSValue* arg2, size_t arg3, JSC__Exception** arg4, const unsigned char* arg5); -CPP_DECL JSC__JSValue JSC__JSFunction__callWithArgumentsAndThis(JSC__JSValue JSValue0, JSC__JSValue JSValue1, JSC__JSGlobalObject* arg2, JSC__JSValue* arg3, size_t arg4, JSC__Exception** arg5, const unsigned char* arg6); -CPP_DECL JSC__JSValue JSC__JSFunction__callWithoutAnyArgumentsOrThis(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, JSC__Exception** arg2, const unsigned char* arg3); -CPP_DECL JSC__JSValue JSC__JSFunction__callWithThis(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, JSC__JSValue JSValue2, JSC__Exception** arg3, const unsigned char* arg4); -CPP_DECL JSC__JSValue JSC__JSFunction__constructWithArguments(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, JSC__JSValue* arg2, size_t arg3, JSC__Exception** arg4, const unsigned char* arg5); -CPP_DECL JSC__JSValue JSC__JSFunction__constructWithArgumentsAndNewTarget(JSC__JSValue JSValue0, JSC__JSValue JSValue1, JSC__JSGlobalObject* arg2, JSC__JSValue* arg3, size_t arg4, JSC__Exception** arg5, const unsigned char* arg6); -CPP_DECL JSC__JSValue JSC__JSFunction__constructWithNewTarget(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, JSC__JSValue JSValue2, JSC__Exception** arg3, const unsigned char* arg4); -CPP_DECL JSC__JSValue JSC__JSFunction__constructWithoutAnyArgumentsOrNewTarget(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, JSC__Exception** arg2, const unsigned char* arg3); -CPP_DECL JSC__JSFunction* JSC__JSFunction__createFromNative(JSC__JSGlobalObject* arg0, uint16_t arg1, const WTF__String* arg2, void* arg3, JSC__JSValue (* ArgFn4)(void* arg0, JSC__JSGlobalObject* arg1, JSC__CallFrame* arg2)); CPP_DECL bWTF__String JSC__JSFunction__displayName(JSC__JSFunction* arg0, JSC__VM* arg1); CPP_DECL bWTF__String JSC__JSFunction__getName(JSC__JSFunction* arg0, JSC__VM* arg1); @@ -597,17 +583,6 @@ CPP_DECL void JSC__CatchScope__clearException(JSC__CatchScope* arg0); CPP_DECL bJSC__CatchScope JSC__CatchScope__declare(JSC__VM* arg0, unsigned char* arg1, unsigned char* arg2, size_t arg3); CPP_DECL JSC__Exception* JSC__CatchScope__exception(JSC__CatchScope* arg0); -#pragma mark - JSC::CallFrame - -CPP_DECL JSC__JSValue JSC__CallFrame__argument(const JSC__CallFrame* arg0, uint16_t arg1); -CPP_DECL size_t JSC__CallFrame__argumentsCount(const JSC__CallFrame* arg0); -CPP_DECL JSC__JSObject* JSC__CallFrame__jsCallee(const JSC__CallFrame* arg0); -CPP_DECL JSC__JSValue JSC__CallFrame__newTarget(const JSC__CallFrame* arg0); -CPP_DECL JSC__JSValue JSC__CallFrame__setNewTarget(JSC__CallFrame* arg0, JSC__JSValue JSValue1); -CPP_DECL JSC__JSValue JSC__CallFrame__setThisValue(JSC__CallFrame* arg0, JSC__JSValue JSValue1); -CPP_DECL JSC__JSValue JSC__CallFrame__thisValue(const JSC__CallFrame* arg0); -CPP_DECL JSC__JSValue JSC__CallFrame__uncheckedArgument(const JSC__CallFrame* arg0, uint16_t arg1); - #pragma mark - JSC::Identifier CPP_DECL void JSC__Identifier__deinit(const JSC__Identifier* arg0); @@ -740,6 +715,12 @@ ZIG_DECL JSC__JSValue Bun__Path__resolve(JSC__JSGlobalObject* arg0, bool arg1, J #ifdef __cplusplus +ZIG_DECL JSC__JSValue ByteBlob__JSReadableStreamSource__load(JSC__JSGlobalObject* arg0); + +#endif + +#ifdef __cplusplus + ZIG_DECL void Bun__Process__exit(JSC__JSGlobalObject* arg0, int32_t arg1); ZIG_DECL JSC__JSValue Bun__Process__getArgv(JSC__JSGlobalObject* arg0); ZIG_DECL JSC__JSValue Bun__Process__getCwd(JSC__JSGlobalObject* arg0); diff --git a/src/javascript/jsc/bindings/headers.zig b/src/javascript/jsc/bindings/headers.zig index 44ce2e7945..3dd158d3ee 100644 --- a/src/javascript/jsc/bindings/headers.zig +++ b/src/javascript/jsc/bindings/headers.zig @@ -108,10 +108,9 @@ pub const WTF__URL = bWTF__URL; pub const JSC__IteratorPrototype = struct_JSC__IteratorPrototype; pub const JSC__JSInternalPromise = bJSC__JSInternalPromise; -pub const JSC__MapIteratorPrototype = struct_JSC__MapIteratorPrototype; - pub const JSC__RegExpPrototype = struct_JSC__RegExpPrototype; -pub const JSC__CallFrame = bJSC__CallFrame; + +pub const JSC__MapIteratorPrototype = struct_JSC__MapIteratorPrototype; pub const WebCore__FetchHeaders = struct_WebCore__FetchHeaders; pub const WTF__StringView = bWTF__StringView; @@ -224,15 +223,6 @@ pub extern fn JSC__JSInternalPromise__status(arg0: [*c]const JSC__JSInternalProm pub extern fn JSC__SourceOrigin__fromURL(arg0: [*c]const WTF__URL) bJSC__SourceOrigin; pub extern fn JSC__SourceCode__fromString(arg0: [*c]JSC__SourceCode, arg1: [*c]const WTF__String, arg2: [*c]const JSC__SourceOrigin, arg3: [*c]WTF__String, SourceType4: u8) void; pub extern fn JSC__JSFunction__calculatedDisplayName(arg0: [*c]JSC__JSFunction, arg1: [*c]JSC__VM) bWTF__String; -pub extern fn JSC__JSFunction__callWithArguments(JSValue0: JSC__JSValue, arg1: [*c]JSC__JSGlobalObject, arg2: [*c]JSC__JSValue, arg3: usize, arg4: *?*JSC__Exception, arg5: [*c]const u8) JSC__JSValue; -pub extern fn JSC__JSFunction__callWithArgumentsAndThis(JSValue0: JSC__JSValue, JSValue1: JSC__JSValue, arg2: [*c]JSC__JSGlobalObject, arg3: [*c]JSC__JSValue, arg4: usize, arg5: *?*JSC__Exception, arg6: [*c]const u8) JSC__JSValue; -pub extern fn JSC__JSFunction__callWithoutAnyArgumentsOrThis(JSValue0: JSC__JSValue, arg1: [*c]JSC__JSGlobalObject, arg2: *?*JSC__Exception, arg3: [*c]const u8) JSC__JSValue; -pub extern fn JSC__JSFunction__callWithThis(JSValue0: JSC__JSValue, arg1: [*c]JSC__JSGlobalObject, JSValue2: JSC__JSValue, arg3: *?*JSC__Exception, arg4: [*c]const u8) JSC__JSValue; -pub extern fn JSC__JSFunction__constructWithArguments(JSValue0: JSC__JSValue, arg1: [*c]JSC__JSGlobalObject, arg2: [*c]JSC__JSValue, arg3: usize, arg4: *?*JSC__Exception, arg5: [*c]const u8) JSC__JSValue; -pub extern fn JSC__JSFunction__constructWithArgumentsAndNewTarget(JSValue0: JSC__JSValue, JSValue1: JSC__JSValue, arg2: [*c]JSC__JSGlobalObject, arg3: [*c]JSC__JSValue, arg4: usize, arg5: *?*JSC__Exception, arg6: [*c]const u8) JSC__JSValue; -pub extern fn JSC__JSFunction__constructWithNewTarget(JSValue0: JSC__JSValue, arg1: [*c]JSC__JSGlobalObject, JSValue2: JSC__JSValue, arg3: *?*JSC__Exception, arg4: [*c]const u8) JSC__JSValue; -pub extern fn JSC__JSFunction__constructWithoutAnyArgumentsOrNewTarget(JSValue0: JSC__JSValue, arg1: [*c]JSC__JSGlobalObject, arg2: *?*JSC__Exception, arg3: [*c]const u8) JSC__JSValue; -pub extern fn JSC__JSFunction__createFromNative(arg0: [*c]JSC__JSGlobalObject, arg1: u16, arg2: [*c]const WTF__String, arg3: ?*anyopaque, ArgFn4: ?fn (?*anyopaque, [*c]JSC__JSGlobalObject, [*c]JSC__CallFrame) callconv(.C) JSC__JSValue) [*c]JSC__JSFunction; pub extern fn JSC__JSFunction__displayName(arg0: [*c]JSC__JSFunction, arg1: [*c]JSC__VM) bWTF__String; pub extern fn JSC__JSFunction__getName(arg0: [*c]JSC__JSFunction, arg1: [*c]JSC__VM) bWTF__String; pub extern fn JSC__JSGlobalObject__arrayIteratorPrototype(arg0: [*c]JSC__JSGlobalObject) ?*JSC__ArrayIteratorPrototype; @@ -423,14 +413,6 @@ pub extern fn JSC__ThrowScope__release(arg0: [*c]JSC__ThrowScope) void; pub extern fn JSC__CatchScope__clearException(arg0: [*c]JSC__CatchScope) void; pub extern fn JSC__CatchScope__declare(arg0: [*c]JSC__VM, arg1: [*c]u8, arg2: [*c]u8, arg3: usize) bJSC__CatchScope; pub extern fn JSC__CatchScope__exception(arg0: [*c]JSC__CatchScope) [*c]JSC__Exception; -pub extern fn JSC__CallFrame__argument(arg0: [*c]const JSC__CallFrame, arg1: u16) JSC__JSValue; -pub extern fn JSC__CallFrame__argumentsCount(arg0: [*c]const JSC__CallFrame) usize; -pub extern fn JSC__CallFrame__jsCallee(arg0: [*c]const JSC__CallFrame) [*c]JSC__JSObject; -pub extern fn JSC__CallFrame__newTarget(arg0: [*c]const JSC__CallFrame) JSC__JSValue; -pub extern fn JSC__CallFrame__setNewTarget(arg0: [*c]JSC__CallFrame, JSValue1: JSC__JSValue) JSC__JSValue; -pub extern fn JSC__CallFrame__setThisValue(arg0: [*c]JSC__CallFrame, JSValue1: JSC__JSValue) JSC__JSValue; -pub extern fn JSC__CallFrame__thisValue(arg0: [*c]const JSC__CallFrame) JSC__JSValue; -pub extern fn JSC__CallFrame__uncheckedArgument(arg0: [*c]const JSC__CallFrame, arg1: u16) JSC__JSValue; pub extern fn JSC__Identifier__deinit(arg0: [*c]const JSC__Identifier) void; pub extern fn JSC__Identifier__eqlIdent(arg0: [*c]const JSC__Identifier, arg1: [*c]const JSC__Identifier) bool; pub extern fn JSC__Identifier__eqlStringImpl(arg0: [*c]const JSC__Identifier, arg1: [*c]const WTF__StringImpl) bool; diff --git a/src/javascript/jsc/bindings/helpers.h b/src/javascript/jsc/bindings/helpers.h index 7b72b3566e..30c2d095dc 100644 --- a/src/javascript/jsc/bindings/helpers.h +++ b/src/javascript/jsc/bindings/helpers.h @@ -58,9 +58,6 @@ template To ccast(From v) return *static_cast(static_cast(v)); } -typedef JSC__JSValue (*NativeCallbackFunction)(void* arg0, JSC__JSGlobalObject* arg1, - JSC__CallFrame* arg2); - static const JSC::ArgList makeArgs(JSC__JSValue* v, size_t count) { JSC::MarkedArgumentBuffer args = JSC::MarkedArgumentBuffer(); diff --git a/src/javascript/jsc/bindings/webcore/JSReadableStream.cpp b/src/javascript/jsc/bindings/webcore/JSReadableStream.cpp index c3f63929df..b9316d130e 100644 --- a/src/javascript/jsc/bindings/webcore/JSReadableStream.cpp +++ b/src/javascript/jsc/bindings/webcore/JSReadableStream.cpp @@ -40,13 +40,11 @@ #include #include - namespace WebCore { using namespace JSC; // Functions - // Attributes static JSC_DECLARE_CUSTOM_GETTER(jsReadableStreamConstructor); @@ -109,15 +107,14 @@ template<> FunctionExecutable* JSReadableStreamDOMConstructor::initializeExecuta /* Hash table for prototype */ -static const HashTableValue JSReadableStreamPrototypeTableValues[] = -{ - { "constructor"_s, static_cast(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast(jsReadableStreamConstructor), (intptr_t) static_cast(0) } }, - { "locked"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast(readableStreamLockedCodeGenerator), (intptr_t) (0) } }, - { "cancel"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast(readableStreamCancelCodeGenerator), (intptr_t) (0) } }, - { "getReader"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast(readableStreamGetReaderCodeGenerator), (intptr_t) (0) } }, - { "pipeTo"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast(readableStreamPipeToCodeGenerator), (intptr_t) (1) } }, - { "pipeThrough"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast(readableStreamPipeThroughCodeGenerator), (intptr_t) (2) } }, - { "tee"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast(readableStreamTeeCodeGenerator), (intptr_t) (0) } }, +static const HashTableValue JSReadableStreamPrototypeTableValues[] = { + { "constructor"_s, static_cast(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast(jsReadableStreamConstructor), (intptr_t) static_cast(0) } }, + { "locked"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast(readableStreamLockedCodeGenerator), (intptr_t)(0) } }, + { "cancel"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast(readableStreamCancelCodeGenerator), (intptr_t)(0) } }, + { "getReader"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast(readableStreamGetReaderCodeGenerator), (intptr_t)(0) } }, + { "pipeTo"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast(readableStreamPipeToCodeGenerator), (intptr_t)(1) } }, + { "pipeThrough"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast(readableStreamPipeThroughCodeGenerator), (intptr_t)(2) } }, + { "tee"_s, static_cast(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast(readableStreamTeeCodeGenerator), (intptr_t)(0) } }, }; const ClassInfo JSReadableStreamPrototype::s_info = { "ReadableStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamPrototype) }; @@ -125,6 +122,8 @@ const ClassInfo JSReadableStreamPrototype::s_info = { "ReadableStream"_s, &Base: void JSReadableStreamPrototype::finishCreation(VM& vm) { Base::finishCreation(vm); + auto clientData = WebCore::clientData(vm); + this->putDirect(vm, clientData->builtinNames().bunNativeTagPrivateName(), jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | 0); reifyStaticProperties(vm, JSReadableStream::info(), JSReadableStreamPrototypeTableValues, *this); JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); } @@ -132,13 +131,14 @@ void JSReadableStreamPrototype::finishCreation(VM& vm) const ClassInfo JSReadableStream::s_info = { "ReadableStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStream) }; JSReadableStream::JSReadableStream(Structure* structure, JSDOMGlobalObject& globalObject) - : JSDOMObject(structure, globalObject) { } + : JSDOMObject(structure, globalObject) +{ +} void JSReadableStream::finishCreation(VM& vm) { Base::finishCreation(vm); ASSERT(inherits(info())); - } JSObject* JSReadableStream::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) @@ -162,7 +162,7 @@ void JSReadableStream::destroy(JSC::JSCell* cell) thisObject->JSReadableStream::~JSReadableStream(); } -JSC_DEFINE_CUSTOM_GETTER(jsReadableStreamConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +JSC_DEFINE_CUSTOM_GETTER(jsReadableStreamConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) { VM& vm = JSC::getVM(lexicalGlobalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); @@ -174,13 +174,12 @@ JSC_DEFINE_CUSTOM_GETTER(jsReadableStreamConstructor, (JSGlobalObject* lexicalGl JSC::GCClient::IsoSubspace* JSReadableStream::subspaceForImpl(JSC::VM& vm) { - return WebCore::subspaceForImpl(vm, - [] (auto& spaces) { return spaces.m_clientSubspaceForReadableStream.get(); }, - [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForReadableStream = WTFMove(space); }, - [] (auto& spaces) { return spaces.m_subspaceForReadableStream.get(); }, - [] (auto& spaces, auto&& space) { spaces.m_subspaceForReadableStream = WTFMove(space); } - ); + return WebCore::subspaceForImpl( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForReadableStream.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForReadableStream = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForReadableStream.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForReadableStream = WTFMove(space); }); } - } diff --git a/src/javascript/jsc/webcore/response.zig b/src/javascript/jsc/webcore/response.zig index b0393abd8c..0f4e06f5ce 100644 --- a/src/javascript/jsc/webcore/response.zig +++ b/src/javascript/jsc/webcore/response.zig @@ -7,7 +7,7 @@ const ZigURL = @import("../../../url.zig").URL; const HTTPClient = @import("http"); const NetworkThread = HTTPClient.NetworkThread; const AsyncIO = NetworkThread.AsyncIO; -const JSC = @import("../../../jsc.zig"); +const JSC = @import("javascript_core"); const js = JSC.C; const Method = @import("../../../http/method.zig").Method; @@ -1020,14 +1020,35 @@ pub const Fetch = struct { }; pub const ReadableStream = struct { - pub fn fromBlob(globalThis: *JSGlobalObject, this: *Blob) JSC.JSValue { + pub const Tag = enum(i32) { + Blob = 1, + File = 2, + }; + + extern fn ZigGlobalObject__createNativeReadableStream(*JSGlobalObject, nativeTag: JSValue, nativeID: JSValue) JSValue; + + pub fn fromNative(globalThis: *JSGlobalObject, id: Tag, ptr: *anyopaque) JSC.JSValue { + return ZigGlobalObject__createNativeReadableStream(globalThis, JSValue.fromPtr(ptr), JSValue.jsNumber(@enumToInt(id))); + } + pub fn fromBlob(globalThis: *JSGlobalObject, blob: *const Blob) JSC.JSValue { if (comptime JSC.is_bindgen) unreachable; - var store = this.store orelse { + var store = blob.store orelse { return ReadableStream.empty(globalThis); }; - store.ref(); - return ReadableStream__fromBlob(globalThis, store, this.offset, this.size); + switch (store.data) { + .bytes => { + var reader = bun.default_allocator.create(ByteBlobLoader.Source) catch unreachable; + reader.* = .{ + .context = undefined, + }; + reader.context.setup(blob); + return reader.toJS(globalThis); + }, + .file => { + return JSValue.jsUndefined(); + }, + } } pub fn empty(globalThis: *JSGlobalObject) JSC.JSValue { @@ -1648,230 +1669,9 @@ pub const Blob = struct { // return BlobStore__onRead(ctx, slice.ptr, slice.len) and has_more; // }, - // .file => |*file| { - // var file_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; - // var auto_close = file.pathlike != .fd; - // var fd = if (!auto_close) - // file.pathlike.fd - // else switch (JSC.Node.Syscall.open(file.pathlike.path.sliceZ(&file_buf), std.os.O.RDONLY | std.os.O.NONBLOCK | std.os.O.CLOEXEC, 0)) { - // .result => |_fd| _fd, - // .err => |err| { - // BlobStore__onError(ctx, &err.withPath(file.pathlike.path.slice()).toSystemError(), JSC.VirtualMachine.vm.global); - // return false; - // }, - // }; - - // if (!auto_close) { - // // ensure we have non-blocking IO set - // const flags = (std.os.fcntl(fd, std.os.F.GETFL, 0) catch return false); - - // // if we do not, clone the descriptor and set non-blocking - // // it is important for us to clone it so we don't cause Weird Things to happen - // if ((flags & std.os.O.NONBLOCK) == 0) { - // auto_close = false; - // fd = @intCast(@TypeOf(fd), std.os.fcntl(fd, std.os.F.DUPFD, 0) catch return false); - // _ = std.os.fcntl(fd, std.os.F.SETFL, flags | std.os.O.NONBLOCK) catch return false; - // } - // } - - // const stat: std.os.Stat = switch (JSC.Node.Syscall.fstat(fd)) { - // .result => |result| result, - // .err => |err| { - // BlobStore__onError(ctx, &err.withPath(file.pathlike.path.slice()).toSystemError(), JSC.VirtualMachine.vm.global); - - // if (auto_close) { - // _ = JSC.Node.Syscall.close(fd); - // } - // return false; - // }, - // }; - - // if (std.os.S.ISDIR(stat.mode)) { - // const err = JSC.SystemError{ - // .code = ZigString.init("EISDIR"), - // .path = if (file.pathlike == .path) - // ZigString.init(file.pathlike.path.slice()) - // else - // ZigString.Empty, - // .message = ZigString.init("Directories cannot be read like files"), - // .syscall = ZigString.init("read"), - // }; - - // BlobStore__onError(ctx, &err, JSC.VirtualMachine.vm.global); - - // if (auto_close) { - // _ = JSC.Node.Syscall.close(fd); - // } - // return false; - // } - - // if (std.os.S.ISSOCK(stat.mode)) { - // const err = JSC.SystemError{ - // .code = ZigString.init("ENOTSUP"), - // .path = if (file.pathlike == .path) - // ZigString.init(file.pathlike.path.slice()) - // else - // ZigString.Empty, - // .message = ZigString.init("Sockets cannot be read like files with this API"), - // .syscall = ZigString.init("read"), - // }; - - // BlobStore__onError(ctx, &err, JSC.VirtualMachine.vm.global); - - // if (auto_close) { - // _ = JSC.Node.Syscall.close(fd); - // } - // return false; - // } - - // // if (comptime Environment.isMac) { - // // if (std.os.S.ISSOCK(stat.mode)) { - // // // darwin doesn't support os.MSG.NOSIGNAL, - // // // but instead a socket option to avoid SIGPIPE. - // // const _bytes = &std.mem.toBytes(@as(c_int, 1)); - // // _ = std.os.darwin.setsockopt(fd, std.os.SOL.SOCKET, std.os.SO.NOSIGPIPE, _bytes, @intCast(std.os.socklen_t, _bytes.len)); - // // } - // // } - - // file.seekable = std.os.S.ISREG(stat.mode); - // file.mode = @intCast(JSC.Node.Mode, stat.mode); - - // if (file.seekable orelse false) - // file.max_size = @intCast(SizeType, stat.size); - - // if ((file.seekable orelse false) and file.max_size == 0) { - // if (auto_close) { - // _ = JSC.Node.Syscall.close(fd); - // } - // return false; - // } - - // const this_chunk_size = if (file.max_size > 0) - // @minimum(chunk_size, file.max_size) - // else if (std.os.S.ISFIFO(stat.mode)) - // fifo_chunk_size - // else - // chunk_size; - - // var buf = bun.default_allocator.alloc( - // u8, - // this_chunk_size, - // ) catch { - // const err = JSC.SystemError{ - // .code = ZigString.init("ENOMEM"), - // .path = if (file.pathlike == .path) - // ZigString.init(file.pathlike.path.slice()) - // else - // ZigString.Empty, - // .message = ZigString.init("Out of memory"), - // .syscall = ZigString.init("malloc"), - // }; - // BlobStore__onError(ctx, &err, JSC.VirtualMachine.vm.global); - - // if (auto_close) { - // _ = JSC.Node.Syscall.close(fd); - // } - // return false; - // }; - - // const rc = // read() for files - // JSC.Node.Syscall.read(fd, buf); - - // switch (rc) { - // .err => |err| { - // const retry = comptime if (Environment.isLinux) - // std.os.E.WOULDBLOCK - // else - // std.os.E.AGAIN; - - // switch (err.getErrno()) { - // retry => { - // outer: { - // NetworkThread.init() catch break :outer; - - // _ = FileReader.init( - // bun.default_allocator, - // ctx, - // buf, - // fd, - // file.mode, - // if (!std.os.S.ISREG(stat.mode)) @as(?u64, null) else offset, - // ) catch { - // const sys = JSC.SystemError{ - // .code = ZigString.init("ENOMEM"), - // .path = if (file.pathlike == .path) - // ZigString.init(file.pathlike.path.slice()) - // else - // ZigString.Empty, - // .message = ZigString.init("Out of memory"), - // .syscall = ZigString.init("malloc"), - // }; - // BlobStore__onError(ctx, &sys, JSC.VirtualMachine.vm.global); - - // if (auto_close) { - // _ = JSC.Node.Syscall.close(fd); - // } - // return false; - // }; - // streamer.* = ReadableStream.StreamTag.init(fd); - // return true; - // } - // }, - // else => {}, - // } - // const sys = err.toSystemError(); - - // if (auto_close) { - // _ = JSC.Node.Syscall.close(fd); - // } - - // BlobStore__onError(ctx, &sys, JSC.VirtualMachine.vm.global); - // bun.default_allocator.free(buf); - // return false; - // }, - // .result => |result| { - // // this handles: - // // - empty file - // // - stream closed for some reason - // if ((result == 0 and (file.seekable orelse false)) or - // BlobReadableStreamSource_isCancelled(ctx)) - // { - // if (auto_close) { - // _ = JSC.Node.Syscall.close(fd); - // } - - // bun.default_allocator.free(buf); - // return false; - // } - - // const will_continue = BlobStore__onReadExternal( - // ctx, - // buf.ptr, - // result, - // buf.ptr, - // JSC.MarkedArrayBuffer_deallocator, - // ) and - // // if it's not a regular file, we don't know how much to read so we should continue - // (!(file.seekable orelse false) or - // // if it is a regular file, we stop reading when we've read all the data - // !((file.seekable orelse false) and @intCast(SizeType, result) >= file.max_size)); - - // // did the first read cover the whole file? - // // if yes, then we are done! - // // we can safely close the file descriptor now - // if (auto_close and !will_continue) { - // _ = JSC.Node.Syscall.close(fd); - // } - - // if (will_continue) { - // streamer.* = ReadableStream.StreamTag.init(fd); - // } - - // return will_continue; - // }, - // } - // }, - // } + .file => |*file| { + + } } comptime { @@ -5152,11 +4952,43 @@ pub const FetchEvent = struct { }; pub const StreamResult = union(enum) { - owned: bun.ByteList(u8), - temporary: bun.ByteList(u8), - pending: anyframe->StreamResult, + owned: bun.ByteList, + temporary: bun.ByteList, + pending: JSC.Async(StreamResult), err: JSC.Node.Syscall.Error, done: void, + + pub fn toJS(this: *const StreamResult, globalThis: *JSGlobalObject) JSValue { + switch (this.*) { + .owned => |list| { + return JSC.ArrayBuffer.fromBytes(list.slice(), .Uint8Array).toJS(globalThis.ref(), null); + }, + .temporary => |temp| { + var array = JSC.JSValue.createUninitializedUint8Array(globalThis, temp.len); + var slice = array.asArrayBuffer(globalThis).?.slice(); + @memcpy(slice.ptr, temp.ptr, temp.len); + return array; + }, + .pending => |pend| { + if (pend.promise.*) |promise| { + return promise.asValue(globalThis); + } + + pend.promise.* = JSC.JSPromise.create(globalThis); + return pend.promise.*.?.asValue(globalThis); + }, + + .err => |err| { + return JSC.JSPromise.rejectedPromise(globalThis, JSValue.c(err.toJS(globalThis.ref()))).asValue(globalThis); + }, + + // false == controller.close() + // undefined == noop, but we probably won't send it + .done => { + return JSC.JSValue.jsBoolean(false); + }, + } + } }; pub fn WritableStreamSink( @@ -5191,11 +5023,11 @@ pub fn WritableStreamSink( if (this.closed or this.aborted or this.deinited) { return .{ .result = 0 }; } - return onWrite(this.context, bytes); + return onWrite(&this.context, bytes); } pub fn start(this: *This) StreamResult { - return onStart(this.context); + return onStart(&this.context); } pub fn abort(this: *This) void { @@ -5204,7 +5036,7 @@ pub fn WritableStreamSink( } this.aborted = true; - onAbort(this.context); + onAbort(&this.context); } pub fn didAbort(this: *This) void { @@ -5351,25 +5183,41 @@ pub const HTTPWriter = HTTPServerWritable(false); pub fn ReadableStreamSource( comptime Context: type, - comptime onStart: fn (this: Context) StreamResult, - comptime onPull: fn (this: Context) StreamResult, - comptime onCancel: fn (this: Context) void, - comptime deinit: fn (this: Context) void, + comptime name_: []const u8, + comptime onStart: anytype, + comptime onPull: anytype, + comptime onCancel: fn (this: *Context) void, + comptime deinit: fn (this: *Context) void, ) type { return struct { context: Context, cancelled: bool = false, deinited: bool = false, pending_err: ?JSC.Node.Syscall.Error = null, + close_handler: ?fn (*anyopaque) void = null, + close_ctx: ?*anyopaque = null, + close_jsvalue: JSValue = JSValue.zero, + globalThis: *JSGlobalObject = undefined, - pub const This = @This(); + const This = @This(); + const ReadableStreamSourceType = @This(); pub fn pull(this: *This) StreamResult { - return onPull(this.context); + return onPull(this.context, undefined, false); } - pub fn start(this: *This) StreamResult { - return onStart(this.context); + pub fn start( + this: *This, + ) StreamResult { + return onStart(&this.context, undefined, false); + } + + pub fn pullFromJS(this: *This, globalThis: *JSGlobalObject) StreamResult { + return onPull(&this.context, globalThis, true); + } + + pub fn startFromJS(this: *This, globalThis: *JSGlobalObject) StreamResult { + return onStart(&this.context, globalThis, true); } pub fn cancel(this: *This) void { @@ -5378,7 +5226,18 @@ pub fn ReadableStreamSource( } this.cancelled = true; - onCancel(this.context); + onCancel(&this.context); + } + + pub fn onClose(this: *This) void { + if (this.cancelled or this.deinited) { + return; + } + + if (this.close_handler) |close| { + this.close_handler = null; + close(this.close_ctx); + } } pub fn deinit(this: *This) void { @@ -5386,7 +5245,7 @@ pub fn ReadableStreamSource( return; } this.deinited = true; - deinit(this.context); + deinit(&this.context); } pub fn getError(this: *This) ?JSC.Node.Syscall.Error { @@ -5398,44 +5257,118 @@ pub fn ReadableStreamSource( return null; } - pub const JSReadableStreamSource = struct { - pub fn pull(globalThis: *JSGlobalObject, callFrame: *JSC.CallFrame) - pub fn start(globalThis: *JSGlobalObject, callFrame: *JSC.CallFrame) - pub fn cancel(globalThis: *JSGlobalObject, callFrame: *JSC.CallFrame) - pub fn deinit(globalThis: *JSGlobalObject, callFrame: *JSC.CallFrame) + pub fn toJS(this: *ReadableStreamSourceType, globalThis: *JSGlobalObject) JSC.JSValue { + return ReadableStream.fromNative(globalThis, Context.tag, this); + } + pub const JSReadableStreamSource = struct { + pub const shim = JSC.Shimmer(std.mem.span(name_), "JSReadableStreamSource", @This()); + pub const name = std.fmt.comptimePrint("{s}_JSReadableStreamSource", .{std.mem.span(name_)}); + + pub fn pull(globalThis: *JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSC.JSValue { + var this = callFrame.argument(0).asPtr(ReadableStreamSourceType); + return this.pullFromJS(globalThis).toJS(globalThis); + } + pub fn start(globalThis: *JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSC.JSValue { + var this = callFrame.argument(0).asPtr(ReadableStreamSourceType); + return this.startFromJS(globalThis).toJS(globalThis); + } + pub fn cancel(_: *JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSC.JSValue { + var this = callFrame.argument(0).asPtr(ReadableStreamSourceType); + this.cancel(); + return JSC.JSValue.jsUndefined(); + } + pub fn setClose(globalThis: *JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSC.JSValue { + var this = callFrame.argument(0).asPtr(ReadableStreamSourceType); + this.close_ctx = this; + this.close_handler = JSReadableStreamSource.onClose; + this.globalThis = globalThis; + this.close_jsvalue = callFrame.argument(1); + return JSC.JSValue.jsUndefined(); + } + + fn onClose(ptr: *anyopaque) void { + var this = bun.cast(*ReadableStreamSourceType, ptr); + _ = this.close_jsvalue.call(this.globalThis, &.{}); + // this.closer + } + + pub fn deinit(_: *JSGlobalObject, callFrame: *JSC.CallFrame) callconv(.C) JSC.JSValue { + var this = callFrame.argument(0).asPtr(ReadableStreamSourceType); + this.deinit(); + return JSValue.jsUndefined(); + } + + pub fn load(globalThis: *JSGlobalObject) callconv(.C) JSC.JSValue { + if (comptime JSC.is_bindgen) unreachable; + if (comptime Environment.allow_assert) { + // this should be cached per globals object + const OnlyOnce = struct { + pub threadlocal var last_globals: ?*JSGlobalObject = null; + }; + if (OnlyOnce.last_globals) |last_globals| { + std.debug.assert(last_globals != globalThis); + } + OnlyOnce.last_globals = globalThis; + } + return JSC.JSArray.from(globalThis, &.{ + JSC.NewFunction(globalThis, null, 1, JSReadableStreamSource.pull), + JSC.NewFunction(globalThis, null, 1, JSReadableStreamSource.start), + JSC.NewFunction(globalThis, null, 1, JSReadableStreamSource.cancel), + JSC.NewFunction(globalThis, null, 1, JSReadableStreamSource.setClose), + JSC.NewFunction(globalThis, null, 1, JSReadableStreamSource.deinit), + }); + } + + pub const Export = shim.exportFunctions(.{ + .@"load" = load, + }); + + comptime { + if (!JSC.is_bindgen) { + @export(load, .{ .name = Export[0].symbol_name }); + _ = JSReadableStreamSource.pull; + _ = JSReadableStreamSource.start; + _ = JSReadableStreamSource.cancel; + _ = JSReadableStreamSource.setClose; + _ = JSReadableStreamSource.load; + } + } }; }; } -const ByteBlobLoader = struct { +pub const ByteBlobLoader = struct { offset: Blob.SizeType = 0, store: *Blob.Store, chunk_size: Blob.SizeType = 1024 * 1024 * 2, remain: Blob.SizeType = 1024 * 1024 * 2, - source: Source, done: bool = false, + pub const tag = ReadableStream.Tag.Blob; + pub fn setup( this: *ByteBlobLoader, - blob: Blob, - ) ByteBlobLoader { - blob.store.ref(); + blob: *const Blob, + ) void { + blob.store.?.ref(); + var blobe = blob.*; + blobe.resolveSize(); this.* = ByteBlobLoader{ - .offset = blob.offset, - .store = blob.store, - .chunk_size = @minimum(1024 * 1024 * 2, blob.size), - .remain = blob.size, - .source = Source{ .context = this }, + .offset = blobe.offset, + .store = blobe.store.?, + .chunk_size = @minimum(1024 * 1024 * 2, blobe.size), + .remain = blobe.size, + .done = false, }; } - pub fn onStart(this: *ByteBlobLoader) StreamResult { - return this.onPull(); + pub fn onStart(this: *ByteBlobLoader, global: *JSGlobalObject, comptime is_js: bool) StreamResult { + return this.onPull(global, is_js); } - pub fn onPull(this: *ByteBlobLoader) StreamResult { + pub fn onPull(this: *ByteBlobLoader, _: *JSGlobalObject, comptime _: bool) StreamResult { if (this.done) { return .{ .done = {} }; } @@ -5453,133 +5386,136 @@ const ByteBlobLoader = struct { this.offset +|= @intCast(Blob.SizeType, temporary.len); return .{ - .temporary = temporary, + .temporary = bun.ByteList.init(temporary), }; } pub fn onCancel(_: *ByteBlobLoader) void {} pub fn deinit(this: *ByteBlobLoader) void { - if (!this.done) + if (!this.done) { + this.done = true; this.store.deref(); + } + + bun.default_allocator.destroy(this); } - const Source = ReadableStreamSource(@This(), onStart, onPull, onCancel, deinit); + pub const Source = ReadableStreamSource(@This(), "ByteBlob", onStart, onPull, onCancel, deinit); }; -pub fn NewFileReader( - comptime Context: type, - comptime onRead: fn (ctx: *Context, buf: []u8, len: Blob.SizeType) bool, - comptime onError: fn (ctx: *Context, err: JSC.SystemError) void, - comptime onWouldBlock: fn (ctx: *Context, err: JSC.SystemError) void, - comptime isCancelled: fn (ctx: *Context) bool, -) type { - return struct { - buf: []u8, - fd: JSC.Node.FileDescriptor, - loop: *JSC.EventLoop = undefined, - mode: JSC.Node.Mode, - ctx: *Context, - const FileReader = @This(); +// pub const FileStreamReader = struct { +// buf: []u8, +// fd: JSC.Node.FileDescriptor, +// loop: *JSC.EventLoop = undefined, +// mode: JSC.Node.Mode, +// pending: ?*JSC.JSPromise = null, - pub fn init(ctx: *Context, buf: []u8, fd: JSC.Node.FileDescriptor, mode: JSC.Node.Mode) FileReader { - return .{ - .buf = buf, - .fd = fd, - .ctx = ctx, - .loop = JSC.VirtualMachine.vm.eventLoop(), - .mode = mode, - }; - } +// onRead: fn (ctx: *Context, buf: []u8, len: Blob.SizeType) bool +// onError: fn (ctx: *Context, err: JSC.SystemError) void +// onWouldBlock: fn (ctx: *Context,) void +// isCancelled: fn (ctx: *Context) bool - pub fn watch(this: *FileReader) void { - _ = JSC.VirtualMachine.vm.poller.watch(this.fd, .read, this, callback); - } +// const FileReader = @This(); - pub fn read( - ctx: *Context, - path: []const u8, - buf: []u8, - fd: JSC.Node.FileDescriptor, - remaining: usize, - global: *JSGlobalObject, - would_block: ?*bool, - ) bool { - const rc = // read() for files - JSC.Node.Syscall.read(fd, buf); +// pub fn init(ctx: *Context, buf: []u8, fd: JSC.Node.FileDescriptor, mode: JSC.Node.Mode) FileReader { +// return .{ +// .buf = buf, +// .fd = fd, +// .ctx = ctx, +// .loop = JSC.VirtualMachine.vm.eventLoop(), +// .mode = mode, +// }; +// } - switch (rc) { - .err => |err| { - const retry = comptime if (Environment.isLinux) - std.os.E.WOULDBLOCK - else - std.os.E.AGAIN; +// pub fn watch(this: *FileReader) void { +// _ = JSC.VirtualMachine.vm.poller.watch(this.fd, .read, this, callback); +// } - switch (err.getErrno()) { - retry => { - if (would_block) |blocker| { - blocker.* = true; - } else { - onWouldBlock(ctx); - } +// pub fn read( +// ctx: *Context, +// path: []const u8, +// buf: []u8, +// fd: JSC.Node.FileDescriptor, +// remaining: usize, +// global: *JSGlobalObject, +// would_block: ?*bool, +// ) bool { +// const rc = // read() for files +// JSC.Node.Syscall.read(fd, buf); - return true; - }, - else => {}, - } - const sys = if (path.len > 0) err.withPath(path).toSystemError() else err.toSystemError(); +// switch (rc) { +// .err => |err| { +// const retry = comptime if (Environment.isLinux) +// std.os.E.WOULDBLOCK +// else +// std.os.E.AGAIN; - onError(ctx, &sys, global); - return false; - }, - .result => |result| { - // this handles: - // - empty file - // - stream closed for some reason - if ((result == 0 and remaining == 0) or - isCancelled(ctx)) - { - return false; - } +// switch (err.getErrno()) { +// retry => { +// if (would_block) |blocker| { +// blocker.* = true; +// } else { +// onWouldBlock(ctx); +// } - return onRead( - ctx, - buf, - result, - ) and - // if it's not a regular file, we don't know how much to read so we should continue - (remaining == std.math.maxInt(usize)) or - // if it is a regular file, we stop reading when we've read all the data - !(@intCast(Blob.SizeType, result) >= remaining); - }, - } - } +// return true; +// }, +// else => {}, +// } +// const sys = if (path.len > 0) err.withPath(path).toSystemError() else err.toSystemError(); - pub fn callback(task: ?*anyopaque, sizeOrOffset: i64, _: u16) void { - var this: *FileReader = bun.cast(*FileReader, task.?); - var buf = this.buf; - var blocked = false; - var remaining = std.math.maxInt(usize); - if (comptime Environment.isMac) { - if (std.os.S.ISREG(this.mode)) { - remaining = @intCast(usize, @maximum(sizeOrOffset, 0)); - // Returns when the file pointer is not at the end of - // file. data contains the offset from current position - // to end of file, and may be negative. - buf = buf[0..@minimum(remaining, this.buf.len)]; - } else if (std.os.S.ISCHR(this.mode) or std.os.S.ISFIFO(this.mode)) { - buf = buf[0..@minimum(@intCast(usize, @maximum(sizeOrOffset, 0)), this.buf.len)]; - } - } +// onError(ctx, &sys, global); +// return false; +// }, +// .result => |result| { +// // this handles: +// // - empty file +// // - stream closed for some reason +// if ((result == 0 and remaining == 0) or +// isCancelled(ctx)) +// { +// return false; +// } + +// return onRead( +// ctx, +// buf, +// result, +// ) and +// // if it's not a regular file, we don't know how much to read so we should continue +// (remaining == std.math.maxInt(usize)) or +// // if it is a regular file, we stop reading when we've read all the data +// !(@intCast(Blob.SizeType, result) >= remaining); +// }, +// } +// } + +// pub fn callback(task: ?*anyopaque, sizeOrOffset: i64, _: u16) void { +// var this: *FileReader = bun.cast(*FileReader, task.?); +// var buf = this.buf; +// var blocked = false; +// var remaining = std.math.maxInt(usize); +// if (comptime Environment.isMac) { +// if (std.os.S.ISREG(this.mode)) { +// remaining = @intCast(usize, @maximum(sizeOrOffset, 0)); +// // Returns when the file pointer is not at the end of +// // file. data contains the offset from current position +// // to end of file, and may be negative. +// buf = buf[0..@minimum(remaining, this.buf.len)]; +// } else if (std.os.S.ISCHR(this.mode) or std.os.S.ISFIFO(this.mode)) { +// buf = buf[0..@minimum(@intCast(usize, @maximum(sizeOrOffset, 0)), this.buf.len)]; +// } +// } + +// if (read(this.ctx, "", buf, this.fd, remaining, this.loop.global, &blocked) and blocked) { +// this.watch(); +// return; +// } +// } +// }; - if (read(this.ctx, "", buf, this.fd, remaining, this.loop.global, &blocked) and blocked) { - this.watch(); - return; - } - } - }; -} // pub const BlobFileLoader = struct { // reader: Reader, diff --git a/src/jsc.zig b/src/jsc.zig index 85c3b9dc39..fa7f801f70 100644 --- a/src/jsc.zig +++ b/src/jsc.zig @@ -7,6 +7,7 @@ pub usingnamespace @import("./javascript/jsc/bindings/bindings.zig"); pub usingnamespace @import("./javascript/jsc/event_loop.zig"); pub usingnamespace @import("./javascript/jsc/base.zig"); pub const RareData = @import("./javascript/jsc/rare_data.zig"); +pub const Shimmer = @import("./javascript/jsc/bindings/shimmer.zig").Shimmer; pub usingnamespace @import("./javascript/jsc/javascript.zig"); pub const C = @import("./javascript/jsc/javascript_core_c_api.zig"); pub const WebCore = @import("./javascript/jsc/webcore.zig");