diff options
author | 2022-04-01 19:54:02 -0700 | |
---|---|---|
committer | 2022-04-01 19:54:02 -0700 | |
commit | 5c989c957a6b6464e9faacde6d820830a7e70aaf (patch) | |
tree | 572605a71082cfcb857d7a7ebb4c149650d2112f /src | |
parent | 8af0764b3b9da137a15b7881c1b08376c5ab0bcc (diff) | |
download | bun-5c989c957a6b6464e9faacde6d820830a7e70aaf.tar.gz bun-5c989c957a6b6464e9faacde6d820830a7e70aaf.tar.zst bun-5c989c957a6b6464e9faacde6d820830a7e70aaf.zip |
Add abstraction for protecting values we're iterating on
Diffstat (limited to 'src')
-rw-r--r-- | src/javascript/jsc/base.zig | 11 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/bindings.zig | 8 | ||||
-rw-r--r-- | src/javascript/jsc/node/node_fs_binding.zig | 9 | ||||
-rw-r--r-- | src/javascript/jsc/node/types.zig | 43 |
4 files changed, 47 insertions, 24 deletions
diff --git a/src/javascript/jsc/base.zig b/src/javascript/jsc/base.zig index aa9e9abd2..c6a861e17 100644 --- a/src/javascript/jsc/base.zig +++ b/src/javascript/jsc/base.zig @@ -2690,7 +2690,7 @@ pub fn wrap( args[i] = ctx.ptr(); }, ZigString => { - var string_value = iter.nextEat() orelse { + var string_value = iter.protectEatNext() orelse { JSC.throwInvalidArguments("Missing argument", .{}, ctx, exception); return null; }; @@ -2712,7 +2712,7 @@ pub fn wrap( } }, *Response => { - args[i] = (iter.nextEat() orelse { + args[i] = (iter.protectEatNext() orelse { JSC.throwInvalidArguments("Missing Response object", .{}, ctx, exception); return null; }).as(Response) orelse { @@ -2721,7 +2721,7 @@ pub fn wrap( }; }, *Request => { - args[i] = (iter.nextEat() orelse { + args[i] = (iter.protectEatNext() orelse { JSC.throwInvalidArguments("Missing Request object", .{}, ctx, exception); return null; }).as(Request) orelse { @@ -2740,7 +2740,7 @@ pub fn wrap( args[i] = exception; }, JSValue => { - const val = iter.nextEat() orelse { + const val = iter.protectEatNext() orelse { JSC.throwInvalidArguments("Missing argument", .{}, ctx, exception); return null; }; @@ -2753,6 +2753,7 @@ pub fn wrap( var result: JSValue = @call(.{}, @field(Container, name), args); if (result.isError()) { exception.* = result.asObjectRef(); + iter.deinit(); return null; } @@ -2778,6 +2779,8 @@ pub fn wrap( } } + iter.deinit(); + return result.asObjectRef(); } }.callback; diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig index 8d916af11..ef4b3edfe 100644 --- a/src/javascript/jsc/bindings/bindings.zig +++ b/src/javascript/jsc/bindings/bindings.zig @@ -2402,13 +2402,13 @@ pub const JSValue = enum(u64) { return cppFn("toInt64", .{this}); } - pub fn isUndefined(this: JSValue) bool { + pub inline fn isUndefined(this: JSValue) bool { return @enumToInt(this) == 0xa; } - pub fn isNull(this: JSValue) bool { + pub inline fn isNull(this: JSValue) bool { return @enumToInt(this) == 0x2; } - pub fn isEmptyOrUndefinedOrNull(this: JSValue) bool { + pub inline fn isEmptyOrUndefinedOrNull(this: JSValue) bool { return switch (@enumToInt(this)) { 0, 0xa, 0x2 => true, else => false, @@ -2421,7 +2421,7 @@ pub const JSValue = enum(u64) { }; } /// Empty as in "JSValue {}" rather than an empty string - pub fn isEmpty(this: JSValue) bool { + pub inline fn isEmpty(this: JSValue) bool { return switch (@enumToInt(this)) { 0 => true, else => false, diff --git a/src/javascript/jsc/node/node_fs_binding.zig b/src/javascript/jsc/node/node_fs_binding.zig index ea3376ffb..59b58778a 100644 --- a/src/javascript/jsc/node/node_fs_binding.zig +++ b/src/javascript/jsc/node/node_fs_binding.zig @@ -42,14 +42,7 @@ fn callSync(comptime FunctionEnum: NodeFSFunctionEnum) NodeFSFunction { exception: JSC.C.ExceptionRef, ) JSC.C.JSValueRef { var slice = ArgumentsSlice.init(@ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]); - - defer { - // TODO: fix this - for (arguments) |arg| { - JSC.C.JSValueUnprotect(ctx, arg); - } - slice.arena.deinit(); - } + defer slice.deinit(); const args = if (comptime Arguments != void) (Arguments.fromJS(ctx, &slice, exception) orelse return null) diff --git a/src/javascript/jsc/node/types.zig b/src/javascript/jsc/node/types.zig index 9ad49e756..f7c8ac967 100644 --- a/src/javascript/jsc/node/types.zig +++ b/src/javascript/jsc/node/types.zig @@ -301,8 +301,7 @@ pub const PathLike = union(Tag) { if (exception.* != null) return null; if (!Valid.pathBuffer(buffer, ctx, exception)) return null; - JSC.C.JSValueProtect(ctx, arg.asObjectRef()); - arguments.eat(); + arguments.protectEat(); return PathLike{ .buffer = buffer }; }, @@ -311,8 +310,7 @@ pub const PathLike = union(Tag) { if (exception.* != null) return null; if (!Valid.pathBuffer(buffer, ctx, exception)) return null; - JSC.C.JSValueProtect(ctx, arg.asObjectRef()); - arguments.eat(); + arguments.protectEat(); return PathLike{ .buffer = buffer }; }, @@ -326,8 +324,7 @@ pub const PathLike = union(Tag) { if (!Valid.pathString(zig_str, ctx, exception)) return null; - JSC.C.JSValueProtect(ctx, arg.asObjectRef()); - arguments.eat(); + arguments.protectEat(); if (zig_str.is16Bit()) { var printed = std.mem.span(std.fmt.allocPrintZ(arguments.arena.allocator(), "{}", .{zig_str}) catch unreachable); @@ -341,8 +338,7 @@ pub const PathLike = union(Tag) { var zig_str = domurl.pathname(); if (!Valid.pathString(zig_str, ctx, exception)) return null; - JSC.C.JSValueProtect(ctx, arg.asObjectRef()); - arguments.eat(); + arguments.protectEat(); if (zig_str.is16Bit()) { var printed = std.mem.span(std.fmt.allocPrintZ(arguments.arena.allocator(), "{}", .{zig_str}) catch unreachable); @@ -421,6 +417,37 @@ pub const ArgumentsSlice = struct { arena: std.heap.ArenaAllocator = std.heap.ArenaAllocator.init(bun.default_allocator), all: []const JSC.JSValue, threw: bool = false, + protected: std.bit_set.IntegerBitSet(32) = std.bit_set.IntegerBitSet(32).initEmpty(), + + pub fn unprotect(this: *ArgumentsSlice) void { + var iter = this.protected.iterator(.{}); + var ctx = JSC.VirtualMachine.vm.global.ref(); + while (iter.next()) |i| { + JSC.C.JSValueUnprotect(ctx, this.all[i].asObjectRef()); + } + this.protected = std.bit_set.IntegerBitSet(32).initEmpty(); + } + + pub fn deinit(this: *ArgumentsSlice) void { + this.unprotect(); + this.arena.deinit(); + } + + pub fn protectEat(this: *ArgumentsSlice) void { + if (this.remaining.len == 0) return; + const index = this.all.len - this.remaining.len; + this.protected.set(index); + JSC.C.JSValueProtect(JSC.VirtualMachine.vm.global.ref(), this.all[index].asObjectRef()); + this.eat(); + } + + pub fn protectEatNext(this: *ArgumentsSlice) ?JSC.JSValue { + if (this.remaining.len == 0) return null; + const index = this.all.len - this.remaining.len; + this.protected.set(index); + JSC.C.JSValueProtect(JSC.VirtualMachine.vm.global.ref(), this.all[index].asObjectRef()); + return this.nextEat(); + } pub fn from(arguments: []const JSC.JSValueRef) ArgumentsSlice { return init(@ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]); |