intrinsics rewritten without ++, --, etc
This commit is contained in:
130
internal/shop.cm
130
internal/shop.cm
@@ -5,7 +5,6 @@ var fd = use('fd')
|
||||
var http = use('http')
|
||||
var miniz = use('miniz')
|
||||
var time = use('time')
|
||||
var js = use('js')
|
||||
var crypto = use('crypto')
|
||||
var blob = use('blob')
|
||||
|
||||
@@ -13,6 +12,10 @@ var pkg_tools = use('package')
|
||||
var os = use('os')
|
||||
var link = use('link')
|
||||
|
||||
var analyze = os.analyze
|
||||
var run_ast_fn = os.run_ast_fn
|
||||
var shop_json = os.json
|
||||
|
||||
var core = "core"
|
||||
|
||||
function pull_from_cache(content)
|
||||
@@ -34,7 +37,7 @@ function ensure_dir(path) {
|
||||
var current = starts_with(path, '/') ? '/' : ''
|
||||
for (var i = 0; i < length(parts); i++) {
|
||||
if (parts[i] == '') continue
|
||||
current += parts[i] + '/'
|
||||
current = current + parts[i] + '/'
|
||||
if (!fd.stat(current).isDirectory) {
|
||||
fd.mkdir(current)
|
||||
}
|
||||
@@ -142,8 +145,10 @@ function package_in_shop(package) {
|
||||
|
||||
function abs_path_to_package(package_dir)
|
||||
{
|
||||
if (!fd.is_file(package_dir + '/cell.toml'))
|
||||
throw Error('Not a valid package directory (no cell.toml): ' + package_dir)
|
||||
if (!fd.is_file(package_dir + '/cell.toml')) {
|
||||
print('Not a valid package directory (no cell.toml): ' + package_dir)
|
||||
disrupt
|
||||
}
|
||||
|
||||
var packages_prefix = get_packages_dir() + '/'
|
||||
var core_dir = packages_prefix + core_package
|
||||
@@ -175,13 +180,12 @@ function abs_path_to_package(package_dir)
|
||||
return package_dir
|
||||
|
||||
// For local directories (e.g., linked targets), read the package name from cell.toml
|
||||
try {
|
||||
var content = text(fd.slurp(package_dir + '/cell.toml'))
|
||||
var _toml_path = package_dir + '/cell.toml'
|
||||
if (fd.is_file(_toml_path)) {
|
||||
var content = text(fd.slurp(_toml_path))
|
||||
var cfg = toml.decode(content)
|
||||
if (cfg.package)
|
||||
return cfg.package
|
||||
} catch (e) {
|
||||
// Fall through
|
||||
}
|
||||
|
||||
return null
|
||||
@@ -299,12 +303,14 @@ Shop.resolve_package_info = function(pkg) {
|
||||
|
||||
// Verify if a package name is valid and return status
|
||||
Shop.verify_package_name = function(pkg) {
|
||||
if (!pkg) throw Error("Empty package name")
|
||||
if (pkg == 'local') throw Error("local is not a valid package name")
|
||||
if (pkg == 'core') throw Error("core is not a valid package name")
|
||||
|
||||
if (search(pkg, '://') != null)
|
||||
throw Error(`Invalid package name: ${pkg}; did you mean ${array(pkg, '://')[1]}?`)
|
||||
if (!pkg) { print("Empty package name"); disrupt }
|
||||
if (pkg == 'local') { print("local is not a valid package name"); disrupt }
|
||||
if (pkg == 'core') { print("core is not a valid package name"); disrupt }
|
||||
|
||||
if (search(pkg, '://') != null) {
|
||||
print(`Invalid package name: ${pkg}; did you mean ${array(pkg, '://')[1]}?`)
|
||||
disrupt
|
||||
}
|
||||
}
|
||||
|
||||
// Convert module package to download URL
|
||||
@@ -383,9 +389,7 @@ function inject_env(inject) {
|
||||
var env = {}
|
||||
var rt = my$_.os ? my$_.os.runtime_env : null
|
||||
if (rt) {
|
||||
for (var k in rt) {
|
||||
env[k] = rt[k]
|
||||
}
|
||||
arrfor(array(rt), function(k) { env[k] = rt[k] })
|
||||
}
|
||||
|
||||
// Add capability injections
|
||||
@@ -441,28 +445,30 @@ ${script}
|
||||
// Resolve module function, hashing it in the process
|
||||
// path is the exact path to the script file
|
||||
function resolve_mod_fn(path, pkg) {
|
||||
if (!fd.is_file(path)) throw Error(`path ${path} is not a file`)
|
||||
if (!fd.is_file(path)) { print(`path ${path} is not a file`); disrupt }
|
||||
|
||||
var file_info = Shop.file_info(path)
|
||||
var file_pkg = file_info.package
|
||||
var inject = Shop.script_inject_for(file_info)
|
||||
var content = text(fd.slurp(path))
|
||||
var script = script_form(path, content, file_pkg, inject);
|
||||
var script = script_form(path, content, file_pkg, inject)
|
||||
|
||||
var obj = pull_from_cache(stone(blob(script)))
|
||||
if (obj) {
|
||||
var fn = js.compile_unblob(obj)
|
||||
return js.integrate(fn, null)
|
||||
// Check cache for pre-compiled .mach blob
|
||||
var cached = pull_from_cache(stone(blob(script)))
|
||||
if (cached) {
|
||||
return mach_load(cached)
|
||||
}
|
||||
|
||||
// Compile name is just for debug/stack traces
|
||||
var compile_name = path
|
||||
// Compile via new pipeline
|
||||
var ast = analyze(script, path)
|
||||
var ast_json = shop_json.encode(ast)
|
||||
|
||||
var fn = js.compile(compile_name, script)
|
||||
// Cache compiled binary
|
||||
var compiled = mach_compile_ast(path, ast_json)
|
||||
put_into_cache(stone(blob(script)), compiled)
|
||||
|
||||
put_into_cache(stone(blob(script)), js.compile_blob(fn))
|
||||
|
||||
return js.integrate(fn, null)
|
||||
// Evaluate to get the function object
|
||||
return mach_eval_ast(path, ast_json)
|
||||
}
|
||||
|
||||
// given a path and a package context
|
||||
@@ -576,33 +582,20 @@ Shop.open_package_dylib = function(pkg) {
|
||||
|
||||
var toml_path = pkg_dir + '/cell.toml'
|
||||
if (fd.is_file(toml_path)) {
|
||||
try {
|
||||
var content = text(fd.slurp(toml_path))
|
||||
var cfg = toml.decode(content)
|
||||
if (cfg.dependencies) {
|
||||
arrfor(array(cfg.dependencies), function(alias, i) {
|
||||
var dep_pkg = cfg.dependencies[alias]
|
||||
try {
|
||||
Shop.open_package_dylib(dep_pkg)
|
||||
} catch (dep_e) {
|
||||
// Dependency dylib load failed, continue with others
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
// Error reading toml, continue
|
||||
var content = text(fd.slurp(toml_path))
|
||||
var cfg = toml.decode(content)
|
||||
if (cfg.dependencies) {
|
||||
arrfor(array(cfg.dependencies), function(alias, i) {
|
||||
var dep_pkg = cfg.dependencies[alias]
|
||||
Shop.open_package_dylib(dep_pkg)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var dl_path = get_lib_path(pkg)
|
||||
if (fd.is_file(dl_path)) {
|
||||
if (!open_dls[dl_path]) {
|
||||
try {
|
||||
open_dls[dl_path] = os.dylib_open(dl_path)
|
||||
} catch (e) {
|
||||
dylib_visited[pkg] = false
|
||||
throw e
|
||||
}
|
||||
open_dls[dl_path] = os.dylib_open(dl_path)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -642,8 +635,8 @@ function resolve_c_symbol(path, package_context) {
|
||||
|
||||
// If no package context, only check core internal symbols
|
||||
if (!package_context || package_context == 'core') {
|
||||
path = replace(path, '/', '_')
|
||||
var core_sym = `js_${path}_use`
|
||||
var _path = replace(path, '/', '_')
|
||||
var core_sym = `js_${_path}_use`
|
||||
if (os.internal_exists(core_sym)) {
|
||||
return {
|
||||
symbol: function() { return os.load_internal(core_sym) },
|
||||
@@ -836,14 +829,13 @@ function execute_module(info)
|
||||
// C only
|
||||
used = call_c_module(c_resolve)
|
||||
} else {
|
||||
throw Error(`Module ${info.path} could not be found`)
|
||||
print(`Module ${info.path} could not be found`); disrupt
|
||||
}
|
||||
|
||||
// if (is_function(used))
|
||||
// throw Error('C module loader returned a function; did you forget to call it?')
|
||||
|
||||
if (!used)
|
||||
throw Error(`Module ${info} returned null`)
|
||||
if (!used) { print(`Module ${info} returned null`); disrupt }
|
||||
|
||||
// stone(used)
|
||||
return used
|
||||
@@ -852,16 +844,14 @@ function execute_module(info)
|
||||
function get_module(path, package_context) {
|
||||
var info = resolve_module_info(path, package_context)
|
||||
|
||||
if (!info)
|
||||
throw Error(`Module ${path} could not be found in ${package_context}`)
|
||||
if (!info) { print(`Module ${path} could not be found in ${package_context}`); disrupt }
|
||||
|
||||
return execute_module(info)
|
||||
}
|
||||
|
||||
Shop.use = function use(path, package_context) {
|
||||
var info = resolve_module_info(path, package_context)
|
||||
if (!info)
|
||||
throw Error(`Module ${path} could not be found in ${package_context}`)
|
||||
if (!info) { print(`Module ${path} could not be found in ${package_context}`); disrupt }
|
||||
|
||||
if (use_cache[info.cache_key])
|
||||
return use_cache[info.cache_key]
|
||||
@@ -889,13 +879,13 @@ function fetch_remote_hash(pkg) {
|
||||
if (!api_url) return null
|
||||
|
||||
|
||||
try {
|
||||
var _fetch_hash = function() {
|
||||
var resp = http.fetch(api_url)
|
||||
return Shop.extract_commit_hash(pkg, text(resp))
|
||||
} catch (e) {
|
||||
log.console("Warning: Could not check for updates for " + pkg)
|
||||
} disruption {
|
||||
return null
|
||||
}
|
||||
return _fetch_hash()
|
||||
}
|
||||
|
||||
// Download a zip for a package at a specific commit and cache it
|
||||
@@ -909,14 +899,14 @@ function download_zip(pkg, commit_hash) {
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
var _download = function() {
|
||||
var zip_blob = http.fetch(download_url)
|
||||
fd.slurpwrite(cache_path, zip_blob)
|
||||
return zip_blob
|
||||
} catch (e) {
|
||||
log.error("Download failed for " + pkg + ": " + e)
|
||||
} disruption {
|
||||
return null
|
||||
}
|
||||
return _download()
|
||||
}
|
||||
|
||||
// Get zip from cache, returns null if not cached
|
||||
@@ -1028,7 +1018,7 @@ Shop.extract = function(pkg) {
|
||||
var zip_blob = get_package_zip(pkg)
|
||||
|
||||
if (!zip_blob)
|
||||
throw Error("No zip blob available for " + pkg)
|
||||
print("No zip blob available for " + pkg); disrupt
|
||||
|
||||
// Extract zip for remote package
|
||||
install_zip(zip_blob, target_dir)
|
||||
@@ -1113,7 +1103,7 @@ Shop.update = function(pkg) {
|
||||
|
||||
function install_zip(zip_blob, target_dir) {
|
||||
var zip = miniz.read(zip_blob)
|
||||
if (!zip) throw Error("Failed to read zip archive")
|
||||
if (!zip) { print("Failed to read zip archive"); disrupt }
|
||||
|
||||
if (fd.is_link(target_dir)) fd.unlink(target_dir)
|
||||
if (fd.is_dir(target_dir)) fd.rmdir(target_dir, 1)
|
||||
@@ -1165,14 +1155,14 @@ Shop.get = function(pkg) {
|
||||
if (!lock[pkg]) {
|
||||
var info = Shop.resolve_package_info(pkg)
|
||||
if (!info) {
|
||||
throw Error("Invalid package: " + pkg)
|
||||
print("Invalid package: " + pkg); disrupt
|
||||
}
|
||||
|
||||
var commit = null
|
||||
if (info != 'local') {
|
||||
commit = fetch_remote_hash(pkg)
|
||||
if (!commit) {
|
||||
throw Error("Could not resolve commit for " + pkg)
|
||||
print("Could not resolve commit for " + pkg); disrupt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1188,8 +1178,6 @@ Shop.get = function(pkg) {
|
||||
// Compile a module
|
||||
// List all files in a package
|
||||
|
||||
var debug = use('debug')
|
||||
|
||||
Shop.file_reload = function(file)
|
||||
{
|
||||
var info = Shop.file_info(file)
|
||||
|
||||
Reference in New Issue
Block a user