aboutsummaryrefslogtreecommitdiff
path: root/integration/bunjs-only-snippets/ffi.test.fixture.receiver.c
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-05-02 03:40:14 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-05-02 03:40:14 -0700
commit125a4c747b24fde0cc7f19d23c5f6b7c78244329 (patch)
tree53693dcbe5ba1e49779482de3c6ef46b44a409b2 /integration/bunjs-only-snippets/ffi.test.fixture.receiver.c
parent69668d49e5ddb5169eae7966d8a30e9ae9e32cea (diff)
downloadbun-125a4c747b24fde0cc7f19d23c5f6b7c78244329.tar.gz
bun-125a4c747b24fde0cc7f19d23c5f6b7c78244329.tar.zst
bun-125a4c747b24fde0cc7f19d23c5f6b7c78244329.zip
[bun:ffi] cleanup
Diffstat (limited to 'integration/bunjs-only-snippets/ffi.test.fixture.receiver.c')
-rw-r--r--integration/bunjs-only-snippets/ffi.test.fixture.receiver.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/integration/bunjs-only-snippets/ffi.test.fixture.receiver.c b/integration/bunjs-only-snippets/ffi.test.fixture.receiver.c
new file mode 100644
index 000000000..2107b684e
--- /dev/null
+++ b/integration/bunjs-only-snippets/ffi.test.fixture.receiver.c
@@ -0,0 +1,211 @@
+#define HAS_ARGUMENTS
+// 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 IS_CALLBACK
+// #define INJECT_BEFORE printf("bun_call %p cachedJSContext %p cachedCallbackFunction %p\n", &bun_call, cachedJSContext, cachedCallbackFunction);
+#endif
+
+#define IS_BIG_ENDIAN 0
+#define USE_JSVALUE64 1
+#define USE_JSVALUE32_64 0
+
+// #include <stdint.h>
+#ifdef INJECT_BEFORE
+// #include <stdio.h>
+#endif
+// #include <tcclib.h>
+
+// // /* 7.18.1.1 Exact-width integer types */
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+typedef uint64_t size_t;
+typedef long intptr_t;
+typedef uint64_t uintptr_t;
+typedef _Bool bool;
+
+#define true 1
+#define false 0
+
+#ifdef USES_FLOAT
+// https://git.musl-libc.org/cgit/musl/tree/src/math/trunc.c
+double trunc(double x);
+double trunc(double x)
+{
+ union {double f; uint64_t i;} u = {x};
+ int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12;
+ uint64_t m;
+
+ if (e >= 52 + 12)
+ return x;
+ if (e < 12)
+ e = 1;
+ m = -1ULL >> e;
+ if ((u.i & m) == 0)
+ return x;
+ x + 0x1p120f;
+ u.i &= ~m;
+ return u.f;
+}
+#endif
+
+
+// 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 49
+#define DoubleEncodeOffset (1ll << DoubleEncodeOffsetBit)
+#define OtherTag 0x2
+#define BoolTag 0x4
+#define UndefinedTag 0x8
+#define TagValueFalse (OtherTag | BoolTag | false)
+#define TagValueTrue (OtherTag | BoolTag | true)
+#define TagValueUndefined (OtherTag | UndefinedTag)
+#define TagValueNull (OtherTag)
+
+// If all bits in the mask are set, this indicates an integer number,
+// if any but not all are set this value is a double precision number.
+#define NumberTag 0xfffe000000000000ll
+
+typedef void* JSCell;
+
+typedef union EncodedJSValue {
+ int64_t asInt64;
+#if USE_JSVALUE32_64
+ double asDouble;
+#elif USE_JSVALUE64
+ JSCell *ptr;
+#endif
+
+#if IS_BIG_ENDIAN
+ struct {
+ int32_t tag;
+ int32_t payload;
+ } asBits;
+#else
+ struct {
+ int32_t payload;
+ int32_t tag;
+ } asBits;
+#endif
+
+ void* asPtr;
+} EncodedJSValue;
+
+EncodedJSValue ValueUndefined = { TagValueUndefined };
+EncodedJSValue ValueTrue = { TagValueTrue };
+
+typedef void* JSContext;
+
+#define LOAD_ARGUMENTS_FROM_CALL_FRAME EncodedJSValue* args = (EncodedJSValue*)((size_t*)callFrame + Bun_FFI_PointerOffsetToArgumentsList);
+
+
+#ifdef IS_CALLBACK
+extern int64_t bun_call(JSContext, void* func, void* thisValue, size_t len, const EncodedJSValue args[], void* exception);
+JSContext cachedJSContext;
+void* cachedCallbackFunction;
+#endif
+
+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 EncodedJSValue PTR_TO_JSVALUE(void* ptr) __attribute__((__always_inline__));
+
+static void* JSVALUE_TO_PTR(EncodedJSValue 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 void* JSVALUE_TO_PTR(EncodedJSValue val) {
+ // must be a double
+ return (void*)(val.asInt64 - DoubleEncodeOffset);
+}
+
+static EncodedJSValue PTR_TO_JSVALUE(void* ptr) {
+ EncodedJSValue val;
+ val.asInt64 = (int64_t)ptr + DoubleEncodeOffset;
+ return val;
+}
+
+static int32_t JSVALUE_TO_INT32(EncodedJSValue val) {
+ return val.asInt64;
+}
+
+static EncodedJSValue INT32_TO_JSVALUE(int32_t val) {
+ EncodedJSValue res;
+ res.asInt64 = NumberTag | (uint32_t)val;
+ return res;
+}
+
+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;
+}
+
+static EncodedJSValue FLOAT_TO_JSVALUE(float val) {
+ return DOUBLE_TO_JSVALUE(val);
+}
+
+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;
+}
+
+#define arg(i) ((EncodedJSValue*)args)[i]
+void* JSFunctionCall(void* globalObject, void* callFrame);
+// int64_t JSFunctionCall(void* globalObject, void* callFrame) {
+// EncodedJSValue* args = (EncodedJSValue*)((unsigned char*)callFrame + Bun_FFI_PointerOffsetToArgumentsList);
+// }
+
+
+
+// --- Generated Code ---
+/* --- The Function To Call */
+void callback(void* arg0);
+
+/* ---- Your Wrapper Function ---- */
+void* JSFunctionCall(void* globalObject, void* callFrame) {
+#ifdef HAS_ARGUMENTS
+ LOAD_ARGUMENTS_FROM_CALL_FRAME;
+#endif
+#ifdef INJECT_BEFORE
+//Bun_FFI_PointerOffsetToArgumentsList: 6
+//Bun_FFI_PointerOffsetToArgumentsCount: 0
+#endif
+ callback( JSVALUE_TO_PTR(arg(0)));
+
+ return ValueUndefined.asPtr;
+}
+