diff options
-rw-r--r-- | src/bun.js/api/bun.zig | 6 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 21 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.h | 1 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 2 | ||||
-rw-r--r-- | src/bun.js/webcore/response.zig | 50 | ||||
-rw-r--r-- | test/js/web/fetch/fetch.test.ts | 5 |
6 files changed, 53 insertions, 32 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig index 43fcd5143..5b965e969 100644 --- a/src/bun.js/api/bun.zig +++ b/src/bun.js/api/bun.zig @@ -1165,9 +1165,9 @@ pub const Class = NewClass( .sleepSync = .{ .rfn = &sleepSync, }, - .fetch = .{ - .rfn = &Fetch.call, - }, + // .fetch = .{ + // .rfn = &Fetch.call, + // }, .getImportedStyles = .{ .rfn = &Bun.getImportedStyles, }, diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index dd1c4b08d..6816af84e 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -2969,6 +2969,13 @@ extern "C" void Bun__setOnEachMicrotaskTick(JSC::VM* vm, void* ptr, void (*callb }); } + + +static JSC_DEFINE_HOST_FUNCTION(functionFetch, + (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) +{ + return JSC::JSValue::encode(Bun__fetch(globalObject, callFrame)); +} // This implementation works the same as setTimeout(myFunction, 0) // TODO: make it more efficient // https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate @@ -3118,10 +3125,15 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm) auto& builtinNames = WebCore::builtinNames(vm); WTF::Vector<GlobalPropertyInfo> extraStaticGlobals; - extraStaticGlobals.reserveCapacity(42); + extraStaticGlobals.reserveCapacity(43); JSC::Identifier queueMicrotaskIdentifier = JSC::Identifier::fromString(vm, "queueMicrotask"_s); extraStaticGlobals.uncheckedAppend( + GlobalPropertyInfo { JSC::Identifier::fromString(vm, "fetch"_s), + JSC::JSFunction::create(vm, JSC::jsCast<JSC::JSGlobalObject*>(globalObject()), 2, + "fetch"_s, functionFetch, ImplementationVisibility::Public), + JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 }); + extraStaticGlobals.uncheckedAppend( GlobalPropertyInfo { queueMicrotaskIdentifier, JSC::JSFunction::create(vm, JSC::jsCast<JSC::JSGlobalObject*>(globalObject()), 2, "queueMicrotask"_s, functionQueueMicrotask, ImplementationVisibility::Public), @@ -3381,6 +3393,13 @@ void GlobalObject::installAPIGlobals(JSClassRef* globals, int count, JSC::VM& vm if (JSObject* prototype = object->classRef()->prototype(this)) object->setPrototypeDirect(vm, prototype); + + { + JSC::Identifier identifier = JSC::Identifier::fromString(vm, "fetch"_s); + object->putDirectNativeFunction(vm, this, identifier, 2, functionFetch, ImplementationVisibility::Public, NoIntrinsic, + JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0); + } + { JSC::Identifier identifier = JSC::Identifier::fromString(vm, "escapeHTML"_s); static ClassInfo escapeHTMLClassInfo = *object->classInfo(); diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index 0bdfd1d82..5e12260a8 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -48,6 +48,7 @@ extern "C" void Bun__reportUnhandledError(JSC__JSGlobalObject*, JSC::EncodedJSVa // defined in ModuleLoader.cpp extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultResolve(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame); extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultReject(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame); +extern "C" JSC::JSObject* Bun__fetch(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); // #include "EventTarget.h" // namespace WebCore { diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 9f0e1841d..67f016ad2 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -98,7 +98,7 @@ pub const GlobalClasses = [_]type{ BuildError.Class, ResolveError.Class, - Fetch.Class, + // Fetch.Class, js_ast.Macro.JSNode.BunJSXCallbackFunction, WebCore.Crypto.Prototype, diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig index e7160aee0..29b39be1f 100644 --- a/src/bun.js/webcore/response.zig +++ b/src/bun.js/webcore/response.zig @@ -609,17 +609,11 @@ pub const Fetch = struct { break :brk errors; }; - pub const Class = NewClass( - void, - .{ .name = "fetch" }, - .{ - .call = .{ - .rfn = Fetch.call, - .ts = d.ts{}, - }, - }, - .{}, - ); + comptime { + if (!JSC.is_bindgen) { + @export(Fetch.jsFunction, .{ .name = "Bun__fetch" }); + } + } pub const FetchTasklet = struct { const log = Output.scoped(.FetchTasklet, false); @@ -929,15 +923,20 @@ pub const Fetch = struct { } }; - pub fn call( - _: void, - ctx: js.JSContextRef, - _: js.JSObjectRef, - _: js.JSObjectRef, - arguments: []const js.JSValueRef, - exception: js.ExceptionRef, - ) js.JSObjectRef { - var globalThis = ctx.ptr(); + pub fn jsFunction( + ctx: *JSC.JSGlobalObject, + callframe: *JSC.CallFrame, + ) callconv(.C) js.JSObjectRef { + var exception_val = [_]JSC.C.JSValueRef{null}; + var exception: JSC.C.ExceptionRef = &exception_val; + defer { + if (exception.* != null) { + ctx.throwValue(JSC.JSValue.c(exception.*)); + } + } + + const globalThis = ctx.ptr(); + const arguments = callframe.arguments(2); if (arguments.len == 0) { const err = JSC.toTypeError(.ERR_MISSING_ARGS, fetch_error_no_args, .{}, ctx); @@ -948,8 +947,7 @@ pub const Fetch = struct { var method = Method.GET; var script_ctx = globalThis.bunVM(); - var args = JSC.Node.ArgumentsSlice.from(script_ctx, arguments); - defer args.deinit(); + var args = JSC.Node.ArgumentsSlice.init(script_ctx, arguments.ptr[0..arguments.len]); var url = ZigURL{}; var first_arg = args.nextEat().?; @@ -968,8 +966,7 @@ pub const Fetch = struct { var url_proxy_buffer: []const u8 = undefined; if (first_arg.as(Request)) |request| { - if (arguments.len >= 2) { - const options = arguments[1].?.value(); + if (args.nextEat()) |options| { if (options.isObject() or options.jsType() == .DOMWrapper) { if (options.fastGet(ctx.ptr(), .method)) |method_| { var slice_ = method_.toSlice(ctx.ptr(), getAllocator(ctx)); @@ -1107,8 +1104,7 @@ pub const Fetch = struct { } } } else if (first_arg.toStringOrNull(globalThis)) |jsstring| { - if (arguments.len >= 2) { - const options = arguments[1].?.value(); + if (args.nextEat()) |options| { if (options.isObject() or options.jsType() == .DOMWrapper) { if (options.fastGet(ctx.ptr(), .method)) |method_| { var slice_ = method_.toSlice(ctx.ptr(), getAllocator(ctx)); @@ -1293,7 +1289,7 @@ pub const Fetch = struct { url_proxy_buffer = url.href; } } else { - const fetch_error = fetch_type_error_strings.get(js.JSValueGetType(ctx, arguments[0])); + const fetch_error = fetch_type_error_strings.get(js.JSValueGetType(ctx, first_arg.asRef())); const err = JSC.toTypeError(.ERR_INVALID_ARG_TYPE, "{s}", .{fetch_error}, ctx); exception.* = err.asObjectRef(); return null; diff --git a/test/js/web/fetch/fetch.test.ts b/test/js/web/fetch/fetch.test.ts index cc59ba3f6..6e07db40b 100644 --- a/test/js/web/fetch/fetch.test.ts +++ b/test/js/web/fetch/fetch.test.ts @@ -1129,3 +1129,8 @@ it("#874", () => { expect(new Request(new Request("https://example.com")).url).toBe("https://example.com"); expect(new Request({ url: "https://example.com" }).url).toBe("https://example.com"); }); + +it("#2794", () => { + expect(typeof globalThis.fetch.bind).toBe("function"); + expect(typeof Bun.fetch.bind).toBe("function"); +}); |