This commit is contained in:
2026-02-19 03:12:58 -06:00
parent ab43ab0d2c
commit 65fa37cc03
7 changed files with 886 additions and 54 deletions

View File

@@ -421,6 +421,15 @@ Shop.extract_commit_hash = function(pkg, response) {
var open_dls = {}
var package_dylibs = {} // pkg -> [{file, symbol, dylib}, ...]
function open_dylib_cached(path) {
var handle = open_dls[path]
if (handle) return handle
handle = os.dylib_open(path)
if (!handle) return null
open_dls[path] = handle
return handle
}
// Host target detection for native dylib resolution
function detect_host_target() {
var platform = os.platform()
@@ -457,7 +466,7 @@ function try_native_mod_dylib(pkg, stem) {
if (!fd.is_file(build_path)) return null
log.shop('native dylib cache hit: ' + stem)
var handle = os.dylib_open(build_path)
var handle = open_dylib_cached(build_path)
if (!handle) return null
var sym = Shop.c_symbol_for_file(pkg, stem)
return {_native: true, _handle: handle, _sym: sym}
@@ -924,11 +933,7 @@ function try_dylib_symbol(sym, pkg, file_stem) {
})
if (!entry || !entry.dylib) return null
var handle = open_dls[entry.dylib]
if (!handle) {
handle = os.dylib_open(entry.dylib)
if (handle) open_dls[entry.dylib] = handle
}
var handle = open_dylib_cached(entry.dylib)
if (!handle) return null
if (!os.dylib_has_symbol(handle, sym)) return null
@@ -1168,8 +1173,17 @@ Shop.is_loaded = function is_loaded(path, package_context) {
}
// Create a use function bound to a specific package context
function make_use_fn(pkg) {
function make_use_fn(pkg, force_native) {
return function(path) {
var _native = null
if (force_native && !native_mode) {
_native = function() {
return Shop.use_native(path, pkg)
} disruption {
return Shop.use(path, pkg)
}
return _native()
}
return Shop.use(path, pkg)
}
}
@@ -1200,7 +1214,7 @@ function execute_module(info)
inject = Shop.script_inject_for(file_info)
env = inject_env(inject)
pkg = file_info.package
env.use = make_use_fn(pkg)
env.use = make_use_fn(pkg, true)
env = stone(env)
used = os.native_module_load_named(
mod_resolve.symbol._handle, mod_resolve.symbol._sym, env)
@@ -1844,7 +1858,7 @@ Shop.load_as_dylib = function(path, pkg) {
if (!file_info) file_info = Shop.file_info(file_path)
inject = Shop.script_inject_for(file_info)
env = inject_env(inject)
env.use = make_use_fn(real_pkg)
env.use = make_use_fn(real_pkg, true)
env = stone(env)
return os.native_module_load_named(result._handle, result._sym, env)
}
@@ -1891,32 +1905,63 @@ Shop.parse_package = function(locator) {
Shop.use_native = function(path, package_context) {
var src_path = path
if (!starts_with(path, '/'))
var locator = null
var lookup = null
var cache_key = null
var cfg = null
var old_native = null
if (!starts_with(path, '/') && !fd.is_file(path)) {
lookup = ends_with(path, '.cm') ? path : path + '.cm'
locator = resolve_locator(lookup, package_context)
if (!locator) { print('Module not found: ' + path); disrupt }
src_path = locator.path
} else 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 pkg = file_info.package || (locator ? locator.pkg : package_context)
var sym_stem = fd.basename(src_path)
var pkg_dir = null
cache_key = 'native:' + text(pkg || '') + ':' + src_path
if (use_cache[cache_key]) return use_cache[cache_key]
var sym_name = null
if (pkg)
sym_name = Shop.c_symbol_for_file(pkg, fd.basename(src_path))
if (pkg) {
pkg_dir = get_packages_dir() + '/' + safe_package_path(pkg)
if (starts_with(src_path, pkg_dir + '/')) {
sym_stem = text(src_path, length(pkg_dir) + 1)
}
sym_name = Shop.c_symbol_for_file(pkg, sym_stem)
}
var build = Shop.use('build', 'core')
var build = use_cache['core/build'] || use_cache['build']
if (!build) {
cfg = Shop.load_config()
old_native = cfg.policy.native
cfg.policy.native = false
build = Shop.use('build', 'core')
cfg.policy.native = old_native
}
var dylib_path = build.compile_native(src_path, null, null, pkg)
var handle = os.dylib_open(dylib_path)
var handle = open_dylib_cached(dylib_path)
if (!handle) { print('Failed to open native dylib: ' + dylib_path); disrupt }
// Build env with runtime functions and capabilities
var inject = Shop.script_inject_for(file_info)
var env = inject_env(inject)
env.use = make_use_fn(pkg)
env.use = make_use_fn(pkg, true)
env = stone(env)
var loaded = null
if (sym_name)
return os.native_module_load_named(handle, sym_name, env)
return os.native_module_load(handle, env)
loaded = os.native_module_load_named(handle, sym_name, env)
else
loaded = os.native_module_load(handle, env)
use_cache[cache_key] = loaded
return loaded
}
return Shop