[bun ffi] support i32, i8, u8, u16, i16, u32, bool

This commit is contained in:
Jarred Sumner
2022-04-29 05:02:01 -07:00
parent 75374fdc32
commit f07463bdfd
5 changed files with 272 additions and 171 deletions

View File

@@ -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 ---

View File

@@ -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,
};
}