native flag
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// Hidden vars (os, actorsym, init, core_path, shop_path, json, args) come from env
|
||||
// Engine is self-sufficient: defines its own compilation pipeline
|
||||
var ACTORDATA = actorsym
|
||||
var native_mode = false
|
||||
var SYSYM = '__SYSTEM__'
|
||||
|
||||
var _cell = {}
|
||||
@@ -216,13 +217,24 @@ var _program = null
|
||||
var _user_args = []
|
||||
var _j = 1
|
||||
var _init = init
|
||||
if (args != null && _init == null) {
|
||||
|
||||
// Inherit native_mode from init (set by C for --native, or by parent actor)
|
||||
if (_init != null && _init.native_mode)
|
||||
native_mode = true
|
||||
|
||||
// CLI path: convert args to init record
|
||||
if (args != null && (_init == null || !_init.program)) {
|
||||
_program = args[0]
|
||||
while (_j < length(args)) {
|
||||
push(_user_args, args[_j])
|
||||
_j = _j + 1
|
||||
}
|
||||
_init = {program: _program, arg: _user_args}
|
||||
if (_init == null) {
|
||||
_init = {program: _program, arg: _user_args}
|
||||
} else {
|
||||
_init.program = _program
|
||||
_init.arg = _user_args
|
||||
}
|
||||
}
|
||||
|
||||
use_cache['core/os'] = os
|
||||
@@ -413,9 +425,11 @@ core_extras.content_hash = content_hash
|
||||
core_extras.cache_path = cache_path
|
||||
core_extras.ensure_build_dir = ensure_build_dir
|
||||
core_extras.compile_to_blob = compile_to_blob
|
||||
core_extras.native_mode = native_mode
|
||||
|
||||
// NOW load shop -- it receives all of the above via env
|
||||
var shop = use_core('internal/shop')
|
||||
if (native_mode) use_core('build')
|
||||
var time = use_core('time')
|
||||
|
||||
var pronto = use_core('pronto')
|
||||
@@ -690,6 +704,7 @@ $_.start = function start(cb, program) {
|
||||
overling_id: oid,
|
||||
root_id: root ? root[ACTORDATA].id : null,
|
||||
program,
|
||||
native_mode: native_mode,
|
||||
}
|
||||
greeters[id] = cb
|
||||
push(message_queue, { startup })
|
||||
@@ -1082,6 +1097,28 @@ $_.clock(_ => {
|
||||
env.log = log
|
||||
env = stone(env)
|
||||
|
||||
var native_build = null
|
||||
var native_dylib_path = null
|
||||
var native_handle = null
|
||||
var native_parts = null
|
||||
var native_basename = null
|
||||
var native_sym = null
|
||||
|
||||
// Native execution path: compile to dylib and run
|
||||
if (native_mode) {
|
||||
native_build = use_core('build')
|
||||
native_dylib_path = native_build.compile_native(prog_path, null, null, pkg)
|
||||
native_handle = os.dylib_open(native_dylib_path)
|
||||
native_parts = array(prog_path, '/')
|
||||
native_basename = native_parts[length(native_parts) - 1]
|
||||
native_sym = pkg ? shop.c_symbol_for_file(pkg, native_basename) : null
|
||||
if (native_sym)
|
||||
os.native_module_load_named(native_handle, native_sym, env)
|
||||
else
|
||||
os.native_module_load(native_handle, env)
|
||||
return
|
||||
}
|
||||
|
||||
var source_blob = fd.slurp(prog_path)
|
||||
var hash = content_hash(source_blob)
|
||||
var cached_path = cache_path(hash)
|
||||
|
||||
@@ -303,7 +303,8 @@ var _default_policy = {
|
||||
allow_dylib: true,
|
||||
allow_static: true,
|
||||
allow_mach: true,
|
||||
allow_compile: true
|
||||
allow_compile: true,
|
||||
native: false
|
||||
}
|
||||
|
||||
Shop.load_config = function() {
|
||||
@@ -336,6 +337,7 @@ Shop.load_config = function() {
|
||||
|
||||
function get_policy() {
|
||||
var config = Shop.load_config()
|
||||
if (native_mode) config.policy.native = true
|
||||
return config.policy
|
||||
}
|
||||
|
||||
@@ -433,14 +435,37 @@ function detect_host_target() {
|
||||
var host_target = detect_host_target()
|
||||
|
||||
// Check for a native .cm dylib at the deterministic lib path
|
||||
// Returns the loaded module value, or null if no native dylib exists
|
||||
// Returns a native descriptor {_native, _handle, _sym}, or null if no native dylib exists
|
||||
// Also checks staleness: if source has changed, the content-addressed build artifact
|
||||
// won't exist for the new hash, so the installed dylib is treated as stale.
|
||||
function try_native_mod_dylib(pkg, stem) {
|
||||
var dylib_path = get_dylib_path(pkg, stem)
|
||||
var src_path = null
|
||||
var src = null
|
||||
var host = null
|
||||
var hash = null
|
||||
var tc_ext = null
|
||||
var build_path = null
|
||||
var handle = null
|
||||
var sym = null
|
||||
|
||||
if (!fd.is_file(dylib_path)) return null
|
||||
var handle = os.dylib_open(dylib_path)
|
||||
|
||||
// Staleness check: verify the content-addressed build artifact exists
|
||||
src_path = get_packages_dir() + '/' + safe_package_path(pkg) + '/' + stem
|
||||
if (fd.is_file(src_path)) {
|
||||
src = text(fd.slurp(src_path))
|
||||
host = detect_host_target()
|
||||
hash = content_hash(src + '\n' + host + '\nnative')
|
||||
tc_ext = dylib_ext
|
||||
build_path = global_shop_path + '/build/' + hash + '.' + host + tc_ext
|
||||
if (!fd.is_file(build_path)) return null
|
||||
}
|
||||
|
||||
handle = os.dylib_open(dylib_path)
|
||||
if (!handle) return null
|
||||
var sym = Shop.c_symbol_for_file(pkg, stem)
|
||||
return os.native_module_load_named(handle, sym)
|
||||
sym = Shop.c_symbol_for_file(pkg, stem)
|
||||
return {_native: true, _handle: handle, _sym: sym}
|
||||
}
|
||||
|
||||
// Default capabilities injected into scripts
|
||||
@@ -511,6 +536,10 @@ function resolve_mod_fn(path, pkg) {
|
||||
var _pkg_dir = null
|
||||
var _stem = null
|
||||
var policy = null
|
||||
var build_mod = null
|
||||
var dylib_path = null
|
||||
var handle = null
|
||||
var sym = null
|
||||
|
||||
policy = get_policy()
|
||||
|
||||
@@ -525,8 +554,21 @@ function resolve_mod_fn(path, pkg) {
|
||||
// Check for native .cm dylib at deterministic path first
|
||||
if (policy.allow_dylib && pkg && _stem) {
|
||||
native_result = try_native_mod_dylib(pkg, _stem)
|
||||
if (native_result != null) {
|
||||
return {_native: true, value: native_result}
|
||||
if (native_result != null) return native_result
|
||||
}
|
||||
|
||||
// Native compilation path: compile to native dylib instead of mach
|
||||
if (policy.native && policy.allow_compile) {
|
||||
build_mod = use_cache['core/build']
|
||||
if (build_mod) {
|
||||
dylib_path = build_mod.compile_native(path, null, null, pkg)
|
||||
if (dylib_path) {
|
||||
handle = os.dylib_open(dylib_path)
|
||||
if (handle) {
|
||||
sym = pkg && _stem ? Shop.c_symbol_for_file(pkg, _stem) : null
|
||||
return {_native: true, _handle: handle, _sym: sym}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,9 +992,16 @@ function execute_module(info)
|
||||
var pkg = null
|
||||
|
||||
if (mod_resolve.scope < 900) {
|
||||
// Check if native dylib was resolved
|
||||
// Check if native dylib was resolved (descriptor with _handle and _sym)
|
||||
if (is_object(mod_resolve.symbol) && mod_resolve.symbol._native) {
|
||||
used = mod_resolve.symbol.value
|
||||
file_info = Shop.file_info(mod_resolve.path)
|
||||
inject = Shop.script_inject_for(file_info)
|
||||
env = inject_env(inject)
|
||||
pkg = file_info.package
|
||||
env.use = make_use_fn(pkg)
|
||||
env = stone(env)
|
||||
used = os.native_module_load_named(
|
||||
mod_resolve.symbol._handle, mod_resolve.symbol._sym, env)
|
||||
} else {
|
||||
// Build env with runtime fns, capabilities, and use function
|
||||
file_info = Shop.file_info(mod_resolve.path)
|
||||
@@ -1607,6 +1656,8 @@ Shop.load_as_dylib = function(path, pkg) {
|
||||
var stem = null
|
||||
var result = null
|
||||
var real_pkg = pkg
|
||||
var inject = null
|
||||
var env = null
|
||||
|
||||
if (!locator) { print('Module ' + path + ' not found'); disrupt }
|
||||
|
||||
@@ -1621,7 +1672,15 @@ Shop.load_as_dylib = function(path, pkg) {
|
||||
if (!starts_with(file_path, pkg_dir + '/')) return null
|
||||
stem = text(file_path, length(pkg_dir) + 1)
|
||||
result = try_native_mod_dylib(real_pkg, stem)
|
||||
return result
|
||||
if (!result) return null
|
||||
|
||||
// Build env and load the native module
|
||||
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 = stone(env)
|
||||
return os.native_module_load_named(result._handle, result._sym, env)
|
||||
}
|
||||
|
||||
Shop.audit_packages = function() {
|
||||
|
||||
Reference in New Issue
Block a user