fix
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user