diff options
author | 2022-08-15 01:48:31 -0700 | |
---|---|---|
committer | 2022-08-17 07:36:35 -0700 | |
commit | 6a65631cbdcae75bfa1e64323a6ad613a922cd1a (patch) | |
tree | d6a8c56e9455eafbcb944fd29b5ba066ab31bca0 /src/bun.js/api | |
parent | 382be2cb46eac458e7f619ee1ee05c9efadcce51 (diff) | |
download | bun-6a65631cbdcae75bfa1e64323a6ad613a922cd1a.tar.gz bun-6a65631cbdcae75bfa1e64323a6ad613a922cd1a.tar.zst bun-6a65631cbdcae75bfa1e64323a6ad613a922cd1a.zip |
[bun:ffi] Improve `ptr()` performance and implement code generation for DOMJIT
Diffstat (limited to 'src/bun.js/api')
-rw-r--r-- | src/bun.js/api/bun.zig | 33 | ||||
-rw-r--r-- | src/bun.js/api/ffi.zig | 29 |
2 files changed, 47 insertions, 15 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig index 45e7cb1a1..8408ce339 100644 --- a/src/bun.js/api/bun.zig +++ b/src/bun.js/api/bun.zig @@ -2392,9 +2392,7 @@ pub const Timer = struct { pub const FFI = struct { pub const Class = NewClass( void, - .{ - .name = "FFI", - }, + .{ .name = "FFI", .has_dom_calls = true }, .{ .viewSource = .{ .rfn = JSC.wrapWithHasContainer(JSC.FFI, "print", false, false, true), @@ -2408,9 +2406,7 @@ pub const FFI = struct { .linkSymbols = .{ .rfn = JSC.wrapWithHasContainer(JSC.FFI, "linkSymbols", false, false, false), }, - .ptr = .{ - .rfn = JSC.wrapWithHasContainer(@This(), "ptr", false, false, true), - }, + .ptr = JSC.DOMCall("FFI", @This(), "ptr", f64, JSC.DOMEffect.forRead(.TypedArrayProperties)), .toBuffer = .{ .rfn = JSC.wrapWithHasContainer(@This(), "toBuffer", false, false, true), }, @@ -2427,6 +2423,26 @@ pub const FFI = struct { pub fn ptr( globalThis: *JSGlobalObject, + _: JSValue, + arguments: []const JSValue, + ) JSValue { + return switch (arguments.len) { + 0 => ptr_(globalThis, JSValue.zero, null), + 1 => ptr_(globalThis, arguments[0], null), + else => ptr_(globalThis, arguments[0], arguments[1]), + }; + } + + pub fn ptrWithoutTypeChecks( + _: *JSGlobalObject, + _: *anyopaque, + array: *JSC.JSUint8Array, + ) callconv(.C) JSValue { + return JSValue.fromPtrAddress(@ptrToInt(array.ptr())); + } + + fn ptr_( + globalThis: *JSGlobalObject, value: JSValue, byteOffset: ?JSValue, ) JSValue { @@ -2435,7 +2451,7 @@ pub const FFI = struct { } const array_buffer = value.asArrayBuffer(globalThis) orelse { - return JSC.toInvalidArguments("Expected ArrayBufferView", .{}, globalThis.ref()); + return JSC.toInvalidArguments("Expected ArrayBufferView but received {s}", .{@tagName(value.jsType())}, globalThis.ref()); }; if (array_buffer.len == 0) { @@ -2443,6 +2459,8 @@ pub const FFI = struct { } var addr: usize = @ptrToInt(array_buffer.ptr); + // const Sizes = @import("../bindings/sizes.zig"); + // std.debug.assert(addr == @ptrToInt(value.asEncoded().ptr) + Sizes.Bun_FFI_PointerOffsetToTypedArrayVector); if (byteOffset) |off| { if (!off.isEmptyOrUndefinedOrNull()) { @@ -2687,6 +2705,7 @@ pub const FFI = struct { var prototype = JSC.C.JSObjectMake(ctx, FFI.Class.get().?[0], null); var base = JSC.C.JSObjectMake(ctx, null, null); JSC.C.JSObjectSetPrototype(ctx, base, prototype); + FFI.Class.putDOMCalls(ctx, JSC.JSValue.c(base)); return ctx.ptr().putCachedObject( &ZigString.init("FFI"), JSValue.fromRef(base), diff --git a/src/bun.js/api/ffi.zig b/src/bun.js/api/ffi.zig index 52c086d5b..46a4d20c8 100644 --- a/src/bun.js/api/ffi.zig +++ b/src/bun.js/api/ffi.zig @@ -92,6 +92,7 @@ pub const FFI = struct { ); pub fn callback(globalThis: *JSGlobalObject, interface: JSC.JSValue, js_callback: JSC.JSValue) JSValue { + JSC.markBinding(); if (!interface.isObject()) { return JSC.toInvalidArguments("Expected object", .{}, globalThis.ref()); } @@ -136,6 +137,7 @@ pub const FFI = struct { } pub fn close(this: *FFI) JSValue { + JSC.markBinding(); if (this.closed) { return JSC.JSValue.jsUndefined(); } @@ -156,6 +158,7 @@ pub const FFI = struct { } pub fn printCallback(global: *JSGlobalObject, object: JSC.JSValue) JSValue { + JSC.markBinding(); const allocator = VirtualMachine.vm.allocator; if (object.isEmptyOrUndefinedOrNull() or !object.isObject()) { @@ -180,6 +183,7 @@ pub const FFI = struct { } pub fn print(global: *JSGlobalObject, object: JSC.JSValue, is_callback_val: ?JSC.JSValue) JSValue { + JSC.markBinding(); const allocator = VirtualMachine.vm.allocator; if (is_callback_val) |is_callback| { if (is_callback.toBoolean()) { @@ -262,6 +266,7 @@ pub const FFI = struct { // } pub fn open(global: *JSGlobalObject, name_str: ZigString, object: JSC.JSValue) JSC.JSValue { + JSC.markBinding(); const allocator = VirtualMachine.vm.allocator; var name_slice = name_str.toSlice(allocator); defer name_slice.deinit(); @@ -289,7 +294,7 @@ pub const FFI = struct { } var dylib = std.DynLib.open(name) catch { - return JSC.toInvalidArguments("Failed to open library", .{}, global.ref()); + return JSC.toInvalidArguments("Failed to find or open library", .{}, global.ref()); }; var obj = JSC.JSValue.c(JSC.C.JSObjectMake(global.ref(), null, null)); @@ -376,6 +381,7 @@ pub const FFI = struct { } pub fn linkSymbols(global: *JSGlobalObject, object: JSC.JSValue) JSC.JSValue { + JSC.markBinding(); const allocator = VirtualMachine.vm.allocator; if (object.isEmptyOrUndefinedOrNull() or !object.isObject()) { @@ -467,6 +473,8 @@ pub const FFI = struct { return JSC.JSValue.createObject2(global, &ZigString.init("close"), &ZigString.init("symbols"), close_object, obj); } pub fn generateSymbolForFunction(global: *JSGlobalObject, allocator: std.mem.Allocator, value: JSC.JSValue, function: *Function) !?JSValue { + JSC.markBinding(); + var abi_types = std.ArrayListUnmanaged(ABIType){}; if (value.get(global, "args")) |args| { @@ -558,6 +566,7 @@ pub const FFI = struct { return null; } pub fn generateSymbols(global: *JSGlobalObject, symbols: *std.StringArrayHashMapUnmanaged(Function), object: JSC.JSValue) !?JSValue { + JSC.markBinding(); const allocator = VirtualMachine.vm.allocator; var symbols_iter = JSC.JSPropertyIterator(.{ @@ -629,6 +638,7 @@ pub const FFI = struct { pending: void, compiled: struct { ptr: *anyopaque, + fast_path_ptr: ?*anyopaque = null, buf: []u8, js_function: ?*anyopaque = null, js_context: ?*anyopaque = null, @@ -687,14 +697,13 @@ pub const FFI = struct { bun_call: *const @TypeOf(JSC.C.JSObjectCallAsFunction), }; const headers = @import("../bindings/headers.zig"); - - var workaround: MyFunctionSStructWorkAround = .{ + var workaround: MyFunctionSStructWorkAround = if (!JSC.is_bindgen) .{ .JSVALUE_TO_INT64 = headers.JSC__JSValue__toInt64, .JSVALUE_TO_UINT64 = headers.JSC__JSValue__toUInt64NoTruncate, .INT64_TO_JSVALUE = headers.JSC__JSValue__fromInt64NoTruncate, .UINT64_TO_JSVALUE = headers.JSC__JSValue__fromUInt64NoTruncate, .bun_call = &JSC.C.JSObjectCallAsFunction, - }; + } else undefined; const tcc_options = "-std=c11 -nostdlib -Wl,--export-all-symbols" ++ if (Environment.isDebug) " -g" else ""; @@ -824,6 +833,7 @@ pub const FFI = struct { } pub fn inject(state: *TCC.TCCState) void { + JSC.markBinding(); _ = TCC.tcc_add_symbol(state, "memset", &memset); _ = TCC.tcc_add_symbol(state, "memcpy", &memcpy); @@ -837,10 +847,12 @@ pub const FFI = struct { "JSVALUE_TO_UINT64_SLOW", workaround.JSVALUE_TO_UINT64, ); - std.mem.doNotOptimizeAway(headers.JSC__JSValue__toUInt64NoTruncate); - std.mem.doNotOptimizeAway(headers.JSC__JSValue__toInt64); - std.mem.doNotOptimizeAway(headers.JSC__JSValue__fromInt64NoTruncate); - std.mem.doNotOptimizeAway(headers.JSC__JSValue__fromUInt64NoTruncate); + if (!comptime JSC.is_bindgen) { + std.mem.doNotOptimizeAway(headers.JSC__JSValue__toUInt64NoTruncate); + std.mem.doNotOptimizeAway(headers.JSC__JSValue__toInt64); + std.mem.doNotOptimizeAway(headers.JSC__JSValue__fromInt64NoTruncate); + std.mem.doNotOptimizeAway(headers.JSC__JSValue__fromUInt64NoTruncate); + } _ = TCC.tcc_add_symbol( state, "INT64_TO_JSVALUE_SLOW", @@ -1203,6 +1215,7 @@ pub const FFI = struct { } }; + // Must be kept in sync with JSFFIFunction.h version pub const ABIType = enum(i32) { char = 0, |