get c symbol
This commit is contained in:
@@ -12,7 +12,7 @@ var dylib_ext = hidden.dylib_ext
|
||||
var load_internal = hidden.load_internal
|
||||
|
||||
function use_embed(name) {
|
||||
return load_internal(name)
|
||||
return load_internal(`js_${name}_use`)
|
||||
}
|
||||
|
||||
var actor_mod = use_embed('actor')
|
||||
@@ -20,6 +20,7 @@ var wota = use_embed('wota')
|
||||
var nota = use_embed('nota')
|
||||
var enet = use_embed('enet')
|
||||
var fd = use_embed('fd')
|
||||
var os = use_embed('os')
|
||||
var console_mod = use_embed('console')
|
||||
|
||||
var ENETSERVICE = 0.1
|
||||
@@ -30,6 +31,41 @@ var ACTOR_EXT = '.ce'
|
||||
|
||||
globalThis.pi = 3.1415926535897932
|
||||
|
||||
var open_dl = {}
|
||||
|
||||
function get_import_package(name) {
|
||||
var parts = name.split('/')
|
||||
if (parts.length > 1)
|
||||
return parts[0]
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function get_import_dl(name) {
|
||||
var pkg = get_import_package(name)
|
||||
if (!pkg) return null
|
||||
if (open_dl[pkg]) return open_dl[pkg]
|
||||
var dlpath = `.cell/modules/${pkg}/${pkg}${dylib_ext}`
|
||||
var dl = os.dylib_open(dlpath)
|
||||
if (dl) {
|
||||
open_dl[pkg] = dl
|
||||
return dl
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// tries to load a C symbol from either a dynamic library or within the executable
|
||||
// an import 'debug/profile' can either be in a dynamic library debug.so or within the executable
|
||||
function get_c_symbol(name) {
|
||||
var dl = get_import_dl(name)
|
||||
var symname = `js_${name.replace('/', '_')}_use`
|
||||
|
||||
if (dl)
|
||||
return os.dylib_symbol(dl, symname)
|
||||
else
|
||||
return load_internal(symname)
|
||||
}
|
||||
|
||||
function caller_data(depth = 0)
|
||||
{
|
||||
var file = "nofile"
|
||||
@@ -78,13 +114,7 @@ log.system = function(msg) {
|
||||
log.console(msg)
|
||||
}
|
||||
|
||||
|
||||
|
||||
log.console(fd.getcwd())
|
||||
log.console(cell.args.program)
|
||||
|
||||
var shop_path = '.cell'
|
||||
var mod_path = '.cell/modules/'
|
||||
|
||||
if (!fd.stat('.cell').isDirectory) {
|
||||
log.console("No cell directory found. Make one.\n");
|
||||
@@ -358,9 +388,10 @@ globalThis.use = function use(file, ...args) {
|
||||
var compiledPath = get_compiled_path(resolved)
|
||||
var useCompiled = false
|
||||
|
||||
if (is_file(compiledPath)) {
|
||||
useCompiled = true
|
||||
}
|
||||
// Always compile from source - never use precompiled for core modules
|
||||
// if (is_file(compiledPath)) {
|
||||
// useCompiled = true
|
||||
// }
|
||||
|
||||
var fn
|
||||
if (useCompiled) {
|
||||
@@ -428,9 +459,10 @@ globalThis.use = function use(file, ...args) {
|
||||
var srcStat = fd.stat(path)
|
||||
var compiledStat = fd.stat(compiledPath)
|
||||
|
||||
if (srcStat && srcStat.isFile && compiledStat && compiledStat.isFile && compiledStat.mtime > srcStat.mtime) {
|
||||
useCompiled = true
|
||||
}
|
||||
// Always compile from source - never use precompiled for regular modules
|
||||
// if (srcStat && srcStat.isFile && compiledStat && compiledStat.isFile && compiledStat.mtime > srcStat.mtime) {
|
||||
// useCompiled = true
|
||||
// }
|
||||
|
||||
var fn
|
||||
var mod_name = path.substring(path.lastIndexOf('/') + 1, path.lastIndexOf('.'))
|
||||
@@ -1078,19 +1110,20 @@ var startfn
|
||||
var compiledPath = get_compiled_path(resolved_prog)
|
||||
var useCompiled = false
|
||||
|
||||
if (resolved_prog.isCore) {
|
||||
// For core, we check if we have a compiled version, else we compile it
|
||||
if (is_file(compiledPath)) {
|
||||
useCompiled = true
|
||||
}
|
||||
} else {
|
||||
// For local/modules, check timestamps
|
||||
var srcStat = fd.stat(prog)
|
||||
var compiledStat = fd.stat(compiledPath)
|
||||
if (srcStat && srcStat.isFile && compiledStat && compiledStat.isFile && compiledStat.mtime > srcStat.mtime) {
|
||||
useCompiled = true
|
||||
}
|
||||
}
|
||||
// Always compile from source - never use precompiled for main program
|
||||
// if (resolved_prog.isCore) {
|
||||
// // For core, we check if we have a compiled version, else we compile it
|
||||
// if (is_file(compiledPath)) {
|
||||
// useCompiled = true
|
||||
// }
|
||||
// } else {
|
||||
// // For local/modules, check timestamps
|
||||
// var srcStat = fd.stat(prog)
|
||||
// var compiledStat = fd.stat(compiledPath)
|
||||
// if (srcStat && srcStat.isFile && compiledStat && compiledStat.isFile && compiledStat.mtime > srcStat.mtime) {
|
||||
// useCompiled = true
|
||||
// }
|
||||
// }
|
||||
|
||||
if (useCompiled) {
|
||||
var compiledBlob = fd.slurp(compiledPath)
|
||||
|
||||
109
scripts/os.c
109
scripts/os.c
@@ -16,12 +16,31 @@
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <dlfcn.h>
|
||||
#ifdef __linux__
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static JSClassID js_dylib_class_id;
|
||||
|
||||
static void js_dylib_finalizer(JSRuntime *rt, JSValue val) {
|
||||
void *handle = JS_GetOpaque(val, js_dylib_class_id);
|
||||
if (handle) {
|
||||
#ifdef _WIN32
|
||||
FreeLibrary((HMODULE)handle);
|
||||
#else
|
||||
dlclose(handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static JSClassDef js_dylib_class = {
|
||||
"dylib",
|
||||
.finalizer = js_dylib_finalizer,
|
||||
};
|
||||
|
||||
JSC_CCALL(os_now, return number2js(js, (double)SDL_GetTicksNS()/1000000000.0))
|
||||
|
||||
JSC_CCALL(os_sleep,
|
||||
@@ -279,6 +298,91 @@ JSC_SCALL(os_exit,
|
||||
exit(0);
|
||||
)
|
||||
|
||||
static JSValue js_os_dylib_open(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 1) {
|
||||
return JS_ThrowTypeError(js, "dylib_open requires a path argument");
|
||||
}
|
||||
|
||||
const char *path = JS_ToCString(js, argv[0]);
|
||||
if (!path) {
|
||||
return JS_ThrowTypeError(js, "path must be a string");
|
||||
}
|
||||
|
||||
void *handle;
|
||||
#ifdef _WIN32
|
||||
handle = LoadLibraryA(path);
|
||||
#else
|
||||
handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
|
||||
#endif
|
||||
|
||||
JS_FreeCString(js, path);
|
||||
|
||||
if (!handle) {
|
||||
const char *error_msg = "Could not load library";
|
||||
#ifndef _WIN32
|
||||
const char *dl_error = dlerror();
|
||||
if (dl_error) {
|
||||
error_msg = dl_error;
|
||||
}
|
||||
#endif
|
||||
return JS_ThrowReferenceError(js, "Failed to load library: %s", error_msg);
|
||||
}
|
||||
|
||||
JSValue dylib_obj = JS_NewObjectClass(js, js_dylib_class_id);
|
||||
if (JS_IsException(dylib_obj)) {
|
||||
#ifdef _WIN32
|
||||
FreeLibrary((HMODULE)handle);
|
||||
#else
|
||||
dlclose(handle);
|
||||
#endif
|
||||
return dylib_obj;
|
||||
}
|
||||
|
||||
JS_SetOpaque(dylib_obj, handle);
|
||||
return dylib_obj;
|
||||
}
|
||||
|
||||
static JSValue js_os_dylib_symbol(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
return JS_ThrowTypeError(js, "dylib_symbol requires dylib object and symbol 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 *symbol_name = JS_ToCString(js, argv[1]);
|
||||
if (!symbol_name) {
|
||||
return JS_ThrowTypeError(js, "symbol name must be a string");
|
||||
}
|
||||
|
||||
void *symbol;
|
||||
#ifdef _WIN32
|
||||
symbol = GetProcAddress((HMODULE)handle, symbol_name);
|
||||
#else
|
||||
symbol = dlsym(handle, symbol_name);
|
||||
#endif
|
||||
|
||||
JS_FreeCString(js, symbol_name);
|
||||
|
||||
if (!symbol) {
|
||||
const char *error_msg = "Symbol not found";
|
||||
#ifndef _WIN32
|
||||
const char *dl_error = dlerror();
|
||||
if (dl_error) {
|
||||
error_msg = dl_error;
|
||||
}
|
||||
#endif
|
||||
return JS_ThrowReferenceError(js, "Failed to get symbol: %s", error_msg);
|
||||
}
|
||||
|
||||
// Return the symbol as a pointer value
|
||||
return JS_NewInt64(js, (int64_t)(uintptr_t)symbol);
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_os_funcs[] = {
|
||||
MIST_FUNC_DEF(os, platform, 0),
|
||||
MIST_FUNC_DEF(os, arch, 0),
|
||||
@@ -294,9 +398,14 @@ static const JSCFunctionListEntry js_os_funcs[] = {
|
||||
MIST_FUNC_DEF(os, frame, 0),
|
||||
MIST_FUNC_DEF(os, system, 1),
|
||||
MIST_FUNC_DEF(os, exit, 0),
|
||||
MIST_FUNC_DEF(os, dylib_open, 1),
|
||||
MIST_FUNC_DEF(os, dylib_symbol, 2),
|
||||
};
|
||||
|
||||
JSValue js_os_use(JSContext *js) {
|
||||
JS_NewClassID(&js_dylib_class_id);
|
||||
JS_NewClass(JS_GetRuntime(js), js_dylib_class_id, &js_dylib_class);
|
||||
|
||||
JSValue mod = JS_NewObject(js);
|
||||
JS_SetPropertyFunctionList(js,mod,js_os_funcs,countof(js_os_funcs));
|
||||
return mod;
|
||||
|
||||
@@ -283,17 +283,13 @@ JSC_CCALL(os_use_dyn,
|
||||
return fn(js);
|
||||
)
|
||||
|
||||
|
||||
JSC_SCALL(os_load_internal,
|
||||
void *handle = get_main_module_handle();
|
||||
if (!handle) {
|
||||
return JS_ThrowReferenceError(js, "Could not get main module handle");
|
||||
}
|
||||
|
||||
char func_name[256];
|
||||
snprintf(func_name, sizeof(func_name), "js_%s_use", str);
|
||||
|
||||
JSValue (*js_use)(JSContext*) = get_symbol(handle, func_name);
|
||||
JSValue (*js_use)(JSContext*) = get_symbol(handle, str);
|
||||
|
||||
if (!js_use) {
|
||||
// Try without "js_" prefix or other variations if needed, but standard is js_<name>_use
|
||||
|
||||
Reference in New Issue
Block a user