native flag

This commit is contained in:
2026-02-17 15:48:49 -06:00
parent 278d685c8f
commit b3573dbf26
5 changed files with 139 additions and 139 deletions

View File

@@ -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)

View File

@@ -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() {