get c symbol
This commit is contained in:
@@ -12,7 +12,7 @@ var dylib_ext = hidden.dylib_ext
|
|||||||
var load_internal = hidden.load_internal
|
var load_internal = hidden.load_internal
|
||||||
|
|
||||||
function use_embed(name) {
|
function use_embed(name) {
|
||||||
return load_internal(name)
|
return load_internal(`js_${name}_use`)
|
||||||
}
|
}
|
||||||
|
|
||||||
var actor_mod = use_embed('actor')
|
var actor_mod = use_embed('actor')
|
||||||
@@ -20,6 +20,7 @@ var wota = use_embed('wota')
|
|||||||
var nota = use_embed('nota')
|
var nota = use_embed('nota')
|
||||||
var enet = use_embed('enet')
|
var enet = use_embed('enet')
|
||||||
var fd = use_embed('fd')
|
var fd = use_embed('fd')
|
||||||
|
var os = use_embed('os')
|
||||||
var console_mod = use_embed('console')
|
var console_mod = use_embed('console')
|
||||||
|
|
||||||
var ENETSERVICE = 0.1
|
var ENETSERVICE = 0.1
|
||||||
@@ -30,6 +31,41 @@ var ACTOR_EXT = '.ce'
|
|||||||
|
|
||||||
globalThis.pi = 3.1415926535897932
|
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)
|
function caller_data(depth = 0)
|
||||||
{
|
{
|
||||||
var file = "nofile"
|
var file = "nofile"
|
||||||
@@ -78,13 +114,7 @@ log.system = function(msg) {
|
|||||||
log.console(msg)
|
log.console(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
log.console(fd.getcwd())
|
|
||||||
log.console(cell.args.program)
|
|
||||||
|
|
||||||
var shop_path = '.cell'
|
var shop_path = '.cell'
|
||||||
var mod_path = '.cell/modules/'
|
|
||||||
|
|
||||||
if (!fd.stat('.cell').isDirectory) {
|
if (!fd.stat('.cell').isDirectory) {
|
||||||
log.console("No cell directory found. Make one.\n");
|
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 compiledPath = get_compiled_path(resolved)
|
||||||
var useCompiled = false
|
var useCompiled = false
|
||||||
|
|
||||||
if (is_file(compiledPath)) {
|
// Always compile from source - never use precompiled for core modules
|
||||||
useCompiled = true
|
// if (is_file(compiledPath)) {
|
||||||
}
|
// useCompiled = true
|
||||||
|
// }
|
||||||
|
|
||||||
var fn
|
var fn
|
||||||
if (useCompiled) {
|
if (useCompiled) {
|
||||||
@@ -428,9 +459,10 @@ globalThis.use = function use(file, ...args) {
|
|||||||
var srcStat = fd.stat(path)
|
var srcStat = fd.stat(path)
|
||||||
var compiledStat = fd.stat(compiledPath)
|
var compiledStat = fd.stat(compiledPath)
|
||||||
|
|
||||||
if (srcStat && srcStat.isFile && compiledStat && compiledStat.isFile && compiledStat.mtime > srcStat.mtime) {
|
// Always compile from source - never use precompiled for regular modules
|
||||||
useCompiled = true
|
// if (srcStat && srcStat.isFile && compiledStat && compiledStat.isFile && compiledStat.mtime > srcStat.mtime) {
|
||||||
}
|
// useCompiled = true
|
||||||
|
// }
|
||||||
|
|
||||||
var fn
|
var fn
|
||||||
var mod_name = path.substring(path.lastIndexOf('/') + 1, path.lastIndexOf('.'))
|
var mod_name = path.substring(path.lastIndexOf('/') + 1, path.lastIndexOf('.'))
|
||||||
@@ -1078,19 +1110,20 @@ var startfn
|
|||||||
var compiledPath = get_compiled_path(resolved_prog)
|
var compiledPath = get_compiled_path(resolved_prog)
|
||||||
var useCompiled = false
|
var useCompiled = false
|
||||||
|
|
||||||
if (resolved_prog.isCore) {
|
// Always compile from source - never use precompiled for main program
|
||||||
// For core, we check if we have a compiled version, else we compile it
|
// if (resolved_prog.isCore) {
|
||||||
if (is_file(compiledPath)) {
|
// // For core, we check if we have a compiled version, else we compile it
|
||||||
useCompiled = true
|
// if (is_file(compiledPath)) {
|
||||||
}
|
// useCompiled = true
|
||||||
} else {
|
// }
|
||||||
// For local/modules, check timestamps
|
// } else {
|
||||||
var srcStat = fd.stat(prog)
|
// // For local/modules, check timestamps
|
||||||
var compiledStat = fd.stat(compiledPath)
|
// var srcStat = fd.stat(prog)
|
||||||
if (srcStat && srcStat.isFile && compiledStat && compiledStat.isFile && compiledStat.mtime > srcStat.mtime) {
|
// var compiledStat = fd.stat(compiledPath)
|
||||||
useCompiled = true
|
// if (srcStat && srcStat.isFile && compiledStat && compiledStat.isFile && compiledStat.mtime > srcStat.mtime) {
|
||||||
}
|
// useCompiled = true
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if (useCompiled) {
|
if (useCompiled) {
|
||||||
var compiledBlob = fd.slurp(compiledPath)
|
var compiledBlob = fd.slurp(compiledPath)
|
||||||
|
|||||||
109
scripts/os.c
109
scripts/os.c
@@ -16,12 +16,31 @@
|
|||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
#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_now, return number2js(js, (double)SDL_GetTicksNS()/1000000000.0))
|
||||||
|
|
||||||
JSC_CCALL(os_sleep,
|
JSC_CCALL(os_sleep,
|
||||||
@@ -279,6 +298,91 @@ JSC_SCALL(os_exit,
|
|||||||
exit(0);
|
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[] = {
|
static const JSCFunctionListEntry js_os_funcs[] = {
|
||||||
MIST_FUNC_DEF(os, platform, 0),
|
MIST_FUNC_DEF(os, platform, 0),
|
||||||
MIST_FUNC_DEF(os, arch, 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, frame, 0),
|
||||||
MIST_FUNC_DEF(os, system, 1),
|
MIST_FUNC_DEF(os, system, 1),
|
||||||
MIST_FUNC_DEF(os, exit, 0),
|
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) {
|
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);
|
JSValue mod = JS_NewObject(js);
|
||||||
JS_SetPropertyFunctionList(js,mod,js_os_funcs,countof(js_os_funcs));
|
JS_SetPropertyFunctionList(js,mod,js_os_funcs,countof(js_os_funcs));
|
||||||
return mod;
|
return mod;
|
||||||
|
|||||||
@@ -283,17 +283,13 @@ JSC_CCALL(os_use_dyn,
|
|||||||
return fn(js);
|
return fn(js);
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
JSC_SCALL(os_load_internal,
|
JSC_SCALL(os_load_internal,
|
||||||
void *handle = get_main_module_handle();
|
void *handle = get_main_module_handle();
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
return JS_ThrowReferenceError(js, "Could not get main module handle");
|
return JS_ThrowReferenceError(js, "Could not get main module handle");
|
||||||
}
|
}
|
||||||
|
|
||||||
char func_name[256];
|
JSValue (*js_use)(JSContext*) = get_symbol(handle, str);
|
||||||
snprintf(func_name, sizeof(func_name), "js_%s_use", str);
|
|
||||||
|
|
||||||
JSValue (*js_use)(JSContext*) = get_symbol(handle, func_name);
|
|
||||||
|
|
||||||
if (!js_use) {
|
if (!js_use) {
|
||||||
// Try without "js_" prefix or other variations if needed, but standard is js_<name>_use
|
// Try without "js_" prefix or other variations if needed, but standard is js_<name>_use
|
||||||
|
|||||||
Reference in New Issue
Block a user