qbe rt
This commit is contained in:
119
qbe_rt.c
119
qbe_rt.c
@@ -1,16 +1,16 @@
|
||||
/*
|
||||
* qbe_rt.c - Runtime support for QBE-compiled ƿit modules
|
||||
* qbe_rt.c - Non-inline wrappers for QBE-compiled ƿit modules
|
||||
*
|
||||
* Provides non-inline versions of static-inline quickjs functions
|
||||
* (which QBE-generated code calls as external symbols) and stub
|
||||
* implementations of cell_rt_* helper functions.
|
||||
* (which QBE-generated code calls as external symbols).
|
||||
*
|
||||
* All cell_rt_* runtime functions are implemented in source/qbe_helpers.c
|
||||
* (compiled into the cell binary) and resolved via -undefined dynamic_lookup.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef uint64_t JSValue;
|
||||
typedef struct JSContext JSContext;
|
||||
@@ -80,112 +80,3 @@ extern JSValue JS_NewStringLen(JSContext *ctx, const char *str, size_t len);
|
||||
JSValue JS_NewString(JSContext *ctx, const char *str) {
|
||||
return JS_NewStringLen(ctx, str, strlen(str));
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
cell_rt_* stubs — error/fallback paths for QBE-compiled code
|
||||
These are called from type-mismatch branches that should not
|
||||
be reached in pure numeric code.
|
||||
============================================================ */
|
||||
|
||||
extern JSValue JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...);
|
||||
|
||||
void cell_rt_disrupt(JSContext *ctx) {
|
||||
JS_ThrowTypeError(ctx, "type error in native code");
|
||||
}
|
||||
|
||||
JSValue cell_rt_lt_text(JSContext *ctx, JSValue a, JSValue b) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
JSValue cell_rt_gt_text(JSContext *ctx, JSValue a, JSValue b) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
JSValue cell_rt_le_text(JSContext *ctx, JSValue a, JSValue b) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
JSValue cell_rt_ge_text(JSContext *ctx, JSValue a, JSValue b) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
JSValue cell_rt_eq_tol(JSContext *ctx, JSValue a, JSValue b) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
JSValue cell_rt_ne_tol(JSContext *ctx, JSValue a, JSValue b) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
|
||||
JSValue cell_rt_get_intrinsic(JSContext *ctx, const char *name) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
JSValue cell_rt_load_field(JSContext *ctx, JSValue obj, const char *name) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
JSValue cell_rt_load_dynamic(JSContext *ctx, JSValue obj, JSValue key) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
JSValue cell_rt_load_index(JSContext *ctx, JSValue arr, JSValue idx) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
void cell_rt_store_field(JSContext *ctx, JSValue val, JSValue obj,
|
||||
const char *name) {}
|
||||
void cell_rt_store_dynamic(JSContext *ctx, JSValue val, JSValue obj,
|
||||
JSValue key) {}
|
||||
void cell_rt_store_index(JSContext *ctx, JSValue val, JSValue arr,
|
||||
JSValue idx) {}
|
||||
JSValue cell_rt_get_closure(JSContext *ctx, void *fp, int64_t depth,
|
||||
int64_t index) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
void cell_rt_put_closure(JSContext *ctx, void *fp, JSValue val, int64_t depth,
|
||||
int64_t index) {}
|
||||
JSValue cell_rt_frame(JSContext *ctx, JSValue fn, int64_t nargs) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
void cell_rt_setarg(JSValue frame, int64_t idx, JSValue val) {}
|
||||
JSValue cell_rt_invoke(JSContext *ctx, JSValue frame) { return JS_VAL_NULL; }
|
||||
JSValue cell_rt_goframe(JSContext *ctx, JSValue fn, int64_t nargs) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
void cell_rt_goinvoke(JSContext *ctx, JSValue frame) {}
|
||||
/*
|
||||
* cell_rt_make_function — create a callable JS function wrapping a
|
||||
* QBE-compiled cell_fn_N. Uses magic to store fn_idx, and dlsym to
|
||||
* look up the compiled symbol at call time.
|
||||
*/
|
||||
|
||||
typedef JSValue (*cell_compiled_fn)(JSContext *ctx, void *fp);
|
||||
|
||||
/* JS_CFUNC_generic_magic = 1 in the JSCFunctionEnum */
|
||||
#define QBE_JS_CFUNC_GENERIC_MAGIC 1
|
||||
|
||||
extern JSValue JS_NewCFunction2(JSContext *ctx, void *func,
|
||||
const char *name, int length,
|
||||
int cproto, int magic);
|
||||
|
||||
static JSValue cell_fn_trampoline(JSContext *ctx, JSValue this_val,
|
||||
int argc, JSValue *argv, int magic) {
|
||||
char name[64];
|
||||
snprintf(name, sizeof(name), "cell_fn_%d", magic);
|
||||
|
||||
cell_compiled_fn fn = (cell_compiled_fn)dlsym(RTLD_DEFAULT, name);
|
||||
if (!fn)
|
||||
return JS_ThrowTypeError(ctx, "native function %s not found", name);
|
||||
|
||||
/* Allocate frame: slot 0 = this, slots 1..argc = args, rest zeroed */
|
||||
JSValue frame[512];
|
||||
memset(frame, 0, sizeof(frame));
|
||||
frame[0] = this_val;
|
||||
for (int i = 0; i < argc && i < 511; i++)
|
||||
frame[1 + i] = argv[i];
|
||||
|
||||
return fn(ctx, frame);
|
||||
}
|
||||
|
||||
JSValue cell_rt_make_function(JSContext *ctx, int64_t fn_idx) {
|
||||
return JS_NewCFunction2(ctx, (void *)cell_fn_trampoline, "native_fn",
|
||||
0, QBE_JS_CFUNC_GENERIC_MAGIC, (int)fn_idx);
|
||||
}
|
||||
void cell_rt_push(JSContext *ctx, JSValue arr, JSValue val) {}
|
||||
JSValue cell_rt_pop(JSContext *ctx, JSValue arr) { return JS_VAL_NULL; }
|
||||
JSValue cell_rt_delete(JSContext *ctx, JSValue obj, JSValue key) {
|
||||
return JS_VAL_NULL;
|
||||
}
|
||||
JSValue cell_rt_typeof(JSContext *ctx, JSValue val) { return JS_VAL_NULL; }
|
||||
|
||||
Reference in New Issue
Block a user