diff options
-rw-r--r-- | src/javascript/jsc/api/FFI.h | 32 | ||||
-rw-r--r-- | src/javascript/jsc/api/ffi.zig | 14 |
2 files changed, 40 insertions, 6 deletions
diff --git a/src/javascript/jsc/api/FFI.h b/src/javascript/jsc/api/FFI.h index 399448cae..498a36d4a 100644 --- a/src/javascript/jsc/api/FFI.h +++ b/src/javascript/jsc/api/FFI.h @@ -9,7 +9,6 @@ #ifdef IS_CALLBACK #define INJECT_BEFORE int c = 500; // This is a callback, so we need to inject code before the call #endif - #define IS_BIG_ENDIAN 0 #define USE_JSVALUE64 1 #define USE_JSVALUE32_64 0 @@ -38,7 +37,38 @@ typedef _Bool bool; #endif // #include <tcclib.h> +// x64 +#ifdef NEEDS_COMPILER_RT_FUNCTIONS + +double __floatundidf(unsigned long a); + +double __floatundidf(unsigned long a) +{ + static const double twop52 = 0x1.0p52; + static const double twop84 = 0x1.0p84; + static const double twop84_plus_twop52 = 0x1.00000001p84; + + union { uint64_t x; double d; } high = { .d = twop84 }; + union { uint64_t x; double d; } low = { .d = twop52 }; + + high.x |= a >> 32; + low.x |= a & 0x00000000ffffffff; + + const double result = (high.d - twop84_plus_twop52) + low.d; + return result; +} + +uint64_t __fixunsdfdi(double a); + +uint64_t __fixunsdfdi(double a) +{ + if (a <= 0.0) return 0; + unsigned high = a/0x1p32f; + unsigned low = a - (double)high*0x1p32f; + return ((unsigned long long)high << 32) | low; +} +#endif NEEDS_COMPILER_RT_FUNCTIONS // This value is 2^49, used to encode doubles such that the encoded value will // begin with a 15-bit pattern within the range 0x0002..0xFFFC. diff --git a/src/javascript/jsc/api/ffi.zig b/src/javascript/jsc/api/ffi.zig index 461e0b1d6..71087b6b6 100644 --- a/src/javascript/jsc/api/ffi.zig +++ b/src/javascript/jsc/api/ffi.zig @@ -101,7 +101,7 @@ pub const FFI = struct { } const allocator = VirtualMachine.vm.allocator; - var function: Function = undefined; + var function: Function = .{}; var func = &function; if (generateSymbolForFunction(globalThis, allocator, interface, func) catch ZigString.init("Out of memory").toErrorInstance(globalThis)) |val| { @@ -159,7 +159,7 @@ pub const FFI = struct { return JSC.toInvalidArguments("Expected an object", .{}, global.ref()); } - var function: Function = undefined; + var function: Function = .{}; if (generateSymbolForFunction(global, allocator, object, &function) catch ZigString.init("Out of memory").toErrorInstance(global)) |val| { return val; } @@ -464,7 +464,7 @@ pub const FFI = struct { return JSC.toTypeError(JSC.Node.ErrorCode.ERR_INVALID_ARG_VALUE, "Expected an object for key \"{s}\"", .{prop}, global.ref()); } - var function: Function = undefined; + var function: Function = .{}; if (try generateSymbolForFunction(global, allocator, value, &function)) |val| { return val; } @@ -481,7 +481,7 @@ pub const FFI = struct { base_name: ?[:0]const u8 = null, state: ?*TCC.TCCState = null, - return_type: ABIType, + return_type: ABIType = ABIType.@"void", arg_types: std.ArrayListUnmanaged(ABIType) = .{}, step: Step = Step{ .pending = {} }, @@ -494,7 +494,7 @@ pub const FFI = struct { } } - val.arg_types.deinit(allocator); + val.arg_types.clearAndFree(allocator); if (val.state) |state| { TCC.tcc_delete(state); @@ -706,6 +706,10 @@ pub const FFI = struct { _ = TCC.tcc_add_symbol(state, "memset", &memset); _ = TCC.tcc_add_symbol(state, "memcpy", &memcpy); + if (comptime Environment.isX64) { + _ = TCC.tcc_define_symbol(state, "NEEDS_COMPILER_RT_FUNCTIONS", "1"); + } + _ = TCC.tcc_add_symbol( state, "JSVALUE_TO_INT64_SLOW", |