run native modules
This commit is contained in:
39
qbe_rt.c
39
qbe_rt.c
@@ -9,6 +9,8 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef uint64_t JSValue;
|
||||
typedef struct JSContext JSContext;
|
||||
@@ -143,8 +145,43 @@ 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_VAL_NULL;
|
||||
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; }
|
||||
|
||||
@@ -24,11 +24,25 @@ var symbol = 'js_' + safe + '_use'
|
||||
var dylib_path = './' + name + '.dylib'
|
||||
var fd = use('fd')
|
||||
|
||||
// --- Test argument for function-returning modules ---
|
||||
var test_arg = 5000000
|
||||
if (length(args) > 1) {
|
||||
test_arg = number(args[1])
|
||||
}
|
||||
|
||||
// --- Interpreted run ---
|
||||
print('--- interpreted ---')
|
||||
var t1 = os.now()
|
||||
var result_interp = use(name)
|
||||
var mod_interp = use(name)
|
||||
var t2 = os.now()
|
||||
var result_interp = null
|
||||
if (is_function(mod_interp)) {
|
||||
print('module returns a function, calling with ' + text(test_arg))
|
||||
t1 = os.now()
|
||||
result_interp = mod_interp(test_arg)
|
||||
t2 = os.now()
|
||||
}
|
||||
result_interp = result_interp != null ? result_interp : mod_interp
|
||||
var ms_interp = (t2 - t1) / 1000000
|
||||
print('result: ' + text(result_interp))
|
||||
print('time: ' + text(ms_interp) + ' ms')
|
||||
@@ -43,8 +57,16 @@ print('\n--- native ---')
|
||||
var t3 = os.now()
|
||||
var lib = os.dylib_open(dylib_path)
|
||||
var t4 = os.now()
|
||||
var result_native = os.dylib_symbol(lib, symbol)
|
||||
var mod_native = os.dylib_symbol(lib, symbol)
|
||||
var t5 = os.now()
|
||||
var result_native = null
|
||||
if (is_function(mod_native)) {
|
||||
print('module returns a function, calling with ' + text(test_arg))
|
||||
t4 = os.now()
|
||||
result_native = mod_native(test_arg)
|
||||
t5 = os.now()
|
||||
}
|
||||
result_native = result_native != null ? result_native : mod_native
|
||||
var ms_load = (t4 - t3) / 1000000
|
||||
var ms_exec = (t5 - t4) / 1000000
|
||||
var ms_native = (t5 - t3) / 1000000
|
||||
|
||||
Reference in New Issue
Block a user