This commit is contained in:
2026-01-18 08:54:48 -06:00
parent a7a323a74e
commit bbd2d298ba
18 changed files with 258 additions and 256 deletions

107
bench.ce
View File

@@ -36,19 +36,19 @@ function median(arr) {
function mean(arr) {
if (arr.length == 0) return 0
var sum = 0
for (var i = 0; i < arr.length; i++) {
sum += arr[i]
}
arrfor(arr, function(val) {
sum += val
})
return sum / arr.length
}
function stddev(arr, mean_val) {
if (arr.length < 2) return 0
var sum_sq_diff = 0
for (var i = 0; i < arr.length; i++) {
var diff = arr[i] - mean_val
arrfor(arr, function(val) {
var diff = val - mean_val
sum_sq_diff += diff * diff
}
})
return math.sqrt(sum_sq_diff / (arr.length - 1))
}
@@ -63,18 +63,18 @@ function percentile(arr, p) {
function min_val(arr) {
if (arr.length == 0) return 0
var m = arr[0]
for (var i = 1; i < arr.length; i++) {
if (arr[i] < m) m = arr[i]
}
arrfor(slice(arr, 1), function(val) {
if (val < m) m = val
})
return m
}
function max_val(arr) {
if (arr.length == 0) return 0
var m = arr[0]
for (var i = 1; i < arr.length; i++) {
if (arr[i] > m) m = arr[i]
}
arrfor(slice(arr, 1), function(val) {
if (val > m) m = val
})
return m
}
@@ -177,19 +177,18 @@ function collect_benches(package_name, specific_bench) {
var files = pkg.list_files(package_name)
var bench_files = []
for (var i = 0; i < files.length; i++) {
var f = files[i]
arrfor(files, function(f) {
if (starts_with(f, "benches/") && ends_with(f, ".cm")) {
if (specific_bench) {
var bench_name = text(f, 0, -3)
var match_name = specific_bench
if (!starts_with(match_name, 'benches/')) match_name = 'benches/' + match_name
var match_base = ends_with(match_name, '.cm') ? text(match_name, 0, -3) : match_name
if (bench_name != match_base) continue
if (bench_name != match_base) return
}
bench_files.push(f)
}
}
})
return bench_files
}
@@ -305,7 +304,7 @@ function run_single_bench(bench_fn, bench_name) {
}
// Warmup phase
for (var i = 0; i < WARMUP_BATCHES; i++) {
arrfor(range(WARMUP_BATCHES), function(i) {
// Ensure batch_size is valid before warmup
if (!is_number(batch_size) || batch_size < 1) {
var type_str = is_null(batch_size) ? 'null' : is_number(batch_size) ? 'number' : is_text(batch_size) ? 'text' : is_object(batch_size) ? 'object' : is_array(batch_size) ? 'array' : is_function(batch_size) ? 'function' : is_logical(batch_size) ? 'logical' : 'unknown'
@@ -331,7 +330,7 @@ function run_single_bench(bench_fn, bench_name) {
}
// Measurement phase - collect SAMPLES timing samples
for (var i = 0; i < SAMPLES; i++) {
arrfor(range(SAMPLES), function(i) {
// Double-check batch_size is valid (should never happen, but defensive)
if (!is_number(batch_size) || batch_size < 1) {
batch_size = 1
@@ -425,8 +424,7 @@ function run_benchmarks(package_name, specific_bench) {
if (package_name) log.console(`Running benchmarks for ${package_name}`)
else log.console(`Running benchmarks for local package`)
for (var i = 0; i < bench_files.length; i++) {
var f = bench_files[i]
arrfor(bench_files, function(f) {
var mod_path = text(f, 0, -3)
var file_result = {
@@ -452,8 +450,7 @@ function run_benchmarks(package_name, specific_bench) {
if (benches.length > 0) {
log.console(` ${f}`)
for (var j = 0; j < benches.length; j++) {
var b = benches[j]
arrfor(benches, function(b) {
try {
var result = run_single_bench(b.fn, b.name)
result.package = pkg_result.package
@@ -507,18 +504,18 @@ if (all_pkgs) {
}
var packages = shop.list_packages()
for (var i = 0; i < packages.length; i++) {
all_results.push(run_benchmarks(packages[i], null))
}
arrfor(packages, function(pkg) {
all_results.push(run_benchmarks(pkg, null))
})
} else {
all_results.push(run_benchmarks(target_pkg, target_bench))
}
// Calculate totals
var total_benches = 0
for (var i = 0; i < all_results.length; i++) {
total_benches += all_results[i].total
}
arrfor(all_results, function(result) {
total_benches += result.total
})
log.console(`----------------------------------------`)
log.console(`Benchmarks: ${total_benches} total`)
@@ -535,34 +532,28 @@ Total benchmarks: ${total_benches}
=== SUMMARY ===
`
for (var i = 0; i < all_results.length; i++) {
var pkg_res = all_results[i]
if (pkg_res.total == 0) continue
arrfor(all_results, function(pkg_res) {
if (pkg_res.total == 0) return
txt_report += `Package: ${pkg_res.package}\n`
for (var j = 0; j < pkg_res.files.length; j++) {
var f = pkg_res.files[j]
arrfor(pkg_res.files, function(f) {
txt_report += ` ${f.name}\n`
for (var k = 0; k < f.benchmarks.length; k++) {
var b = f.benchmarks[k]
arrfor(f.benchmarks, function(b) {
if (b.error) {
txt_report += ` ERROR ${b.name}: ${b.error}\n`
} else {
txt_report += ` ${b.name}: ${format_ns(b.median_ns)}/op (${format_ops(b.ops_per_sec)})\n`
}
}
}
}
})
})
})
txt_report += `\n=== DETAILED RESULTS ===\n`
for (var i = 0; i < all_results.length; i++) {
var pkg_res = all_results[i]
if (pkg_res.total == 0) continue
arrfor(all_results, function(pkg_res) {
if (pkg_res.total == 0) return
for (var j = 0; j < pkg_res.files.length; j++) {
var f = pkg_res.files[j]
for (var k = 0; k < f.benchmarks.length; k++) {
var b = f.benchmarks[k]
if (b.error) continue
arrfor(pkg_res.files, function(f) {
arrfor(f.benchmarks, function(b) {
if (b.error) return
txt_report += `\n${pkg_res.package}::${b.name}\n`
txt_report += ` batch_size: ${b.batch_size} samples: ${b.samples}\n`
@@ -574,30 +565,28 @@ Total benchmarks: ${total_benches}
txt_report += ` p95: ${format_ns(b.p95_ns)}\n`
txt_report += ` p99: ${format_ns(b.p99_ns)}\n`
txt_report += ` ops/s: ${format_ops(b.ops_per_sec)}\n`
}
}
}
})
})
})
testlib.ensure_dir(report_dir)
fd.slurpwrite(`${report_dir}/bench.txt`, stone(blob(txt_report)))
log.console(`Report written to ${report_dir}/bench.txt`)
// Generate JSON per package
for (var i = 0; i < all_results.length; i++) {
var pkg_res = all_results[i]
if (pkg_res.total == 0) continue
arrfor(all_results, function(pkg_res) {
if (pkg_res.total == 0) return
var pkg_benches = []
for (var j = 0; j < pkg_res.files.length; j++) {
var f = pkg_res.files[j]
for (var k = 0; k < f.benchmarks.length; k++) {
pkg_benches.push(f.benchmarks[k])
}
}
arrfor(pkg_res.files, function(f) {
arrfor(f.benchmarks, function(benchmark) {
pkg_benches.push(benchmark)
})
})
var json_path = `${report_dir}/${replace(pkg_res.package, /\//, '_')}.json`
fd.slurpwrite(json_path, stone(blob(json.encode(pkg_benches))))
}
})
}
generate_reports()

View File

@@ -86,10 +86,10 @@ if (target && !build.has_target(target)) {
var packages = shop.list_packages()
log.console('Preparing packages...')
for (var package of packages) {
if (package == 'core') continue
arrfor(packages, function(package) {
if (package == 'core') return
shop.extract(package)
}
})
if (target_package) {
// Build single package

105
build.cm
View File

@@ -34,9 +34,9 @@ function replace_sigils(str) {
// Replace sigils in an array of flags
function replace_sigils_array(flags) {
var result = []
for (var i = 0; i < flags.length; i++) {
result.push(replace_sigils(flags[i]))
}
arrfor(flags, function(flag) {
result.push(replace_sigils(flag))
})
return result
}
@@ -134,18 +134,17 @@ Build.compile_file = function(pkg, file, target, buildtype = 'release') {
cmd_parts.push('-I"' + pkg_dir + '"')
// Add package CFLAGS (resolve relative -I paths)
for (var i = 0; i < cflags.length; i++) {
var flag = cflags[i]
arrfor(cflags, function(flag) {
if (starts_with(flag, '-I') && !starts_with(flag, '-I/')) {
flag = '-I"' + pkg_dir + '/' + text(flag, 2) + '"'
}
cmd_parts.push(flag)
}
})
// Add target CFLAGS
for (var i = 0; i < target_cflags.length; i++) {
cmd_parts.push(target_cflags[i])
}
arrfor(target_cflags, function(flag) {
cmd_parts.push(flag)
})
cmd_parts.push('"' + src_path + '"')
@@ -182,10 +181,10 @@ Build.build_package = function(pkg, target = Build.detect_host_target(), exclude
var c_files = pkg_tools.get_c_files(pkg, target, exclude_main)
var objects = []
for (var i = 0; i < c_files.length; i++) {
var obj = Build.compile_file(pkg, c_files[i], target, buildtype)
arrfor(c_files, function(file) {
var obj = Build.compile_file(pkg, file, target, buildtype)
objects.push(obj)
}
})
return objects
}
@@ -203,16 +202,16 @@ function compute_link_key(objects, ldflags, target_ldflags, target, cc) {
var parts = []
parts.push('target:' + target)
parts.push('cc:' + cc)
for (var i = 0; i < sorted_objects.length; i++) {
arrfor(sorted_objects, function(obj) {
// Object paths are content-addressed, so the path itself is the hash
parts.push('obj:' + sorted_objects[i])
}
for (var i = 0; i < ldflags.length; i++) {
parts.push('ldflag:' + ldflags[i])
}
for (var i = 0; i < target_ldflags.length; i++) {
parts.push('target_ldflag:' + target_ldflags[i])
}
parts.push('obj:' + obj)
})
arrfor(ldflags, function(flag) {
parts.push('ldflag:' + flag)
})
arrfor(target_ldflags, function(flag) {
parts.push('target_ldflag:' + flag)
})
return content_hash(text(parts, '\n'))
}
@@ -248,13 +247,12 @@ Build.build_dynamic = function(pkg, target = Build.detect_host_target(), buildty
// Resolve relative -L paths in ldflags for hash computation
var resolved_ldflags = []
for (var i = 0; i < ldflags.length; i++) {
var flag = ldflags[i]
arrfor(ldflags, function(flag) {
if (starts_with(flag, '-L') && !starts_with(flag, '-L/')) {
flag = '-L"' + pkg_dir + '/' + text(flag, 2) + '"'
}
resolved_ldflags.push(flag)
}
})
// Compute link key
var link_key = compute_link_key(objects, resolved_ldflags, target_ldflags, target, cc)
@@ -307,20 +305,20 @@ Build.build_dynamic = function(pkg, target = Build.detect_host_target(), buildty
// Add .cell/local to library search path
cmd_parts.push('-L"' + local_dir + '"')
for (var i = 0; i < objects.length; i++) {
cmd_parts.push('"' + objects[i] + '"')
}
arrfor(objects, function(obj) {
cmd_parts.push('"' + obj + '"')
})
// Do NOT link against core library - symbols resolved at dlopen time
// Add LDFLAGS
for (var i = 0; i < resolved_ldflags.length; i++) {
cmd_parts.push(resolved_ldflags[i])
}
arrfor(resolved_ldflags, function(flag) {
cmd_parts.push(flag)
})
for (var i = 0; i < target_ldflags.length; i++) {
cmd_parts.push(target_ldflags[i])
}
arrfor(target_ldflags, function(flag) {
cmd_parts.push(flag)
})
cmd_parts.push('-o', '"' + store_path + '"')
@@ -356,16 +354,15 @@ Build.build_static = function(packages, target = Build.detect_host_target(), out
var seen_flags = {}
// Compile all packages
for (var i = 0; i < packages.length; i++) {
var pkg = packages[i]
arrfor(packages, function(pkg) {
var is_core = (pkg == 'core')
// For core, include main.c; for others, exclude it
var objects = Build.build_package(pkg, target, !is_core, buildtype)
for (var j = 0; j < objects.length; j++) {
all_objects.push(objects[j])
}
arrfor(objects, function(obj) {
all_objects.push(obj)
})
// Collect LDFLAGS (with sigil replacement)
var ldflags = replace_sigils_array(pkg_tools.get_flags(pkg, 'LDFLAGS', target))
@@ -375,16 +372,15 @@ Build.build_static = function(packages, target = Build.detect_host_target(), out
var ldflags_key = pkg + ':' + text(ldflags, ' ')
if (!seen_flags[ldflags_key]) {
seen_flags[ldflags_key] = true
for (var j = 0; j < ldflags.length; j++) {
var flag = ldflags[j]
arrfor(ldflags, function(flag) {
// Resolve relative -L paths
if (starts_with(flag, '-L') && !starts_with(flag, '-L/')) {
flag = '-L"' + pkg_dir + '/' + text(flag, 2) + '"'
}
all_ldflags.push(flag)
}
})
}
}
})
if (all_objects.length == 0) {
throw Error('No object files to link')
@@ -401,17 +397,17 @@ Build.build_static = function(packages, target = Build.detect_host_target(), out
var cmd_parts = [cc]
for (var i = 0; i < all_objects.length; i++) {
cmd_parts.push('"' + all_objects[i] + '"')
}
arrfor(all_objects, function(obj) {
cmd_parts.push('"' + obj + '"')
})
for (var i = 0; i < all_ldflags.length; i++) {
cmd_parts.push(all_ldflags[i])
}
arrfor(all_ldflags, function(flag) {
cmd_parts.push(flag)
})
for (var i = 0; i < target_ldflags.length; i++) {
cmd_parts.push(target_ldflags[i])
}
arrfor(target_ldflags, function(flag) {
cmd_parts.push(flag)
})
cmd_parts.push('-o', '"' + output + '"')
@@ -450,9 +446,8 @@ Build.build_all_dynamic = function(target, buildtype = 'release') {
}
// Build other packages
for (var i = 0; i < packages.length; i++) {
var pkg = packages[i]
if (pkg == 'core') continue
arrfor(packages, function(pkg) {
if (pkg == 'core') return
try {
var lib = Build.build_dynamic(pkg, target, buildtype)
@@ -462,7 +457,7 @@ Build.build_all_dynamic = function(target, buildtype = 'release') {
log.error(e)
results.push({ package: pkg, error: e })
}
}
})
return results
}

View File

@@ -94,12 +94,12 @@ function resolve(path, must_exist) {
// Find named mount
var mount = null
for (var m of mounts) {
arrfor(mounts, function(m) {
if (m.name == mount_name) {
mount = m
break
return true
}
}
}, false, true)
if (!mount) {
throw Error("Unknown mount point: @" + mount_name)
@@ -109,10 +109,16 @@ function resolve(path, must_exist) {
}
// Search path
for (var mount of mounts) {
var found_mount = null
arrfor(mounts, function(mount) {
if (mount_exists(mount, path)) {
return { mount: mount, path: path }
found_mount = { mount: mount, path: path }
return true
}
}, false, true)
if (found_mount) {
return found_mount
}
if (must_exist) {
@@ -314,7 +320,7 @@ function enumerate(path, recurse) {
var list = fd.readdir(curr_full)
if (!list) return
for (var item of list) {
arrfor(list, function(item) {
var item_rel = rel_prefix ? rel_prefix + "/" + item : item
results.push(item_rel)
@@ -324,7 +330,7 @@ function enumerate(path, recurse) {
visit(fd.join_paths(curr_full, item), item_rel)
}
}
}
})
}
if (res.mount.type == 'fs') {
@@ -341,10 +347,10 @@ function enumerate(path, recurse) {
// Use a set to avoid duplicates if we are simulating directories
var seen = {}
for (var p of all) {
arrfor(all, function(p) {
if (starts_with(p, prefix)) {
var rel = text(p, prefix_len)
if (rel.length == 0) continue
if (rel.length == 0) return
if (!recurse) {
var slash = search(rel, '/')
@@ -358,7 +364,7 @@ function enumerate(path, recurse) {
results.push(rel)
}
}
}
})
}
return results
@@ -370,17 +376,25 @@ function globfs(globs, dir) {
var results = []
function check_neg(path) {
for (var g of globs) {
if (starts_with(g, "!") && wildstar.match(text(g, 1), path, wildstar.WM_WILDSTAR)) return true;
}
return false;
var result = false
arrfor(globs, function(g) {
if (starts_with(g, "!") && wildstar.match(text(g, 1), path, wildstar.WM_WILDSTAR)) {
result = true
return true
}
}, false, true)
return result
}
function check_pos(path) {
for (var g of globs) {
if (!starts_with(g, "!") && wildstar.match(g, path, wildstar.WM_WILDSTAR)) return true;
}
return false;
var result = false
arrfor(globs, function(g) {
if (!starts_with(g, "!") && wildstar.match(g, path, wildstar.WM_WILDSTAR)) {
result = true
return true
}
}, false, true)
return result
}
function visit(curr_full, rel_prefix) {
@@ -389,7 +403,7 @@ function globfs(globs, dir) {
var list = fd.readdir(curr_full)
if (!list) return
for (var item of list) {
arrfor(list, function(item) {
var item_rel = rel_prefix ? rel_prefix + "/" + item : item
var child_full = fd.join_paths(curr_full, item)
@@ -404,7 +418,7 @@ function globfs(globs, dir) {
results.push(item_rel)
}
}
}
})
}
if (res.mount.type == 'fs') {
@@ -418,16 +432,16 @@ function globfs(globs, dir) {
var prefix = res.path ? res.path + "/" : ""
var prefix_len = prefix.length
for (var p of all) {
arrfor(all, function(p) {
if (starts_with(p, prefix)) {
var rel = text(p, prefix_len)
if (rel.length == 0) continue
if (rel.length == 0) return
if (!check_neg(rel) && check_pos(rel)) {
results.push(rel)
}
}
}
})
}
return results

View File

@@ -99,9 +99,9 @@ if (is_shop_scope) {
if (deep) {
try {
var deps = pkg.gather_dependencies(scope)
for (var dep of deps) {
arrfor(deps, function(dep) {
packages_to_clean.push(dep)
}
})
} catch (e) {
// Skip if can't read dependencies
}
@@ -124,8 +124,8 @@ if (clean_build) {
}
} else {
// Clean specific package libraries
for (var p of packages_to_clean) {
if (p == 'core') continue
arrfor(packages_to_clean, function(p) {
if (p == 'core') return
var lib_name = shop.lib_name_for_package(p)
var dylib_ext = '.dylib'
@@ -144,7 +144,7 @@ if (clean_build) {
if (fd.is_file(dll_path)) {
files_to_delete.push(dll_path)
}
}
})
}
}
@@ -156,14 +156,14 @@ if (clean_fetch) {
}
} else {
// Clean specific package directories
for (var p of packages_to_clean) {
if (p == 'core') continue
arrfor(packages_to_clean, function(p) {
if (p == 'core') return
var pkg_dir = shop.get_package_dir(p)
if (fd.is_dir(pkg_dir) || fd.is_link(pkg_dir)) {
dirs_to_delete.push(pkg_dir)
}
}
})
}
}
@@ -173,17 +173,17 @@ if (dry_run) {
if (files_to_delete.length == 0 && dirs_to_delete.length == 0) {
log.console(" (nothing to clean)")
} else {
for (var f of files_to_delete) {
arrfor(files_to_delete, function(f) {
log.console(" [file] " + f)
}
for (var d of dirs_to_delete) {
})
arrfor(dirs_to_delete, function(d) {
log.console(" [dir] " + d)
}
})
}
} else {
var deleted_count = 0
for (var f of files_to_delete) {
arrfor(files_to_delete, function(f) {
try {
fd.unlink(f)
log.console("Deleted: " + f)
@@ -191,9 +191,9 @@ if (dry_run) {
} catch (e) {
log.error("Failed to delete " + f + ": " + e)
}
}
})
for (var d of dirs_to_delete) {
arrfor(dirs_to_delete, function(d) {
try {
if (fd.is_link(d)) {
fd.unlink(d)
@@ -205,7 +205,7 @@ if (dry_run) {
} catch (e) {
log.error("Failed to delete " + d + ": " + e)
}
}
})
if (deleted_count == 0) {
log.console("Nothing to clean.")

View File

@@ -37,10 +37,10 @@ function parse_key(key) {
// Get a value from nested object using path
function get_nested(obj, path) {
var current = obj
for (var segment of path) {
arrfor(path, function(segment) {
if (is_null(current) || !is_object(current)) return null
current = current[segment]
}
})
return current
}

28
fd.cm
View File

@@ -43,17 +43,25 @@ fd.globfs = function(globs, dir) {
var results = []
function check_neg(path) {
for (var g of globs) {
if (starts_with(g, "!") && wildstar.match(text(g, 1), path, wildstar.WM_WILDSTAR)) return true;
}
return false;
var found = false;
arrfor(globs, function(g) {
if (starts_with(g, "!") && wildstar.match(text(g, 1), path, wildstar.WM_WILDSTAR)) {
found = true;
return true;
}
}, null, true);
return found;
}
function check_pos(path) {
for (var g of globs) {
if (!starts_with(g, "!") && wildstar.match(g, path, wildstar.WM_WILDSTAR)) return true;
}
return false;
var found = false;
arrfor(globs, function(g) {
if (!starts_with(g, "!") && wildstar.match(g, path, wildstar.WM_WILDSTAR)) {
found = true;
return true;
}
}, null, true);
return found;
}
function visit(curr_full, rel_prefix) {
@@ -62,7 +70,7 @@ fd.globfs = function(globs, dir) {
var list = fd.readdir(curr_full)
if (!list) return
for (var item of list) {
arrfor(list, function(item) {
var item_rel = rel_prefix ? rel_prefix + "/" + item : item
var child_full = join_paths(curr_full, item)
@@ -77,7 +85,7 @@ fd.globfs = function(globs, dir) {
results.push(item_rel)
}
}
}
});
}
var st = fd.stat(dir)

View File

@@ -46,11 +46,11 @@ if (target_pkg) {
}
var remote_count = 0
for (var pkg of packages_to_fetch) {
arrfor(packages_to_fetch, function(pkg) {
var entry = lock[pkg]
if (pkg != 'core' && (!entry || entry.type != 'local'))
remote_count++
}
}, null, null)
if (remote_count > 0)
log.console(`Fetching ${text(remote_count)} remote package(s)...`)
@@ -59,14 +59,14 @@ var downloaded_count = 0
var cached_count = 0
var fail_count = 0
for (var pkg of packages_to_fetch) {
arrfor(packages_to_fetch, function(pkg) {
// Skip core (handled separately)
if (pkg == 'core') continue
if (pkg == 'core') return
var result = shop.fetch(pkg)
if (result.status == 'local') {
// Local packages are just symlinks, nothing to fetch
continue
return
} else if (result.status == 'cached') {
cached_count++
} else if (result.status == 'downloaded') {
@@ -76,7 +76,7 @@ for (var pkg of packages_to_fetch) {
log.error(" Failed: " + pkg + (result.message ? " - " + result.message : ""))
fail_count++
}
}
}, null, null)
log.console("")
var parts = []

View File

@@ -112,11 +112,11 @@ var roots = []
if (show_world) {
// Use all packages in shop as roots
var packages = shop.list_packages()
for (var p of packages) {
arrfor(packages, function(p) {
if (p != 'core') {
roots.push(p)
}
}
})
} else {
// Default to current directory
if (!target_locator) {
@@ -134,9 +134,9 @@ if (show_world) {
roots.push(target_locator)
}
for (var root of roots) {
arrfor(roots, function(root) {
gather_graph(root, {})
}
})
// Output based on format
if (format == 'tree') {
@@ -157,11 +157,11 @@ if (format == 'tree') {
// Get children
var children = []
for (var e of edges) {
arrfor(edges, function(e) {
if (e.from == locator) {
children.push(e)
}
}
})
for (var i = 0; i < children.length; i++) {
var child_prefix = prefix + (is_last ? " " : "| ")
@@ -173,11 +173,11 @@ if (format == 'tree') {
log.console(roots[i])
var children = []
for (var e of edges) {
arrfor(edges, function(e) {
if (e.from == roots[i]) {
children.push(e)
}
}
})
for (var j = 0; j < children.length; j++) {
print_tree(children[j].to, "", j == children.length - 1, {})
@@ -209,12 +209,12 @@ if (format == 'tree') {
log.console("")
// Edges
for (var e of edges) {
arrfor(edges, function(e) {
var from_id = replace(e.from, /[^a-zA-Z0-9]/g, '_')
var to_id = replace(e.to, /[^a-zA-Z0-9]/g, '_')
var label = e.alias != e.to ? 'label="' + e.alias + '"' : ''
log.console(' ' + from_id + ' -> ' + to_id + (label ? ' [' + label + ']' : '') + ';')
}
})
log.console("}")

View File

@@ -137,17 +137,17 @@ gather_packages(locator)
if (dry_run) {
log.console("Would install:")
for (var p of packages_to_install) {
arrfor(packages_to_install, function(p) {
var lock = shop.load_lock()
var exists = lock[p] != null
log.console(" " + p + (exists ? " (already installed)" : ""))
}
})
if (skipped_packages.length > 0) {
log.console("")
log.console("Would skip (missing local paths):")
for (var p of skipped_packages) {
arrfor(skipped_packages, function(p) {
log.console(" " + p)
}
})
}
$stop()
}
@@ -171,10 +171,10 @@ function install_package(pkg_locator) {
}
}
for (var p of packages_to_install) {
arrfor(packages_to_install, function(p) {
log.console(" Installing " + p + "...")
install_package(p)
}
})
var summary = "Installed " + text(packages_to_install.length) + " package(s)."
if (skipped_packages.length > 0) {

18
list.ce
View File

@@ -122,8 +122,8 @@ if (mode == 'local') {
var linked_pkgs = []
var remote_pkgs = []
for (var p of packages) {
if (p == 'core') continue
arrfor(packages, function(p) {
if (p == 'core') return
var lock_entry = lock[p]
var link_target = links[p]
@@ -134,32 +134,32 @@ if (mode == 'local') {
} else {
remote_pkgs.push(p)
}
}
})
if (linked_pkgs.length > 0) {
log.console("Linked packages:")
for (var p of linked_pkgs) {
arrfor(linked_pkgs, function(p) {
var target = links[p]
log.console(" " + p + " -> " + target)
}
})
log.console("")
}
if (local_pkgs.length > 0) {
log.console("Local packages:")
for (var p of local_pkgs) {
arrfor(local_pkgs, function(p) {
log.console(" " + p)
}
})
log.console("")
}
if (remote_pkgs.length > 0) {
log.console("Remote packages:")
for (var p of remote_pkgs) {
arrfor(remote_pkgs, function(p) {
var lock_entry = lock[p]
var commit = lock_entry && lock_entry.commit ? " @" + text(lock_entry.commit, 0, 8) : ""
log.console(" " + p + commit)
}
})
log.console("")
}

View File

@@ -104,10 +104,10 @@ for (var i = 0; i < packages.length; i++) {
packages = unique_packages
log.console('Preparing packages...')
for (var package of packages) {
if (package == 'core') continue
arrfor(packages, function(package) {
if (package == 'core') return
shop.extract(package)
}
})
log.console('Building static binary from ' + text(packages.length) + ' packages: ' + text(packages, ', '))

View File

@@ -24,12 +24,12 @@ function list(archive_path) {
}
var files = archive.list()
for (var f of files) {
arrfor(files, function(f) {
var s = archive.stat(f)
// Format: index hash size path
// We don't have index/hash easily available in JS binding yet, just size/path
log.console(`${f} (${s.size} bytes)`)
}
})
archive.close()
}
@@ -48,7 +48,7 @@ function unpack(archive_path) {
}
var files = archive.list()
for (var f of files) {
arrfor(files, function(f) {
var data = archive.read(f)
if (data) {
// Ensure directory exists
@@ -57,17 +57,17 @@ function unpack(archive_path) {
// recursive mkdir
var parts = array(dir, '/')
var curr = "."
for (var p of parts) {
arrfor(parts, function(p) {
curr += "/" + p
try { fd.mkdir(curr) } catch(e) {}
}
})
}
var fh = fd.open(f, "w")
fd.write(fh, data)
fd.close(fh)
log.console("Extracted " + f)
}
}
})
archive.close()
}
@@ -89,11 +89,11 @@ function pack(sources, archive_path, read_dir) {
if (st.isDirectory) {
var list = fd.readdir(full_path)
for (var item of list) {
if (item == "." || item == "..") continue
arrfor(list, function(item) {
if (item == "." || item == "..") return
var sub = path == "." ? item : path + "/" + item
add_recursive(sub)
}
})
} else {
var data = fd.slurp(full_path)
if (data) {
@@ -103,9 +103,9 @@ function pack(sources, archive_path, read_dir) {
}
}
for (var s of sources) {
arrfor(sources, function(s) {
add_recursive(s)
}
})
writer.finalize()
log.console("Created " + archive_path)

View File

@@ -59,37 +59,37 @@ if (prune) {
// Build set of all needed packages (excluding target)
var needed = {}
for (var p of all_packages) {
if (p == target_pkg || p == 'core') continue
arrfor(all_packages, function(p) {
if (p == target_pkg || p == 'core') return
// Mark this package and its deps as needed
needed[p] = true
try {
var deps = pkg.gather_dependencies(p)
for (var dep of deps) {
arrfor(deps, function(dep) {
needed[dep] = true
}
})
} catch (e) {
// Skip if can't read deps
}
}
})
// Find packages that are NOT needed
for (var p of all_packages) {
if (p == 'core') continue
arrfor(all_packages, function(p) {
if (p == 'core') return
if (!needed[p] && find(packages_to_remove, p) == null) {
packages_to_remove.push(p)
}
}
})
}
if (dry_run) {
log.console("Would remove:")
for (var p of packages_to_remove) {
arrfor(packages_to_remove, function(p) {
log.console(" " + p)
}
})
} else {
for (var p of packages_to_remove) {
arrfor(packages_to_remove, function(p) {
// Remove any link for this package
if (link.is_linked(p)) {
link.remove(p)
@@ -97,7 +97,7 @@ if (dry_run) {
// Remove from shop
shop.remove(p)
}
})
log.console("Removed " + text(packages_to_remove.length) + " package(s).")
}

View File

@@ -11,7 +11,7 @@ if (args.length < 1) {
return
}
var query = args[0])
var query = args[0]
var found_packages = []
var found_modules = []
var found_actors = []
@@ -19,31 +19,31 @@ var found_actors = []
// Search through all installed packages
var packages = shop.list_packages()
for (var package_name of packages) {
arrfor(packages, function(package_name) {
// Check if package name matches
if (search(package_name), query) != null) {
if (search(package_name, query) != null) {
found_packages.push(package_name)
}
// Search modules and actors within the package
try {
var modules = pkg.list_modules(package_name)
for (var mod of modules) {
if (search(mod), query) != null) {
arrfor(modules, function(mod) {
if (search(mod, query) != null) {
found_modules.push(package_name + ':' + mod)
}
}
})
var actors = pkg.list_programs(package_name)
for (var actor of actors) {
if (search(actor), query) != null) {
arrfor(actors, function(actor) {
if (search(actor, query) != null) {
found_actors.push(package_name + ':' + actor)
}
}
})
} catch (e) {
// Skip packages that can't be read
}
}
})
// Print results
var total = found_packages.length + found_modules.length + found_actors.length
@@ -56,25 +56,25 @@ if (total == 0) {
if (found_packages.length > 0) {
log.console("Packages:")
for (var p of found_packages) {
arrfor(found_packages, function(p) {
log.console(" " + p)
}
})
log.console("")
}
if (found_modules.length > 0) {
log.console("Modules:")
for (var m of found_modules) {
arrfor(found_modules, function(m) {
log.console(" " + m)
}
})
log.console("")
}
if (found_actors.length > 0) {
log.console("Actors:")
for (var a of found_actors) {
arrfor(found_actors, function(a) {
log.console(" " + a)
}
})
}
}

View File

@@ -29281,9 +29281,6 @@ static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val,
return ret;
}
static const JSCFunctionListEntry js_function_proto_funcs[] = {
};
/* Error class */
static JSValue iterator_to_array(JSContext *ctx, JSValueConst items)
@@ -37073,7 +37070,6 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
js_object_proto_funcs, countof(js_object_proto_funcs));
/* Function */
JS_SetPropertyFunctionList(ctx, ctx->function_proto, js_function_proto_funcs, countof(js_function_proto_funcs));
ctx->function_ctor = JS_NewCFunctionMagic(ctx, js_function_constructor,
"Function", 1, JS_CFUNC_constructor_or_func_magic,
0);

View File

@@ -132,7 +132,7 @@ if (run_build && updated_packages.length > 0) {
log.console("")
log.console("Building updated packages...")
for (var pkg of updated_packages) {
arrfor(updated_packages, function(pkg) {
try {
var lib = build.build_dynamic(pkg, target_triple, 'release')
if (lib) {
@@ -141,7 +141,7 @@ if (run_build && updated_packages.length > 0) {
} catch (e) {
log.error(" Failed to build " + pkg + ": " + e)
}
}
}, null, null)
}
$stop()

View File

@@ -213,9 +213,9 @@ if (scope == 'shop') {
// Gather all dependencies
var all_deps = pkg.gather_dependencies(locator)
packages_to_verify.push(locator)
for (var dep of all_deps) {
arrfor(all_deps, function(dep) {
packages_to_verify.push(dep)
}
})
} else {
packages_to_verify.push(locator)
}
@@ -228,25 +228,25 @@ log.console("")
check_link_cycles()
check_dangling_links()
for (var p of packages_to_verify) {
if (p == 'core') continue
arrfor(packages_to_verify, function(p) {
if (p == 'core') return
verify_package(p)
}
})
// Print results
if (warnings.length > 0) {
log.console("Warnings:")
for (var w of warnings) {
arrfor(warnings, function(w) {
log.console(" " + w)
}
})
log.console("")
}
if (errors.length > 0) {
log.console("Errors:")
for (var e of errors) {
arrfor(errors, function(e) {
log.console(" " + e)
}
})
log.console("")
log.console("Verification FAILED: " + text(errors.length) + " error(s), " + text(warnings.length) + " warning(s)")
// Note: would use process.exit(1) if available