From f4f56ed47010ec5bda6d7e1662a251eca2900ffb Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Mon, 16 Feb 2026 00:35:23 -0600 Subject: [PATCH] run dylibs --- internal/os.c | 20 ++++++++++++++++++++ internal/shop.cm | 27 ++++++++++++++++++++++++++- run_aot.ce | 25 +++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 run_aot.ce diff --git a/internal/os.c b/internal/os.c index 7685c0ec..174e5192 100644 --- a/internal/os.c +++ b/internal/os.c @@ -446,6 +446,7 @@ static JSValue js_os_dylib_close(JSContext *js, JSValue self, int argc, JSValue /* Load a native .cm module from a dylib handle. Uses cell_rt_native_module_load from qbe_helpers.c */ extern JSValue cell_rt_native_module_load(JSContext *ctx, void *dl_handle); +extern JSValue cell_rt_native_module_load_named(JSContext *ctx, void *dl_handle, const char *sym_name); static JSValue js_os_native_module_load(JSContext *js, JSValue self, int argc, JSValue *argv) { @@ -459,6 +460,24 @@ static JSValue js_os_native_module_load(JSContext *js, JSValue self, int argc, J return cell_rt_native_module_load(js, handle); } +static JSValue js_os_native_module_load_named(JSContext *js, JSValue self, int argc, JSValue *argv) +{ + if (argc < 2) + return JS_ThrowTypeError(js, "native_module_load_named requires (dylib, sym_name)"); + + void *handle = JS_GetOpaque(argv[0], js_dylib_class_id); + if (!handle) + return JS_ThrowTypeError(js, "First argument must be a dylib object"); + + const char *sym_name = JS_ToCString(js, argv[1]); + if (!sym_name) + return JS_EXCEPTION; + + JSValue result = cell_rt_native_module_load_named(js, handle, sym_name); + JS_FreeCString(js, sym_name); + return result; +} + JSC_CCALL(os_print, size_t len; const char *str = JS_ToCStringLen(js, &len, argv[0]); @@ -635,6 +654,7 @@ static const JSCFunctionListEntry js_os_funcs[] = { MIST_FUNC_DEF(os, dylib_symbol, 2), MIST_FUNC_DEF(os, dylib_has_symbol, 2), MIST_FUNC_DEF(os, native_module_load, 1), + MIST_FUNC_DEF(os, native_module_load_named, 2), MIST_FUNC_DEF(os, embedded_module, 1), MIST_FUNC_DEF(os, load_internal, 1), MIST_FUNC_DEF(os, internal_exists, 1), diff --git a/internal/shop.cm b/internal/shop.cm index 6ccd21a4..1c77f55c 100644 --- a/internal/shop.cm +++ b/internal/shop.cm @@ -481,7 +481,8 @@ function try_native_mod_dylib(pkg, stem) { if (!fd.is_file(dylib_path)) return null var handle = os.dylib_open(dylib_path) if (!handle) return null - return os.native_module_load(handle) + var sym = Shop.c_symbol_for_file(pkg, stem) + return os.native_module_load_named(handle, sym) } // Default capabilities injected into scripts @@ -1677,4 +1678,28 @@ Shop.parse_package = function(locator) { } } +Shop.use_native = function(path, package_context) { + var src_path = path + if (!starts_with(path, '/')) + src_path = fd.realpath(path) + if (!fd.is_file(src_path)) { print('File not found: ' + path); disrupt } + + var file_info = Shop.file_info(src_path) + var pkg = file_info.package || package_context + + var sym_name = null + if (pkg) + sym_name = Shop.c_symbol_for_file(pkg, fd.basename(src_path)) + + var build = Shop.use('build', 'core') + var dylib_path = build.compile_native(src_path, null, null, pkg) + + var handle = os.dylib_open(dylib_path) + if (!handle) { print('Failed to open native dylib: ' + dylib_path); disrupt } + + if (sym_name) + return os.native_module_load_named(handle, sym_name) + return os.native_module_load(handle) +} + return Shop \ No newline at end of file diff --git a/run_aot.ce b/run_aot.ce new file mode 100644 index 00000000..1e3588ff --- /dev/null +++ b/run_aot.ce @@ -0,0 +1,25 @@ +// run_aot.ce — compile a .ce program to native dylib and run it +// +// Usage: +// cell run_aot + +var shop = use('internal/shop') +var fd = use('fd') + +if (length(args) < 1) { + print('usage: cell run_aot ') + return +} + +var file = args[0] +if (!fd.is_file(file)) { + if (!ends_with(file, '.ce') && fd.is_file(file + '.ce')) + file = file + '.ce' + else { + print('file not found: ' + file) + return + } +} + +var abs = fd.realpath(file) +shop.use_native(abs)