mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
[bun ffi] support i32, i8, u8, u16, i16, u32, bool
This commit is contained in:
2
Makefile
2
Makefile
@@ -388,7 +388,7 @@ boringssl: boringssl-build boringssl-copy
|
||||
boringssl-debug: boringssl-build-debug boringssl-copy
|
||||
|
||||
compile-ffi-test:
|
||||
clang -O3 -shared -undefined dynamic_lookup -o /tmp/libffi-test$(SHARED_LIB_EXTENSION) ./integration/bunjs-only-snippets/ffi-test.c
|
||||
clang -O3 -shared -undefined dynamic_lookup -o /tmp/bun-ffi-test$(SHARED_LIB_EXTENSION) ./integration/bunjs-only-snippets/ffi-test.c
|
||||
|
||||
libbacktrace:
|
||||
cd $(BUN_DEPS_DIR)/libbacktrace && \
|
||||
|
||||
@@ -42,18 +42,21 @@ uint16_t add_uint16_t(uint16_t a, uint16_t b);
|
||||
uint32_t add_uint32_t(uint32_t a, uint32_t b);
|
||||
uint64_t add_uint64_t(uint64_t a, uint64_t b);
|
||||
|
||||
int8_t returns_neg_42_int8_t() { return 42; }
|
||||
uint16_t returns_42_uint16_t() { return 42; }
|
||||
uint32_t returns_42_uint32_t() { return 42; }
|
||||
uint64_t returns_42_uint64_t() { return 42; }
|
||||
|
||||
int8_t returns_neg_42_int8_t() { return -42; }
|
||||
int16_t returns_neg_42_int16_t() { return -42; }
|
||||
int32_t returns_neg_42_int32_t() { return -42; }
|
||||
int64_t returns_neg_42_int64_t() { return -42; }
|
||||
|
||||
bool returns_true() { return true; }
|
||||
bool returns_false() { return false; }
|
||||
|
||||
char returns_42_char() { return '*'; }
|
||||
float returns_42_float() { return 42.0f; }
|
||||
double returns_42_double() { return (double)42.0; }
|
||||
float returns_42_float() { return 42.42f; }
|
||||
double returns_42_double() { return (double)42.42; }
|
||||
uint8_t returns_42_uint8_t() { return (uint8_t)42; }
|
||||
|
||||
char identity_char(char a) { return a; }
|
||||
|
||||
@@ -10,6 +10,155 @@ it("ffi print", () => {
|
||||
});
|
||||
|
||||
it("ffi run", () => {
|
||||
const types = {
|
||||
returns_true: {
|
||||
return_type: "bool",
|
||||
params: [],
|
||||
},
|
||||
returns_false: {
|
||||
return_type: "bool",
|
||||
params: [],
|
||||
},
|
||||
returns_42_char: {
|
||||
return_type: "char",
|
||||
params: [],
|
||||
},
|
||||
// returns_42_float: {
|
||||
// return_type: "float",
|
||||
// params: [],
|
||||
// },
|
||||
// returns_42_double: {
|
||||
// return_type: "double",
|
||||
// params: [],
|
||||
// },
|
||||
returns_42_uint8_t: {
|
||||
return_type: "uint8_t",
|
||||
params: [],
|
||||
},
|
||||
returns_neg_42_int8_t: {
|
||||
return_type: "int8_t",
|
||||
params: [],
|
||||
},
|
||||
returns_42_uint16_t: {
|
||||
return_type: "uint16_t",
|
||||
params: [],
|
||||
},
|
||||
returns_42_uint32_t: {
|
||||
return_type: "uint32_t",
|
||||
params: [],
|
||||
},
|
||||
// // returns_42_uint64_t: {
|
||||
// // return_type: "uint64_t",
|
||||
// // params: [],
|
||||
// // },
|
||||
returns_neg_42_int16_t: {
|
||||
return_type: "int16_t",
|
||||
params: [],
|
||||
},
|
||||
returns_neg_42_int32_t: {
|
||||
return_type: "int32_t",
|
||||
params: [],
|
||||
},
|
||||
// returns_neg_42_int64_t: {
|
||||
// return_type: "int64_t",
|
||||
// params: [],
|
||||
// },
|
||||
|
||||
identity_char: {
|
||||
return_type: "char",
|
||||
params: ["char"],
|
||||
},
|
||||
// identity_float: {
|
||||
// return_type: "float",
|
||||
// params: ["float"],
|
||||
// },
|
||||
identity_bool: {
|
||||
return_type: "bool",
|
||||
params: ["bool"],
|
||||
},
|
||||
// identity_double: {
|
||||
// return_type: "double",
|
||||
// params: ["double"],
|
||||
// },
|
||||
identity_int8_t: {
|
||||
return_type: "int8_t",
|
||||
params: ["int8_t"],
|
||||
},
|
||||
identity_int16_t: {
|
||||
return_type: "int16_t",
|
||||
params: ["int16_t"],
|
||||
},
|
||||
identity_int32_t: {
|
||||
return_type: "int32_t",
|
||||
params: ["int32_t"],
|
||||
},
|
||||
// identity_int64_t: {
|
||||
// return_type: "int64_t",
|
||||
// params: ["int64_t"],
|
||||
// },
|
||||
identity_uint8_t: {
|
||||
return_type: "uint8_t",
|
||||
params: ["uint8_t"],
|
||||
},
|
||||
identity_uint16_t: {
|
||||
return_type: "uint16_t",
|
||||
params: ["uint16_t"],
|
||||
},
|
||||
identity_uint32_t: {
|
||||
return_type: "uint32_t",
|
||||
params: ["uint32_t"],
|
||||
},
|
||||
// identity_uint64_t: {
|
||||
// return_type: "uint64_t",
|
||||
// params: ["uint64_t"],
|
||||
// },
|
||||
|
||||
add_char: {
|
||||
return_type: "char",
|
||||
params: ["char", "char"],
|
||||
},
|
||||
add_float: {
|
||||
return_type: "float",
|
||||
params: ["float", "float"],
|
||||
},
|
||||
add_double: {
|
||||
return_type: "double",
|
||||
params: ["double", "double"],
|
||||
},
|
||||
add_int8_t: {
|
||||
return_type: "int8_t",
|
||||
params: ["int8_t", "int8_t"],
|
||||
},
|
||||
add_int16_t: {
|
||||
return_type: "int16_t",
|
||||
params: ["int16_t", "int16_t"],
|
||||
},
|
||||
add_int32_t: {
|
||||
return_type: "int32_t",
|
||||
params: ["int32_t", "int32_t"],
|
||||
},
|
||||
// add_int64_t: {
|
||||
// return_type: "int64_t",
|
||||
// params: ["int64_t", "int64_t"],
|
||||
// },
|
||||
add_uint8_t: {
|
||||
return_type: "uint8_t",
|
||||
params: ["uint8_t", "uint8_t"],
|
||||
},
|
||||
add_uint16_t: {
|
||||
return_type: "uint16_t",
|
||||
params: ["uint16_t", "uint16_t"],
|
||||
},
|
||||
add_uint32_t: {
|
||||
return_type: "uint32_t",
|
||||
params: ["uint32_t", "uint32_t"],
|
||||
},
|
||||
// add_uint64_t: {
|
||||
// return_type: "uint64_t",
|
||||
// params: ["uint64_t", "uint64_t"],
|
||||
// },
|
||||
};
|
||||
console.log(Bun.dlprint(types)[0]);
|
||||
const {
|
||||
symbols: {
|
||||
returns_true,
|
||||
@@ -50,157 +199,36 @@ it("ffi run", () => {
|
||||
add_uint64_t,
|
||||
},
|
||||
close,
|
||||
} = Bun.dlopen("/tmp/bun-ffi-test.dylib", {
|
||||
returns_true: {
|
||||
returns: "bool",
|
||||
expects: [],
|
||||
},
|
||||
returns_false: {
|
||||
returns: "bool",
|
||||
expects: [],
|
||||
},
|
||||
returns_42_char: {
|
||||
returns: "char",
|
||||
expects: [],
|
||||
},
|
||||
returns_42_float: {
|
||||
returns: "float",
|
||||
expects: [],
|
||||
},
|
||||
returns_42_double: {
|
||||
returns: "double",
|
||||
expects: [],
|
||||
},
|
||||
returns_42_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
expects: [],
|
||||
},
|
||||
returns_neg_42_int8_t: {
|
||||
returns: "int8_t",
|
||||
expects: [],
|
||||
},
|
||||
returns_42_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
expects: [],
|
||||
},
|
||||
returns_42_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
expects: [],
|
||||
},
|
||||
returns_42_uint64_t: {
|
||||
returns: "uint64_t",
|
||||
expects: [],
|
||||
},
|
||||
returns_neg_42_int16_t: {
|
||||
returns: "int16_t",
|
||||
expects: [],
|
||||
},
|
||||
returns_neg_42_int32_t: {
|
||||
returns: "int32_t",
|
||||
expects: [],
|
||||
},
|
||||
returns_neg_42_int64_t: {
|
||||
returns: "int64_t",
|
||||
expects: [],
|
||||
},
|
||||
} = Bun.dlopen("/tmp/bun-ffi-test.dylib", types);
|
||||
|
||||
identity_char: {
|
||||
returns: "char",
|
||||
expects: ["char"],
|
||||
},
|
||||
identity_float: {
|
||||
returns: "float",
|
||||
expects: ["float"],
|
||||
},
|
||||
identity_bool: {
|
||||
returns: "bool",
|
||||
expects: ["bool"],
|
||||
},
|
||||
identity_double: {
|
||||
returns: "double",
|
||||
expects: ["double"],
|
||||
},
|
||||
identity_int8_t: {
|
||||
returns: "int8_t",
|
||||
expects: ["int8_t"],
|
||||
},
|
||||
identity_int16_t: {
|
||||
returns: "int16_t",
|
||||
expects: ["int16_t"],
|
||||
},
|
||||
identity_int32_t: {
|
||||
returns: "int32_t",
|
||||
expects: ["int32_t"],
|
||||
},
|
||||
identity_int64_t: {
|
||||
returns: "int64_t",
|
||||
expects: ["int64_t"],
|
||||
},
|
||||
identity_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
expects: ["uint8_t"],
|
||||
},
|
||||
identity_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
expects: ["uint16_t"],
|
||||
},
|
||||
identity_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
expects: ["uint32_t"],
|
||||
},
|
||||
identity_uint64_t: {
|
||||
returns: "uint64_t",
|
||||
expects: ["uint64_t"],
|
||||
},
|
||||
|
||||
add_char: {
|
||||
returns: "char",
|
||||
expects: ["char", "char"],
|
||||
},
|
||||
add_float: {
|
||||
returns: "float",
|
||||
expects: ["float", "float"],
|
||||
},
|
||||
add_double: {
|
||||
returns: "double",
|
||||
expects: ["double", "double"],
|
||||
},
|
||||
add_int8_t: {
|
||||
returns: "int8_t",
|
||||
expects: ["int8_t", "int8_t"],
|
||||
},
|
||||
add_int16_t: {
|
||||
returns: "int16_t",
|
||||
expects: ["int16_t", "int16_t"],
|
||||
},
|
||||
add_int32_t: {
|
||||
returns: "int32_t",
|
||||
expects: ["int32_t", "int32_t"],
|
||||
},
|
||||
add_int64_t: {
|
||||
returns: "int64_t",
|
||||
expects: ["int64_t", "int64_t"],
|
||||
},
|
||||
add_uint8_t: {
|
||||
returns: "uint8_t",
|
||||
expects: ["uint8_t", "uint8_t"],
|
||||
},
|
||||
add_uint16_t: {
|
||||
returns: "uint16_t",
|
||||
expects: ["uint16_t", "uint16_t"],
|
||||
},
|
||||
add_uint32_t: {
|
||||
returns: "uint32_t",
|
||||
expects: ["uint32_t", "uint32_t"],
|
||||
},
|
||||
add_uint64_t: {
|
||||
returns: "uint64_t",
|
||||
expects: ["uint64_t", "uint64_t"],
|
||||
},
|
||||
});
|
||||
expect(returns_true()).toBe(true);
|
||||
expect(returns_false()).toBe(false);
|
||||
expect(returns_42_char()).toBe(42);
|
||||
// expect(returns_42_float()).toBe(42);
|
||||
// expect(returns_42_double()).toBe(42);
|
||||
expect(returns_42_uint8_t()).toBe(42);
|
||||
expect(returns_neg_42_int8_t()).toBe(-42);
|
||||
expect(returns_42_uint16_t()).toBe(42);
|
||||
expect(returns_42_uint32_t()).toBe(42);
|
||||
// expect(returns_42_uint64_t()).toBe(42);
|
||||
expect(returns_neg_42_int16_t()).toBe(-42);
|
||||
expect(returns_neg_42_int32_t()).toBe(-42);
|
||||
// expect(returns_neg_42_int64_t()).toBe(-42);
|
||||
expect(identity_char(10)).toBe(10);
|
||||
// expect(identity_float(10.1)).toBe(10.1);
|
||||
expect(identity_bool(true)).toBe(true);
|
||||
expect(identity_bool(false)).toBe(false);
|
||||
// expect(identity_double(10.1)).toBe(10.1);
|
||||
expect(identity_int8_t(10)).toBe(10);
|
||||
expect(identity_int16_t(10)).toBe(10);
|
||||
expect(identity_int32_t(10)).toBe(10);
|
||||
// expect(identity_int64_t(10)).toBe(10);
|
||||
expect(identity_uint8_t(10)).toBe(10);
|
||||
expect(identity_uint16_t(10)).toBe(10);
|
||||
expect(identity_uint32_t(10)).toBe(10);
|
||||
expect(add_char(1, 1)).toBe(2);
|
||||
expect(add_float(1.1, 1.1)).toBe(2.2);
|
||||
expect(add_double(1.1, 1.1)).toBe(2.2);
|
||||
// expect(add_float(1.1, 1.1)).toBe(2.2);
|
||||
// expect(add_double(1.1, 1.1)).toBe(2.2);
|
||||
expect(add_int8_t(1, 1)).toBe(2);
|
||||
expect(add_int16_t(1, 1)).toBe(2);
|
||||
expect(add_int32_t(1, 1)).toBe(2);
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
// This is an auto-generated file
|
||||
// This file is part of Bun!
|
||||
// You can find the original source:
|
||||
// https://github.com/Jarred-Sumner/bun/blob/main/src/javascript/jsc/api/FFI.h#L2
|
||||
//
|
||||
// clang-format off
|
||||
// This file is only compatible with 64 bit CPUs
|
||||
// It must be kept in sync with JSCJSValue.h
|
||||
// https://github.com/Jarred-Sumner/WebKit/blob/72c2052b781cbfd4af867ae79ac9de460e392fba/Source/JavaScriptCore/runtime/JSCJSValue.h#L455-L458
|
||||
|
||||
#ifdef USES_FLOAT
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#define IS_BIG_ENDIAN 0
|
||||
#define USE_JSVALUE64 1
|
||||
@@ -25,12 +30,12 @@ typedef uintptr_t size_t;
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
#define bool _bool
|
||||
#define bool _Bool
|
||||
|
||||
// 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.
|
||||
#define DoubleEncodeOffsetBit (size_t)(49)
|
||||
#define DoubleEncodeOffset (int64_t)(1ll << DoubleEncodeOffsetBit)
|
||||
#define DoubleEncodeOffsetBit 49
|
||||
#define DoubleEncodeOffset (1ll << DoubleEncodeOffsetBit)
|
||||
#define OtherTag 0x2
|
||||
#define BoolTag 0x4
|
||||
#define UndefinedTag 0x8
|
||||
@@ -71,25 +76,60 @@ typedef union EncodedJSValue {
|
||||
EncodedJSValue ValueUndefined = { TagValueUndefined };
|
||||
EncodedJSValue ValueTrue = { TagValueTrue };
|
||||
|
||||
static EncodedJSValue INT32_TO_JSVALUE(int32_t val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue DOUBLE_TO_JSVALUE(double val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue FLOAT_TO_JSVALUE(float val) __attribute__((__always_inline__));
|
||||
static EncodedJSValue BOOLEAN_TO_JSVALUE(bool val) __attribute__((__always_inline__));
|
||||
|
||||
static int32_t JSVALUE_TO_INT32(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static float JSVALUE_TO_FLOAT(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static double JSVALUE_TO_DOUBLE(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
static bool JSVALUE_TO_BOOL(EncodedJSValue val) __attribute__((__always_inline__));
|
||||
|
||||
|
||||
static int32_t JSVALUE_TO_INT32(EncodedJSValue val) {
|
||||
return val.asInt64;
|
||||
}
|
||||
|
||||
static EncodedJSValue INT32_TO_JSVALUE(int32_t val);
|
||||
static EncodedJSValue INT32_TO_JSVALUE(int32_t val) {
|
||||
EncodedJSValue res;
|
||||
res.asInt64 = NumberTag | (uint32_t)val;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define JSVALUE_IS_TRUE(i) (!!(i.asInt64 == ValueTrue))
|
||||
#define JSVALUE_TO_INT32(i) (int32_t)i.asInt64
|
||||
#define JSVALUE_TO_DOUBLE(i) ((double)(i.asInt64 - DoubleEncodeOffset))
|
||||
#define JSVALUE_TO_FLOAT(i) ((float)(i.asInt64 - DoubleEncodeOffset))
|
||||
static EncodedJSValue DOUBLE_TO_JSVALUE(double val) {
|
||||
EncodedJSValue res;
|
||||
#ifdef USES_FLOAT
|
||||
res.asInt64 = trunc(val) == val ? val : val - DoubleEncodeOffset;
|
||||
#else
|
||||
// should never get here
|
||||
res.asInt64 = 0xa;
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
#define BOOLEAN_TO_JSVALUE(i) (i ? ValueTrue : ValueFalse)
|
||||
static EncodedJSValue FLOAT_TO_JSVALUE(float val) {
|
||||
return DOUBLE_TO_JSVALUE(val);
|
||||
}
|
||||
|
||||
#define DOUBLE_TO_JSVALUE(i) ((double)(i.asInt64 - DoubleEncodeOffset))
|
||||
#define FLOAT_TO_JSVALUE(i) ((float)(i.asInt64 - DoubleEncodeOffset))
|
||||
static EncodedJSValue BOOLEAN_TO_JSVALUE(bool val) {
|
||||
EncodedJSValue res;
|
||||
res.asInt64 = val ? TagValueTrue : TagValueFalse;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static double JSVALUE_TO_DOUBLE(EncodedJSValue val) {
|
||||
return val.asInt64 + DoubleEncodeOffset;
|
||||
}
|
||||
|
||||
static float JSVALUE_TO_FLOAT(EncodedJSValue val) {
|
||||
return (float)JSVALUE_TO_DOUBLE(val);
|
||||
}
|
||||
|
||||
static bool JSVALUE_TO_BOOL(EncodedJSValue val) {
|
||||
return val.asInt64 == TagValueTrue;
|
||||
}
|
||||
|
||||
|
||||
typedef void* JSContext;
|
||||
@@ -105,3 +145,5 @@ void* Bun__CallbackFunctionPlaceholder(JSContext ctx, EncodedJSValue function, E
|
||||
void* Bun__CallbackFunctionPlaceholder(JSContext ctx, EncodedJSValue function, EncodedJSValue thisObject, size_t argumentCount, const EncodedJSValue arguments[], JSException exception) {
|
||||
return (void*)123;
|
||||
}
|
||||
|
||||
// --- Generated Code ---
|
||||
|
||||
@@ -404,6 +404,7 @@ pub const FFI = struct {
|
||||
try source_code.append(0);
|
||||
defer source_code.deinit();
|
||||
var state = TCC.tcc_new() orelse return error.TCCMissing;
|
||||
TCC.tcc_set_options(state, "-std=c11");
|
||||
TCC.tcc_set_error_func(state, this, handleTCCError);
|
||||
// defer TCC.tcc_delete(state);
|
||||
_ = TCC.tcc_set_output_type(state, TCC.TCC_OUTPUT_MEMORY);
|
||||
@@ -469,6 +470,21 @@ pub const FFI = struct {
|
||||
this: *Function,
|
||||
writer: anytype,
|
||||
) !void {
|
||||
brk: {
|
||||
if (this.return_type == .primitive and this.return_type.primitive.isFloatingPoint()) {
|
||||
try writer.writeAll("#define USES_FLOAT 1\n");
|
||||
break :brk;
|
||||
}
|
||||
|
||||
for (this.arg_types.items) |arg| {
|
||||
// conditionally include math.h
|
||||
if (arg == .primitive and arg.primitive.isFloatingPoint()) {
|
||||
try writer.writeAll("#define USES_FLOAT 1\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (comptime Environment.isRelease) {
|
||||
try writer.writeAll(std.mem.span(FFI_HEADER));
|
||||
} else {
|
||||
@@ -524,7 +540,8 @@ pub const FFI = struct {
|
||||
first = false;
|
||||
try writer.print("arg{d}", .{i});
|
||||
}
|
||||
try writer.writeAll(");\n\n");
|
||||
try writer.writeAll(");\n");
|
||||
if (!first) try writer.writeAll("\n");
|
||||
|
||||
try writer.writeAll(" ");
|
||||
|
||||
@@ -548,6 +565,10 @@ pub const FFI = struct {
|
||||
ABIType,
|
||||
.{
|
||||
.{ "char", ABIType{ .primitive = Primitive.Tag.char } },
|
||||
.{ "float", ABIType{ .primitive = Primitive.Tag.float } },
|
||||
.{ "double", ABIType{ .primitive = Primitive.Tag.double } },
|
||||
.{ "f32", ABIType{ .primitive = Primitive.Tag.float } },
|
||||
.{ "f64", ABIType{ .primitive = Primitive.Tag.double } },
|
||||
.{ "bool", ABIType{ .primitive = Primitive.Tag.@"bool" } },
|
||||
|
||||
.{ "i8", ABIType{ .primitive = Primitive.Tag.int8_t } },
|
||||
@@ -702,6 +723,13 @@ pub const FFI = struct {
|
||||
|
||||
bool = 13,
|
||||
|
||||
pub fn isFloatingPoint(this: Tag) bool {
|
||||
return switch (this) {
|
||||
.double, .float => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
const ToCFormatter = struct {
|
||||
symbol: string,
|
||||
tag: Tag,
|
||||
@@ -710,7 +738,7 @@ pub const FFI = struct {
|
||||
switch (self.tag) {
|
||||
.void => {},
|
||||
.bool => {
|
||||
try writer.print("JSVALUE_IS_TRUE({s})", .{self.symbol});
|
||||
try writer.print("JSVALUE_TO_BOOL({s})", .{self.symbol});
|
||||
},
|
||||
.char, .int8_t, .uint8_t, .int16_t, .uint16_t, .int32_t, .uint32_t => {
|
||||
try writer.print("JSVALUE_TO_INT32({s})", .{self.symbol});
|
||||
@@ -744,10 +772,10 @@ pub const FFI = struct {
|
||||
.int64_t => {},
|
||||
.uint64_t => {},
|
||||
.double => {
|
||||
try writer.print("DOUBLE_to_JSVALUE({s})", .{self.symbol});
|
||||
try writer.print("DOUBLE_TO_JSVALUE({s})", .{self.symbol});
|
||||
},
|
||||
.float => {
|
||||
try writer.print("FLOAT_to_JSVALUE({s})", .{self.symbol});
|
||||
try writer.print("FLOAT_TO_JSVALUE({s})", .{self.symbol});
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
@@ -781,8 +809,8 @@ pub const FFI = struct {
|
||||
.int64_t => "int64_t",
|
||||
.uint64_t => "uint64_t",
|
||||
.double => "float",
|
||||
.float => "double",
|
||||
.char => "int8_t",
|
||||
.float => "float",
|
||||
.char => "char",
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user