diff --git a/src/browser/js/Local.zig b/src/browser/js/Local.zig index 4affc114..312d7127 100644 --- a/src/browser/js/Local.zig +++ b/src/browser/js/Local.zig @@ -207,7 +207,10 @@ pub fn mapZigInstanceToJs(self: *const Local, js_obj_handle: ?*const v8.Object, } try ctx.finalizer_callbacks.put(ctx.arena, @intFromPtr(resolved.ptr), .init(value)); - if (@hasDecl(JsApi.Meta, "finalizer")) { + if (@hasDecl(JsApi.Meta, "weak")) { + if (comptime IS_DEBUG) { + std.debug.assert(JsApi.Meta.weak == true); + } v8.v8__Global__SetWeakFinalizer(gop.value_ptr, resolved.ptr, JsApi.Meta.finalizer.from_v8, v8.kParameter); } } diff --git a/src/browser/webapi/net/XMLHttpRequest.zig b/src/browser/webapi/net/XMLHttpRequest.zig index 85b961c5..38ef0564 100644 --- a/src/browser/webapi/net/XMLHttpRequest.zig +++ b/src/browser/webapi/net/XMLHttpRequest.zig @@ -81,8 +81,7 @@ const ResponseType = enum { pub fn init(page: *Page) !*XMLHttpRequest { const arena = try page.getArena(.{.debug = "XMLHttpRequest"}); errdefer page.releaseArena(arena); - - return try page._factory.xhrEventTarget(XMLHttpRequest{ + return page._factory.xhrEventTarget(XMLHttpRequest{ ._page = page, ._arena = arena, ._proto = undefined, @@ -157,6 +156,7 @@ pub fn send(self: *XMLHttpRequest, body_: ?[]const u8) !void { if (self._ready_state != .opened) { return error.InvalidStateError; } + self._page.js.strongRef(self); if (body_) |b| { if (self._method != .GET and self._method != .HEAD) { @@ -394,6 +394,8 @@ fn httpDoneCallback(ctx: *anyopaque) !void { .total = loaded, .loaded = loaded, }, local, page); + + page.js.weakRef(self); } fn httpErrorCallback(ctx: *anyopaque, err: anyerror) void { @@ -401,6 +403,7 @@ fn httpErrorCallback(ctx: *anyopaque, err: anyerror) void { // http client will close it after an error, it isn't safe to keep around self._transfer = null; self.handleError(err); + self._page.js.weakRef(self); } pub fn abort(self: *XMLHttpRequest) void { @@ -409,6 +412,7 @@ pub fn abort(self: *XMLHttpRequest) void { transfer.abort(error.Abort); self._transfer = null; } + self._page.js.weakRef(self); } fn handleError(self: *XMLHttpRequest, err: anyerror) void { @@ -486,6 +490,7 @@ pub const JsApi = struct { pub const name = "XMLHttpRequest"; pub const prototype_chain = bridge.prototypeChain(); pub var class_id: bridge.ClassId = undefined; + pub const weak = true; pub const finalizer = bridge.finalizer(XMLHttpRequest.deinit); };