Compare commits
6 Commits
async_http
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1b41d5ecf | ||
|
|
eb19b18594 | ||
|
|
e203700d37 | ||
|
|
c56444556d | ||
|
|
080e675d18 | ||
|
|
957b964d9d |
4
audit.ce
4
audit.ce
@@ -114,13 +114,13 @@ var run = function() {
|
|||||||
total_scripts = total_scripts + result.total
|
total_scripts = total_scripts + result.total
|
||||||
|
|
||||||
arrfor(result.errors, function(e) {
|
arrfor(result.errors, function(e) {
|
||||||
push(all_failures, p + ": " + e)
|
all_failures[] = p + ": " + e
|
||||||
})
|
})
|
||||||
|
|
||||||
// Check use() resolution
|
// Check use() resolution
|
||||||
resolution = shop.audit_use_resolution(p)
|
resolution = shop.audit_use_resolution(p)
|
||||||
arrfor(resolution.unresolved, function(u) {
|
arrfor(resolution.unresolved, function(u) {
|
||||||
push(all_unresolved, p + '/' + u.script + ": use('" + u.module + "') cannot be resolved")
|
all_unresolved[] = p + '/' + u.script + ": use('" + u.module + "') cannot be resolved"
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
30
bench.ce
30
bench.ce
@@ -28,7 +28,7 @@ function strip_mode_flags() {
|
|||||||
} else if (a == '--compare') {
|
} else if (a == '--compare') {
|
||||||
bench_mode = "compare"
|
bench_mode = "compare"
|
||||||
} else {
|
} else {
|
||||||
push(filtered, a)
|
filtered[] = a
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
_args = filtered
|
_args = filtered
|
||||||
@@ -197,7 +197,7 @@ function collect_benches(package_name, specific_bench) {
|
|||||||
match_base = ends_with(match_name, '.cm') ? text(match_name, 0, -3) : match_name
|
match_base = ends_with(match_name, '.cm') ? text(match_name, 0, -3) : match_name
|
||||||
if (bench_name != match_base) return
|
if (bench_name != match_base) return
|
||||||
}
|
}
|
||||||
push(bench_files, f)
|
bench_files[] = f
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return bench_files
|
return bench_files
|
||||||
@@ -355,7 +355,7 @@ function run_single_bench(bench_fn, bench_name) {
|
|||||||
if (teardown_fn) teardown_fn(state)
|
if (teardown_fn) teardown_fn(state)
|
||||||
|
|
||||||
ns_per_op = is_batch ? duration / batch_size : duration
|
ns_per_op = is_batch ? duration / batch_size : duration
|
||||||
push(timings_per_op, ns_per_op)
|
timings_per_op[] = ns_per_op
|
||||||
} else {
|
} else {
|
||||||
start = os.now()
|
start = os.now()
|
||||||
if (is_batch) {
|
if (is_batch) {
|
||||||
@@ -366,7 +366,7 @@ function run_single_bench(bench_fn, bench_name) {
|
|||||||
duration = os.now() - start
|
duration = os.now() - start
|
||||||
|
|
||||||
ns_per_op = is_batch ? duration / batch_size : duration
|
ns_per_op = is_batch ? duration / batch_size : duration
|
||||||
push(timings_per_op, ns_per_op)
|
timings_per_op[] = ns_per_op
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,11 +442,11 @@ function load_bench_module(f, package_name, mode) {
|
|||||||
function collect_bench_fns(bench_mod) {
|
function collect_bench_fns(bench_mod) {
|
||||||
var benches = []
|
var benches = []
|
||||||
if (is_function(bench_mod)) {
|
if (is_function(bench_mod)) {
|
||||||
push(benches, {name: 'main', fn: bench_mod})
|
benches[] = {name: 'main', fn: bench_mod}
|
||||||
} else if (is_object(bench_mod)) {
|
} else if (is_object(bench_mod)) {
|
||||||
arrfor(array(bench_mod), function(k) {
|
arrfor(array(bench_mod), function(k) {
|
||||||
if (is_function(bench_mod[k]))
|
if (is_function(bench_mod[k]))
|
||||||
push(benches, {name: k, fn: bench_mod[k]})
|
benches[] = {name: k, fn: bench_mod[k]}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return benches
|
return benches
|
||||||
@@ -524,7 +524,7 @@ function run_benchmarks(package_name, specific_bench) {
|
|||||||
result = run_single_bench(b.fn, b.name)
|
result = run_single_bench(b.fn, b.name)
|
||||||
result.package = pkg_result.package
|
result.package = pkg_result.package
|
||||||
result.mode = bench_mode == "compare" ? "bytecode" : bench_mode
|
result.mode = bench_mode == "compare" ? "bytecode" : bench_mode
|
||||||
push(file_result.benchmarks, result)
|
file_result.benchmarks[] = result
|
||||||
pkg_result.total++
|
pkg_result.total++
|
||||||
|
|
||||||
log.console(` ${result.name}`)
|
log.console(` ${result.name}`)
|
||||||
@@ -538,7 +538,7 @@ function run_benchmarks(package_name, specific_bench) {
|
|||||||
nat_result = run_single_bench(native_benches[nat_b].fn, b.name)
|
nat_result = run_single_bench(native_benches[nat_b].fn, b.name)
|
||||||
nat_result.package = pkg_result.package
|
nat_result.package = pkg_result.package
|
||||||
nat_result.mode = "native"
|
nat_result.mode = "native"
|
||||||
push(file_result.benchmarks, nat_result)
|
file_result.benchmarks[] = nat_result
|
||||||
pkg_result.total++
|
pkg_result.total++
|
||||||
print_bench_result(nat_result, "native ")
|
print_bench_result(nat_result, "native ")
|
||||||
|
|
||||||
@@ -570,7 +570,7 @@ function run_benchmarks(package_name, specific_bench) {
|
|||||||
name: b.name,
|
name: b.name,
|
||||||
error: "benchmark disrupted"
|
error: "benchmark disrupted"
|
||||||
}
|
}
|
||||||
push(file_result.benchmarks, error_result)
|
file_result.benchmarks[] = error_result
|
||||||
pkg_result.total++
|
pkg_result.total++
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -586,12 +586,12 @@ function run_benchmarks(package_name, specific_bench) {
|
|||||||
name: "load_module",
|
name: "load_module",
|
||||||
error: "error loading module"
|
error: "error loading module"
|
||||||
}
|
}
|
||||||
push(file_result.benchmarks, error_result)
|
file_result.benchmarks[] = error_result
|
||||||
pkg_result.total++
|
pkg_result.total++
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length(file_result.benchmarks) > 0) {
|
if (length(file_result.benchmarks) > 0) {
|
||||||
push(pkg_result.files, file_result)
|
pkg_result.files[] = file_result
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -604,15 +604,15 @@ var packages = null
|
|||||||
|
|
||||||
if (all_pkgs) {
|
if (all_pkgs) {
|
||||||
if (testlib.is_valid_package('.')) {
|
if (testlib.is_valid_package('.')) {
|
||||||
push(all_results, run_benchmarks(null, null))
|
all_results[] = run_benchmarks(null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
packages = shop.list_packages()
|
packages = shop.list_packages()
|
||||||
arrfor(packages, function(p) {
|
arrfor(packages, function(p) {
|
||||||
push(all_results, run_benchmarks(p, null))
|
all_results[] = run_benchmarks(p, null)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
push(all_results, run_benchmarks(target_pkg, target_bench))
|
all_results[] = run_benchmarks(target_pkg, target_bench)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate totals
|
// Calculate totals
|
||||||
@@ -688,7 +688,7 @@ Total benchmarks: ${total_benches}
|
|||||||
var pkg_benches = []
|
var pkg_benches = []
|
||||||
arrfor(pkg_res.files, function(f) {
|
arrfor(pkg_res.files, function(f) {
|
||||||
arrfor(f.benchmarks, function(benchmark) {
|
arrfor(f.benchmarks, function(benchmark) {
|
||||||
push(pkg_benches, benchmark)
|
pkg_benches[] = benchmark
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ function send(mailbox, msg) {
|
|||||||
function receive(mailbox) {
|
function receive(mailbox) {
|
||||||
if (length(mailbox.queue) == 0) return null
|
if (length(mailbox.queue) == 0) return null
|
||||||
mailbox.delivered++
|
mailbox.delivered++
|
||||||
return pop(mailbox.queue)
|
return mailbox.queue[]
|
||||||
}
|
}
|
||||||
|
|
||||||
function drain(mailbox) {
|
function drain(mailbox) {
|
||||||
var count = 0
|
var count = 0
|
||||||
while (length(mailbox.queue) > 0) {
|
while (length(mailbox.queue) > 0) {
|
||||||
pop(mailbox.queue)
|
mailbox.queue[]
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
return count
|
return count
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ function generate_records(n) {
|
|||||||
var dept_vals = ["eng", "sales", "ops", "hr", "marketing"]
|
var dept_vals = ["eng", "sales", "ops", "hr", "marketing"]
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
x = ((x * 1103515245 + 12345) & 0x7FFFFFFF) | 0
|
x = ((x * 1103515245 + 12345) & 0x7FFFFFFF) | 0
|
||||||
push(records, {
|
records[] = {
|
||||||
id: i + 1,
|
id: i + 1,
|
||||||
name: `user_${i}`,
|
name: `user_${i}`,
|
||||||
score: (x % 1000) / 10,
|
score: (x % 1000) / 10,
|
||||||
status: status_vals[i % 4],
|
status: status_vals[i % 4],
|
||||||
department: dept_vals[i % 5]
|
department: dept_vals[i % 5]
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
return records
|
return records
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ function filter_records(records, field, value) {
|
|||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < length(records); i++) {
|
for (i = 0; i < length(records); i++) {
|
||||||
if (records[i][field] == value) {
|
if (records[i][field] == value) {
|
||||||
push(result, records[i])
|
result[] = records[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@@ -45,7 +45,7 @@ function group_by(records, field) {
|
|||||||
key = records[i][field]
|
key = records[i][field]
|
||||||
if (!key) key = "unknown"
|
if (!key) key = "unknown"
|
||||||
if (!groups[key]) groups[key] = []
|
if (!groups[key]) groups[key] = []
|
||||||
push(groups[key], records[i])
|
groups[key][] = records[i]
|
||||||
}
|
}
|
||||||
return groups
|
return groups
|
||||||
}
|
}
|
||||||
@@ -70,13 +70,13 @@ function aggregate(groups) {
|
|||||||
if (grp[j].score < mn) mn = grp[j].score
|
if (grp[j].score < mn) mn = grp[j].score
|
||||||
if (grp[j].score > mx) mx = grp[j].score
|
if (grp[j].score > mx) mx = grp[j].score
|
||||||
}
|
}
|
||||||
push(result, {
|
result[] = {
|
||||||
group: keys[i],
|
group: keys[i],
|
||||||
count: length(grp),
|
count: length(grp),
|
||||||
average: total / length(grp),
|
average: total / length(grp),
|
||||||
low: mn,
|
low: mn,
|
||||||
high: mx
|
high: mx
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ function build_chain(n) {
|
|||||||
var constraints = []
|
var constraints = []
|
||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
push(vars, make_variable(`v${i}`, 0))
|
vars[] = make_variable(`v${i}`, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set first variable
|
// Set first variable
|
||||||
@@ -69,8 +69,8 @@ function build_chain(n) {
|
|||||||
self.variables[1].value = self.variables[0].value + 1
|
self.variables[1].value = self.variables[0].value + 1
|
||||||
self.output = self.variables[1]
|
self.output = self.variables[1]
|
||||||
})
|
})
|
||||||
push(constraints, c)
|
constraints[] = c
|
||||||
push(vars[i].constraints, c)
|
vars[i].constraints[] = c
|
||||||
}
|
}
|
||||||
|
|
||||||
return {vars: vars, constraints: constraints}
|
return {vars: vars, constraints: constraints}
|
||||||
@@ -83,8 +83,8 @@ function build_projection(n) {
|
|||||||
var constraints = []
|
var constraints = []
|
||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
push(src, make_variable(`src${i}`, i * 10))
|
src[] = make_variable(`src${i}`, i * 10)
|
||||||
push(dst, make_variable(`dst${i}`, 0))
|
dst[] = make_variable(`dst${i}`, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
var scale_c = null
|
var scale_c = null
|
||||||
@@ -93,8 +93,8 @@ function build_projection(n) {
|
|||||||
self.variables[1].value = self.variables[0].value * 2 + 1
|
self.variables[1].value = self.variables[0].value * 2 + 1
|
||||||
self.output = self.variables[1]
|
self.output = self.variables[1]
|
||||||
})
|
})
|
||||||
push(constraints, scale_c)
|
constraints[] = scale_c
|
||||||
push(dst[i].constraints, scale_c)
|
dst[i].constraints[] = scale_c
|
||||||
}
|
}
|
||||||
|
|
||||||
return {src: src, dst: dst, constraints: constraints}
|
return {src: src, dst: dst, constraints: constraints}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ function make_words(count) {
|
|||||||
var words = []
|
var words = []
|
||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
push(words, base_words[i % length(base_words)])
|
words[] = base_words[i % length(base_words)]
|
||||||
}
|
}
|
||||||
return words
|
return words
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ function top_n(freq, n) {
|
|||||||
var pairs = []
|
var pairs = []
|
||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < length(keys); i++) {
|
for (i = 0; i < length(keys); i++) {
|
||||||
push(pairs, {word: keys[i], count: freq[keys[i]]})
|
pairs[] = {word: keys[i], count: freq[keys[i]]}
|
||||||
}
|
}
|
||||||
var sorted = sort(pairs, "count")
|
var sorted = sort(pairs, "count")
|
||||||
// Return last N (highest counts)
|
// Return last N (highest counts)
|
||||||
@@ -47,7 +47,7 @@ function top_n(freq, n) {
|
|||||||
var start = length(sorted) - n
|
var start = length(sorted) - n
|
||||||
if (start < 0) start = 0
|
if (start < 0) start = 0
|
||||||
for (i = start; i < length(sorted); i++) {
|
for (i = start; i < length(sorted); i++) {
|
||||||
push(result, sorted[i])
|
result[] = sorted[i]
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ function group_by_length(words) {
|
|||||||
w = words[i]
|
w = words[i]
|
||||||
k = text(length(w))
|
k = text(length(w))
|
||||||
if (!groups[k]) groups[k] = []
|
if (!groups[k]) groups[k] = []
|
||||||
push(groups[k], w)
|
groups[k][] = w
|
||||||
}
|
}
|
||||||
return groups
|
return groups
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ function make_array_data(size) {
|
|||||||
var arr = []
|
var arr = []
|
||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
push(arr, {
|
arr[] = {
|
||||||
id: i,
|
id: i,
|
||||||
name: `item_${i}`,
|
name: `item_${i}`,
|
||||||
active: i % 2 == 0,
|
active: i % 2 == 0,
|
||||||
score: i * 1.5,
|
score: i * 1.5,
|
||||||
tags: [`tag_${i % 5}`, `tag_${(i + 1) % 5}`]
|
tags: [`tag_${i % 5}`, `tag_${(i + 1) % 5}`]
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ function make_obj_yx(x, y) {
|
|||||||
function make_packed_array(n) {
|
function make_packed_array(n) {
|
||||||
var a = []
|
var a = []
|
||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < n; i++) push(a, i)
|
for (i = 0; i < n; i++) a[] = i
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ return {
|
|||||||
var a = null
|
var a = null
|
||||||
for (j = 0; j < n; j++) {
|
for (j = 0; j < n; j++) {
|
||||||
a = []
|
a = []
|
||||||
for (i = 0; i < 256; i++) push(a, i)
|
for (i = 0; i < 256; i++) a[] = i
|
||||||
x = (x + length(a)) | 0
|
x = (x + length(a)) | 0
|
||||||
}
|
}
|
||||||
return blackhole(sink, x)
|
return blackhole(sink, x)
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ return {
|
|||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
push(a, i)
|
push(a, i)
|
||||||
if (length(a) > 64) {
|
if (length(a) > 64) {
|
||||||
v = pop(a)
|
v = a[]
|
||||||
x = (x + v) | 0
|
x = (x + v) | 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,21 +16,21 @@ function tokenize(src) {
|
|||||||
ch = chars[i]
|
ch = chars[i]
|
||||||
if (ch == " " || ch == "\n" || ch == "\t") {
|
if (ch == " " || ch == "\n" || ch == "\t") {
|
||||||
if (length(buf) > 0) {
|
if (length(buf) > 0) {
|
||||||
push(tokens, buf)
|
tokens[] = buf
|
||||||
buf = ""
|
buf = ""
|
||||||
}
|
}
|
||||||
} else if (ch == "(" || ch == ")" || ch == "+" || ch == "-"
|
} else if (ch == "(" || ch == ")" || ch == "+" || ch == "-"
|
||||||
|| ch == "*" || ch == "=" || ch == ";" || ch == ",") {
|
|| ch == "*" || ch == "=" || ch == ";" || ch == ",") {
|
||||||
if (length(buf) > 0) {
|
if (length(buf) > 0) {
|
||||||
push(tokens, buf)
|
tokens[] = buf
|
||||||
buf = ""
|
buf = ""
|
||||||
}
|
}
|
||||||
push(tokens, ch)
|
tokens[] = ch
|
||||||
} else {
|
} else {
|
||||||
buf = buf + ch
|
buf = buf + ch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (length(buf) > 0) push(tokens, buf)
|
if (length(buf) > 0) tokens[] = buf
|
||||||
return tokens
|
return tokens
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,21 +49,21 @@ function parse_tokens(tokens) {
|
|||||||
i++ // skip =
|
i++ // skip =
|
||||||
i++
|
i++
|
||||||
if (i < length(tokens)) node.value = tokens[i]
|
if (i < length(tokens)) node.value = tokens[i]
|
||||||
push(ast, node)
|
ast[] = node
|
||||||
} else if (tok == "return") {
|
} else if (tok == "return") {
|
||||||
node = {type: "return", value: null}
|
node = {type: "return", value: null}
|
||||||
i++
|
i++
|
||||||
if (i < length(tokens)) node.value = tokens[i]
|
if (i < length(tokens)) node.value = tokens[i]
|
||||||
push(ast, node)
|
ast[] = node
|
||||||
} else if (tok == "function") {
|
} else if (tok == "function") {
|
||||||
node = {type: "func", name: null, body: []}
|
node = {type: "func", name: null, body: []}
|
||||||
i++
|
i++
|
||||||
if (i < length(tokens)) node.name = tokens[i]
|
if (i < length(tokens)) node.name = tokens[i]
|
||||||
// Skip to matching )
|
// Skip to matching )
|
||||||
while (i < length(tokens) && tokens[i] != ")") i++
|
while (i < length(tokens) && tokens[i] != ")") i++
|
||||||
push(ast, node)
|
ast[] = node
|
||||||
} else {
|
} else {
|
||||||
push(ast, {type: "expr", value: tok})
|
ast[] = {type: "expr", value: tok}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ast
|
return ast
|
||||||
@@ -121,7 +121,7 @@ function simulate_build(n_modules, deps_per_module) {
|
|||||||
// Generate all module sources
|
// Generate all module sources
|
||||||
for (i = 0; i < n_modules; i++) {
|
for (i = 0; i < n_modules; i++) {
|
||||||
src = generate_module(i, deps_per_module)
|
src = generate_module(i, deps_per_module)
|
||||||
push(modules, src)
|
modules[] = src
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Load" each module: tokenize → parse → evaluate
|
// "Load" each module: tokenize → parse → evaluate
|
||||||
@@ -173,7 +173,7 @@ function topo_sort(n_modules, deps_per_module) {
|
|||||||
for (j = 0; j < deps_per_module; j++) {
|
for (j = 0; j < deps_per_module; j++) {
|
||||||
if (j < i) {
|
if (j < i) {
|
||||||
dep = "mod_" + text(j)
|
dep = "mod_" + text(j)
|
||||||
push(adj[dep], name)
|
adj[dep][] = name
|
||||||
in_degree[name] = in_degree[name] + 1
|
in_degree[name] = in_degree[name] + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,7 +183,7 @@ function topo_sort(n_modules, deps_per_module) {
|
|||||||
var queue = []
|
var queue = []
|
||||||
var keys = array(in_degree)
|
var keys = array(in_degree)
|
||||||
for (i = 0; i < length(keys); i++) {
|
for (i = 0; i < length(keys); i++) {
|
||||||
if (in_degree[keys[i]] == 0) push(queue, keys[i])
|
if (in_degree[keys[i]] == 0) queue[] = keys[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
var order = []
|
var order = []
|
||||||
@@ -193,12 +193,12 @@ function topo_sort(n_modules, deps_per_module) {
|
|||||||
while (qi < length(queue)) {
|
while (qi < length(queue)) {
|
||||||
current = queue[qi]
|
current = queue[qi]
|
||||||
qi++
|
qi++
|
||||||
push(order, current)
|
order[] = current
|
||||||
neighbors = adj[current]
|
neighbors = adj[current]
|
||||||
if (neighbors) {
|
if (neighbors) {
|
||||||
for (i = 0; i < length(neighbors); i++) {
|
for (i = 0; i < length(neighbors); i++) {
|
||||||
in_degree[neighbors[i]] = in_degree[neighbors[i]] - 1
|
in_degree[neighbors[i]] = in_degree[neighbors[i]] - 1
|
||||||
if (in_degree[neighbors[i]] == 0) push(queue, neighbors[i])
|
if (in_degree[neighbors[i]] == 0) queue[] = neighbors[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ function make_random_array(n, seed) {
|
|||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
x = ((x * 1103515245 + 12345) & 0x7FFFFFFF) | 0
|
x = ((x * 1103515245 + 12345) & 0x7FFFFFFF) | 0
|
||||||
push(a, x % 10000)
|
a[] = x % 10000
|
||||||
}
|
}
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ function make_random_array(n, seed) {
|
|||||||
function make_descending(n) {
|
function make_descending(n) {
|
||||||
var a = []
|
var a = []
|
||||||
var i = 0
|
var i = 0
|
||||||
for (i = n - 1; i >= 0; i--) push(a, i)
|
for (i = n - 1; i >= 0; i--) a[] = i
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,19 +58,19 @@ function merge(a, b) {
|
|||||||
var j = 0
|
var j = 0
|
||||||
while (i < length(a) && j < length(b)) {
|
while (i < length(a) && j < length(b)) {
|
||||||
if (a[i] <= b[j]) {
|
if (a[i] <= b[j]) {
|
||||||
push(result, a[i])
|
result[] = a[i]
|
||||||
i++
|
i++
|
||||||
} else {
|
} else {
|
||||||
push(result, b[j])
|
result[] = b[j]
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (i < length(a)) {
|
while (i < length(a)) {
|
||||||
push(result, a[i])
|
result[] = a[i]
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
while (j < length(b)) {
|
while (j < length(b)) {
|
||||||
push(result, b[j])
|
result[] = b[j]
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@@ -97,7 +97,7 @@ function sort_records(n) {
|
|||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
x = ((x * 1103515245 + 12345) & 0x7FFFFFFF) | 0
|
x = ((x * 1103515245 + 12345) & 0x7FFFFFFF) | 0
|
||||||
push(records, {id: i, score: x % 10000, name: `item_${i}`})
|
records[] = {id: i, score: x % 10000, name: `item_${i}`}
|
||||||
}
|
}
|
||||||
return sort(records, "score")
|
return sort(records, "score")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function build_index(txt) {
|
|||||||
if (!index[w]) {
|
if (!index[w]) {
|
||||||
index[w] = []
|
index[w] = []
|
||||||
}
|
}
|
||||||
push(index[w], i)
|
index[w][] = i
|
||||||
}
|
}
|
||||||
return index
|
return index
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ function tree_map(node, fn) {
|
|||||||
function tree_flatten(node, result) {
|
function tree_flatten(node, result) {
|
||||||
if (!node) return null
|
if (!node) return null
|
||||||
tree_flatten(node.left, result)
|
tree_flatten(node.left, result)
|
||||||
push(result, node.val)
|
result[] = node.val
|
||||||
tree_flatten(node.right, result)
|
tree_flatten(node.right, result)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ return {
|
|||||||
// Build a balanced BST of 1024 elements
|
// Build a balanced BST of 1024 elements
|
||||||
var data = []
|
var data = []
|
||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < 1024; i++) push(data, i)
|
for (i = 0; i < 1024; i++) data[] = i
|
||||||
var bst = build_balanced(data, 0, 1023)
|
var bst = build_balanced(data, 0, 1023)
|
||||||
var found = 0
|
var found = 0
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
|||||||
@@ -95,12 +95,12 @@ function benchArrayOps() {
|
|||||||
var arr = [];
|
var arr = [];
|
||||||
var j = 0
|
var j = 0
|
||||||
for (j = 0; j < iterations.medium; j++) {
|
for (j = 0; j < iterations.medium; j++) {
|
||||||
push(arr, j);
|
arr[] = j;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var arr = [];
|
var arr = [];
|
||||||
for (i = 0; i < 10000; i++) push(arr, i);
|
for (i = 0; i < 10000; i++) arr[] = i;
|
||||||
|
|
||||||
var accessTime = measureTime(function() {
|
var accessTime = measureTime(function() {
|
||||||
var sum = 0;
|
var sum = 0;
|
||||||
@@ -188,7 +188,7 @@ function benchStringOps() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (i = 0; i < 1000; i++) {
|
for (i = 0; i < 1000; i++) {
|
||||||
push(strings, "string" + i);
|
strings[] = "string" + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
var joinTime = measureTime(function() {
|
var joinTime = measureTime(function() {
|
||||||
@@ -261,13 +261,13 @@ function benchClosures() {
|
|||||||
var funcs = [];
|
var funcs = [];
|
||||||
var j = 0
|
var j = 0
|
||||||
for (j = 0; j < iterations.medium; j++) {
|
for (j = 0; j < iterations.medium; j++) {
|
||||||
push(funcs, makeAdder(j));
|
funcs[] = makeAdder(j);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var adders = [];
|
var adders = [];
|
||||||
for (i = 0; i < 1000; i++) {
|
for (i = 0; i < 1000; i++) {
|
||||||
push(adders, makeAdder(i));
|
adders[] = makeAdder(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
var closureCallTime = measureTime(function() {
|
var closureCallTime = measureTime(function() {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ var nll = null
|
|||||||
var oll = null
|
var oll = null
|
||||||
for (i = 0; i < 10000; i++) {
|
for (i = 0; i < 10000; i++) {
|
||||||
accstr += i;
|
accstr += i;
|
||||||
push(newarr, text(i))
|
newarr[] = text(i)
|
||||||
}
|
}
|
||||||
var jsonDecodeTimes = [];
|
var jsonDecodeTimes = [];
|
||||||
var jsonEncodeTimes = [];
|
var jsonEncodeTimes = [];
|
||||||
@@ -26,19 +26,19 @@ var notaSizes = [];
|
|||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 100; i++) {
|
||||||
start = os.now();
|
start = os.now();
|
||||||
jll = json.decode(ll);
|
jll = json.decode(ll);
|
||||||
push(jsonDecodeTimes, (os.now() - start) * 1000);
|
jsonDecodeTimes[] = (os.now() - start) * 1000;
|
||||||
|
|
||||||
start = os.now();
|
start = os.now();
|
||||||
jsonStr = JSON.stringify(jll);
|
jsonStr = JSON.stringify(jll);
|
||||||
push(jsonEncodeTimes, (os.now() - start) * 1000);
|
jsonEncodeTimes[] = (os.now() - start) * 1000;
|
||||||
|
|
||||||
start = os.now();
|
start = os.now();
|
||||||
nll = nota.encode(jll);
|
nll = nota.encode(jll);
|
||||||
push(notaEncodeTimes, (os.now() - start) * 1000);
|
notaEncodeTimes[] = (os.now() - start) * 1000;
|
||||||
|
|
||||||
start = os.now();
|
start = os.now();
|
||||||
oll = nota.decode(nll);
|
oll = nota.decode(nll);
|
||||||
push(notaDecodeTimes, (os.now() - start) * 1000);
|
notaDecodeTimes[] = (os.now() - start) * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStats(arr) {
|
function getStats(arr) {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ function runBenchmarkForLibrary(lib, bench) {
|
|||||||
for (j = 0; j < length(bench.data); j++) {
|
for (j = 0; j < length(bench.data); j++) {
|
||||||
e = lib.encode(bench.data[j]);
|
e = lib.encode(bench.data[j]);
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
push(encodedList, e);
|
encodedList[] = e;
|
||||||
totalSize += lib.getSize(e);
|
totalSize += lib.getSize(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5251,88 +5251,54 @@
|
|||||||
["add", 29, 29, 7, 260, 17],
|
["add", 29, 29, 7, 260, 17],
|
||||||
["jump", "while_start_360", 260, 17],
|
["jump", "while_start_360", 260, 17],
|
||||||
"while_end_361",
|
"while_end_361",
|
||||||
["access", 7, "bootstrap: native cache seeded\n", 262, 12],
|
["jump", "if_end_350", 260, 17],
|
||||||
[
|
|
||||||
"access",
|
|
||||||
11,
|
|
||||||
{
|
|
||||||
"name": "os",
|
|
||||||
"kind": "name",
|
|
||||||
"make": "intrinsic"
|
|
||||||
},
|
|
||||||
262,
|
|
||||||
3
|
|
||||||
],
|
|
||||||
["is_proxy", 12, 11, 262, 3],
|
|
||||||
["jump_false", 12, "record_path_368", 262, 3],
|
|
||||||
["null", 12, 262, 3],
|
|
||||||
["access", 14, "print", 262, 3],
|
|
||||||
["array", 31, 0, 262, 3],
|
|
||||||
["stone_text", 7],
|
|
||||||
["push", 31, 7, 262, 3],
|
|
||||||
["frame", 32, 11, 2, 262, 3],
|
|
||||||
["setarg", 32, 0, 12, 262, 3],
|
|
||||||
["stone_text", 14],
|
|
||||||
["setarg", 32, 1, 14, 262, 3],
|
|
||||||
["setarg", 32, 2, 31, 262, 3],
|
|
||||||
["invoke", 32, 12, 262, 3],
|
|
||||||
["jump", "call_done_369", 262, 3],
|
|
||||||
"record_path_368",
|
|
||||||
["load_field", 14, 11, "print", 262, 3],
|
|
||||||
["frame", 31, 14, 1, 262, 3],
|
|
||||||
["setarg", 31, 0, 11, 262, 3],
|
|
||||||
["stone_text", 7],
|
|
||||||
["setarg", 31, 1, 7, 262, 3],
|
|
||||||
["invoke", 31, 12, 262, 3],
|
|
||||||
"call_done_369",
|
|
||||||
["jump", "if_end_350", 262, 3],
|
|
||||||
"if_else_349",
|
"if_else_349",
|
||||||
["record", 7, 2],
|
["record", 7, 2],
|
||||||
["access", 11, "tokenize", 266, 12],
|
["access", 11, "tokenize", 265, 12],
|
||||||
["store_field", 7, 11, "name", 266, 12],
|
["store_field", 7, 11, "name", 265, 12],
|
||||||
["access", 11, "tokenize.cm", 266, 30],
|
["access", 11, "tokenize.cm", 265, 30],
|
||||||
["store_field", 7, 11, "path", 266, 30],
|
["store_field", 7, 11, "path", 265, 30],
|
||||||
["record", 11, 2],
|
["record", 11, 2],
|
||||||
["access", 12, "parse", 267, 12],
|
["access", 12, "parse", 266, 12],
|
||||||
["store_field", 11, 12, "name", 267, 12],
|
["store_field", 11, 12, "name", 266, 12],
|
||||||
["access", 12, "parse.cm", 267, 27],
|
["access", 12, "parse.cm", 266, 27],
|
||||||
["store_field", 11, 12, "path", 267, 27],
|
["store_field", 11, 12, "path", 266, 27],
|
||||||
["record", 12, 2],
|
["record", 12, 2],
|
||||||
["access", 14, "fold", 268, 12],
|
["access", 14, "fold", 267, 12],
|
||||||
["store_field", 12, 14, "name", 268, 12],
|
["store_field", 12, 14, "name", 267, 12],
|
||||||
["access", 14, "fold.cm", 268, 26],
|
["access", 14, "fold.cm", 267, 26],
|
||||||
["store_field", 12, 14, "path", 268, 26],
|
["store_field", 12, 14, "path", 267, 26],
|
||||||
["record", 14, 2],
|
["record", 14, 2],
|
||||||
["access", 31, "mcode", 269, 12],
|
["access", 31, "mcode", 268, 12],
|
||||||
["store_field", 14, 31, "name", 269, 12],
|
["store_field", 14, 31, "name", 268, 12],
|
||||||
["access", 31, "mcode.cm", 269, 27],
|
["access", 31, "mcode.cm", 268, 27],
|
||||||
["store_field", 14, 31, "path", 269, 27],
|
["store_field", 14, 31, "path", 268, 27],
|
||||||
["record", 31, 2],
|
["record", 31, 2],
|
||||||
["access", 32, "streamline", 270, 12],
|
["access", 32, "streamline", 269, 12],
|
||||||
["store_field", 31, 32, "name", 270, 12],
|
["store_field", 31, 32, "name", 269, 12],
|
||||||
["access", 32, "streamline.cm", 270, 32],
|
["access", 32, "streamline.cm", 269, 32],
|
||||||
["store_field", 31, 32, "path", 270, 32],
|
["store_field", 31, 32, "path", 269, 32],
|
||||||
["record", 32, 2],
|
["record", 32, 2],
|
||||||
["access", 33, "engine", 271, 12],
|
["access", 33, "engine", 270, 12],
|
||||||
["store_field", 32, 33, "name", 271, 12],
|
["store_field", 32, 33, "name", 270, 12],
|
||||||
["access", 33, "internal/engine.cm", 271, 28],
|
["access", 33, "internal/engine.cm", 270, 28],
|
||||||
["store_field", 32, 33, "path", 271, 28],
|
["store_field", 32, 33, "path", 270, 28],
|
||||||
["array", 33, 6, 271, 28],
|
["array", 33, 6, 270, 28],
|
||||||
["push", 33, 7, 271, 28],
|
["push", 33, 7, 270, 28],
|
||||||
["push", 33, 11, 271, 28],
|
["push", 33, 11, 270, 28],
|
||||||
["push", 33, 12, 271, 28],
|
["push", 33, 12, 270, 28],
|
||||||
["push", 33, 14, 271, 28],
|
["push", 33, 14, 270, 28],
|
||||||
["push", 33, 31, 271, 28],
|
["push", 33, 31, 270, 28],
|
||||||
["push", 33, 32, 271, 28],
|
["push", 33, 32, 270, 28],
|
||||||
["move", 28, 33, 271, 28],
|
["move", 28, 33, 270, 28],
|
||||||
["access", 29, 0, 273, 9],
|
["access", 29, 0, 272, 9],
|
||||||
"while_start_370",
|
"while_start_368",
|
||||||
["length", 7, 28, 274, 23],
|
["length", 7, 28, 273, 23],
|
||||||
["lt", 11, 29, 7, 274, 23],
|
["lt", 11, 29, 7, 273, 23],
|
||||||
["jump_false", 11, "while_end_371", 274, 23],
|
["jump_false", 11, "while_end_369", 273, 23],
|
||||||
["load_dynamic", 7, 28, 29, 275, 20],
|
["load_dynamic", 7, 28, 29, 274, 20],
|
||||||
["move", 30, 7, 275, 20],
|
["move", 30, 7, 274, 20],
|
||||||
["load_field", 11, 7, "name", 276, 23],
|
["load_field", 11, 7, "name", 275, 23],
|
||||||
[
|
[
|
||||||
"access",
|
"access",
|
||||||
7,
|
7,
|
||||||
@@ -5341,24 +5307,24 @@
|
|||||||
"kind": "name",
|
"kind": "name",
|
||||||
"make": "intrinsic"
|
"make": "intrinsic"
|
||||||
},
|
},
|
||||||
276,
|
275,
|
||||||
33
|
33
|
||||||
],
|
],
|
||||||
["access", 12, "/", 276, 45],
|
["access", 12, "/", 275, 45],
|
||||||
["is_text", 14, 7, 276, 45],
|
["is_text", 14, 7, 275, 45],
|
||||||
["jump_false", 14, "add_cn_373", 276, 45],
|
["jump_false", 14, "add_cn_371", 275, 45],
|
||||||
"_nop_tc_7",
|
"_nop_tc_7",
|
||||||
"_nop_tc_8",
|
"_nop_tc_8",
|
||||||
["concat", 31, 7, 12, 276, 45],
|
["concat", 31, 7, 12, 275, 45],
|
||||||
["jump", "add_done_372", 276, 45],
|
["jump", "add_done_370", 275, 45],
|
||||||
"add_cn_373",
|
"add_cn_371",
|
||||||
["is_num", 14, 7, 276, 45],
|
["is_num", 14, 7, 275, 45],
|
||||||
["jump_false", 14, "add_err_374", 276, 45],
|
["jump_false", 14, "add_err_372", 275, 45],
|
||||||
"_nop_tc_9",
|
"_nop_tc_9",
|
||||||
"_nop_dj_3",
|
"_nop_dj_3",
|
||||||
"_nop_ucfg_6",
|
"_nop_ucfg_6",
|
||||||
"_nop_ucfg_7",
|
"_nop_ucfg_7",
|
||||||
"add_err_374",
|
"add_err_372",
|
||||||
[
|
[
|
||||||
"access",
|
"access",
|
||||||
7,
|
7,
|
||||||
@@ -5367,38 +5333,38 @@
|
|||||||
"kind": "name",
|
"kind": "name",
|
||||||
"make": "intrinsic"
|
"make": "intrinsic"
|
||||||
},
|
},
|
||||||
276,
|
275,
|
||||||
45
|
45
|
||||||
],
|
],
|
||||||
["access", 12, "error", 276, 45],
|
["access", 12, "error", 275, 45],
|
||||||
["access", 14, "cannot apply '+': operands must both be text or both be numbers", 276, 45],
|
["access", 14, "cannot apply '+': operands must both be text or both be numbers", 275, 45],
|
||||||
["array", 32, 0, 276, 45],
|
["array", 32, 0, 275, 45],
|
||||||
["stone_text", 14],
|
["stone_text", 14],
|
||||||
["push", 32, 14, 276, 45],
|
["push", 32, 14, 275, 45],
|
||||||
["frame", 14, 7, 2, 276, 45],
|
["frame", 14, 7, 2, 275, 45],
|
||||||
["null", 7, 276, 45],
|
["null", 7, 275, 45],
|
||||||
["setarg", 14, 0, 7, 276, 45],
|
["setarg", 14, 0, 7, 275, 45],
|
||||||
["stone_text", 12],
|
["stone_text", 12],
|
||||||
["setarg", 14, 1, 12, 276, 45],
|
["setarg", 14, 1, 12, 275, 45],
|
||||||
["setarg", 14, 2, 32, 276, 45],
|
["setarg", 14, 2, 32, 275, 45],
|
||||||
["invoke", 14, 7, 276, 45],
|
["invoke", 14, 7, 275, 45],
|
||||||
["disrupt", 276, 45],
|
["disrupt", 275, 45],
|
||||||
"add_done_372",
|
"add_done_370",
|
||||||
["load_field", 7, 30, "path", 276, 51],
|
["load_field", 7, 30, "path", 275, 51],
|
||||||
"_nop_tc_4",
|
"_nop_tc_4",
|
||||||
"_nop_tc_5",
|
"_nop_tc_5",
|
||||||
["is_text", 12, 7, 276, 51],
|
["is_text", 12, 7, 275, 51],
|
||||||
["jump_false", 12, "add_cn_376", 276, 51],
|
["jump_false", 12, "add_cn_374", 275, 51],
|
||||||
["concat", 12, 31, 7, 276, 51],
|
["concat", 12, 31, 7, 275, 51],
|
||||||
["jump", "add_done_375", 276, 51],
|
["jump", "add_done_373", 275, 51],
|
||||||
"add_cn_376",
|
"add_cn_374",
|
||||||
"_nop_tc_6",
|
"_nop_tc_6",
|
||||||
["jump", "add_err_377", 276, 51],
|
["jump", "add_err_375", 275, 51],
|
||||||
"_nop_ucfg_5",
|
"_nop_ucfg_5",
|
||||||
"_nop_ucfg_6",
|
"_nop_ucfg_6",
|
||||||
"_nop_ucfg_7",
|
"_nop_ucfg_7",
|
||||||
"_nop_ucfg_8",
|
"_nop_ucfg_8",
|
||||||
"add_err_377",
|
"add_err_375",
|
||||||
[
|
[
|
||||||
"access",
|
"access",
|
||||||
7,
|
7,
|
||||||
@@ -5407,71 +5373,37 @@
|
|||||||
"kind": "name",
|
"kind": "name",
|
||||||
"make": "intrinsic"
|
"make": "intrinsic"
|
||||||
},
|
},
|
||||||
276,
|
275,
|
||||||
51
|
51
|
||||||
],
|
],
|
||||||
["access", 14, "error", 276, 51],
|
["access", 14, "error", 275, 51],
|
||||||
["access", 31, "cannot apply '+': operands must both be text or both be numbers", 276, 51],
|
["access", 31, "cannot apply '+': operands must both be text or both be numbers", 275, 51],
|
||||||
["array", 32, 0, 276, 51],
|
["array", 32, 0, 275, 51],
|
||||||
["stone_text", 31],
|
["stone_text", 31],
|
||||||
["push", 32, 31, 276, 51],
|
["push", 32, 31, 275, 51],
|
||||||
["frame", 31, 7, 2, 276, 51],
|
["frame", 31, 7, 2, 275, 51],
|
||||||
["null", 7, 276, 51],
|
["null", 7, 275, 51],
|
||||||
["setarg", 31, 0, 7, 276, 51],
|
["setarg", 31, 0, 7, 275, 51],
|
||||||
["stone_text", 14],
|
["stone_text", 14],
|
||||||
["setarg", 31, 1, 14, 276, 51],
|
["setarg", 31, 1, 14, 275, 51],
|
||||||
["setarg", 31, 2, 32, 276, 51],
|
["setarg", 31, 2, 32, 275, 51],
|
||||||
["invoke", 31, 7, 276, 51],
|
["invoke", 31, 7, 275, 51],
|
||||||
["disrupt", 276, 51],
|
["disrupt", 275, 51],
|
||||||
"add_done_375",
|
"add_done_373",
|
||||||
["frame", 7, 10, 2, 276, 5],
|
["frame", 7, 10, 2, 275, 5],
|
||||||
["setarg", 7, 1, 11, 276, 5],
|
["setarg", 7, 1, 11, 275, 5],
|
||||||
["stone_text", 12],
|
["stone_text", 12],
|
||||||
["setarg", 7, 2, 12, 276, 5],
|
["setarg", 7, 2, 12, 275, 5],
|
||||||
["invoke", 7, 11, 276, 5],
|
["invoke", 7, 11, 275, 5],
|
||||||
["access", 7, 1, 277, 17],
|
["access", 7, 1, 276, 17],
|
||||||
["add", 29, 29, 7, 277, 17],
|
["add", 29, 29, 7, 276, 17],
|
||||||
["jump", "while_start_370", 277, 17],
|
["jump", "while_start_368", 276, 17],
|
||||||
"while_end_371",
|
"while_end_369",
|
||||||
["access", 7, "bootstrap: cache seeded\n", 279, 12],
|
|
||||||
[
|
|
||||||
"access",
|
|
||||||
10,
|
|
||||||
{
|
|
||||||
"name": "os",
|
|
||||||
"kind": "name",
|
|
||||||
"make": "intrinsic"
|
|
||||||
},
|
|
||||||
279,
|
|
||||||
3
|
|
||||||
],
|
|
||||||
["is_proxy", 11, 10, 279, 3],
|
|
||||||
["jump_false", 11, "record_path_378", 279, 3],
|
|
||||||
["null", 11, 279, 3],
|
|
||||||
["access", 12, "print", 279, 3],
|
|
||||||
["array", 14, 0, 279, 3],
|
|
||||||
["stone_text", 7],
|
|
||||||
["push", 14, 7, 279, 3],
|
|
||||||
["frame", 28, 10, 2, 279, 3],
|
|
||||||
["setarg", 28, 0, 11, 279, 3],
|
|
||||||
["stone_text", 12],
|
|
||||||
["setarg", 28, 1, 12, 279, 3],
|
|
||||||
["setarg", 28, 2, 14, 279, 3],
|
|
||||||
["invoke", 28, 11, 279, 3],
|
|
||||||
["jump", "call_done_379", 279, 3],
|
|
||||||
"record_path_378",
|
|
||||||
["load_field", 12, 10, "print", 279, 3],
|
|
||||||
["frame", 14, 12, 1, 279, 3],
|
|
||||||
["setarg", 14, 0, 10, 279, 3],
|
|
||||||
["stone_text", 7],
|
|
||||||
["setarg", 14, 1, 7, 279, 3],
|
|
||||||
["invoke", 14, 11, 279, 3],
|
|
||||||
"call_done_379",
|
|
||||||
"if_end_350",
|
"if_end_350",
|
||||||
["null", 7, 279, 3],
|
["null", 7, 276, 17],
|
||||||
["return", 7, 279, 3]
|
["return", 7, 276, 17]
|
||||||
],
|
],
|
||||||
"_write_types": [null, null, null, "bool", null, null, null, null, "function", "function", "function", null, "function", null, null, null, null, null, "function", null, null, null, "function", "function", null, null, "int", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", null, null, "text", null, null, "text", null, null, "text", null, null, "text", null, null, "text", null, null, "text", null, null, "text", null, null, "text", null, null, "function", null, null, "text", null, null, "text", null, null, null, null, null, null, null, null, null, "null", "text", "array", null, null, null, "text", null, "text", null, null, null, "null", "text", "array", null, null, null, "text", null, "text", "text", "bool", null, null, "text", "text", "array", null, null, "null", null, null, "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "array", "int", "bool", null, null, null, "text", "text", "bool", null, null, "text", "text", "array", null, null, "null", null, null, "bool", "bool", null, "text", "text", "array", null, null, "null", null, null, "int", "text", null, null, null, "null", "text", "array", null, null, null, "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "array", "int", "bool", null, null, null, "text", "text", "bool", null, null, "text", "text", "array", null, null, "null", null, null, "bool", "bool", null, "text", "text", "array", null, null, "null", null, null, "int", "text", null, null, null, "null", "text", "array", null, null, null, "null"],
|
"_write_types": [null, null, null, "bool", null, null, null, null, "function", "function", "function", null, "function", null, null, null, null, null, "function", null, null, null, "function", "function", null, null, "int", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", "function", null, null, "text", null, null, "text", null, null, "text", null, null, "text", null, null, "text", null, null, "text", null, null, "text", null, null, "text", null, null, "function", null, null, "text", null, null, "text", null, null, null, null, null, null, null, null, null, "null", "text", "array", null, null, null, "text", null, "text", null, null, null, "null", "text", "array", null, null, null, "text", null, "text", "text", "bool", null, null, "text", "text", "array", null, null, "null", null, null, "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "array", "int", "bool", null, null, null, "text", "text", "bool", null, null, "text", "text", "array", null, null, "null", null, null, "bool", "bool", null, "text", "text", "array", null, null, "null", null, null, "int", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "record", "text", "text", "array", "int", "bool", null, null, null, "text", "text", "bool", null, null, "text", "text", "array", null, null, "null", null, null, "bool", "bool", null, "text", "text", "array", null, null, "null", null, null, "int", "null"],
|
||||||
"nr_args": 0,
|
"nr_args": 0,
|
||||||
"closure_written": {
|
"closure_written": {
|
||||||
"7": true,
|
"7": true,
|
||||||
|
|||||||
17499
boot/mcode.cm.mcode
17499
boot/mcode.cm.mcode
File diff suppressed because one or more lines are too long
@@ -3348,7 +3348,7 @@
|
|||||||
{
|
{
|
||||||
"_closure_slot_types": {},
|
"_closure_slot_types": {},
|
||||||
"disruption_pc": 0,
|
"disruption_pc": 0,
|
||||||
"nr_slots": 7,
|
"nr_slots": 8,
|
||||||
"nr_close_slots": 0,
|
"nr_close_slots": 0,
|
||||||
"instructions": [
|
"instructions": [
|
||||||
["get", 2, 14, 2, 1167, 15],
|
["get", 2, 14, 2, 1167, 15],
|
||||||
@@ -3356,23 +3356,35 @@
|
|||||||
["invoke", 3, 2, 1167, 15],
|
["invoke", 3, 2, 1167, 15],
|
||||||
["move", 3, 2, 1167, 15],
|
["move", 3, 2, 1167, 15],
|
||||||
["access", 2, 8, 1, 13],
|
["access", 2, 8, 1, 13],
|
||||||
"_nop_tc_1",
|
["is_num", 4, 1, 1, 13],
|
||||||
"_nop_tc_2",
|
["jump_false", 4, "num_err_160", 1, 13],
|
||||||
["multiply", 4, 1, 2, 1, 13],
|
["multiply", 4, 1, 2, 1, 13],
|
||||||
["jump", "num_done_161", 1, 13],
|
["jump", "num_done_161", 1, 13],
|
||||||
"num_err_160",
|
"num_err_160",
|
||||||
"_nop_ucfg_1",
|
[
|
||||||
"_nop_ucfg_2",
|
"access",
|
||||||
"_nop_ucfg_3",
|
2,
|
||||||
"_nop_ucfg_4",
|
{
|
||||||
"_nop_ucfg_5",
|
"name": "log",
|
||||||
"_nop_ucfg_6",
|
"kind": "name",
|
||||||
"_nop_ucfg_7",
|
"make": "intrinsic"
|
||||||
"_nop_ucfg_8",
|
},
|
||||||
"_nop_ucfg_9",
|
1,
|
||||||
"_nop_ucfg_10",
|
13
|
||||||
"_nop_ucfg_11",
|
],
|
||||||
"_nop_ucfg_12",
|
["access", 5, "error", 1, 13],
|
||||||
|
["access", 6, "operands must be numbers", 1, 13],
|
||||||
|
["array", 7, 0, 1, 13],
|
||||||
|
["stone_text", 6],
|
||||||
|
["push", 7, 6, 1, 13],
|
||||||
|
["frame", 6, 2, 2, 1, 13],
|
||||||
|
["null", 2, 1, 13],
|
||||||
|
["setarg", 6, 0, 2, 1, 13],
|
||||||
|
["stone_text", 5],
|
||||||
|
["setarg", 6, 1, 5, 1, 13],
|
||||||
|
["setarg", 6, 2, 7, 1, 13],
|
||||||
|
["invoke", 6, 2, 1, 13],
|
||||||
|
["disrupt", 1, 13],
|
||||||
"num_done_161",
|
"num_done_161",
|
||||||
[
|
[
|
||||||
"access",
|
"access",
|
||||||
@@ -3459,7 +3471,7 @@
|
|||||||
"_nop_ur_1",
|
"_nop_ur_1",
|
||||||
"_nop_ur_2"
|
"_nop_ur_2"
|
||||||
],
|
],
|
||||||
"_write_types": [null, null, null, null, null, null, "int", "num", null, null, null, null, null, null, null, null, null, null, null, "array", null, "text", null, null, null, null, null, "array", null, "text", null, null, null, null, null, "array", null, "text", null, null, null],
|
"_write_types": [null, null, null, null, null, null, "int", "num", "bool", null, "text", "text", "array", null, null, "null", null, null, null, "array", null, "text", null, null, null, null, null, "array", null, "text", null, null, null, null, null, "array", null, "text", null, null, null],
|
||||||
"name": "<anonymous>",
|
"name": "<anonymous>",
|
||||||
"filename": ".cell/packages/core/qbe_emit.cm",
|
"filename": ".cell/packages/core/qbe_emit.cm",
|
||||||
"nr_args": 1
|
"nr_args": 1
|
||||||
@@ -3467,7 +3479,7 @@
|
|||||||
{
|
{
|
||||||
"_closure_slot_types": {},
|
"_closure_slot_types": {},
|
||||||
"disruption_pc": 0,
|
"disruption_pc": 0,
|
||||||
"nr_slots": 9,
|
"nr_slots": 10,
|
||||||
"nr_close_slots": 0,
|
"nr_close_slots": 0,
|
||||||
"instructions": [
|
"instructions": [
|
||||||
["get", 3, 14, 2, 1174, 15],
|
["get", 3, 14, 2, 1174, 15],
|
||||||
@@ -3541,23 +3553,35 @@
|
|||||||
"if_else_162",
|
"if_else_162",
|
||||||
"if_end_163",
|
"if_end_163",
|
||||||
["access", 5, 8, 1, 13],
|
["access", 5, 8, 1, 13],
|
||||||
"_nop_tc_1",
|
["is_num", 6, 1, 1, 13],
|
||||||
"_nop_tc_2",
|
["jump_false", 6, "num_err_164", 1, 13],
|
||||||
["multiply", 6, 1, 5, 1, 13],
|
["multiply", 6, 1, 5, 1, 13],
|
||||||
["jump", "num_done_165", 1, 13],
|
["jump", "num_done_165", 1, 13],
|
||||||
"num_err_164",
|
"num_err_164",
|
||||||
"_nop_ucfg_1",
|
[
|
||||||
"_nop_ucfg_2",
|
"access",
|
||||||
"_nop_ucfg_3",
|
5,
|
||||||
"_nop_ucfg_4",
|
{
|
||||||
"_nop_ucfg_5",
|
"name": "log",
|
||||||
"_nop_ucfg_6",
|
"kind": "name",
|
||||||
"_nop_ucfg_7",
|
"make": "intrinsic"
|
||||||
"_nop_ucfg_8",
|
},
|
||||||
"_nop_ucfg_9",
|
1,
|
||||||
"_nop_ucfg_10",
|
13
|
||||||
"_nop_ucfg_11",
|
],
|
||||||
"_nop_ucfg_12",
|
["access", 7, "error", 1, 13],
|
||||||
|
["access", 8, "operands must be numbers", 1, 13],
|
||||||
|
["array", 9, 0, 1, 13],
|
||||||
|
["stone_text", 8],
|
||||||
|
["push", 9, 8, 1, 13],
|
||||||
|
["frame", 8, 5, 2, 1, 13],
|
||||||
|
["null", 5, 1, 13],
|
||||||
|
["setarg", 8, 0, 5, 1, 13],
|
||||||
|
["stone_text", 7],
|
||||||
|
["setarg", 8, 1, 7, 1, 13],
|
||||||
|
["setarg", 8, 2, 9, 1, 13],
|
||||||
|
["invoke", 8, 5, 1, 13],
|
||||||
|
["disrupt", 1, 13],
|
||||||
"num_done_165",
|
"num_done_165",
|
||||||
[
|
[
|
||||||
"access",
|
"access",
|
||||||
@@ -3624,7 +3648,7 @@
|
|||||||
["null", 3, 1181, 7],
|
["null", 3, 1181, 7],
|
||||||
["return", 3, 1181, 7]
|
["return", 3, 1181, 7]
|
||||||
],
|
],
|
||||||
"_write_types": [null, null, null, null, null, null, null, null, "text", "bool", null, null, null, "array", null, "text", null, "array", null, "text", null, null, null, null, null, "int", "num", null, null, null, null, null, null, null, null, null, null, null, "array", null, "text", null, null, null, null, null, "array", null, "text", null, null, null, null, null, "null"],
|
"_write_types": [null, null, null, null, null, null, null, null, "text", "bool", null, null, null, "array", null, "text", null, "array", null, "text", null, null, null, null, null, "int", "num", "bool", null, "text", "text", "array", null, null, "null", null, null, null, "array", null, "text", null, null, null, null, null, "array", null, "text", null, null, null, null, null, "null"],
|
||||||
"name": "<anonymous>",
|
"name": "<anonymous>",
|
||||||
"filename": ".cell/packages/core/qbe_emit.cm",
|
"filename": ".cell/packages/core/qbe_emit.cm",
|
||||||
"nr_args": 2
|
"nr_args": 2
|
||||||
|
|||||||
20117
boot/streamline.cm.mcode
20117
boot/streamline.cm.mcode
File diff suppressed because one or more lines are too long
140
build.cm
140
build.cm
@@ -65,7 +65,7 @@ function replace_sigils(str, pkg_dir) {
|
|||||||
function replace_sigils_array(flags, pkg_dir) {
|
function replace_sigils_array(flags, pkg_dir) {
|
||||||
var result = []
|
var result = []
|
||||||
arrfor(flags, function(flag) {
|
arrfor(flags, function(flag) {
|
||||||
push(result, replace_sigils(flag, pkg_dir))
|
result[] = replace_sigils(flag, pkg_dir)
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -179,7 +179,7 @@ function bmfst_save(cmd_str, src_path, deps, obj_path) {
|
|||||||
arrfor(deps, function(dep_path) {
|
arrfor(deps, function(dep_path) {
|
||||||
var st = memo_stat(dep_path)
|
var st = memo_stat(dep_path)
|
||||||
if (st)
|
if (st)
|
||||||
push(entries, {p: dep_path, m: st.m, s: st.s})
|
entries[] = {p: dep_path, m: st.m, s: st.s}
|
||||||
})
|
})
|
||||||
var mf = {o: obj_path, d: entries}
|
var mf = {o: obj_path, d: entries}
|
||||||
var mf_path = bmfst_path(cmd_str, src_path)
|
var mf_path = bmfst_path(cmd_str, src_path)
|
||||||
@@ -191,16 +191,16 @@ function bmfst_save(cmd_str, src_path, deps, obj_path) {
|
|||||||
|
|
||||||
function bmfst_dl_key(setup, link_info) {
|
function bmfst_dl_key(setup, link_info) {
|
||||||
var parts = [setup.cmd_str, setup.src_path]
|
var parts = [setup.cmd_str, setup.src_path]
|
||||||
push(parts, 'target:' + text(link_info.target))
|
parts[] = 'target:' + text(link_info.target)
|
||||||
push(parts, 'cc:' + text(link_info.cc))
|
parts[] = 'cc:' + text(link_info.cc)
|
||||||
arrfor(link_info.extra_objects, function(obj) {
|
arrfor(link_info.extra_objects, function(obj) {
|
||||||
if (obj != null) push(parts, 'extra:' + text(obj))
|
if (obj != null) parts[] = 'extra:' + text(obj)
|
||||||
})
|
})
|
||||||
arrfor(link_info.ldflags, function(flag) {
|
arrfor(link_info.ldflags, function(flag) {
|
||||||
push(parts, 'ldflag:' + text(flag))
|
parts[] = 'ldflag:' + text(flag)
|
||||||
})
|
})
|
||||||
arrfor(link_info.target_ldflags, function(flag) {
|
arrfor(link_info.target_ldflags, function(flag) {
|
||||||
push(parts, 'target_ldflag:' + text(flag))
|
parts[] = 'target_ldflag:' + text(flag)
|
||||||
})
|
})
|
||||||
return text(parts, '\n')
|
return text(parts, '\n')
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ function bmfst_dl_save(setup, link_info, deps, dylib_path) {
|
|||||||
arrfor(deps, function(dep_path) {
|
arrfor(deps, function(dep_path) {
|
||||||
var st = memo_stat(dep_path)
|
var st = memo_stat(dep_path)
|
||||||
if (st)
|
if (st)
|
||||||
push(entries, {p: dep_path, m: st.m, s: st.s})
|
entries[] = {p: dep_path, m: st.m, s: st.s}
|
||||||
})
|
})
|
||||||
var mf = {dylib: dylib_path, d: entries}
|
var mf = {dylib: dylib_path, d: entries}
|
||||||
var mf_path = cache_path(bmfst_dl_key(setup, link_info), SALT_BMFST_DL)
|
var mf_path = cache_path(bmfst_dl_key(setup, link_info), SALT_BMFST_DL)
|
||||||
@@ -259,7 +259,7 @@ function get_c_deps(cc, flags, src_path) {
|
|||||||
var dep_file = '/tmp/cell_deps_' + content_hash(src_path) + '.d'
|
var dep_file = '/tmp/cell_deps_' + content_hash(src_path) + '.d'
|
||||||
var dep_cmd = [cc, '-MM', '-MG', '-MF', '"' + dep_file + '"']
|
var dep_cmd = [cc, '-MM', '-MG', '-MF', '"' + dep_file + '"']
|
||||||
dep_cmd = array(dep_cmd, flags)
|
dep_cmd = array(dep_cmd, flags)
|
||||||
push(dep_cmd, '"' + src_path + '"')
|
dep_cmd[] = '"' + src_path + '"'
|
||||||
var ret = os.system(text(dep_cmd, ' ') + ' 2>/dev/null')
|
var ret = os.system(text(dep_cmd, ' ') + ' 2>/dev/null')
|
||||||
if (ret != 0) return [src_path]
|
if (ret != 0) return [src_path]
|
||||||
if (!fd.is_file(dep_file)) return [src_path]
|
if (!fd.is_file(dep_file)) return [src_path]
|
||||||
@@ -274,9 +274,9 @@ function hash_all_deps(cmd_str, deps) {
|
|||||||
arrfor(deps, function(dep_path) {
|
arrfor(deps, function(dep_path) {
|
||||||
var content = memo_read(dep_path)
|
var content = memo_read(dep_path)
|
||||||
if (content != null)
|
if (content != null)
|
||||||
push(parts, dep_path + '\n' + content)
|
parts[] = dep_path + '\n' + content
|
||||||
else
|
else
|
||||||
push(parts, dep_path + '\n<missing>')
|
parts[] = dep_path + '\n<missing>'
|
||||||
})
|
})
|
||||||
return text(parts, '\n')
|
return text(parts, '\n')
|
||||||
}
|
}
|
||||||
@@ -310,16 +310,16 @@ function compile_setup(pkg, file, target, opts) {
|
|||||||
common_flags = array(common_flags, ['-Os', '-DNDEBUG'])
|
common_flags = array(common_flags, ['-Os', '-DNDEBUG'])
|
||||||
}
|
}
|
||||||
|
|
||||||
push(common_flags, '-DCELL_USE_NAME=' + sym_name)
|
common_flags[] = '-DCELL_USE_NAME=' + sym_name
|
||||||
push(common_flags, '-I"' + pkg_dir + '"')
|
common_flags[] = '-I"' + pkg_dir + '"'
|
||||||
|
|
||||||
if (fd.is_dir(pkg_dir + '/include')) {
|
if (fd.is_dir(pkg_dir + '/include')) {
|
||||||
push(common_flags, '-I"' + pkg_dir + '/include"')
|
common_flags[] = '-I"' + pkg_dir + '/include"'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkg != 'core') {
|
if (pkg != 'core') {
|
||||||
core_dir = shop.get_package_dir('core')
|
core_dir = shop.get_package_dir('core')
|
||||||
push(common_flags, '-I"' + core_dir + '/source"')
|
common_flags[] = '-I"' + core_dir + '/source"'
|
||||||
}
|
}
|
||||||
|
|
||||||
arrfor(cflags, function(flag) {
|
arrfor(cflags, function(flag) {
|
||||||
@@ -331,16 +331,16 @@ function compile_setup(pkg, file, target, opts) {
|
|||||||
f = '-I"' + pkg_dir + '/' + ipath + '"'
|
f = '-I"' + pkg_dir + '/' + ipath + '"'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(common_flags, f)
|
common_flags[] = f
|
||||||
})
|
})
|
||||||
|
|
||||||
arrfor(target_cflags, function(flag) {
|
arrfor(target_cflags, function(flag) {
|
||||||
push(common_flags, flag)
|
common_flags[] = flag
|
||||||
})
|
})
|
||||||
|
|
||||||
var cmd_parts = [cc, '-c', '-fPIC']
|
var cmd_parts = [cc, '-c', '-fPIC']
|
||||||
cmd_parts = array(cmd_parts, common_flags)
|
cmd_parts = array(cmd_parts, common_flags)
|
||||||
push(cmd_parts, '"' + src_path + '"')
|
cmd_parts[] = '"' + src_path + '"'
|
||||||
|
|
||||||
return {
|
return {
|
||||||
cmd_str: text(cmd_parts, ' '),
|
cmd_str: text(cmd_parts, ' '),
|
||||||
@@ -513,7 +513,7 @@ Build.build_package = function(pkg, target, exclude_main, buildtype) {
|
|||||||
|
|
||||||
arrfor(c_files, function(file) {
|
arrfor(c_files, function(file) {
|
||||||
var obj = Build.compile_file(pkg, file, _target, {buildtype: _buildtype, cflags: cached_cflags})
|
var obj = Build.compile_file(pkg, file, _target, {buildtype: _buildtype, cflags: cached_cflags})
|
||||||
push(objects, obj)
|
objects[] = obj
|
||||||
})
|
})
|
||||||
|
|
||||||
return objects
|
return objects
|
||||||
@@ -527,16 +527,16 @@ Build.build_package = function(pkg, target, exclude_main, buildtype) {
|
|||||||
// link_opts: {extra_objects, ldflags, target_ldflags, target, cc}
|
// link_opts: {extra_objects, ldflags, target_ldflags, target, cc}
|
||||||
function compute_dylib_content(full_content, link_opts) {
|
function compute_dylib_content(full_content, link_opts) {
|
||||||
var parts = [full_content]
|
var parts = [full_content]
|
||||||
push(parts, 'target:' + text(link_opts.target))
|
parts[] = 'target:' + text(link_opts.target)
|
||||||
push(parts, 'cc:' + text(link_opts.cc))
|
parts[] = 'cc:' + text(link_opts.cc)
|
||||||
arrfor(link_opts.extra_objects, function(obj) {
|
arrfor(link_opts.extra_objects, function(obj) {
|
||||||
if (obj != null) push(parts, 'extra:' + text(obj))
|
if (obj != null) parts[] = 'extra:' + text(obj)
|
||||||
})
|
})
|
||||||
arrfor(link_opts.ldflags, function(flag) {
|
arrfor(link_opts.ldflags, function(flag) {
|
||||||
push(parts, 'ldflag:' + text(flag))
|
parts[] = 'ldflag:' + text(flag)
|
||||||
})
|
})
|
||||||
arrfor(link_opts.target_ldflags, function(flag) {
|
arrfor(link_opts.target_ldflags, function(flag) {
|
||||||
push(parts, 'target_ldflag:' + text(flag))
|
parts[] = 'target_ldflag:' + text(flag)
|
||||||
})
|
})
|
||||||
return text(parts, '\n')
|
return text(parts, '\n')
|
||||||
}
|
}
|
||||||
@@ -570,7 +570,7 @@ Build.build_module_dylib = function(pkg, file, target, opts) {
|
|||||||
f = '-L"' + setup.pkg_dir + '/' + lpath + '"'
|
f = '-L"' + setup.pkg_dir + '/' + lpath + '"'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(resolved_ldflags, f)
|
resolved_ldflags[] = f
|
||||||
})
|
})
|
||||||
|
|
||||||
var build_dir = get_build_dir()
|
var build_dir = get_build_dir()
|
||||||
@@ -683,18 +683,18 @@ Build.build_module_dylib = function(pkg, file, target, opts) {
|
|||||||
'-Wl,-rpath,' + local_dir
|
'-Wl,-rpath,' + local_dir
|
||||||
])
|
])
|
||||||
} else if (tc.system == 'windows') {
|
} else if (tc.system == 'windows') {
|
||||||
push(cmd_parts, '-Wl,--allow-shlib-undefined')
|
cmd_parts[] = '-Wl,--allow-shlib-undefined'
|
||||||
}
|
}
|
||||||
|
|
||||||
push(cmd_parts, '-L"' + local_dir + '"')
|
cmd_parts[] = '-L"' + local_dir + '"'
|
||||||
push(cmd_parts, '"' + text(obj) + '"')
|
cmd_parts[] = '"' + text(obj) + '"'
|
||||||
arrfor(_extra, function(extra_obj) {
|
arrfor(_extra, function(extra_obj) {
|
||||||
if (extra_obj != null) push(cmd_parts, '"' + text(extra_obj) + '"')
|
if (extra_obj != null) cmd_parts[] = '"' + text(extra_obj) + '"'
|
||||||
})
|
})
|
||||||
cmd_parts = array(cmd_parts, resolved_ldflags)
|
cmd_parts = array(cmd_parts, resolved_ldflags)
|
||||||
cmd_parts = array(cmd_parts, target_ldflags)
|
cmd_parts = array(cmd_parts, target_ldflags)
|
||||||
push(cmd_parts, '-o')
|
cmd_parts[] = '-o'
|
||||||
push(cmd_parts, '"' + dylib_path + '"')
|
cmd_parts[] = '"' + dylib_path + '"'
|
||||||
|
|
||||||
cmd_str = text(cmd_parts, ' ')
|
cmd_str = text(cmd_parts, ' ')
|
||||||
if (_opts.verbose) log.build('[verbose] link: ' + cmd_str)
|
if (_opts.verbose) log.build('[verbose] link: ' + cmd_str)
|
||||||
@@ -737,7 +737,7 @@ Build.compile_c_module = function(pkg, file, target, opts) {
|
|||||||
if (pkg != 'core') {
|
if (pkg != 'core') {
|
||||||
arrfor(sources, function(src_file) {
|
arrfor(sources, function(src_file) {
|
||||||
var obj = Build.compile_file(pkg, src_file, _target, {buildtype: _buildtype, cflags: cached_cflags})
|
var obj = Build.compile_file(pkg, src_file, _target, {buildtype: _buildtype, cflags: cached_cflags})
|
||||||
if (obj != null) push(support_objects, obj)
|
if (obj != null) support_objects[] = obj
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,27 +767,23 @@ Build.build_dynamic = function(pkg, target, buildtype, opts) {
|
|||||||
if (pkg != 'core') {
|
if (pkg != 'core') {
|
||||||
arrfor(sources, function(src_file) {
|
arrfor(sources, function(src_file) {
|
||||||
var obj = Build.compile_file(pkg, src_file, _target, {buildtype: _buildtype, cflags: cached_cflags, verbose: _opts.verbose, force: _opts.force})
|
var obj = Build.compile_file(pkg, src_file, _target, {buildtype: _buildtype, cflags: cached_cflags, verbose: _opts.verbose, force: _opts.force})
|
||||||
if (obj != null) push(support_objects, obj)
|
if (obj != null) support_objects[] = obj
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (total > 0)
|
|
||||||
os.print(' Building C modules ')
|
|
||||||
|
|
||||||
arrfor(c_files, function(file) {
|
arrfor(c_files, function(file) {
|
||||||
var sym_name = shop.c_symbol_for_file(pkg, file)
|
var sym_name = shop.c_symbol_for_file(pkg, file)
|
||||||
var dylib = Build.build_module_dylib(pkg, file, _target, {buildtype: _buildtype, extra_objects: support_objects, cflags: cached_cflags, verbose: _opts.verbose, force: _opts.force})
|
var dylib = Build.build_module_dylib(pkg, file, _target, {buildtype: _buildtype, extra_objects: support_objects, cflags: cached_cflags, verbose: _opts.verbose, force: _opts.force})
|
||||||
if (dylib) {
|
if (dylib) {
|
||||||
push(results, {file: file, symbol: sym_name, dylib: dylib})
|
results[] = {file: file, symbol: sym_name, dylib: dylib}
|
||||||
} else {
|
} else {
|
||||||
failed = failed + 1
|
failed = failed + 1
|
||||||
}
|
}
|
||||||
done = done + 1
|
done = done + 1
|
||||||
os.print('.')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (total > 0)
|
if (total > 0)
|
||||||
os.print(` ${text(done)}/${text(total)}${failed > 0 ? `, ${text(failed)} failed` : ''}\n`)
|
log.build(` Building C modules (${text(done)} ok${failed > 0 ? `, ${text(failed)} failed` : ''})`)
|
||||||
|
|
||||||
// Write manifest so runtime can find dylibs without the build module
|
// Write manifest so runtime can find dylibs without the build module
|
||||||
var mpath = manifest_path(pkg)
|
var mpath = manifest_path(pkg)
|
||||||
@@ -818,7 +814,7 @@ Build.build_static = function(packages, target, output, buildtype) {
|
|||||||
var objects = Build.build_package(pkg, _target, !is_core, _buildtype)
|
var objects = Build.build_package(pkg, _target, !is_core, _buildtype)
|
||||||
|
|
||||||
arrfor(objects, function(obj) {
|
arrfor(objects, function(obj) {
|
||||||
push(all_objects, obj)
|
all_objects[] = obj
|
||||||
})
|
})
|
||||||
|
|
||||||
// Collect LDFLAGS (with sigil replacement)
|
// Collect LDFLAGS (with sigil replacement)
|
||||||
@@ -838,7 +834,7 @@ Build.build_static = function(packages, target, output, buildtype) {
|
|||||||
f = '-L"' + pkg_dir + '/' + lpath + '"'
|
f = '-L"' + pkg_dir + '/' + lpath + '"'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(all_ldflags, f)
|
all_ldflags[] = f
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -860,18 +856,18 @@ Build.build_static = function(packages, target, output, buildtype) {
|
|||||||
var cmd_parts = [cc]
|
var cmd_parts = [cc]
|
||||||
|
|
||||||
arrfor(all_objects, function(obj) {
|
arrfor(all_objects, function(obj) {
|
||||||
push(cmd_parts, '"' + obj + '"')
|
cmd_parts[] = '"' + obj + '"'
|
||||||
})
|
})
|
||||||
|
|
||||||
arrfor(all_ldflags, function(flag) {
|
arrfor(all_ldflags, function(flag) {
|
||||||
push(cmd_parts, flag)
|
cmd_parts[] = flag
|
||||||
})
|
})
|
||||||
|
|
||||||
arrfor(target_ldflags, function(flag) {
|
arrfor(target_ldflags, function(flag) {
|
||||||
push(cmd_parts, flag)
|
cmd_parts[] = flag
|
||||||
})
|
})
|
||||||
|
|
||||||
push(cmd_parts, '-o', '"' + out_path + '"')
|
cmd_parts[] = '-o', '"' + out_path + '"'
|
||||||
|
|
||||||
var cmd_str = text(cmd_parts, ' ')
|
var cmd_str = text(cmd_parts, ' ')
|
||||||
|
|
||||||
@@ -925,7 +921,7 @@ function qbe_insert_dead_labels(il_text) {
|
|||||||
line = lines[i]
|
line = lines[i]
|
||||||
trimmed = trim(line)
|
trimmed = trim(line)
|
||||||
if (need_label && !starts_with(trimmed, '@') && !starts_with(trimmed, '}') && length(trimmed) > 0) {
|
if (need_label && !starts_with(trimmed, '@') && !starts_with(trimmed, '}') && length(trimmed) > 0) {
|
||||||
push(result, "@_dead_" + text(dead_id))
|
result[] = "@_dead_" + text(dead_id)
|
||||||
dead_id = dead_id + 1
|
dead_id = dead_id + 1
|
||||||
need_label = false
|
need_label = false
|
||||||
}
|
}
|
||||||
@@ -935,7 +931,7 @@ function qbe_insert_dead_labels(il_text) {
|
|||||||
if (starts_with(trimmed, 'ret ') || starts_with(trimmed, 'jmp ')) {
|
if (starts_with(trimmed, 'ret ') || starts_with(trimmed, 'jmp ')) {
|
||||||
need_label = true
|
need_label = true
|
||||||
}
|
}
|
||||||
push(result, line)
|
result[] = line
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
return text(result, "\n")
|
return text(result, "\n")
|
||||||
@@ -1126,16 +1122,16 @@ Build.compile_cm_to_mach = function(src_path) {
|
|||||||
// output: path to write the generated .c file
|
// output: path to write the generated .c file
|
||||||
Build.generate_module_table = function(modules, output) {
|
Build.generate_module_table = function(modules, output) {
|
||||||
var lines = []
|
var lines = []
|
||||||
push(lines, '/* Generated module table — do not edit */')
|
lines[] = '/* Generated module table — do not edit */'
|
||||||
push(lines, '#include <stddef.h>')
|
lines[] = '#include <stddef.h>'
|
||||||
push(lines, '#include <string.h>')
|
lines[] = '#include <string.h>'
|
||||||
push(lines, '')
|
lines[] = ''
|
||||||
push(lines, 'struct cell_embedded_entry {')
|
lines[] = 'struct cell_embedded_entry {'
|
||||||
push(lines, ' const char *name;')
|
lines[] = ' const char *name;'
|
||||||
push(lines, ' const unsigned char *data;')
|
lines[] = ' const unsigned char *data;'
|
||||||
push(lines, ' size_t size;')
|
lines[] = ' size_t size;'
|
||||||
push(lines, '};')
|
lines[] = '};'
|
||||||
push(lines, '')
|
lines[] = ''
|
||||||
|
|
||||||
var entries = []
|
var entries = []
|
||||||
arrfor(modules, function(mod) {
|
arrfor(modules, function(mod) {
|
||||||
@@ -1144,27 +1140,27 @@ Build.generate_module_table = function(modules, output) {
|
|||||||
var bytes = array(mach)
|
var bytes = array(mach)
|
||||||
var hex = []
|
var hex = []
|
||||||
arrfor(bytes, function(b) {
|
arrfor(bytes, function(b) {
|
||||||
push(hex, '0x' + text(b, 'h2'))
|
hex[] = '0x' + text(b, 'h2')
|
||||||
})
|
})
|
||||||
push(lines, 'static const unsigned char mod_' + safe + '_data[] = {')
|
lines[] = 'static const unsigned char mod_' + safe + '_data[] = {'
|
||||||
push(lines, ' ' + text(hex, ', '))
|
lines[] = ' ' + text(hex, ', ')
|
||||||
push(lines, '};')
|
lines[] = '};'
|
||||||
push(lines, '')
|
lines[] = ''
|
||||||
push(entries, safe)
|
entries[] = safe
|
||||||
log.console('Embedded: ' + mod.name + ' (' + text(length(bytes)) + ' bytes)')
|
log.console('Embedded: ' + mod.name + ' (' + text(length(bytes)) + ' bytes)')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Lookup function
|
// Lookup function
|
||||||
push(lines, 'const struct cell_embedded_entry *cell_embedded_module_lookup(const char *name) {')
|
lines[] = 'const struct cell_embedded_entry *cell_embedded_module_lookup(const char *name) {'
|
||||||
arrfor(modules, function(mod, i) {
|
arrfor(modules, function(mod, i) {
|
||||||
var safe = entries[i]
|
var safe = entries[i]
|
||||||
push(lines, ' if (strcmp(name, "' + mod.name + '") == 0) {')
|
lines[] = ' if (strcmp(name, "' + mod.name + '") == 0) {'
|
||||||
push(lines, ' static const struct cell_embedded_entry e = {"' + mod.name + '", mod_' + safe + '_data, sizeof(mod_' + safe + '_data)};')
|
lines[] = ' static const struct cell_embedded_entry e = {"' + mod.name + '", mod_' + safe + '_data, sizeof(mod_' + safe + '_data)};'
|
||||||
push(lines, ' return &e;')
|
lines[] = ' return &e;'
|
||||||
push(lines, ' }')
|
lines[] = ' }'
|
||||||
})
|
})
|
||||||
push(lines, ' return (void *)0;')
|
lines[] = ' return (void *)0;'
|
||||||
push(lines, '}')
|
lines[] = '}'
|
||||||
|
|
||||||
var c_text = text(lines, '\n')
|
var c_text = text(lines, '\n')
|
||||||
fd.slurpwrite(output, stone(blob(c_text)))
|
fd.slurpwrite(output, stone(blob(c_text)))
|
||||||
@@ -1192,14 +1188,14 @@ Build.build_all_dynamic = function(target, buildtype, opts) {
|
|||||||
// Build core first
|
// Build core first
|
||||||
if (find(packages, function(p) { return p == 'core' }) != null) {
|
if (find(packages, function(p) { return p == 'core' }) != null) {
|
||||||
core_mods = Build.build_dynamic('core', _target, _buildtype, _opts)
|
core_mods = Build.build_dynamic('core', _target, _buildtype, _opts)
|
||||||
push(results, {package: 'core', modules: core_mods})
|
results[] = {package: 'core', modules: core_mods}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build other packages
|
// Build other packages
|
||||||
arrfor(packages, function(pkg) {
|
arrfor(packages, function(pkg) {
|
||||||
if (pkg == 'core') return
|
if (pkg == 'core') return
|
||||||
var pkg_mods = Build.build_dynamic(pkg, _target, _buildtype, _opts)
|
var pkg_mods = Build.build_dynamic(pkg, _target, _buildtype, _opts)
|
||||||
push(results, {package: pkg, modules: pkg_mods})
|
results[] = {package: pkg, modules: pkg_mods}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Print build report
|
// Print build report
|
||||||
|
|||||||
12
cellfs.cm
12
cellfs.cm
@@ -152,7 +152,7 @@ function mount(source, name) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(mounts, mount_info)
|
mounts[] = mount_info
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ function mount(source, name) {
|
|||||||
log.error("Unsupported mount source type: " + source); disrupt
|
log.error("Unsupported mount source type: " + source); disrupt
|
||||||
}
|
}
|
||||||
|
|
||||||
push(mounts, mount_info)
|
mounts[] = mount_info
|
||||||
}
|
}
|
||||||
|
|
||||||
function unmount(name_or_source) {
|
function unmount(name_or_source) {
|
||||||
@@ -356,7 +356,7 @@ function enumerate(_path, recurse) {
|
|||||||
arrfor(list, function(item) {
|
arrfor(list, function(item) {
|
||||||
var item_rel = rel_prefix ? rel_prefix + "/" + item : item
|
var item_rel = rel_prefix ? rel_prefix + "/" + item : item
|
||||||
var child_st = null
|
var child_st = null
|
||||||
push(results, item_rel)
|
results[] = item_rel
|
||||||
|
|
||||||
if (recurse) {
|
if (recurse) {
|
||||||
child_st = fd.stat(fd.join_paths(curr_full, item))
|
child_st = fd.stat(fd.join_paths(curr_full, item))
|
||||||
@@ -396,7 +396,7 @@ function enumerate(_path, recurse) {
|
|||||||
|
|
||||||
if (!seen[rel]) {
|
if (!seen[rel]) {
|
||||||
seen[rel] = true
|
seen[rel] = true
|
||||||
push(results, rel)
|
results[] = rel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -455,7 +455,7 @@ function globfs(globs, _dir) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!check_neg(item_rel) && check_pos(item_rel)) {
|
if (!check_neg(item_rel) && check_pos(item_rel)) {
|
||||||
push(results, item_rel)
|
results[] = item_rel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -479,7 +479,7 @@ function globfs(globs, _dir) {
|
|||||||
if (length(rel) == 0) return
|
if (length(rel) == 0) return
|
||||||
|
|
||||||
if (!check_neg(rel) && check_pos(rel)) {
|
if (!check_neg(rel) && check_pos(rel)) {
|
||||||
push(results, rel)
|
results[] = rel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
18
cfg.ce
18
cfg.ce
@@ -168,7 +168,7 @@ var run = function() {
|
|||||||
if (is_array(instr)) {
|
if (is_array(instr)) {
|
||||||
if (block_start_pcs[text(pc)]) {
|
if (block_start_pcs[text(pc)]) {
|
||||||
if (current_block != null) {
|
if (current_block != null) {
|
||||||
push(blocks, current_block)
|
blocks[] = current_block
|
||||||
}
|
}
|
||||||
current_block = {
|
current_block = {
|
||||||
id: length(blocks),
|
id: length(blocks),
|
||||||
@@ -184,7 +184,7 @@ var run = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (current_block != null) {
|
if (current_block != null) {
|
||||||
push(current_block.instrs, {pc: pc, instr: instr})
|
current_block.instrs[] = {pc: pc, instr: instr}
|
||||||
current_block.end_pc = pc
|
current_block.end_pc = pc
|
||||||
n = length(instr)
|
n = length(instr)
|
||||||
line_num = instr[n - 2]
|
line_num = instr[n - 2]
|
||||||
@@ -200,7 +200,7 @@ var run = function() {
|
|||||||
ii = ii + 1
|
ii = ii + 1
|
||||||
}
|
}
|
||||||
if (current_block != null) {
|
if (current_block != null) {
|
||||||
push(blocks, current_block)
|
blocks[] = current_block
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build block index
|
// Build block index
|
||||||
@@ -235,19 +235,19 @@ var run = function() {
|
|||||||
if (target_bi <= bi) {
|
if (target_bi <= bi) {
|
||||||
edge_type = "loop back-edge"
|
edge_type = "loop back-edge"
|
||||||
}
|
}
|
||||||
push(blk.edges, {target: target_bi, kind: edge_type})
|
blk.edges[] = {target: target_bi, kind: edge_type}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_conditional_jump(last_op)) {
|
if (is_conditional_jump(last_op)) {
|
||||||
if (bi + 1 < length(blocks)) {
|
if (bi + 1 < length(blocks)) {
|
||||||
push(blk.edges, {target: bi + 1, kind: "fallthrough"})
|
blk.edges[] = {target: bi + 1, kind: "fallthrough"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (is_terminator(last_op)) {
|
} else if (is_terminator(last_op)) {
|
||||||
push(blk.edges, {target: -1, kind: "EXIT (" + last_op + ")"})
|
blk.edges[] = {target: -1, kind: "EXIT (" + last_op + ")"}
|
||||||
} else {
|
} else {
|
||||||
if (bi + 1 < length(blocks)) {
|
if (bi + 1 < length(blocks)) {
|
||||||
push(blk.edges, {target: bi + 1, kind: "fallthrough"})
|
blk.edges[] = {target: bi + 1, kind: "fallthrough"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@ var run = function() {
|
|||||||
parts = []
|
parts = []
|
||||||
j = 1
|
j = 1
|
||||||
while (j < n - 2) {
|
while (j < n - 2) {
|
||||||
push(parts, fmt_val(instr[j]))
|
parts[] = fmt_val(instr[j])
|
||||||
j = j + 1
|
j = j + 1
|
||||||
}
|
}
|
||||||
operands = text(parts, ", ")
|
operands = text(parts, ", ")
|
||||||
@@ -381,7 +381,7 @@ var run = function() {
|
|||||||
parts = []
|
parts = []
|
||||||
j = 1
|
j = 1
|
||||||
while (j < n - 2) {
|
while (j < n - 2) {
|
||||||
push(parts, fmt_val(instr[j]))
|
parts[] = fmt_val(instr[j])
|
||||||
j = j + 1
|
j = j + 1
|
||||||
}
|
}
|
||||||
operands = text(parts, ", ")
|
operands = text(parts, ", ")
|
||||||
|
|||||||
12
clean.ce
12
clean.ce
@@ -93,13 +93,13 @@ if (is_shop_scope) {
|
|||||||
packages_to_clean = shop.list_packages()
|
packages_to_clean = shop.list_packages()
|
||||||
} else {
|
} else {
|
||||||
// Single package
|
// Single package
|
||||||
push(packages_to_clean, scope)
|
packages_to_clean[] = scope
|
||||||
|
|
||||||
if (deep) {
|
if (deep) {
|
||||||
_gather = function() {
|
_gather = function() {
|
||||||
deps = pkg.gather_dependencies(scope)
|
deps = pkg.gather_dependencies(scope)
|
||||||
arrfor(deps, function(dep) {
|
arrfor(deps, function(dep) {
|
||||||
push(packages_to_clean, dep)
|
packages_to_clean[] = dep
|
||||||
})
|
})
|
||||||
} disruption {
|
} disruption {
|
||||||
// Skip if can't read dependencies
|
// Skip if can't read dependencies
|
||||||
@@ -116,11 +116,11 @@ var packages_dir = replace(shop.get_package_dir(''), /\/$/, '') // Get base pack
|
|||||||
if (clean_build) {
|
if (clean_build) {
|
||||||
// Nuke entire build cache (content-addressed, per-package clean impractical)
|
// Nuke entire build cache (content-addressed, per-package clean impractical)
|
||||||
if (fd.is_dir(build_dir)) {
|
if (fd.is_dir(build_dir)) {
|
||||||
push(dirs_to_delete, build_dir)
|
dirs_to_delete[] = build_dir
|
||||||
}
|
}
|
||||||
// Clean orphaned lib/ directory if it exists (legacy)
|
// Clean orphaned lib/ directory if it exists (legacy)
|
||||||
if (fd.is_dir(lib_dir)) {
|
if (fd.is_dir(lib_dir)) {
|
||||||
push(dirs_to_delete, lib_dir)
|
dirs_to_delete[] = lib_dir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ if (clean_fetch) {
|
|||||||
if (is_shop_scope) {
|
if (is_shop_scope) {
|
||||||
// Clean entire packages directory (dangerous!)
|
// Clean entire packages directory (dangerous!)
|
||||||
if (fd.is_dir(packages_dir)) {
|
if (fd.is_dir(packages_dir)) {
|
||||||
push(dirs_to_delete, packages_dir)
|
dirs_to_delete[] = packages_dir
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Clean specific package directories
|
// Clean specific package directories
|
||||||
@@ -137,7 +137,7 @@ if (clean_fetch) {
|
|||||||
|
|
||||||
var pkg_dir = shop.get_package_dir(p)
|
var pkg_dir = shop.get_package_dir(p)
|
||||||
if (fd.is_dir(pkg_dir) || fd.is_link(pkg_dir)) {
|
if (fd.is_dir(pkg_dir) || fd.is_link(pkg_dir)) {
|
||||||
push(dirs_to_delete, pkg_dir)
|
dirs_to_delete[] = pkg_dir
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
24
diff.ce
24
diff.ce
@@ -55,7 +55,7 @@ function collect_tests(specific_test) {
|
|||||||
match_base = ends_with(match_name, '.cm') ? text(match_name, 0, -3) : match_name
|
match_base = ends_with(match_name, '.cm') ? text(match_name, 0, -3) : match_name
|
||||||
if (test_name != match_base) continue
|
if (test_name != match_base) continue
|
||||||
}
|
}
|
||||||
push(test_files, f)
|
test_files[] = f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return test_files
|
return test_files
|
||||||
@@ -100,7 +100,7 @@ function diff_test_file(file_path) {
|
|||||||
src = text(fd.slurp(src_path))
|
src = text(fd.slurp(src_path))
|
||||||
ast = analyze(src, src_path)
|
ast = analyze(src, src_path)
|
||||||
} disruption {
|
} disruption {
|
||||||
push(results.errors, `failed to parse ${file_path}`)
|
results.errors[] = `failed to parse ${file_path}`
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
_read()
|
_read()
|
||||||
@@ -124,14 +124,14 @@ function diff_test_file(file_path) {
|
|||||||
|
|
||||||
// Compare module-level behavior
|
// Compare module-level behavior
|
||||||
if (opt_error != noopt_error) {
|
if (opt_error != noopt_error) {
|
||||||
push(results.errors, `module load mismatch: opt=${opt_error != null ? opt_error : "ok"} noopt=${noopt_error != null ? noopt_error : "ok"}`)
|
results.errors[] = `module load mismatch: opt=${opt_error != null ? opt_error : "ok"} noopt=${noopt_error != null ? noopt_error : "ok"}`
|
||||||
results.failed = results.failed + 1
|
results.failed = results.failed + 1
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
if (opt_error != null) {
|
if (opt_error != null) {
|
||||||
// Both disrupted during load — that's consistent
|
// Both disrupted during load — that's consistent
|
||||||
results.passed = results.passed + 1
|
results.passed = results.passed + 1
|
||||||
push(results.tests, {name: "<module>", status: "passed"})
|
results.tests[] = {name: "<module>", status: "passed"}
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,15 +161,15 @@ function diff_test_file(file_path) {
|
|||||||
_run_one_noopt()
|
_run_one_noopt()
|
||||||
|
|
||||||
if (opt_err != noopt_err) {
|
if (opt_err != noopt_err) {
|
||||||
push(results.tests, {name: k, status: "failed"})
|
results.tests[] = {name: k, status: "failed"}
|
||||||
push(results.errors, `${k}: disruption mismatch opt=${opt_err != null ? opt_err : "ok"} noopt=${noopt_err != null ? noopt_err : "ok"}`)
|
results.errors[] = `${k}: disruption mismatch opt=${opt_err != null ? opt_err : "ok"} noopt=${noopt_err != null ? noopt_err : "ok"}`
|
||||||
results.failed = results.failed + 1
|
results.failed = results.failed + 1
|
||||||
} else if (!values_equal(opt_result, noopt_result)) {
|
} else if (!values_equal(opt_result, noopt_result)) {
|
||||||
push(results.tests, {name: k, status: "failed"})
|
results.tests[] = {name: k, status: "failed"}
|
||||||
push(results.errors, `${k}: result mismatch opt=${describe(opt_result)} noopt=${describe(noopt_result)}`)
|
results.errors[] = `${k}: result mismatch opt=${describe(opt_result)} noopt=${describe(noopt_result)}`
|
||||||
results.failed = results.failed + 1
|
results.failed = results.failed + 1
|
||||||
} else {
|
} else {
|
||||||
push(results.tests, {name: k, status: "passed"})
|
results.tests[] = {name: k, status: "passed"}
|
||||||
results.passed = results.passed + 1
|
results.passed = results.passed + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,11 +178,11 @@ function diff_test_file(file_path) {
|
|||||||
} else {
|
} else {
|
||||||
// Compare direct return values
|
// Compare direct return values
|
||||||
if (!values_equal(mod_opt, mod_noopt)) {
|
if (!values_equal(mod_opt, mod_noopt)) {
|
||||||
push(results.tests, {name: "<return>", status: "failed"})
|
results.tests[] = {name: "<return>", status: "failed"}
|
||||||
push(results.errors, `return value mismatch: opt=${describe(mod_opt)} noopt=${describe(mod_noopt)}`)
|
results.errors[] = `return value mismatch: opt=${describe(mod_opt)} noopt=${describe(mod_noopt)}`
|
||||||
results.failed = results.failed + 1
|
results.failed = results.failed + 1
|
||||||
} else {
|
} else {
|
||||||
push(results.tests, {name: "<return>", status: "passed"})
|
results.tests[] = {name: "<return>", status: "passed"}
|
||||||
results.passed = results.passed + 1
|
results.passed = results.passed + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ var run = function() {
|
|||||||
var operands = null
|
var operands = null
|
||||||
var line_str = null
|
var line_str = null
|
||||||
while (j < n - 2) {
|
while (j < n - 2) {
|
||||||
push(parts, fmt_val(instr[j]))
|
parts[] = fmt_val(instr[j])
|
||||||
j = j + 1
|
j = j + 1
|
||||||
}
|
}
|
||||||
operands = text(parts, ", ")
|
operands = text(parts, ", ")
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ var run = function() {
|
|||||||
parts = []
|
parts = []
|
||||||
j = 1
|
j = 1
|
||||||
while (j < n - 2) {
|
while (j < n - 2) {
|
||||||
push(parts, fmt_val(instr[j]))
|
parts[] = fmt_val(instr[j])
|
||||||
j = j + 1
|
j = j + 1
|
||||||
}
|
}
|
||||||
operands = text(parts, ", ")
|
operands = text(parts, ", ")
|
||||||
|
|||||||
2
fd.cm
2
fd.cm
@@ -83,7 +83,7 @@ fd.globfs = function(globs, dir) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!check_neg(item_rel) && check_pos(item_rel)) {
|
if (!check_neg(item_rel) && check_pos(item_rel)) {
|
||||||
push(results, item_rel)
|
results[] = item_rel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
26
fold.cm
26
fold.cm
@@ -709,26 +709,26 @@ var fold = function(ast) {
|
|||||||
if (sv != null && sv.nr_uses == 0) {
|
if (sv != null && sv.nr_uses == 0) {
|
||||||
if (is_pure(stmt.right)) stmt.dead = true
|
if (is_pure(stmt.right)) stmt.dead = true
|
||||||
if (stmt.right != null && stmt.right.kind == "(" && stmt.right.expression != null && stmt.right.expression.name == "use") {
|
if (stmt.right != null && stmt.right.kind == "(" && stmt.right.expression != null && stmt.right.expression.name == "use") {
|
||||||
push(ast._diagnostics, {
|
ast._diagnostics[] = {
|
||||||
severity: "warning",
|
severity: "warning",
|
||||||
line: stmt.left.from_row + 1,
|
line: stmt.left.from_row + 1,
|
||||||
col: stmt.left.from_column + 1,
|
col: stmt.left.from_column + 1,
|
||||||
message: `unused import '${name}'`
|
message: `unused import '${name}'`
|
||||||
})
|
}
|
||||||
} else if (stmt.kind == "def") {
|
} else if (stmt.kind == "def") {
|
||||||
push(ast._diagnostics, {
|
ast._diagnostics[] = {
|
||||||
severity: "warning",
|
severity: "warning",
|
||||||
line: stmt.left.from_row + 1,
|
line: stmt.left.from_row + 1,
|
||||||
col: stmt.left.from_column + 1,
|
col: stmt.left.from_column + 1,
|
||||||
message: `unused constant '${name}'`
|
message: `unused constant '${name}'`
|
||||||
})
|
}
|
||||||
} else {
|
} else {
|
||||||
push(ast._diagnostics, {
|
ast._diagnostics[] = {
|
||||||
severity: "warning",
|
severity: "warning",
|
||||||
line: stmt.left.from_row + 1,
|
line: stmt.left.from_row + 1,
|
||||||
col: stmt.left.from_column + 1,
|
col: stmt.left.from_column + 1,
|
||||||
message: `unused variable '${name}'`
|
message: `unused variable '${name}'`
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -742,15 +742,15 @@ var fold = function(ast) {
|
|||||||
sv = scope_var(fn_nr, stmt.name)
|
sv = scope_var(fn_nr, stmt.name)
|
||||||
if (sv != null && sv.nr_uses == 0) {
|
if (sv != null && sv.nr_uses == 0) {
|
||||||
stmt.dead = true
|
stmt.dead = true
|
||||||
push(ast._diagnostics, {
|
ast._diagnostics[] = {
|
||||||
severity: "warning",
|
severity: "warning",
|
||||||
line: stmt.from_row + 1,
|
line: stmt.from_row + 1,
|
||||||
col: stmt.from_column + 1,
|
col: stmt.from_column + 1,
|
||||||
message: `unused function '${stmt.name}'`
|
message: `unused function '${stmt.name}'`
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stmt.dead != true) push(out, stmt)
|
if (stmt.dead != true) out[] = stmt
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
@@ -1039,7 +1039,7 @@ var fold = function(ast) {
|
|||||||
i = 0
|
i = 0
|
||||||
while (i < length(ast.intrinsics)) {
|
while (i < length(ast.intrinsics)) {
|
||||||
if (used_intrinsics[ast.intrinsics[i]] == true) {
|
if (used_intrinsics[ast.intrinsics[i]] == true) {
|
||||||
push(new_intrinsics, ast.intrinsics[i])
|
new_intrinsics[] = ast.intrinsics[i]
|
||||||
}
|
}
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
@@ -1071,16 +1071,16 @@ var fold = function(ast) {
|
|||||||
fn_sv = scope_var(0, fn.name)
|
fn_sv = scope_var(0, fn.name)
|
||||||
if (fn_sv != null && fn_sv.nr_uses == 0) {
|
if (fn_sv != null && fn_sv.nr_uses == 0) {
|
||||||
fn.dead = true
|
fn.dead = true
|
||||||
push(ast._diagnostics, {
|
ast._diagnostics[] = {
|
||||||
severity: "warning",
|
severity: "warning",
|
||||||
line: fn.from_row + 1,
|
line: fn.from_row + 1,
|
||||||
col: fn.from_column + 1,
|
col: fn.from_column + 1,
|
||||||
message: `unused function '${fn.name}'`
|
message: `unused function '${fn.name}'`
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fn.dead != true) {
|
if (fn.dead != true) {
|
||||||
push(live_fns, fn)
|
live_fns[] = fn
|
||||||
}
|
}
|
||||||
fi = fi + 1
|
fi = fi + 1
|
||||||
}
|
}
|
||||||
|
|||||||
12
fuzz.ce
12
fuzz.ce
@@ -89,7 +89,7 @@ function run_fuzz(seed_val) {
|
|||||||
var _parse = function() {
|
var _parse = function() {
|
||||||
ast = analyze(src, name + ".cm")
|
ast = analyze(src, name + ".cm")
|
||||||
} disruption {
|
} disruption {
|
||||||
push(errors, "parse error")
|
errors[] = "parse error"
|
||||||
}
|
}
|
||||||
_parse()
|
_parse()
|
||||||
if (length(errors) > 0) return {seed: seed_val, errors: errors, src: src}
|
if (length(errors) > 0) return {seed: seed_val, errors: errors, src: src}
|
||||||
@@ -112,7 +112,7 @@ function run_fuzz(seed_val) {
|
|||||||
|
|
||||||
// Check module-level behavior
|
// Check module-level behavior
|
||||||
if (opt_err != noopt_err) {
|
if (opt_err != noopt_err) {
|
||||||
push(errors, `module load: opt=${opt_err != null ? opt_err : "ok"} noopt=${noopt_err != null ? noopt_err : "ok"}`)
|
errors[] = `module load: opt=${opt_err != null ? opt_err : "ok"} noopt=${noopt_err != null ? noopt_err : "ok"}`
|
||||||
return {seed: seed_val, errors: errors, src: src}
|
return {seed: seed_val, errors: errors, src: src}
|
||||||
}
|
}
|
||||||
if (opt_err != null) {
|
if (opt_err != null) {
|
||||||
@@ -137,10 +137,10 @@ function run_fuzz(seed_val) {
|
|||||||
_run()
|
_run()
|
||||||
|
|
||||||
if (is_text(ret)) {
|
if (is_text(ret)) {
|
||||||
push(errors, `self-check ${key}: ${ret}`)
|
errors[] = `self-check ${key}: ${ret}`
|
||||||
}
|
}
|
||||||
if (run_err != null) {
|
if (run_err != null) {
|
||||||
push(errors, `self-check ${key}: unexpected disruption`)
|
errors[] = `self-check ${key}: unexpected disruption`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
k = k + 1
|
k = k + 1
|
||||||
@@ -174,9 +174,9 @@ function run_fuzz(seed_val) {
|
|||||||
_run_noopt()
|
_run_noopt()
|
||||||
|
|
||||||
if (opt_fn_err != noopt_fn_err) {
|
if (opt_fn_err != noopt_fn_err) {
|
||||||
push(errors, `diff ${key2}: opt=${opt_fn_err != null ? opt_fn_err : "ok"} noopt=${noopt_fn_err != null ? noopt_fn_err : "ok"}`)
|
errors[] = `diff ${key2}: opt=${opt_fn_err != null ? opt_fn_err : "ok"} noopt=${noopt_fn_err != null ? noopt_fn_err : "ok"}`
|
||||||
} else if (!values_equal(opt_result, noopt_result)) {
|
} else if (!values_equal(opt_result, noopt_result)) {
|
||||||
push(errors, `diff ${key2}: opt=${describe(opt_result)} noopt=${describe(noopt_result)}`)
|
errors[] = `diff ${key2}: opt=${describe(opt_result)} noopt=${describe(noopt_result)}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
k2 = k2 + 1
|
k2 = k2 + 1
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ function gen_array_test() {
|
|||||||
var v = 0
|
var v = 0
|
||||||
while (i < n) {
|
while (i < n) {
|
||||||
v = rand_int(-100, 100)
|
v = rand_int(-100, 100)
|
||||||
push(vals, v)
|
vals[] = v
|
||||||
sum = sum + v
|
sum = sum + v
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
@@ -249,7 +249,7 @@ function gen_array_test() {
|
|||||||
var val_strs = []
|
var val_strs = []
|
||||||
i = 0
|
i = 0
|
||||||
while (i < n) {
|
while (i < n) {
|
||||||
push(val_strs, text(vals[i]))
|
val_strs[] = text(vals[i])
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
graph.ce
12
graph.ce
@@ -98,7 +98,7 @@ function gather_graph(locator, visited) {
|
|||||||
arrfor(array(deps), function(alias) {
|
arrfor(array(deps), function(alias) {
|
||||||
var dep_locator = deps[alias]
|
var dep_locator = deps[alias]
|
||||||
add_node(dep_locator)
|
add_node(dep_locator)
|
||||||
push(edges, { from: locator, to: dep_locator, alias: alias })
|
edges[] = { from: locator, to: dep_locator, alias: alias }
|
||||||
gather_graph(dep_locator, visited)
|
gather_graph(dep_locator, visited)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ if (show_world) {
|
|||||||
packages = shop.list_packages()
|
packages = shop.list_packages()
|
||||||
arrfor(packages, function(p) {
|
arrfor(packages, function(p) {
|
||||||
if (p != 'core') {
|
if (p != 'core') {
|
||||||
push(roots, p)
|
roots[] = p
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -128,7 +128,7 @@ if (show_world) {
|
|||||||
|
|
||||||
target_locator = shop.resolve_locator(target_locator)
|
target_locator = shop.resolve_locator(target_locator)
|
||||||
|
|
||||||
push(roots, target_locator)
|
roots[] = target_locator
|
||||||
}
|
}
|
||||||
|
|
||||||
arrfor(roots, function(root) {
|
arrfor(roots, function(root) {
|
||||||
@@ -164,7 +164,7 @@ if (format == 'tree') {
|
|||||||
children = []
|
children = []
|
||||||
arrfor(edges, function(e) {
|
arrfor(edges, function(e) {
|
||||||
if (e.from == locator) {
|
if (e.from == locator) {
|
||||||
push(children, e)
|
children[] = e
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ if (format == 'tree') {
|
|||||||
children = []
|
children = []
|
||||||
arrfor(edges, function(e) {
|
arrfor(edges, function(e) {
|
||||||
if (e.from == roots[i]) {
|
if (e.from == roots[i]) {
|
||||||
push(children, e)
|
children[] = e
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ if (format == 'tree') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
arrfor(array(nodes), function(id) {
|
arrfor(array(nodes), function(id) {
|
||||||
push(output.nodes, nodes[id])
|
output.nodes[] = nodes[id]
|
||||||
})
|
})
|
||||||
|
|
||||||
output.edges = edges
|
output.edges = edges
|
||||||
|
|||||||
47
http.cm
47
http.cm
@@ -457,7 +457,7 @@ function parse_headers(raw) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode chunked transfer encoding
|
// decode chunked transfer encoding (text version, for async responses)
|
||||||
function decode_chunked(body_text) {
|
function decode_chunked(body_text) {
|
||||||
var result = ""
|
var result = ""
|
||||||
var pos = 0
|
var pos = 0
|
||||||
@@ -475,6 +475,37 @@ function decode_chunked(body_text) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// decode chunked transfer encoding (blob version, preserves binary data)
|
||||||
|
function decode_chunked_blob(buf, body_start_bytes) {
|
||||||
|
var result = Blob()
|
||||||
|
var pos = body_start_bytes
|
||||||
|
var total_bytes = length(buf) / 8
|
||||||
|
var header_end = null
|
||||||
|
var header_blob = null
|
||||||
|
var header_text = null
|
||||||
|
var crlf_pos = null
|
||||||
|
var chunk_size = null
|
||||||
|
var chunk_data = null
|
||||||
|
while (pos < total_bytes) {
|
||||||
|
header_end = pos + 20
|
||||||
|
if (header_end > total_bytes) header_end = total_bytes
|
||||||
|
header_blob = buf.read_blob(pos * 8, header_end * 8)
|
||||||
|
stone(header_blob)
|
||||||
|
header_text = text(header_blob)
|
||||||
|
crlf_pos = search(header_text, CRLF)
|
||||||
|
if (crlf_pos == null) break
|
||||||
|
chunk_size = number(text(header_text, 0, crlf_pos), 16)
|
||||||
|
if (chunk_size == null || chunk_size == 0) break
|
||||||
|
pos = pos + crlf_pos + 2
|
||||||
|
chunk_data = buf.read_blob(pos * 8, (pos + chunk_size) * 8)
|
||||||
|
stone(chunk_data)
|
||||||
|
result.write_blob(chunk_data)
|
||||||
|
pos = pos + chunk_size + 2
|
||||||
|
}
|
||||||
|
stone(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// receive_response requestor — async incremental receive
|
// receive_response requestor — async incremental receive
|
||||||
var receive_response = function(callback, state) {
|
var receive_response = function(callback, state) {
|
||||||
var cancelled = false
|
var cancelled = false
|
||||||
@@ -650,6 +681,8 @@ var fetch = function(url) {
|
|||||||
var addrs = null
|
var addrs = null
|
||||||
var address = null
|
var address = null
|
||||||
var ok = true
|
var ok = true
|
||||||
|
var status_line = null
|
||||||
|
var status_code = null
|
||||||
|
|
||||||
if (scheme_end != null) {
|
if (scheme_end != null) {
|
||||||
scheme = lower(text(url, 0, scheme_end))
|
scheme = lower(text(url, 0, scheme_end))
|
||||||
@@ -705,8 +738,16 @@ var fetch = function(url) {
|
|||||||
hdr_end = search(raw_text, CRLF + CRLF)
|
hdr_end = search(raw_text, CRLF + CRLF)
|
||||||
if (hdr_end == null) return null
|
if (hdr_end == null) return null
|
||||||
header_text = text(raw_text, 0, hdr_end)
|
header_text = text(raw_text, 0, hdr_end)
|
||||||
if (search(lower(header_text), "transfer-encoding: chunked") != null)
|
status_line = text(header_text, 0, search(header_text, CRLF) || length(header_text))
|
||||||
return decode_chunked(text(raw_text, hdr_end + 4))
|
status_code = number(text(status_line, 9, 12))
|
||||||
|
if (status_code == null || status_code < 200 || status_code >= 300) {
|
||||||
|
log.error("fetch: " + status_line)
|
||||||
|
disrupt
|
||||||
|
}
|
||||||
|
if (search(lower(header_text), "transfer-encoding: chunked") != null) {
|
||||||
|
body = decode_chunked_blob(buf, hdr_end + 4)
|
||||||
|
return body
|
||||||
|
}
|
||||||
// Headers are ASCII so char offset = byte offset
|
// Headers are ASCII so char offset = byte offset
|
||||||
body_start_bits = (hdr_end + 4) * 8
|
body_start_bits = (hdr_end + 4) * 8
|
||||||
body = buf.read_blob(body_start_bits, length(buf))
|
body = buf.read_blob(body_start_bits, length(buf))
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ function trace_imports(file_path, depth) {
|
|||||||
|
|
||||||
all_packages[imp_pkg] = true
|
all_packages[imp_pkg] = true
|
||||||
|
|
||||||
push(all_imports, {
|
all_imports[] = {
|
||||||
from: file_path,
|
from: file_path,
|
||||||
from_pkg: file_pkg,
|
from_pkg: file_pkg,
|
||||||
module_path: mod_path,
|
module_path: mod_path,
|
||||||
@@ -117,7 +117,7 @@ function trace_imports(file_path, depth) {
|
|||||||
package: imp_pkg,
|
package: imp_pkg,
|
||||||
type: imp_type,
|
type: imp_type,
|
||||||
depth: depth
|
depth: depth
|
||||||
})
|
}
|
||||||
|
|
||||||
// Recurse into resolved scripts
|
// Recurse into resolved scripts
|
||||||
if (resolved && (ends_with(resolved, '.cm') || ends_with(resolved, '.ce'))) {
|
if (resolved && (ends_with(resolved, '.cm') || ends_with(resolved, '.ce'))) {
|
||||||
|
|||||||
512
internal/enet.c
512
internal/enet.c
@@ -14,31 +14,28 @@ static void js_enet_host_finalizer(JSRuntime *rt, JSValue val)
|
|||||||
if (host) enet_host_destroy(host);
|
if (host) enet_host_destroy(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void js_enet_peer_finalizer(JSRuntime *rt, JSValue val)
|
static JSClassDef enet_host_def = {
|
||||||
|
"ENetHost",
|
||||||
|
.finalizer = js_enet_host_finalizer,
|
||||||
|
};
|
||||||
|
|
||||||
|
static JSClassDef enet_peer_def = {
|
||||||
|
"ENetPeer",
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Helper: create a JS peer wrapper for an ENetPeer pointer.
|
||||||
|
Fresh wrapper each time — no caching in peer->data. */
|
||||||
|
static JSValue peer_wrap(JSContext *ctx, ENetPeer *peer)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(val, enet_peer_class_id);
|
JSValue obj = JS_NewObjectClass(ctx, enet_peer_class_id);
|
||||||
if (peer && peer->data) {
|
if (JS_IsException(obj)) return obj;
|
||||||
free(peer->data);
|
JS_SetOpaque(obj, peer);
|
||||||
}
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the ENet library. Must be called before using any ENet functionality.
|
/* ── Host functions ─────────────────────────────────────────── */
|
||||||
static JSValue js_enet_initialize(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
|
||||||
{
|
|
||||||
if (enet_initialize() != 0) return JS_RaiseDisrupt(ctx, "Error initializing ENet");
|
|
||||||
return JS_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deinitialize the ENet library, cleaning up all resources.
|
static JSValue js_enet_create_host(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
static JSValue js_enet_deinitialize(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
|
||||||
{
|
|
||||||
enet_deinitialize();
|
|
||||||
return JS_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an ENet host for either a client-like unbound host or a server bound to a specific
|
|
||||||
// address and port.
|
|
||||||
static JSValue js_enet_host_create(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
|
||||||
{
|
{
|
||||||
ENetHost *host;
|
ENetHost *host;
|
||||||
ENetAddress address;
|
ENetAddress address;
|
||||||
@@ -74,7 +71,7 @@ static JSValue js_enet_host_create(JSContext *ctx, JSValueConst this_val, int ar
|
|||||||
int err = enet_address_set_host_ip(&address, addr_str);
|
int err = enet_address_set_host_ip(&address, addr_str);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
JS_FreeCString(ctx, addr_str);
|
JS_FreeCString(ctx, addr_str);
|
||||||
return JS_RaiseDisrupt(ctx, "Failed to set host IP from '%s'. Error: %d", addr_str, err);
|
return JS_RaiseDisrupt(ctx, "Failed to set host IP. Error: %d", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
address.port = (enet_uint16)port32;
|
address.port = (enet_uint16)port32;
|
||||||
@@ -103,97 +100,76 @@ wrap:
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to get a JSValue for an ENetPeer.
|
/* service(host, callback [, timeout]) */
|
||||||
static JSValue peer_get_value(JSContext *ctx, ENetPeer *peer)
|
static JSValue js_enet_service(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
if (!peer->data) {
|
if (argc < 2) return JS_RaiseDisrupt(ctx, "service: expected (host, callback)");
|
||||||
peer->data = malloc(sizeof(JSValue));
|
|
||||||
*(JSValue*)peer->data = JS_NewObjectClass(ctx, enet_peer_class_id);
|
|
||||||
JS_SetOpaque(*(JSValue*)peer->data, peer);
|
|
||||||
}
|
|
||||||
return *(JSValue*)peer->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poll for and process any available network events from this host,
|
ENetHost *host = JS_GetOpaque(argv[0], enet_host_id);
|
||||||
// calling the provided callback for each event.
|
if (!host) return JS_RaiseDisrupt(ctx, "service: invalid host");
|
||||||
static JSValue js_enet_host_service(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
|
||||||
{
|
|
||||||
ENetHost *host = JS_GetOpaque(this_val, enet_host_id);
|
|
||||||
if (!host) return JS_EXCEPTION;
|
|
||||||
|
|
||||||
if (argc < 1 || !JS_IsFunction(argv[0]))
|
if (!JS_IsFunction(argv[1]))
|
||||||
return JS_RaiseDisrupt(ctx, "Expected a callback function as first argument");
|
return JS_RaiseDisrupt(ctx, "service: expected callback function");
|
||||||
|
|
||||||
enet_uint32 timeout_ms = 0;
|
enet_uint32 timeout_ms = 0;
|
||||||
if (argc >= 2 && !JS_IsNull(argv[1])) {
|
if (argc >= 3 && !JS_IsNull(argv[2])) {
|
||||||
double secs = 0;
|
double secs = 0;
|
||||||
JS_ToFloat64(ctx, &secs, argv[1]);
|
JS_ToFloat64(ctx, &secs, argv[2]);
|
||||||
if (secs > 0) timeout_ms = (enet_uint32)(secs * 1000.0);
|
if (secs > 0) timeout_ms = (enet_uint32)(secs * 1000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_FRAME(ctx);
|
JS_FRAME(ctx);
|
||||||
JSGCRef event_ref = { .val = JS_NULL, .prev = NULL };
|
JS_ROOT(event_obj, JS_NULL);
|
||||||
JS_PushGCRef(ctx, &event_ref);
|
|
||||||
|
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
while (enet_host_service(host, &event, timeout_ms) > 0) {
|
while (enet_host_service(host, &event, timeout_ms) > 0) {
|
||||||
event_ref.val = JS_NewObject(ctx);
|
event_obj.val = JS_NewObject(ctx);
|
||||||
|
|
||||||
JSValue peer_val = peer_get_value(ctx, event.peer);
|
JSValue peer_val = peer_wrap(ctx, event.peer);
|
||||||
JS_SetPropertyStr(ctx, event_ref.val, "peer", peer_val);
|
JS_SetPropertyStr(ctx, event_obj.val, "peer", peer_val);
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case ENET_EVENT_TYPE_CONNECT: {
|
case ENET_EVENT_TYPE_CONNECT:
|
||||||
JSValue type_str = JS_NewString(ctx, "connect");
|
JS_SetPropertyStr(ctx, event_obj.val, "type", JS_NewString(ctx, "connect"));
|
||||||
JS_SetPropertyStr(ctx, event_ref.val, "type", type_str);
|
|
||||||
break;
|
break;
|
||||||
}
|
case ENET_EVENT_TYPE_RECEIVE:
|
||||||
case ENET_EVENT_TYPE_RECEIVE: {
|
JS_SetPropertyStr(ctx, event_obj.val, "type", JS_NewString(ctx, "receive"));
|
||||||
JSValue type_str = JS_NewString(ctx, "receive");
|
JS_SetPropertyStr(ctx, event_obj.val, "channelID", JS_NewInt32(ctx, event.channelID));
|
||||||
JS_SetPropertyStr(ctx, event_ref.val, "type", type_str);
|
|
||||||
JS_SetPropertyStr(ctx, event_ref.val, "channelID", JS_NewInt32(ctx, event.channelID));
|
|
||||||
if (event.packet->dataLength > 0) {
|
if (event.packet->dataLength > 0) {
|
||||||
JSValue data_val = js_new_blob_stoned_copy(ctx, event.packet->data, event.packet->dataLength);
|
JSValue data_val = js_new_blob_stoned_copy(ctx, event.packet->data, event.packet->dataLength);
|
||||||
JS_SetPropertyStr(ctx, event_ref.val, "data", data_val);
|
JS_SetPropertyStr(ctx, event_obj.val, "data", data_val);
|
||||||
}
|
}
|
||||||
enet_packet_destroy(event.packet);
|
enet_packet_destroy(event.packet);
|
||||||
break;
|
break;
|
||||||
}
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
case ENET_EVENT_TYPE_DISCONNECT: {
|
JS_SetPropertyStr(ctx, event_obj.val, "type", JS_NewString(ctx, "disconnect"));
|
||||||
JSValue type_str = JS_NewString(ctx, "disconnect");
|
|
||||||
JS_SetPropertyStr(ctx, event_ref.val, "type", type_str);
|
|
||||||
break;
|
break;
|
||||||
}
|
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
|
||||||
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: {
|
JS_SetPropertyStr(ctx, event_obj.val, "type", JS_NewString(ctx, "disconnect_timeout"));
|
||||||
JSValue type_str = JS_NewString(ctx, "disconnect_timeout");
|
|
||||||
JS_SetPropertyStr(ctx, event_ref.val, "type", type_str);
|
|
||||||
break;
|
break;
|
||||||
}
|
case ENET_EVENT_TYPE_NONE:
|
||||||
case ENET_EVENT_TYPE_NONE: {
|
JS_SetPropertyStr(ctx, event_obj.val, "type", JS_NewString(ctx, "none"));
|
||||||
JSValue type_str = JS_NewString(ctx, "none");
|
|
||||||
JS_SetPropertyStr(ctx, event_ref.val, "type", type_str);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_Call(ctx, argv[0], JS_NULL, 1, &event_ref.val);
|
JS_Call(ctx, argv[1], JS_NULL, 1, &event_obj.val);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_RETURN_NULL();
|
JS_RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initiate a connection from this host to a remote server.
|
/* connect(host, address, port) → peer */
|
||||||
static JSValue js_enet_host_connect(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
static JSValue js_enet_connect(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetHost *host = JS_GetOpaque(this_val, enet_host_id);
|
if (argc < 3) return JS_RaiseDisrupt(ctx, "connect: expected (host, address, port)");
|
||||||
if (!host) return JS_EXCEPTION;
|
|
||||||
|
|
||||||
if (argc < 2) return JS_RaiseDisrupt(ctx, "Expected 2 arguments: hostname, port");
|
ENetHost *host = JS_GetOpaque(argv[0], enet_host_id);
|
||||||
|
if (!host) return JS_RaiseDisrupt(ctx, "connect: invalid host");
|
||||||
|
|
||||||
const char *hostname = JS_ToCString(ctx, argv[0]);
|
const char *hostname = JS_ToCString(ctx, argv[1]);
|
||||||
if (!hostname) return JS_EXCEPTION;
|
if (!hostname) return JS_EXCEPTION;
|
||||||
int port;
|
int port;
|
||||||
JS_ToInt32(ctx, &port, argv[1]);
|
JS_ToInt32(ctx, &port, argv[2]);
|
||||||
|
|
||||||
ENetAddress address;
|
ENetAddress address;
|
||||||
enet_address_set_host(&address, hostname);
|
enet_address_set_host(&address, hostname);
|
||||||
@@ -201,43 +177,43 @@ static JSValue js_enet_host_connect(JSContext *ctx, JSValueConst this_val, int a
|
|||||||
address.port = port;
|
address.port = port;
|
||||||
|
|
||||||
ENetPeer *peer = enet_host_connect(host, &address, 2, 0);
|
ENetPeer *peer = enet_host_connect(host, &address, 2, 0);
|
||||||
if (!peer) return JS_RaiseDisrupt(ctx, "No available peers for initiating an ENet connection");
|
if (!peer) return JS_RaiseDisrupt(ctx, "No available peers for connection");
|
||||||
|
|
||||||
return peer_get_value(ctx, peer);
|
return peer_wrap(ctx, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush all pending outgoing packets for this host immediately.
|
/* flush(host) */
|
||||||
static JSValue js_enet_host_flush(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
static JSValue js_enet_flush(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetHost *host = JS_GetOpaque(this_val, enet_host_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "flush: expected (host)");
|
||||||
if (!host) return JS_EXCEPTION;
|
ENetHost *host = JS_GetOpaque(argv[0], enet_host_id);
|
||||||
|
if (!host) return JS_RaiseDisrupt(ctx, "flush: invalid host");
|
||||||
enet_host_flush(host);
|
enet_host_flush(host);
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broadcast a string or blob to all connected peers on channel 0.
|
/* broadcast(host, data) */
|
||||||
static JSValue js_enet_host_broadcast(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
static JSValue js_enet_broadcast(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetHost *host = JS_GetOpaque(this_val, enet_host_id);
|
if (argc < 2) return JS_RaiseDisrupt(ctx, "broadcast: expected (host, data)");
|
||||||
if (!host) return JS_EXCEPTION;
|
ENetHost *host = JS_GetOpaque(argv[0], enet_host_id);
|
||||||
|
if (!host) return JS_RaiseDisrupt(ctx, "broadcast: invalid host");
|
||||||
if (argc < 1) return JS_RaiseDisrupt(ctx, "Expected a string or blob to broadcast");
|
|
||||||
|
|
||||||
const char *data_str = NULL;
|
const char *data_str = NULL;
|
||||||
size_t data_len = 0;
|
size_t data_len = 0;
|
||||||
uint8_t *buf = NULL;
|
uint8_t *buf = NULL;
|
||||||
|
|
||||||
if (JS_IsText(argv[0])) {
|
if (JS_IsText(argv[1])) {
|
||||||
data_str = JS_ToCStringLen(ctx, &data_len, argv[0]);
|
data_str = JS_ToCStringLen(ctx, &data_len, argv[1]);
|
||||||
if (!data_str) return JS_EXCEPTION;
|
if (!data_str) return JS_EXCEPTION;
|
||||||
} else if (js_is_blob(ctx, argv[0])) {
|
} else if (js_is_blob(ctx, argv[1])) {
|
||||||
buf = js_get_blob_data(ctx, &data_len, argv[0]);
|
buf = js_get_blob_data(ctx, &data_len, argv[1]);
|
||||||
if (!buf) return JS_EXCEPTION;
|
if (!buf) return JS_EXCEPTION;
|
||||||
} else {
|
} else {
|
||||||
return JS_RaiseDisrupt(ctx, "broadcast() only accepts a string or blob");
|
return JS_RaiseDisrupt(ctx, "broadcast: data must be string or blob");
|
||||||
}
|
}
|
||||||
|
|
||||||
ENetPacket *packet = enet_packet_create(data_str ? (const void*)data_str : (const void*)buf, data_len, ENET_PACKET_FLAG_RELIABLE);
|
ENetPacket *packet = enet_packet_create(data_str ? (const void *)data_str : (const void *)buf, data_len, ENET_PACKET_FLAG_RELIABLE);
|
||||||
if (data_str) JS_FreeCString(ctx, data_str);
|
if (data_str) JS_FreeCString(ctx, data_str);
|
||||||
if (!packet) return JS_RaiseDisrupt(ctx, "Failed to create ENet packet");
|
if (!packet) return JS_RaiseDisrupt(ctx, "Failed to create ENet packet");
|
||||||
|
|
||||||
@@ -245,55 +221,51 @@ static JSValue js_enet_host_broadcast(JSContext *ctx, JSValueConst this_val, int
|
|||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Host property getters
|
/* host_port(host) → number */
|
||||||
static JSValue js_enet_host_get_port(JSContext *js, JSValueConst self)
|
static JSValue js_enet_host_port(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetHost *host = JS_GetOpaque(self, enet_host_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "host_port: expected (host)");
|
||||||
if (!host) return JS_EXCEPTION;
|
ENetHost *host = JS_GetOpaque(argv[0], enet_host_id);
|
||||||
return JS_NewInt32(js, host->address.port);
|
if (!host) return JS_RaiseDisrupt(ctx, "host_port: invalid host");
|
||||||
|
return JS_NewInt32(ctx, host->address.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_enet_host_get_address(JSContext *js, JSValueConst self)
|
/* host_address(host) → string */
|
||||||
|
static JSValue js_enet_host_address(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetHost *me = JS_GetOpaque(self, enet_host_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "host_address: expected (host)");
|
||||||
if (!me) return JS_EXCEPTION;
|
ENetHost *host = JS_GetOpaque(argv[0], enet_host_id);
|
||||||
|
if (!host) return JS_RaiseDisrupt(ctx, "host_address: invalid host");
|
||||||
char ip_str[128];
|
char ip_str[128];
|
||||||
if (enet_address_get_host_ip(&me->address, ip_str, sizeof(ip_str)) != 0)
|
if (enet_address_get_host_ip(&host->address, ip_str, sizeof(ip_str)) != 0)
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
return JS_NewString(js, ip_str);
|
return JS_NewString(ctx, ip_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Peer-level operations
|
/* ── Peer functions ─────────────────────────────────────────── */
|
||||||
static JSValue js_enet_peer_disconnect(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_EXCEPTION;
|
|
||||||
enet_peer_disconnect(peer, 0);
|
|
||||||
return JS_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_send(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
/* send(peer, data) */
|
||||||
|
static JSValue js_enet_send(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 2) return JS_RaiseDisrupt(ctx, "send: expected (peer, data)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
|
if (!peer) return JS_RaiseDisrupt(ctx, "send: invalid peer");
|
||||||
if (argc < 1) return JS_RaiseDisrupt(ctx, "Expected a string or blob to send");
|
|
||||||
|
|
||||||
const char *data_str = NULL;
|
const char *data_str = NULL;
|
||||||
size_t data_len = 0;
|
size_t data_len = 0;
|
||||||
uint8_t *buf = NULL;
|
uint8_t *buf = NULL;
|
||||||
|
|
||||||
if (JS_IsText(argv[0])) {
|
if (JS_IsText(argv[1])) {
|
||||||
data_str = JS_ToCStringLen(ctx, &data_len, argv[0]);
|
data_str = JS_ToCStringLen(ctx, &data_len, argv[1]);
|
||||||
if (!data_str) return JS_EXCEPTION;
|
if (!data_str) return JS_EXCEPTION;
|
||||||
} else if (js_is_blob(ctx, argv[0])) {
|
} else if (js_is_blob(ctx, argv[1])) {
|
||||||
buf = js_get_blob_data(ctx, &data_len, argv[0]);
|
buf = js_get_blob_data(ctx, &data_len, argv[1]);
|
||||||
if (!buf) return JS_EXCEPTION;
|
if (!buf) return JS_EXCEPTION;
|
||||||
} else {
|
} else {
|
||||||
return JS_RaiseDisrupt(ctx, "send() only accepts a string or blob");
|
return JS_RaiseDisrupt(ctx, "send: data must be string or blob");
|
||||||
}
|
}
|
||||||
|
|
||||||
ENetPacket *packet = enet_packet_create(data_str ? (const void*)data_str : (const void*)buf, data_len, ENET_PACKET_FLAG_RELIABLE);
|
ENetPacket *packet = enet_packet_create(data_str ? (const void *)data_str : (const void *)buf, data_len, ENET_PACKET_FLAG_RELIABLE);
|
||||||
if (data_str) JS_FreeCString(ctx, data_str);
|
if (data_str) JS_FreeCString(ctx, data_str);
|
||||||
if (!packet) return JS_RaiseDisrupt(ctx, "Failed to create ENet packet");
|
if (!packet) return JS_RaiseDisrupt(ctx, "Failed to create ENet packet");
|
||||||
|
|
||||||
@@ -301,225 +273,185 @@ static JSValue js_enet_peer_send(JSContext *ctx, JSValueConst this_val, int argc
|
|||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_enet_peer_disconnect_now(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
/* disconnect(peer) */
|
||||||
|
static JSValue js_enet_disconnect(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "disconnect: expected (peer)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
|
if (!peer) return JS_RaiseDisrupt(ctx, "disconnect: invalid peer");
|
||||||
|
enet_peer_disconnect(peer, 0);
|
||||||
|
return JS_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disconnect_now(peer) */
|
||||||
|
static JSValue js_enet_disconnect_now(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
|
{
|
||||||
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "disconnect_now: expected (peer)");
|
||||||
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
|
if (!peer) return JS_RaiseDisrupt(ctx, "disconnect_now: invalid peer");
|
||||||
enet_peer_disconnect_now(peer, 0);
|
enet_peer_disconnect_now(peer, 0);
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_enet_peer_disconnect_later(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
/* disconnect_later(peer) */
|
||||||
|
static JSValue js_enet_disconnect_later(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "disconnect_later: expected (peer)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
|
if (!peer) return JS_RaiseDisrupt(ctx, "disconnect_later: invalid peer");
|
||||||
enet_peer_disconnect_later(peer, 0);
|
enet_peer_disconnect_later(peer, 0);
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_enet_peer_reset(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
/* reset(peer) */
|
||||||
|
static JSValue js_enet_reset(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "reset: expected (peer)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
|
if (!peer) return JS_RaiseDisrupt(ctx, "reset: invalid peer");
|
||||||
enet_peer_reset(peer);
|
enet_peer_reset(peer);
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_enet_peer_ping(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
/* ping(peer) */
|
||||||
|
static JSValue js_enet_ping(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "ping: expected (peer)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
|
if (!peer) return JS_RaiseDisrupt(ctx, "ping: invalid peer");
|
||||||
enet_peer_ping(peer);
|
enet_peer_ping(peer);
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_enet_peer_throttle_configure(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
/* throttle_configure(peer, interval, acceleration, deceleration) */
|
||||||
|
static JSValue js_enet_throttle_configure(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 4) return JS_RaiseDisrupt(ctx, "throttle_configure: expected (peer, interval, accel, decel)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
|
if (!peer) return JS_RaiseDisrupt(ctx, "throttle_configure: invalid peer");
|
||||||
int interval, acceleration, deceleration;
|
int interval, acceleration, deceleration;
|
||||||
if (argc < 3 || JS_ToInt32(ctx, &interval, argv[0]) || JS_ToInt32(ctx, &acceleration, argv[1]) || JS_ToInt32(ctx, &deceleration, argv[2]))
|
if (JS_ToInt32(ctx, &interval, argv[1]) || JS_ToInt32(ctx, &acceleration, argv[2]) || JS_ToInt32(ctx, &deceleration, argv[3]))
|
||||||
return JS_RaiseDisrupt(ctx, "Expected 3 int arguments: interval, acceleration, deceleration");
|
return JS_RaiseDisrupt(ctx, "throttle_configure: expected integer arguments");
|
||||||
|
|
||||||
enet_peer_throttle_configure(peer, interval, acceleration, deceleration);
|
enet_peer_throttle_configure(peer, interval, acceleration, deceleration);
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* peer_timeout(peer, limit, min, max) */
|
||||||
static JSValue js_enet_peer_timeout(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
static JSValue js_enet_peer_timeout(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 4) return JS_RaiseDisrupt(ctx, "peer_timeout: expected (peer, limit, min, max)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
|
if (!peer) return JS_RaiseDisrupt(ctx, "peer_timeout: invalid peer");
|
||||||
int timeout_limit, timeout_min, timeout_max;
|
int timeout_limit, timeout_min, timeout_max;
|
||||||
if (argc < 3 || JS_ToInt32(ctx, &timeout_limit, argv[0]) || JS_ToInt32(ctx, &timeout_min, argv[1]) || JS_ToInt32(ctx, &timeout_max, argv[2]))
|
if (JS_ToInt32(ctx, &timeout_limit, argv[1]) || JS_ToInt32(ctx, &timeout_min, argv[2]) || JS_ToInt32(ctx, &timeout_max, argv[3]))
|
||||||
return JS_RaiseDisrupt(ctx, "Expected 3 integer arguments: timeout_limit, timeout_min, timeout_max");
|
return JS_RaiseDisrupt(ctx, "peer_timeout: expected integer arguments");
|
||||||
|
|
||||||
enet_peer_timeout(peer, timeout_limit, timeout_min, timeout_max);
|
enet_peer_timeout(peer, timeout_limit, timeout_min, timeout_max);
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Class definitions
|
/* ── Peer property getters ──────────────────────────────────── */
|
||||||
static JSClassDef enet_host = {
|
|
||||||
"ENetHost",
|
|
||||||
.finalizer = js_enet_host_finalizer,
|
|
||||||
};
|
|
||||||
|
|
||||||
static JSClassDef enet_peer_class = {
|
#define PEER_GETTER(name, field, convert) \
|
||||||
"ENetPeer",
|
static JSValue js_enet_##name(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { \
|
||||||
.finalizer = js_enet_peer_finalizer,
|
if (argc < 1) return JS_RaiseDisrupt(ctx, #name ": expected (peer)"); \
|
||||||
};
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id); \
|
||||||
|
if (!peer) return JS_RaiseDisrupt(ctx, #name ": invalid peer"); \
|
||||||
static JSValue js_enet_resolve_hostname(JSContext *js, JSValue self, int argc, JSValue *argv)
|
return convert(ctx, peer->field); \
|
||||||
{
|
|
||||||
const char *hostname = JS_ToCString(js, argv[0]);
|
|
||||||
JS_FreeCString(js, hostname);
|
|
||||||
return JS_NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_enet_funcs[] = {
|
static inline JSValue _int32(JSContext *ctx, int v) { return JS_NewInt32(ctx, v); }
|
||||||
JS_CFUNC_DEF("initialize", 0, js_enet_initialize),
|
static inline JSValue _uint32(JSContext *ctx, unsigned int v) { return JS_NewUint32(ctx, v); }
|
||||||
JS_CFUNC_DEF("deinitialize", 0, js_enet_deinitialize),
|
|
||||||
JS_CFUNC_DEF("create_host", 1, js_enet_host_create),
|
|
||||||
JS_CFUNC_DEF("resolve_hostname", 1, js_enet_resolve_hostname),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_enet_host_funcs[] = {
|
PEER_GETTER(peer_rtt, roundTripTime, _int32)
|
||||||
JS_CFUNC_DEF("service", 2, js_enet_host_service),
|
PEER_GETTER(peer_rtt_variance, roundTripTimeVariance, _int32)
|
||||||
JS_CFUNC_DEF("connect", 2, js_enet_host_connect),
|
PEER_GETTER(peer_last_send_time, lastSendTime, _int32)
|
||||||
JS_CFUNC_DEF("flush", 0, js_enet_host_flush),
|
PEER_GETTER(peer_last_receive_time, lastReceiveTime, _int32)
|
||||||
JS_CFUNC_DEF("broadcast", 1, js_enet_host_broadcast),
|
PEER_GETTER(peer_mtu, mtu, _int32)
|
||||||
JS_CFUNC0_DEF("port", js_enet_host_get_port),
|
PEER_GETTER(peer_outgoing_data_total, outgoingDataTotal, _int32)
|
||||||
JS_CFUNC0_DEF("address", js_enet_host_get_address),
|
PEER_GETTER(peer_incoming_data_total, incomingDataTotal, _int32)
|
||||||
};
|
PEER_GETTER(peer_packet_loss, packetLoss, _int32)
|
||||||
|
PEER_GETTER(peer_state, state, _int32)
|
||||||
|
PEER_GETTER(peer_reliable_data_in_transit, reliableDataInTransit, _int32)
|
||||||
|
|
||||||
// Peer property getters (zero-arg methods)
|
static JSValue js_enet_peer_incoming_bandwidth(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
static JSValue js_enet_peer_get_rtt(JSContext *ctx, JSValueConst this_val)
|
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "peer_incoming_bandwidth: expected (peer)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
return JS_NewInt32(ctx, peer->roundTripTime);
|
if (!peer) return JS_RaiseDisrupt(ctx, "peer_incoming_bandwidth: invalid peer");
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_incoming_bandwidth(JSContext *ctx, JSValueConst this_val)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_EXCEPTION;
|
|
||||||
if (peer->incomingBandwidth == 0) return JS_NewFloat64(ctx, INFINITY);
|
if (peer->incomingBandwidth == 0) return JS_NewFloat64(ctx, INFINITY);
|
||||||
return JS_NewInt32(ctx, peer->incomingBandwidth);
|
return JS_NewInt32(ctx, peer->incomingBandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_outgoing_bandwidth(JSContext *ctx, JSValueConst this_val)
|
static JSValue js_enet_peer_outgoing_bandwidth(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "peer_outgoing_bandwidth: expected (peer)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
|
if (!peer) return JS_RaiseDisrupt(ctx, "peer_outgoing_bandwidth: invalid peer");
|
||||||
if (peer->outgoingBandwidth == 0) return JS_NewFloat64(ctx, INFINITY);
|
if (peer->outgoingBandwidth == 0) return JS_NewFloat64(ctx, INFINITY);
|
||||||
return JS_NewInt32(ctx, peer->outgoingBandwidth);
|
return JS_NewInt32(ctx, peer->outgoingBandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_last_send_time(JSContext *ctx, JSValueConst this_val)
|
static JSValue js_enet_peer_port(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "peer_port: expected (peer)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
return JS_NewInt32(ctx, peer->lastSendTime);
|
if (!peer) return JS_RaiseDisrupt(ctx, "peer_port: invalid peer");
|
||||||
|
return JS_NewUint32(ctx, peer->address.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_last_receive_time(JSContext *ctx, JSValueConst this_val)
|
static JSValue js_enet_peer_address(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
if (argc < 1) return JS_RaiseDisrupt(ctx, "peer_address: expected (peer)");
|
||||||
if (!peer) return JS_EXCEPTION;
|
ENetPeer *peer = JS_GetOpaque(argv[0], enet_peer_class_id);
|
||||||
return JS_NewInt32(ctx, peer->lastReceiveTime);
|
if (!peer) return JS_RaiseDisrupt(ctx, "peer_address: invalid peer");
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_mtu(JSContext *ctx, JSValueConst this_val)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_NewFloat64(ctx, INFINITY);
|
|
||||||
return JS_NewInt32(ctx, peer->mtu);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_outgoing_data_total(JSContext *ctx, JSValueConst this_val)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_NewFloat64(ctx, INFINITY);
|
|
||||||
return JS_NewInt32(ctx, peer->outgoingDataTotal);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_incoming_data_total(JSContext *ctx, JSValueConst this_val)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_NewFloat64(ctx, INFINITY);
|
|
||||||
return JS_NewInt32(ctx, peer->incomingDataTotal);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_rtt_variance(JSContext *ctx, JSValueConst this_val)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_NewFloat64(ctx, INFINITY);
|
|
||||||
return JS_NewInt32(ctx, peer->roundTripTimeVariance);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_packet_loss(JSContext *ctx, JSValueConst this_val)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_NewFloat64(ctx, INFINITY);
|
|
||||||
return JS_NewInt32(ctx, peer->packetLoss);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_state(JSContext *ctx, JSValueConst this_val)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_NewInt32(ctx, -1);
|
|
||||||
return JS_NewInt32(ctx, peer->state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_reliable_data_in_transit(JSContext *ctx, JSValueConst this_val)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(this_val, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_NewFloat64(ctx, INFINITY);
|
|
||||||
return JS_NewInt32(ctx, peer->reliableDataInTransit);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_port(JSContext *js, JSValueConst self)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(self, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_EXCEPTION;
|
|
||||||
return JS_NewUint32(js, peer->address.port);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_enet_peer_get_address(JSContext *js, JSValueConst self)
|
|
||||||
{
|
|
||||||
ENetPeer *peer = JS_GetOpaque(self, enet_peer_class_id);
|
|
||||||
if (!peer) return JS_EXCEPTION;
|
|
||||||
char ip_str[128];
|
char ip_str[128];
|
||||||
if (enet_address_get_host_ip(&peer->address, ip_str, sizeof(ip_str)) != 0)
|
if (enet_address_get_host_ip(&peer->address, ip_str, sizeof(ip_str)) != 0)
|
||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
return JS_NewString(js, ip_str);
|
return JS_NewString(ctx, ip_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_enet_peer_funcs[] = {
|
static JSValue js_enet_resolve_hostname(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
||||||
JS_CFUNC_DEF("send", 1, js_enet_peer_send),
|
{
|
||||||
JS_CFUNC_DEF("disconnect", 0, js_enet_peer_disconnect),
|
const char *hostname = JS_ToCString(ctx, argv[0]);
|
||||||
JS_CFUNC_DEF("disconnect_now", 0, js_enet_peer_disconnect_now),
|
JS_FreeCString(ctx, hostname);
|
||||||
JS_CFUNC_DEF("disconnect_later", 0, js_enet_peer_disconnect_later),
|
return JS_NULL;
|
||||||
JS_CFUNC_DEF("reset", 0, js_enet_peer_reset),
|
}
|
||||||
JS_CFUNC_DEF("ping", 0, js_enet_peer_ping),
|
|
||||||
JS_CFUNC_DEF("throttle_configure", 3, js_enet_peer_throttle_configure),
|
/* ── Module export ──────────────────────────────────────────── */
|
||||||
JS_CFUNC_DEF("timeout", 3, js_enet_peer_timeout),
|
|
||||||
JS_CFUNC0_DEF("rtt", js_enet_peer_get_rtt),
|
static const JSCFunctionListEntry js_enet_funcs[] = {
|
||||||
JS_CFUNC0_DEF("incoming_bandwidth", js_enet_peer_get_incoming_bandwidth),
|
/* host */
|
||||||
JS_CFUNC0_DEF("outgoing_bandwidth", js_enet_peer_get_outgoing_bandwidth),
|
JS_CFUNC_DEF("create_host", 1, js_enet_create_host),
|
||||||
JS_CFUNC0_DEF("last_send_time", js_enet_peer_get_last_send_time),
|
JS_CFUNC_DEF("service", 2, js_enet_service),
|
||||||
JS_CFUNC0_DEF("last_receive_time", js_enet_peer_get_last_receive_time),
|
JS_CFUNC_DEF("connect", 3, js_enet_connect),
|
||||||
JS_CFUNC0_DEF("mtu", js_enet_peer_get_mtu),
|
JS_CFUNC_DEF("flush", 1, js_enet_flush),
|
||||||
JS_CFUNC0_DEF("outgoing_data_total", js_enet_peer_get_outgoing_data_total),
|
JS_CFUNC_DEF("broadcast", 2, js_enet_broadcast),
|
||||||
JS_CFUNC0_DEF("incoming_data_total", js_enet_peer_get_incoming_data_total),
|
JS_CFUNC_DEF("host_port", 1, js_enet_host_port),
|
||||||
JS_CFUNC0_DEF("rtt_variance", js_enet_peer_get_rtt_variance),
|
JS_CFUNC_DEF("host_address", 1, js_enet_host_address),
|
||||||
JS_CFUNC0_DEF("packet_loss", js_enet_peer_get_packet_loss),
|
/* peer */
|
||||||
JS_CFUNC0_DEF("state", js_enet_peer_get_state),
|
JS_CFUNC_DEF("send", 2, js_enet_send),
|
||||||
JS_CFUNC0_DEF("reliable_data_in_transit", js_enet_peer_get_reliable_data_in_transit),
|
JS_CFUNC_DEF("disconnect", 1, js_enet_disconnect),
|
||||||
JS_CFUNC0_DEF("port", js_enet_peer_get_port),
|
JS_CFUNC_DEF("disconnect_now", 1, js_enet_disconnect_now),
|
||||||
JS_CFUNC0_DEF("address", js_enet_peer_get_address),
|
JS_CFUNC_DEF("disconnect_later", 1, js_enet_disconnect_later),
|
||||||
|
JS_CFUNC_DEF("reset", 1, js_enet_reset),
|
||||||
|
JS_CFUNC_DEF("ping", 1, js_enet_ping),
|
||||||
|
JS_CFUNC_DEF("throttle_configure", 4, js_enet_throttle_configure),
|
||||||
|
JS_CFUNC_DEF("peer_timeout", 4, js_enet_peer_timeout),
|
||||||
|
JS_CFUNC_DEF("peer_address", 1, js_enet_peer_address),
|
||||||
|
JS_CFUNC_DEF("peer_port", 1, js_enet_peer_port),
|
||||||
|
JS_CFUNC_DEF("peer_rtt", 1, js_enet_peer_rtt),
|
||||||
|
JS_CFUNC_DEF("peer_rtt_variance", 1, js_enet_peer_rtt_variance),
|
||||||
|
JS_CFUNC_DEF("peer_incoming_bandwidth", 1, js_enet_peer_incoming_bandwidth),
|
||||||
|
JS_CFUNC_DEF("peer_outgoing_bandwidth", 1, js_enet_peer_outgoing_bandwidth),
|
||||||
|
JS_CFUNC_DEF("peer_last_send_time", 1, js_enet_peer_last_send_time),
|
||||||
|
JS_CFUNC_DEF("peer_last_receive_time", 1, js_enet_peer_last_receive_time),
|
||||||
|
JS_CFUNC_DEF("peer_mtu", 1, js_enet_peer_mtu),
|
||||||
|
JS_CFUNC_DEF("peer_outgoing_data_total", 1, js_enet_peer_outgoing_data_total),
|
||||||
|
JS_CFUNC_DEF("peer_incoming_data_total", 1, js_enet_peer_incoming_data_total),
|
||||||
|
JS_CFUNC_DEF("peer_packet_loss", 1, js_enet_peer_packet_loss),
|
||||||
|
JS_CFUNC_DEF("peer_state", 1, js_enet_peer_state),
|
||||||
|
JS_CFUNC_DEF("peer_reliable_data_in_transit", 1, js_enet_peer_reliable_data_in_transit),
|
||||||
|
JS_CFUNC_DEF("resolve_hostname", 1, js_enet_resolve_hostname),
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_core_internal_enet_use(JSContext *ctx)
|
JSValue js_core_internal_enet_use(JSContext *ctx)
|
||||||
@@ -529,16 +461,10 @@ JSValue js_core_internal_enet_use(JSContext *ctx)
|
|||||||
JS_FRAME(ctx);
|
JS_FRAME(ctx);
|
||||||
|
|
||||||
JS_NewClassID(&enet_host_id);
|
JS_NewClassID(&enet_host_id);
|
||||||
JS_NewClass(ctx, enet_host_id, &enet_host);
|
JS_NewClass(ctx, enet_host_id, &enet_host_def);
|
||||||
JS_ROOT(host_proto, JS_NewObject(ctx));
|
|
||||||
JS_SetPropertyFunctionList(ctx, host_proto.val, js_enet_host_funcs, countof(js_enet_host_funcs));
|
|
||||||
JS_SetClassProto(ctx, enet_host_id, host_proto.val);
|
|
||||||
|
|
||||||
JS_NewClassID(&enet_peer_class_id);
|
JS_NewClassID(&enet_peer_class_id);
|
||||||
JS_NewClass(ctx, enet_peer_class_id, &enet_peer_class);
|
JS_NewClass(ctx, enet_peer_class_id, &enet_peer_def);
|
||||||
JS_ROOT(peer_proto, JS_NewObject(ctx));
|
|
||||||
JS_SetPropertyFunctionList(ctx, peer_proto.val, js_enet_peer_funcs, countof(js_enet_peer_funcs));
|
|
||||||
JS_SetClassProto(ctx, enet_peer_class_id, peer_proto.val);
|
|
||||||
|
|
||||||
JS_ROOT(export_obj, JS_NewObject(ctx));
|
JS_ROOT(export_obj, JS_NewObject(ctx));
|
||||||
JS_SetPropertyFunctionList(ctx, export_obj.val, js_enet_funcs, countof(js_enet_funcs));
|
JS_SetPropertyFunctionList(ctx, export_obj.val, js_enet_funcs, countof(js_enet_funcs));
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ var native_mode = false
|
|||||||
var _no_warn = (init != null && init.no_warn) ? true : false
|
var _no_warn = (init != null && init.no_warn) ? true : false
|
||||||
var SYSYM = '__SYSTEM__'
|
var SYSYM = '__SYSTEM__'
|
||||||
|
|
||||||
|
var log = function(name, args) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
var _cell = {}
|
var _cell = {}
|
||||||
var need_stop = false
|
var need_stop = false
|
||||||
|
|
||||||
@@ -539,7 +543,7 @@ if (_init != null && _init.native_mode)
|
|||||||
if (args != null && (_init == null || !_init.program)) {
|
if (args != null && (_init == null || !_init.program)) {
|
||||||
_program = args[0]
|
_program = args[0]
|
||||||
while (_j < length(args)) {
|
while (_j < length(args)) {
|
||||||
push(_user_args, args[_j])
|
_user_args[] = args[_j]
|
||||||
_j = _j + 1
|
_j = _j + 1
|
||||||
}
|
}
|
||||||
if (_init == null) {
|
if (_init == null) {
|
||||||
@@ -908,6 +912,7 @@ $_.delay = function delay(fn, seconds) {
|
|||||||
send_messages()
|
send_messages()
|
||||||
}
|
}
|
||||||
var id = actor_mod.delay(delay_turn, _seconds)
|
var id = actor_mod.delay(delay_turn, _seconds)
|
||||||
|
log.connection(`$delay: registered timer id=${text(id)} seconds=${text(_seconds)}`)
|
||||||
return function() { actor_mod.removetimer(id) }
|
return function() { actor_mod.removetimer(id) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -940,7 +945,7 @@ $_.start = function start(cb, program) {
|
|||||||
no_warn: _no_warn,
|
no_warn: _no_warn,
|
||||||
}
|
}
|
||||||
greeters[id] = cb
|
greeters[id] = cb
|
||||||
push(message_queue, { startup })
|
message_queue[] = { startup }
|
||||||
}
|
}
|
||||||
|
|
||||||
$_.receiver = function receiver(fn) {
|
$_.receiver = function receiver(fn) {
|
||||||
@@ -959,20 +964,34 @@ $_.couple = function couple(actor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$_.contact = function(callback, record) {
|
$_.contact = function(callback, record) {
|
||||||
send(create_actor(record), record, callback)
|
log.connection(`contact: creating actor for ${record.address}:${text(record.port)}`)
|
||||||
|
var a = create_actor(record)
|
||||||
|
log.connection(`contact: actor created, sending contact`)
|
||||||
|
send(a, record, function(reply) {
|
||||||
|
var server = null
|
||||||
|
if (reply && reply.actor_id) {
|
||||||
|
server = create_actor({id: reply.actor_id, address: record.address, port: record.port})
|
||||||
|
log.connection(`contact: connected, server id=${reply.actor_id}`)
|
||||||
|
callback(server)
|
||||||
|
} else {
|
||||||
|
log.connection(`contact: connection failed or no reply`)
|
||||||
|
callback(null)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
$_.portal = function(fn, port) {
|
$_.portal = function(fn, port) {
|
||||||
if (portal) {
|
if (portal) {
|
||||||
log.error(`Already started a portal listening on ${portal.port()}`)
|
log.error(`Already started a portal listening on ${enet.host_port(portal)}`)
|
||||||
disrupt
|
disrupt
|
||||||
}
|
}
|
||||||
if (!port) {
|
if (!port) {
|
||||||
log.error("Requires a valid port.")
|
log.error("Requires a valid port.")
|
||||||
disrupt
|
disrupt
|
||||||
}
|
}
|
||||||
log.system(`starting a portal on port ${port}`)
|
log.connection(`portal: starting on port ${text(port)}`)
|
||||||
portal = enet.create_host({address: "any", port})
|
portal = enet.create_host({address: "any", port})
|
||||||
|
log.connection(`portal: created host=${portal}`)
|
||||||
portal_fn = fn
|
portal_fn = fn
|
||||||
enet_check()
|
enet_check()
|
||||||
}
|
}
|
||||||
@@ -1362,59 +1381,74 @@ function guid(bits)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enet = use_core('internal/enet')
|
enet = use_core('internal/enet')
|
||||||
enet = use_core('enet')
|
|
||||||
|
|
||||||
function peer_connection(peer) {
|
function peer_connection(peer) {
|
||||||
return {
|
return {
|
||||||
latency: peer.rtt(),
|
latency: enet.peer_rtt(peer),
|
||||||
bandwidth: {
|
bandwidth: {
|
||||||
incoming: peer.incoming_bandwidth(),
|
incoming: enet.peer_incoming_bandwidth(peer),
|
||||||
outgoing: peer.outgoing_bandwidth()
|
outgoing: enet.peer_outgoing_bandwidth(peer)
|
||||||
},
|
},
|
||||||
activity: {
|
activity: {
|
||||||
last_sent: peer.last_send_time(),
|
last_sent: enet.peer_last_send_time(peer),
|
||||||
last_received: peer.last_receive_time()
|
last_received: enet.peer_last_receive_time(peer)
|
||||||
},
|
},
|
||||||
mtu: peer.mtu(),
|
mtu: enet.peer_mtu(peer),
|
||||||
data: {
|
data: {
|
||||||
incoming_total: peer.incoming_data_total(),
|
incoming_total: enet.peer_incoming_data_total(peer),
|
||||||
outgoing_total: peer.outgoing_data_total(),
|
outgoing_total: enet.peer_outgoing_data_total(peer),
|
||||||
reliable_in_transit: peer.reliable_data_in_transit()
|
reliable_in_transit: enet.peer_reliable_data_in_transit(peer)
|
||||||
},
|
},
|
||||||
latency_variance: peer.rtt_variance(),
|
latency_variance: enet.peer_rtt_variance(peer),
|
||||||
packet_loss: peer.packet_loss(),
|
packet_loss: enet.peer_packet_loss(peer),
|
||||||
state: peer.state()
|
state: enet.peer_state(peer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strip ::ffff: prefix from IPv6-mapped IPv4 addresses
|
||||||
|
function normalize_addr(addr) {
|
||||||
|
if (starts_with(addr, "::ffff:"))
|
||||||
|
return text(addr, 7)
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
function handle_host(e) {
|
function handle_host(e) {
|
||||||
var queue = null
|
var queue = null
|
||||||
var data = null
|
var data = null
|
||||||
var addr = null
|
var addr = null
|
||||||
var port = null
|
var port = null
|
||||||
|
var pkey = null
|
||||||
|
|
||||||
|
log.connection(`handle_host: event type=${e.type}`)
|
||||||
if (e.type == "connect") {
|
if (e.type == "connect") {
|
||||||
addr = e.peer.address()
|
addr = normalize_addr(enet.peer_address(e.peer))
|
||||||
port = e.peer.port()
|
port = enet.peer_port(e.peer)
|
||||||
log.system(`connected a new peer: ${addr}:${port}`)
|
pkey = addr + ":" + text(port)
|
||||||
peers[`${addr}:${port}`] = e.peer
|
log.connection(`handle_host: peer connected ${pkey}`)
|
||||||
queue = peer_queue[e.peer]
|
peers[pkey] = e.peer
|
||||||
|
queue = peer_queue[pkey]
|
||||||
if (queue) {
|
if (queue) {
|
||||||
arrfor(queue, (msg, index) => e.peer.send(nota.encode(msg)))
|
log.connection(`handle_host: flushing ${text(length(queue))} queued messages to ${pkey}`)
|
||||||
log.system(`sent queue out of queue`)
|
arrfor(queue, (msg, index) => enet.send(e.peer, nota.encode(msg)))
|
||||||
delete peer_queue[e.peer]
|
delete peer_queue[pkey]
|
||||||
|
} else {
|
||||||
|
log.connection(`handle_host: no queued messages for ${pkey}`)
|
||||||
}
|
}
|
||||||
} else if (e.type == "disconnect") {
|
} else if (e.type == "disconnect") {
|
||||||
delete peer_queue[e.peer]
|
addr = normalize_addr(enet.peer_address(e.peer))
|
||||||
arrfor(array(peers), function(id, index) {
|
port = enet.peer_port(e.peer)
|
||||||
if (peers[id] == e.peer) delete peers[id]
|
pkey = addr + ":" + text(port)
|
||||||
})
|
log.connection(`handle_host: peer disconnected ${pkey}`)
|
||||||
log.system('portal got disconnect from ' + e.peer.address() + ":" + e.peer.port())
|
delete peer_queue[pkey]
|
||||||
|
delete peers[pkey]
|
||||||
} else if (e.type == "receive") {
|
} else if (e.type == "receive") {
|
||||||
data = nota.decode(e.data)
|
data = nota.decode(e.data)
|
||||||
if (data.replycc && !data.replycc.address) {
|
log.connection(`handle_host: received data type=${data.type}`)
|
||||||
data.replycc[ACTORDATA].address = e.peer.address()
|
if (data.replycc_id && !data.replycc) {
|
||||||
data.replycc[ACTORDATA].port = e.peer.port()
|
data.replycc = create_actor({id: data.replycc_id, address: normalize_addr(enet.peer_address(e.peer)), port: enet.peer_port(e.peer)})
|
||||||
|
} else if (data.replycc && !data.replycc.address) {
|
||||||
|
data.replycc[ACTORDATA].address = normalize_addr(enet.peer_address(e.peer))
|
||||||
|
data.replycc[ACTORDATA].port = enet.peer_port(e.peer)
|
||||||
}
|
}
|
||||||
if (data.data) populate_actor_addresses(data.data, e)
|
if (data.data) populate_actor_addresses(data.data, e)
|
||||||
handle_message(data)
|
handle_message(data)
|
||||||
@@ -1425,8 +1459,8 @@ function handle_host(e) {
|
|||||||
function populate_actor_addresses(obj, e) {
|
function populate_actor_addresses(obj, e) {
|
||||||
if (!is_object(obj)) return
|
if (!is_object(obj)) return
|
||||||
if (obj[ACTORDATA] && !obj[ACTORDATA].address) {
|
if (obj[ACTORDATA] && !obj[ACTORDATA].address) {
|
||||||
obj[ACTORDATA].address = e.peer.address()
|
obj[ACTORDATA].address = normalize_addr(enet.peer_address(e.peer))
|
||||||
obj[ACTORDATA].port = e.peer.port()
|
obj[ACTORDATA].port = enet.peer_port(e.peer)
|
||||||
}
|
}
|
||||||
arrfor(array(obj), function(key, index) {
|
arrfor(array(obj), function(key, index) {
|
||||||
if (key in obj)
|
if (key in obj)
|
||||||
@@ -1436,7 +1470,7 @@ function populate_actor_addresses(obj, e) {
|
|||||||
|
|
||||||
|
|
||||||
function actor_prep(actor, send) {
|
function actor_prep(actor, send) {
|
||||||
push(message_queue, {actor,send});
|
message_queue[] = {actor,send};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a message immediately without queuing
|
// Send a message immediately without queuing
|
||||||
@@ -1447,6 +1481,7 @@ function actor_send_immediate(actor, send) {
|
|||||||
function actor_send(actor, message) {
|
function actor_send(actor, message) {
|
||||||
var wota_blob = null
|
var wota_blob = null
|
||||||
var peer = null
|
var peer = null
|
||||||
|
var pkey = null
|
||||||
|
|
||||||
if (actor[HEADER] && !actor[HEADER].replycc) // attempting to respond to a message but sender is not expecting; silently drop
|
if (actor[HEADER] && !actor[HEADER].replycc) // attempting to respond to a message but sender is not expecting; silently drop
|
||||||
return
|
return
|
||||||
@@ -1463,12 +1498,14 @@ function actor_send(actor, message) {
|
|||||||
|
|
||||||
// message to self
|
// message to self
|
||||||
if (actor[ACTORDATA].id == _cell.id) {
|
if (actor[ACTORDATA].id == _cell.id) {
|
||||||
|
log.connection(`actor_send: message to self, type=${message.type}`)
|
||||||
if (receive_fn) receive_fn(message.data)
|
if (receive_fn) receive_fn(message.data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// message to actor in same flock
|
// message to actor in same flock
|
||||||
if (actor[ACTORDATA].id && actor_mod.mailbox_exist(actor[ACTORDATA].id)) {
|
if (actor[ACTORDATA].id && actor_mod.mailbox_exist(actor[ACTORDATA].id)) {
|
||||||
|
log.connection(`actor_send: local mailbox for ${text(actor[ACTORDATA].id, 0, 8)}`)
|
||||||
wota_blob = wota.encode(message)
|
wota_blob = wota.encode(message)
|
||||||
actor_mod.mailbox_push(actor[ACTORDATA].id, wota_blob)
|
actor_mod.mailbox_push(actor[ACTORDATA].id, wota_blob)
|
||||||
return
|
return
|
||||||
@@ -1480,23 +1517,27 @@ function actor_send(actor, message) {
|
|||||||
else
|
else
|
||||||
message.type = "contact"
|
message.type = "contact"
|
||||||
|
|
||||||
peer = peers[actor[ACTORDATA].address + ":" + actor[ACTORDATA].port]
|
pkey = actor[ACTORDATA].address + ":" + text(actor[ACTORDATA].port)
|
||||||
|
log.connection(`actor_send: remote ${pkey} msg.type=${message.type}`)
|
||||||
|
peer = peers[pkey]
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
if (!portal) {
|
if (!portal) {
|
||||||
log.system(`creating a contactor ...`)
|
log.connection(`actor_send: no portal, creating contactor`)
|
||||||
portal = enet.create_host({address:"any"})
|
portal = enet.create_host({address:"any"})
|
||||||
log.system(`allowing contact to port ${portal.port()}`)
|
log.connection(`actor_send: contactor on port ${text(enet.host_port(portal))}`)
|
||||||
enet_check()
|
enet_check()
|
||||||
}
|
}
|
||||||
log.system(`no peer! connecting to ${actor[ACTORDATA].address}:${actor[ACTORDATA].port}`)
|
log.connection(`actor_send: no peer for ${pkey}, connecting...`)
|
||||||
peer = portal.connect(actor[ACTORDATA].address, actor[ACTORDATA].port)
|
peer = enet.connect(portal, actor[ACTORDATA].address, actor[ACTORDATA].port)
|
||||||
peer_queue.set(peer, [message])
|
log.connection(`actor_send: connect initiated, peer=${peer}, queuing message`)
|
||||||
|
peer_queue[pkey] = [message]
|
||||||
} else {
|
} else {
|
||||||
peer.send(nota.encode(message))
|
log.connection(`actor_send: have peer for ${pkey}, sending directly`)
|
||||||
|
enet.send(peer, nota.encode(message))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.system(`Unable to send message to actor ${actor[ACTORDATA].id}`)
|
log.connection(`actor_send: no route for actor id=${actor[ACTORDATA].id} (no address, not local)`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function send_messages() {
|
function send_messages() {
|
||||||
@@ -1509,6 +1550,8 @@ function send_messages() {
|
|||||||
|
|
||||||
var _qi = 0
|
var _qi = 0
|
||||||
var _qm = null
|
var _qm = null
|
||||||
|
if (length(message_queue) > 0)
|
||||||
|
log.connection(`send_messages: processing ${text(length(message_queue))} queued messages`)
|
||||||
while (_qi < length(message_queue)) {
|
while (_qi < length(message_queue)) {
|
||||||
_qm = message_queue[_qi]
|
_qm = message_queue[_qi]
|
||||||
if (_qm.startup) {
|
if (_qm.startup) {
|
||||||
@@ -1667,13 +1710,40 @@ function handle_sysym(msg)
|
|||||||
function handle_message(msg) {
|
function handle_message(msg) {
|
||||||
var letter = null
|
var letter = null
|
||||||
var fn = null
|
var fn = null
|
||||||
|
var conn = null
|
||||||
|
var pkey = null
|
||||||
|
var peer = null
|
||||||
|
var reply_msg = null
|
||||||
|
|
||||||
|
log.connection(`handle_message: type=${msg.type}`)
|
||||||
|
|
||||||
if (msg[SYSYM]) {
|
if (msg[SYSYM]) {
|
||||||
handle_sysym(msg[SYSYM])
|
handle_sysym(msg[SYSYM])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.type == "user") {
|
if (msg.type == "contact") {
|
||||||
|
// Remote $contact arrived — create a connection actor for the caller.
|
||||||
|
// msg.replycc was constructed by handle_host with id + address + port.
|
||||||
|
conn = msg.replycc
|
||||||
|
log.connection(`handle_message: contact from ${conn ? conn[ACTORDATA].id : "unknown"}`)
|
||||||
|
|
||||||
|
// Reply directly over enet so the client's $contact callback fires
|
||||||
|
if (conn && msg.reply) {
|
||||||
|
pkey = conn[ACTORDATA].address + ":" + text(conn[ACTORDATA].port)
|
||||||
|
peer = peers[pkey]
|
||||||
|
if (peer) {
|
||||||
|
reply_msg = {type: "user", data: {type: "connected", actor_id: _cell.id}, return: msg.reply}
|
||||||
|
log.connection(`handle_message: sending contact reply to ${pkey}`)
|
||||||
|
enet.send(peer, nota.encode(reply_msg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portal_fn) {
|
||||||
|
log.connection(`handle_message: calling portal_fn`)
|
||||||
|
portal_fn(conn)
|
||||||
|
}
|
||||||
|
} else if (msg.type == "user") {
|
||||||
letter = msg.data // what the sender really sent
|
letter = msg.data // what the sender really sent
|
||||||
if (msg.replycc_id) {
|
if (msg.replycc_id) {
|
||||||
msg.replycc = create_actor({id: msg.replycc_id})
|
msg.replycc = create_actor({id: msg.replycc_id})
|
||||||
@@ -1683,11 +1753,13 @@ function handle_message(msg) {
|
|||||||
|
|
||||||
if (msg.return) {
|
if (msg.return) {
|
||||||
fn = replies[msg.return]
|
fn = replies[msg.return]
|
||||||
|
log.connection(`handle_message: reply callback ${msg.return} fn=${fn ? "yes" : "no"}`)
|
||||||
if (fn) fn(letter)
|
if (fn) fn(letter)
|
||||||
delete replies[msg.return]
|
delete replies[msg.return]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.connection(`handle_message: dispatching to receive_fn=${receive_fn ? "yes" : "no"}`)
|
||||||
if (receive_fn) receive_fn(letter)
|
if (receive_fn) receive_fn(letter)
|
||||||
} else if (msg.type == "stopped") {
|
} else if (msg.type == "stopped") {
|
||||||
handle_actor_disconnect(msg.id)
|
handle_actor_disconnect(msg.id)
|
||||||
@@ -1696,8 +1768,12 @@ function handle_message(msg) {
|
|||||||
|
|
||||||
function enet_check()
|
function enet_check()
|
||||||
{
|
{
|
||||||
if (portal) portal.service(handle_host)
|
if (portal) {
|
||||||
|
log.connection(`enet_check: servicing portal`)
|
||||||
|
enet.service(portal, handle_host)
|
||||||
|
} else {
|
||||||
|
log.connection(`enet_check: no portal`)
|
||||||
|
}
|
||||||
$_.delay(enet_check, ENETSERVICE);
|
$_.delay(enet_check, ENETSERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,10 +117,10 @@ JSC_CCALL(fd_read,
|
|||||||
JSC_SCALL(fd_slurp,
|
JSC_SCALL(fd_slurp,
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(str, &st) != 0)
|
if (stat(str, &st) != 0)
|
||||||
return JS_RaiseDisrupt(js, "stat failed: %s", strerror(errno));
|
return JS_RaiseDisrupt(js, "stat failed for %s: %s", str, strerror(errno));
|
||||||
|
|
||||||
if (!S_ISREG(st.st_mode))
|
if (!S_ISREG(st.st_mode))
|
||||||
return JS_RaiseDisrupt(js, "path is not a regular file");
|
return JS_RaiseDisrupt(js, "path %s is not a regular file", str);
|
||||||
|
|
||||||
size_t size = st.st_size;
|
size_t size = st.st_size;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
|||||||
@@ -1021,19 +1021,41 @@ function ensure_package_dylibs(pkg) {
|
|||||||
var build_mod = use_cache['core/build']
|
var build_mod = use_cache['core/build']
|
||||||
var target = null
|
var target = null
|
||||||
var c_files = null
|
var c_files = null
|
||||||
|
var _all_ok = true
|
||||||
|
var _ri = 0
|
||||||
|
|
||||||
if (build_mod) {
|
if (build_mod) {
|
||||||
target = detect_host_target()
|
// Fast path: if manifest exists and all dylibs are present, skip build_dynamic
|
||||||
if (!target) return null
|
results = read_dylib_manifest(_pkg)
|
||||||
|
if (results != null) {
|
||||||
c_files = pkg_tools.get_c_files(_pkg, target, true)
|
_all_ok = true
|
||||||
if (!c_files || length(c_files) == 0) {
|
_ri = 0
|
||||||
package_dylibs[_pkg] = []
|
while (_ri < length(results)) {
|
||||||
return []
|
if (results[_ri].dylib && !fd.is_file(results[_ri].dylib)) {
|
||||||
|
_all_ok = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ri = _ri + 1
|
||||||
|
}
|
||||||
|
if (_all_ok) {
|
||||||
|
log.shop('manifest ok for ' + _pkg + ' (' + text(length(results)) + ' modules)')
|
||||||
|
} else {
|
||||||
|
results = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (results == null) {
|
||||||
|
target = detect_host_target()
|
||||||
|
if (!target) return null
|
||||||
|
|
||||||
log.shop('ensuring C modules for ' + _pkg)
|
c_files = pkg_tools.get_c_files(_pkg, target, true)
|
||||||
results = build_mod.build_dynamic(_pkg, target, 'release', {})
|
if (!c_files || length(c_files) == 0) {
|
||||||
|
package_dylibs[_pkg] = []
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
log.shop('ensuring C modules for ' + _pkg)
|
||||||
|
results = build_mod.build_dynamic(_pkg, target, 'release', {})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// No build module at runtime — read manifest from cell build
|
// No build module at runtime — read manifest from cell build
|
||||||
results = read_dylib_manifest(_pkg)
|
results = read_dylib_manifest(_pkg)
|
||||||
@@ -1477,18 +1499,18 @@ Shop.use = function use(path, _pkg_ctx) {
|
|||||||
if (use_cache[info.cache_key])
|
if (use_cache[info.cache_key])
|
||||||
return use_cache[info.cache_key]
|
return use_cache[info.cache_key]
|
||||||
|
|
||||||
push(use_stack, _use_entry)
|
use_stack[] = _use_entry
|
||||||
var _use_result = null
|
var _use_result = null
|
||||||
var _use_ok = false
|
var _use_ok = false
|
||||||
var _load = function() {
|
var _load = function() {
|
||||||
_use_result = execute_module(info)
|
_use_result = execute_module(info)
|
||||||
_use_ok = true
|
_use_ok = true
|
||||||
} disruption {
|
} disruption {
|
||||||
pop(use_stack)
|
use_stack[]
|
||||||
disrupt
|
disrupt
|
||||||
}
|
}
|
||||||
_load()
|
_load()
|
||||||
pop(use_stack)
|
use_stack[]
|
||||||
use_cache[info.cache_key] = _use_result
|
use_cache[info.cache_key] = _use_result
|
||||||
return _use_result
|
return _use_result
|
||||||
}
|
}
|
||||||
@@ -1622,12 +1644,16 @@ function download_zip(pkg, commit_hash) {
|
|||||||
return _download()
|
return _download()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get zip from cache, returns null if not cached
|
// Get zip from cache, returns null if not cached or empty
|
||||||
function get_cached_zip(pkg, commit_hash) {
|
function get_cached_zip(pkg, commit_hash) {
|
||||||
var cache_path = get_cache_path(pkg, commit_hash)
|
var cache_path = get_cache_path(pkg, commit_hash)
|
||||||
if (fd.is_file(cache_path))
|
var data = null
|
||||||
return fd.slurp(cache_path)
|
if (fd.is_file(cache_path)) {
|
||||||
|
data = fd.slurp(cache_path)
|
||||||
|
stone(data)
|
||||||
|
if (length(data) > 0) return data
|
||||||
|
fd.remove(cache_path)
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1883,7 +1909,7 @@ Shop.sync_with_deps = function(pkg, opts) {
|
|||||||
if (visited[current]) continue
|
if (visited[current]) continue
|
||||||
visited[current] = true
|
visited[current] = true
|
||||||
|
|
||||||
log.console(' Fetching ' + current + '...')
|
log.build(' Fetching ' + current + '...')
|
||||||
Shop.sync(current, opts)
|
Shop.sync(current, opts)
|
||||||
|
|
||||||
_read_deps = function() {
|
_read_deps = function() {
|
||||||
@@ -1897,7 +1923,7 @@ Shop.sync_with_deps = function(pkg, opts) {
|
|||||||
arrfor(array(deps), function(alias) {
|
arrfor(array(deps), function(alias) {
|
||||||
dep_locator = deps[alias]
|
dep_locator = deps[alias]
|
||||||
if (!visited[dep_locator])
|
if (!visited[dep_locator])
|
||||||
push(queue, dep_locator)
|
queue[] = dep_locator
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2036,7 +2062,7 @@ function get_package_scripts(package)
|
|||||||
for (i = 0; i < length(files); i++) {
|
for (i = 0; i < length(files); i++) {
|
||||||
file = files[i]
|
file = files[i]
|
||||||
if (ends_with(file, '.cm') || ends_with(file, '.ce')) {
|
if (ends_with(file, '.cm') || ends_with(file, '.ce')) {
|
||||||
push(scripts, file)
|
scripts[] = file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2058,7 +2084,7 @@ function extract_use_calls(source) {
|
|||||||
if (end == null) end = search(text(source, start), '"')
|
if (end == null) end = search(text(source, start), '"')
|
||||||
if (end != null) {
|
if (end != null) {
|
||||||
arg = text(source, start, start + end)
|
arg = text(source, start, start + end)
|
||||||
push(uses, arg)
|
uses[] = arg
|
||||||
}
|
}
|
||||||
idx = search(text(source, idx + 4), "use(")
|
idx = search(text(source, idx + 4), "use(")
|
||||||
if (idx != null) idx = idx + (source.length - (source.length - idx))
|
if (idx != null) idx = idx + (source.length - (source.length - idx))
|
||||||
@@ -2081,16 +2107,16 @@ Shop.build_package_scripts = function(package)
|
|||||||
resolve_mod_fn(pkg_dir + '/' + script, package)
|
resolve_mod_fn(pkg_dir + '/' + script, package)
|
||||||
ok = ok + 1
|
ok = ok + 1
|
||||||
} disruption {
|
} disruption {
|
||||||
push(errors, script)
|
errors[] = script
|
||||||
log.console(" compile error: " + package + '/' + script)
|
log.build(" compile error: " + package + '/' + script)
|
||||||
}
|
}
|
||||||
_try()
|
_try()
|
||||||
})
|
})
|
||||||
|
|
||||||
if (length(errors) > 0) {
|
if (length(errors) > 0) {
|
||||||
log.console(' Compiling scripts (' + text(ok) + ' ok, ' + text(length(errors)) + ' errors)')
|
log.build(' Compiling scripts (' + text(ok) + ' ok, ' + text(length(errors)) + ' errors)')
|
||||||
} else if (ok > 0) {
|
} else if (ok > 0) {
|
||||||
log.console(' Compiling scripts (' + text(ok) + ' ok)')
|
log.build(' Compiling scripts (' + text(ok) + ' ok)')
|
||||||
}
|
}
|
||||||
|
|
||||||
return {ok: ok, errors: errors, total: length(scripts)}
|
return {ok: ok, errors: errors, total: length(scripts)}
|
||||||
@@ -2134,14 +2160,14 @@ Shop.audit_use_resolution = function(package) {
|
|||||||
end = search(rest, quote)
|
end = search(rest, quote)
|
||||||
if (end == null) continue
|
if (end == null) continue
|
||||||
arg = text(rest, 0, end)
|
arg = text(rest, 0, end)
|
||||||
if (length(arg) > 0) push(uses, arg)
|
if (length(arg) > 0) uses[] = arg
|
||||||
rest = text(rest, end + 1)
|
rest = text(rest, end + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
arrfor(uses, function(mod) {
|
arrfor(uses, function(mod) {
|
||||||
var _resolve = function() {
|
var _resolve = function() {
|
||||||
info = resolve_module_info(mod, package)
|
info = resolve_module_info(mod, package)
|
||||||
if (!info) push(unresolved, {script: script, module: mod})
|
if (!info) unresolved[] = {script: script, module: mod}
|
||||||
} disruption {}
|
} disruption {}
|
||||||
_resolve()
|
_resolve()
|
||||||
})
|
})
|
||||||
@@ -2392,7 +2418,7 @@ Shop.audit_packages = function() {
|
|||||||
if (package == 'core') return
|
if (package == 'core') return
|
||||||
if (fd.is_dir(package)) return
|
if (fd.is_dir(package)) return
|
||||||
if (fetch_remote_hash(package)) return
|
if (fetch_remote_hash(package)) return
|
||||||
push(bad, package)
|
bad[] = package
|
||||||
})
|
})
|
||||||
|
|
||||||
return bad
|
return bad
|
||||||
|
|||||||
6
link.cm
6
link.cm
@@ -208,11 +208,11 @@ Link.sync_all = function(shop) {
|
|||||||
// Validate target exists
|
// Validate target exists
|
||||||
var link_target = resolve_link_target(target)
|
var link_target = resolve_link_target(target)
|
||||||
if (!fd.is_dir(link_target)) {
|
if (!fd.is_dir(link_target)) {
|
||||||
push(errors, canonical + ': target ' + link_target + ' does not exist')
|
errors[] = canonical + ': target ' + link_target + ' does not exist'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!fd.is_file(link_target + '/cell.toml')) {
|
if (!fd.is_file(link_target + '/cell.toml')) {
|
||||||
push(errors, canonical + ': target ' + link_target + ' is not a valid package')
|
errors[] = canonical + ': target ' + link_target + ' is not a valid package'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ Link.sync_all = function(shop) {
|
|||||||
|
|
||||||
count = count + 1
|
count = count + 1
|
||||||
} disruption {
|
} disruption {
|
||||||
push(errors, canonical + ': sync failed')
|
errors[] = canonical + ': sync failed'
|
||||||
}
|
}
|
||||||
_sync()
|
_sync()
|
||||||
})
|
})
|
||||||
|
|||||||
14
list.ce
14
list.ce
@@ -89,16 +89,16 @@ var run = function() {
|
|||||||
// Add status indicators
|
// Add status indicators
|
||||||
status = []
|
status = []
|
||||||
if (link_target) {
|
if (link_target) {
|
||||||
push(status, "linked -> " + link_target)
|
status[] = "linked -> " + link_target
|
||||||
}
|
}
|
||||||
if (lock_entry && lock_entry.commit) {
|
if (lock_entry && lock_entry.commit) {
|
||||||
push(status, "@" + text(lock_entry.commit, 0, 8))
|
status[] = "@" + text(lock_entry.commit, 0, 8)
|
||||||
}
|
}
|
||||||
if (lock_entry && lock_entry.type == 'local') {
|
if (lock_entry && lock_entry.type == 'local') {
|
||||||
push(status, "local")
|
status[] = "local"
|
||||||
}
|
}
|
||||||
if (!lock_entry) {
|
if (!lock_entry) {
|
||||||
push(status, "not installed")
|
status[] = "not installed"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length(status) > 0) {
|
if (length(status) > 0) {
|
||||||
@@ -136,11 +136,11 @@ if (mode == 'local') {
|
|||||||
var link_target = links[p]
|
var link_target = links[p]
|
||||||
|
|
||||||
if (link_target) {
|
if (link_target) {
|
||||||
push(linked_pkgs, p)
|
linked_pkgs[] = p
|
||||||
} else if (lock_entry && lock_entry.type == 'local') {
|
} else if (lock_entry && lock_entry.type == 'local') {
|
||||||
push(local_pkgs, p)
|
local_pkgs[] = p
|
||||||
} else {
|
} else {
|
||||||
push(remote_pkgs, p)
|
remote_pkgs[] = p
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
10
log.ce
10
log.ce
@@ -371,6 +371,7 @@ function do_enable() {
|
|||||||
var sink = null
|
var sink = null
|
||||||
var i = 0
|
var i = 0
|
||||||
var already = false
|
var already = false
|
||||||
|
var new_exclude = []
|
||||||
if (length(args) < 2) {
|
if (length(args) < 2) {
|
||||||
log.error("Usage: cell log enable <channel>")
|
log.error("Usage: cell log enable <channel>")
|
||||||
return
|
return
|
||||||
@@ -388,9 +389,9 @@ function do_enable() {
|
|||||||
}
|
}
|
||||||
if (is_array(sink.channels) && length(sink.channels) == 1 && sink.channels[0] == "*") {
|
if (is_array(sink.channels) && length(sink.channels) == 1 && sink.channels[0] == "*") {
|
||||||
if (is_array(sink.exclude)) {
|
if (is_array(sink.exclude)) {
|
||||||
var new_exclude = []
|
new_exclude = []
|
||||||
arrfor(sink.exclude, function(ex) {
|
arrfor(sink.exclude, function(ex) {
|
||||||
if (ex != channel) push(new_exclude, ex)
|
if (ex != channel) new_exclude[] = ex
|
||||||
})
|
})
|
||||||
sink.exclude = new_exclude
|
sink.exclude = new_exclude
|
||||||
}
|
}
|
||||||
@@ -411,6 +412,7 @@ function do_disable() {
|
|||||||
var sink = null
|
var sink = null
|
||||||
var i = 0
|
var i = 0
|
||||||
var new_channels = []
|
var new_channels = []
|
||||||
|
var already_excluded = false
|
||||||
if (length(args) < 2) {
|
if (length(args) < 2) {
|
||||||
log.error("Usage: cell log disable <channel>")
|
log.error("Usage: cell log disable <channel>")
|
||||||
return
|
return
|
||||||
@@ -428,7 +430,7 @@ function do_disable() {
|
|||||||
}
|
}
|
||||||
if (is_array(sink.channels) && length(sink.channels) == 1 && sink.channels[0] == "*") {
|
if (is_array(sink.channels) && length(sink.channels) == 1 && sink.channels[0] == "*") {
|
||||||
if (!is_array(sink.exclude)) sink.exclude = []
|
if (!is_array(sink.exclude)) sink.exclude = []
|
||||||
var already_excluded = false
|
already_excluded = false
|
||||||
arrfor(sink.exclude, function(ex) {
|
arrfor(sink.exclude, function(ex) {
|
||||||
if (ex == channel) already_excluded = true
|
if (ex == channel) already_excluded = true
|
||||||
})
|
})
|
||||||
@@ -436,7 +438,7 @@ function do_disable() {
|
|||||||
} else {
|
} else {
|
||||||
if (is_array(sink.channels)) {
|
if (is_array(sink.channels)) {
|
||||||
arrfor(sink.channels, function(ch) {
|
arrfor(sink.channels, function(ch) {
|
||||||
if (ch != channel) push(new_channels, ch)
|
if (ch != channel) new_channels[] = ch
|
||||||
})
|
})
|
||||||
sink.channels = new_channels
|
sink.channels = new_channels
|
||||||
}
|
}
|
||||||
|
|||||||
2
mcode.ce
2
mcode.ce
@@ -85,7 +85,7 @@ var dump_function = function(func, name) {
|
|||||||
parts = []
|
parts = []
|
||||||
j = 1
|
j = 1
|
||||||
while (j < n - 2) {
|
while (j < n - 2) {
|
||||||
push(parts, fmt_val(instr[j]))
|
parts[] = fmt_val(instr[j])
|
||||||
j = j + 1
|
j = j + 1
|
||||||
}
|
}
|
||||||
operands = text(parts, ", ")
|
operands = text(parts, ", ")
|
||||||
|
|||||||
55
mcode.cm
55
mcode.cm
@@ -166,7 +166,7 @@ var mcode = function(ast) {
|
|||||||
|
|
||||||
// Variable tracking
|
// Variable tracking
|
||||||
var add_var = function(name, slot, is_const) {
|
var add_var = function(name, slot, is_const) {
|
||||||
push(s_vars, {name: name, slot: slot, is_const: is_const, is_closure: false})
|
s_vars[] = {name: name, slot: slot, is_const: is_const, is_closure: false}
|
||||||
}
|
}
|
||||||
|
|
||||||
var find_var = function(name) {
|
var find_var = function(name) {
|
||||||
@@ -228,13 +228,13 @@ var mcode = function(ast) {
|
|||||||
|
|
||||||
// Instruction emission
|
// Instruction emission
|
||||||
var add_instr = function(instr) {
|
var add_instr = function(instr) {
|
||||||
push(instr, s_cur_line)
|
instr[] = s_cur_line
|
||||||
push(instr, s_cur_col)
|
instr[] = s_cur_col
|
||||||
push(s_instructions, instr)
|
s_instructions[] = instr
|
||||||
}
|
}
|
||||||
|
|
||||||
var emit_label = function(label) {
|
var emit_label = function(label) {
|
||||||
push(s_instructions, label)
|
s_instructions[] = label
|
||||||
}
|
}
|
||||||
|
|
||||||
var emit_0 = function(op) {
|
var emit_0 = function(op) {
|
||||||
@@ -743,7 +743,7 @@ var mcode = function(ast) {
|
|||||||
slot = alloc_slot()
|
slot = alloc_slot()
|
||||||
lit = {kind: "name", name: name, make: "intrinsic"}
|
lit = {kind: "name", name: name, make: "intrinsic"}
|
||||||
add_instr(["access", slot, lit])
|
add_instr(["access", slot, lit])
|
||||||
push(s_intrinsic_cache, {name: name, slot: slot})
|
s_intrinsic_cache[] = {name: name, slot: slot}
|
||||||
_i = _i + 1
|
_i = _i + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1974,7 +1974,7 @@ var mcode = function(ast) {
|
|||||||
expr_slots = []
|
expr_slots = []
|
||||||
_i = 0
|
_i = 0
|
||||||
while (_i < nexpr) {
|
while (_i < nexpr) {
|
||||||
push(expr_slots, gen_expr(list[_i], -1))
|
expr_slots[] = gen_expr(list[_i], -1)
|
||||||
_i = _i + 1
|
_i = _i + 1
|
||||||
}
|
}
|
||||||
// Create array from expression results
|
// Create array from expression results
|
||||||
@@ -2083,6 +2083,23 @@ var mcode = function(ast) {
|
|||||||
if (kind == "[") {
|
if (kind == "[") {
|
||||||
obj = expr.left
|
obj = expr.left
|
||||||
idx = expr.right
|
idx = expr.right
|
||||||
|
if (idx == null) {
|
||||||
|
// arr[] pop expression
|
||||||
|
obj_slot = gen_expr(obj, -1)
|
||||||
|
guard_t = alloc_slot()
|
||||||
|
guard_err = gen_label("pop_err")
|
||||||
|
guard_done = gen_label("pop_done")
|
||||||
|
emit_2("is_array", guard_t, obj_slot)
|
||||||
|
emit_jump_cond("jump_false", guard_t, guard_err)
|
||||||
|
slot = target >= 0 ? target : alloc_slot()
|
||||||
|
emit_2("pop", slot, obj_slot)
|
||||||
|
emit_jump(guard_done)
|
||||||
|
emit_label(guard_err)
|
||||||
|
emit_log_error("cannot pop: target must be an array")
|
||||||
|
emit_0("disrupt")
|
||||||
|
emit_label(guard_done)
|
||||||
|
return slot
|
||||||
|
}
|
||||||
obj_slot = gen_expr(obj, -1)
|
obj_slot = gen_expr(obj, -1)
|
||||||
idx_slot = gen_expr(idx, -1)
|
idx_slot = gen_expr(idx, -1)
|
||||||
slot = alloc_slot()
|
slot = alloc_slot()
|
||||||
@@ -2264,7 +2281,7 @@ var mcode = function(ast) {
|
|||||||
_i = 0
|
_i = 0
|
||||||
nargs = args_list != null ? length(args_list) : 0
|
nargs = args_list != null ? length(args_list) : 0
|
||||||
while (_i < nargs) {
|
while (_i < nargs) {
|
||||||
push(arg_slots, gen_expr(args_list[_i], -1))
|
arg_slots[] = gen_expr(args_list[_i], -1)
|
||||||
_i = _i + 1
|
_i = _i + 1
|
||||||
}
|
}
|
||||||
dest = alloc_slot()
|
dest = alloc_slot()
|
||||||
@@ -2432,7 +2449,7 @@ var mcode = function(ast) {
|
|||||||
elem_slots = []
|
elem_slots = []
|
||||||
_i = 0
|
_i = 0
|
||||||
while (_i < count) {
|
while (_i < count) {
|
||||||
push(elem_slots, gen_expr(list[_i], -1))
|
elem_slots[] = gen_expr(list[_i], -1)
|
||||||
_i = _i + 1
|
_i = _i + 1
|
||||||
}
|
}
|
||||||
dest = alloc_slot()
|
dest = alloc_slot()
|
||||||
@@ -2449,7 +2466,7 @@ var mcode = function(ast) {
|
|||||||
if (kind == "record") {
|
if (kind == "record") {
|
||||||
list = expr.list
|
list = expr.list
|
||||||
dest = alloc_slot()
|
dest = alloc_slot()
|
||||||
push(s_instructions, ["record", dest, length(list)])
|
s_instructions[] = ["record", dest, length(list)]
|
||||||
_i = 0
|
_i = 0
|
||||||
while (_i < length(list)) {
|
while (_i < length(list)) {
|
||||||
pair = list[_i]
|
pair = list[_i]
|
||||||
@@ -2479,7 +2496,7 @@ var mcode = function(ast) {
|
|||||||
func = gen_function(expr)
|
func = gen_function(expr)
|
||||||
func_id = s_func_counter
|
func_id = s_func_counter
|
||||||
s_func_counter = s_func_counter + 1
|
s_func_counter = s_func_counter + 1
|
||||||
push(s_functions, func)
|
s_functions[] = func
|
||||||
dest = alloc_slot()
|
dest = alloc_slot()
|
||||||
emit_2("function", dest, func_id)
|
emit_2("function", dest, func_id)
|
||||||
return dest
|
return dest
|
||||||
@@ -2797,7 +2814,7 @@ var mcode = function(ast) {
|
|||||||
_i = 0
|
_i = 0
|
||||||
nargs = args_list != null ? length(args_list) : 0
|
nargs = args_list != null ? length(args_list) : 0
|
||||||
while (_i < nargs) {
|
while (_i < nargs) {
|
||||||
push(arg_slots, gen_expr(args_list[_i], -1))
|
arg_slots[] = gen_expr(args_list[_i], -1)
|
||||||
_i = _i + 1
|
_i = _i + 1
|
||||||
}
|
}
|
||||||
callee_kind = callee.kind
|
callee_kind = callee.kind
|
||||||
@@ -2852,7 +2869,7 @@ var mcode = function(ast) {
|
|||||||
case_kind = case_node.kind
|
case_kind = case_node.kind
|
||||||
if (case_kind == "default") {
|
if (case_kind == "default") {
|
||||||
default_label = gen_label("switch_default")
|
default_label = gen_label("switch_default")
|
||||||
push(case_labels, default_label)
|
case_labels[] = default_label
|
||||||
} else {
|
} else {
|
||||||
case_label = gen_label("switch_case")
|
case_label = gen_label("switch_case")
|
||||||
case_expr = case_node.expression
|
case_expr = case_node.expression
|
||||||
@@ -2862,7 +2879,7 @@ var mcode = function(ast) {
|
|||||||
_bp_rn = case_expr
|
_bp_rn = case_expr
|
||||||
emit_binop("eq", cmp_slot, switch_val, case_val)
|
emit_binop("eq", cmp_slot, switch_val, case_val)
|
||||||
emit_jump_cond("jump_true", cmp_slot, case_label)
|
emit_jump_cond("jump_true", cmp_slot, case_label)
|
||||||
push(case_labels, case_label)
|
case_labels[] = case_label
|
||||||
}
|
}
|
||||||
_i = _i + 1
|
_i = _i + 1
|
||||||
}
|
}
|
||||||
@@ -2894,7 +2911,7 @@ var mcode = function(ast) {
|
|||||||
func = gen_function(stmt)
|
func = gen_function(stmt)
|
||||||
func_id = s_func_counter
|
func_id = s_func_counter
|
||||||
s_func_counter = s_func_counter + 1
|
s_func_counter = s_func_counter + 1
|
||||||
push(s_functions, func)
|
s_functions[] = func
|
||||||
local_slot = find_var(name)
|
local_slot = find_var(name)
|
||||||
dest = alloc_slot()
|
dest = alloc_slot()
|
||||||
emit_2("function", dest, func_id)
|
emit_2("function", dest, func_id)
|
||||||
@@ -2948,7 +2965,7 @@ var mcode = function(ast) {
|
|||||||
var saved_func = 0
|
var saved_func = 0
|
||||||
var captured_this = 0
|
var captured_this = 0
|
||||||
|
|
||||||
push(parent_states, saved)
|
parent_states[] = saved
|
||||||
|
|
||||||
s_instructions = []
|
s_instructions = []
|
||||||
s_vars = []
|
s_vars = []
|
||||||
@@ -3039,7 +3056,7 @@ var mcode = function(ast) {
|
|||||||
compiled = gen_function(fn)
|
compiled = gen_function(fn)
|
||||||
func_id = s_func_counter
|
func_id = s_func_counter
|
||||||
s_func_counter = s_func_counter + 1
|
s_func_counter = s_func_counter + 1
|
||||||
push(s_functions, compiled)
|
s_functions[] = compiled
|
||||||
local_slot = find_var(fname)
|
local_slot = find_var(fname)
|
||||||
dest = alloc_slot()
|
dest = alloc_slot()
|
||||||
emit_2("function", dest, func_id)
|
emit_2("function", dest, func_id)
|
||||||
@@ -3112,7 +3129,7 @@ var mcode = function(ast) {
|
|||||||
saved_func = s_func_counter
|
saved_func = s_func_counter
|
||||||
|
|
||||||
// Pop parent state
|
// Pop parent state
|
||||||
pop(parent_states)
|
parent_states[]
|
||||||
restore_state(saved)
|
restore_state(saved)
|
||||||
s_label_counter = saved_label
|
s_label_counter = saved_label
|
||||||
s_func_counter = saved_func
|
s_func_counter = saved_func
|
||||||
@@ -3179,7 +3196,7 @@ var mcode = function(ast) {
|
|||||||
compiled = gen_function(fn)
|
compiled = gen_function(fn)
|
||||||
func_id = s_func_counter
|
func_id = s_func_counter
|
||||||
s_func_counter = s_func_counter + 1
|
s_func_counter = s_func_counter + 1
|
||||||
push(s_functions, compiled)
|
s_functions[] = compiled
|
||||||
local_slot = find_var(name)
|
local_slot = find_var(name)
|
||||||
dest = alloc_slot()
|
dest = alloc_slot()
|
||||||
emit_2("function", dest, func_id)
|
emit_2("function", dest, func_id)
|
||||||
|
|||||||
6
pack.ce
6
pack.ce
@@ -88,9 +88,9 @@ var packages = ['core']
|
|||||||
var deps = pkg_tools.gather_dependencies(target_package)
|
var deps = pkg_tools.gather_dependencies(target_package)
|
||||||
|
|
||||||
for (i = 0; i < length(deps); i++) {
|
for (i = 0; i < length(deps); i++) {
|
||||||
push(packages, deps[i])
|
packages[] = deps[i]
|
||||||
}
|
}
|
||||||
push(packages, target_package)
|
packages[] = target_package
|
||||||
|
|
||||||
// Remove duplicates
|
// Remove duplicates
|
||||||
var unique_packages = []
|
var unique_packages = []
|
||||||
@@ -98,7 +98,7 @@ var seen = {}
|
|||||||
for (i = 0; i < length(packages); i++) {
|
for (i = 0; i < length(packages); i++) {
|
||||||
if (!seen[packages[i]]) {
|
if (!seen[packages[i]]) {
|
||||||
seen[packages[i]] = true
|
seen[packages[i]] = true
|
||||||
push(unique_packages, packages[i])
|
unique_packages[] = packages[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
packages = unique_packages
|
packages = unique_packages
|
||||||
|
|||||||
12
package.cm
12
package.cm
@@ -198,7 +198,7 @@ package.find_packages = function(dir) {
|
|||||||
var list = fd.readdir(dir)
|
var list = fd.readdir(dir)
|
||||||
if (!list) return found
|
if (!list) return found
|
||||||
if (fd.is_file(dir + '/cell.toml'))
|
if (fd.is_file(dir + '/cell.toml'))
|
||||||
push(found, dir)
|
found[] = dir
|
||||||
arrfor(list, function(item) {
|
arrfor(list, function(item) {
|
||||||
if (item == '.' || item == '..' || item == '.cell' || item == '.git') return
|
if (item == '.' || item == '..' || item == '.cell' || item == '.git') return
|
||||||
var full = dir + '/' + item
|
var full = dir + '/' + item
|
||||||
@@ -207,7 +207,7 @@ package.find_packages = function(dir) {
|
|||||||
if (st && st.isDirectory) {
|
if (st && st.isDirectory) {
|
||||||
sub = package.find_packages(full)
|
sub = package.find_packages(full)
|
||||||
arrfor(sub, function(p) {
|
arrfor(sub, function(p) {
|
||||||
push(found, p)
|
found[] = p
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -227,14 +227,14 @@ package.list_modules = function(name) {
|
|||||||
var stem = null
|
var stem = null
|
||||||
for (i = 0; i < length(files); i++) {
|
for (i = 0; i < length(files); i++) {
|
||||||
if (ends_with(files[i], '.cm')) {
|
if (ends_with(files[i], '.cm')) {
|
||||||
push(modules, text(files[i], 0, -3))
|
modules[] = text(files[i], 0, -3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var c_files = package.get_c_files(name, null, true)
|
var c_files = package.get_c_files(name, null, true)
|
||||||
for (i = 0; i < length(c_files); i++) {
|
for (i = 0; i < length(c_files); i++) {
|
||||||
stem = ends_with(c_files[i], '.cpp') ? text(c_files[i], 0, -4) : text(c_files[i], 0, -2)
|
stem = ends_with(c_files[i], '.cpp') ? text(c_files[i], 0, -4) : text(c_files[i], 0, -2)
|
||||||
if (find(modules, function(m) { return m == stem }) == null)
|
if (find(modules, function(m) { return m == stem }) == null)
|
||||||
push(modules, stem)
|
modules[] = stem
|
||||||
}
|
}
|
||||||
return modules
|
return modules
|
||||||
}
|
}
|
||||||
@@ -245,7 +245,7 @@ package.list_programs = function(name) {
|
|||||||
var i = 0
|
var i = 0
|
||||||
for (i = 0; i < length(files); i++) {
|
for (i = 0; i < length(files); i++) {
|
||||||
if (ends_with(files[i], '.ce')) {
|
if (ends_with(files[i], '.ce')) {
|
||||||
push(programs, text(files[i], 0, -3))
|
programs[] = text(files[i], 0, -3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return programs
|
return programs
|
||||||
@@ -360,7 +360,7 @@ package.get_c_files = function(name, target, exclude_main) {
|
|||||||
basename = fd.basename(selected)
|
basename = fd.basename(selected)
|
||||||
if (basename == 'main.c' || starts_with(basename, 'main_')) return
|
if (basename == 'main.c' || starts_with(basename, 'main_')) return
|
||||||
}
|
}
|
||||||
push(result, selected)
|
result[] = selected
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
98
parse.cm
98
parse.cm
@@ -90,12 +90,12 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
var parse_error = function(token, msg) {
|
var parse_error = function(token, msg) {
|
||||||
if (error_count >= 5) return null
|
if (error_count >= 5) return null
|
||||||
error_count = error_count + 1
|
error_count = error_count + 1
|
||||||
push(errors, {
|
errors[] = {
|
||||||
message: msg,
|
message: msg,
|
||||||
line: token.from_row + 1,
|
line: token.from_row + 1,
|
||||||
column: token.from_column + 1,
|
column: token.from_column + 1,
|
||||||
offset: token.at
|
offset: token.at
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _keywords = {
|
var _keywords = {
|
||||||
@@ -230,8 +230,8 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
if (tv[tvi] == "\\" && tvi + 1 < tvlen) {
|
if (tv[tvi] == "\\" && tvi + 1 < tvlen) {
|
||||||
esc_ch = tv[tvi + 1]
|
esc_ch = tv[tvi + 1]
|
||||||
esc_val = template_escape_map[esc_ch]
|
esc_val = template_escape_map[esc_ch]
|
||||||
if (esc_val != null) { push(fmt_parts, esc_val) }
|
if (esc_val != null) { fmt_parts[] = esc_val }
|
||||||
else { push(fmt_parts, esc_ch) }
|
else { fmt_parts[] = esc_ch }
|
||||||
tvi = tvi + 2
|
tvi = tvi + 2
|
||||||
} else if (tv[tvi] == "$" && tvi + 1 < tvlen && tv[tvi + 1] == "{") {
|
} else if (tv[tvi] == "$" && tvi + 1 < tvlen && tv[tvi + 1] == "{") {
|
||||||
tvi = tvi + 2
|
tvi = tvi + 2
|
||||||
@@ -239,27 +239,27 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
expr_parts = []
|
expr_parts = []
|
||||||
while (tvi < tvlen && depth > 0) {
|
while (tvi < tvlen && depth > 0) {
|
||||||
tc = tv[tvi]
|
tc = tv[tvi]
|
||||||
if (tc == "{") { depth = depth + 1; push(expr_parts, tc); tvi = tvi + 1 }
|
if (tc == "{") { depth = depth + 1; expr_parts[] = tc; tvi = tvi + 1 }
|
||||||
else if (tc == "}") {
|
else if (tc == "}") {
|
||||||
depth = depth - 1
|
depth = depth - 1
|
||||||
if (depth > 0) { push(expr_parts, tc) }
|
if (depth > 0) { expr_parts[] = tc }
|
||||||
tvi = tvi + 1
|
tvi = tvi + 1
|
||||||
}
|
}
|
||||||
else if (tc == "'" || tc == "\"" || tc == "`") {
|
else if (tc == "'" || tc == "\"" || tc == "`") {
|
||||||
tq = tc
|
tq = tc
|
||||||
push(expr_parts, tc)
|
expr_parts[] = tc
|
||||||
tvi = tvi + 1
|
tvi = tvi + 1
|
||||||
while (tvi < tvlen && tv[tvi] != tq) {
|
while (tvi < tvlen && tv[tvi] != tq) {
|
||||||
if (tv[tvi] == "\\" && tvi + 1 < tvlen) {
|
if (tv[tvi] == "\\" && tvi + 1 < tvlen) {
|
||||||
push(expr_parts, tv[tvi])
|
expr_parts[] = tv[tvi]
|
||||||
tvi = tvi + 1
|
tvi = tvi + 1
|
||||||
}
|
}
|
||||||
push(expr_parts, tv[tvi])
|
expr_parts[] = tv[tvi]
|
||||||
tvi = tvi + 1
|
tvi = tvi + 1
|
||||||
}
|
}
|
||||||
if (tvi < tvlen) { push(expr_parts, tv[tvi]); tvi = tvi + 1 }
|
if (tvi < tvlen) { expr_parts[] = tv[tvi]; tvi = tvi + 1 }
|
||||||
} else {
|
} else {
|
||||||
push(expr_parts, tc)
|
expr_parts[] = tc
|
||||||
tvi = tvi + 1
|
tvi = tvi + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,14 +274,14 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
} else {
|
} else {
|
||||||
sub_expr = sub_stmt
|
sub_expr = sub_stmt
|
||||||
}
|
}
|
||||||
push(tpl_list, sub_expr)
|
tpl_list[] = sub_expr
|
||||||
}
|
}
|
||||||
push(fmt_parts, "{")
|
fmt_parts[] = "{"
|
||||||
push(fmt_parts, text(idx))
|
fmt_parts[] = text(idx)
|
||||||
push(fmt_parts, "}")
|
fmt_parts[] = "}"
|
||||||
idx = idx + 1
|
idx = idx + 1
|
||||||
} else {
|
} else {
|
||||||
push(fmt_parts, tv[tvi])
|
fmt_parts[] = tv[tvi]
|
||||||
tvi = tvi + 1
|
tvi = tvi + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,7 +332,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
advance()
|
advance()
|
||||||
while (tok.kind != "]" && tok.kind != "eof") {
|
while (tok.kind != "]" && tok.kind != "eof") {
|
||||||
elem = parse_assign_expr()
|
elem = parse_assign_expr()
|
||||||
if (elem != null) push(list, elem)
|
if (elem != null) list[] = elem
|
||||||
if (tok.kind == ",") advance()
|
if (tok.kind == ",") advance()
|
||||||
else break
|
else break
|
||||||
}
|
}
|
||||||
@@ -395,7 +395,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
advance()
|
advance()
|
||||||
param.expression = parse_assign_expr()
|
param.expression = parse_assign_expr()
|
||||||
}
|
}
|
||||||
push(params, param)
|
params[] = param
|
||||||
} else {
|
} else {
|
||||||
parse_error(tok, "expected parameter name")
|
parse_error(tok, "expected parameter name")
|
||||||
break
|
break
|
||||||
@@ -436,7 +436,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
} else {
|
} else {
|
||||||
parse_error(tok, "expected ':' after property name")
|
parse_error(tok, "expected ':' after property name")
|
||||||
}
|
}
|
||||||
push(list, pair)
|
list[] = pair
|
||||||
if (tok.kind == ",") advance()
|
if (tok.kind == ",") advance()
|
||||||
else if (tok.kind == "{") {
|
else if (tok.kind == "{") {
|
||||||
if (right && right.kind == "(") {
|
if (right && right.kind == "(") {
|
||||||
@@ -473,17 +473,17 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
flags_parts = []
|
flags_parts = []
|
||||||
while (rpos < _src_len && src[rpos] != "/") {
|
while (rpos < _src_len && src[rpos] != "/") {
|
||||||
if (src[rpos] == "\\" && rpos + 1 < _src_len) {
|
if (src[rpos] == "\\" && rpos + 1 < _src_len) {
|
||||||
push(pattern_parts, src[rpos])
|
pattern_parts[] = src[rpos]
|
||||||
push(pattern_parts, src[rpos + 1])
|
pattern_parts[] = src[rpos + 1]
|
||||||
rpos = rpos + 2
|
rpos = rpos + 2
|
||||||
} else {
|
} else {
|
||||||
push(pattern_parts, src[rpos])
|
pattern_parts[] = src[rpos]
|
||||||
rpos = rpos + 1
|
rpos = rpos + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rpos < _src_len) rpos = rpos + 1
|
if (rpos < _src_len) rpos = rpos + 1
|
||||||
while (rpos < _src_len && is_letter(src[rpos])) {
|
while (rpos < _src_len && is_letter(src[rpos])) {
|
||||||
push(flags_parts, src[rpos])
|
flags_parts[] = src[rpos]
|
||||||
rpos = rpos + 1
|
rpos = rpos + 1
|
||||||
}
|
}
|
||||||
node.pattern = text(pattern_parts)
|
node.pattern = text(pattern_parts)
|
||||||
@@ -557,7 +557,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
new_node.list = args_list
|
new_node.list = args_list
|
||||||
while (tok.kind != ")" && tok.kind != "eof") {
|
while (tok.kind != ")" && tok.kind != "eof") {
|
||||||
arg = parse_assign_expr()
|
arg = parse_assign_expr()
|
||||||
if (arg != null) push(args_list, arg)
|
if (arg != null) args_list[] = arg
|
||||||
if (tok.kind == ",") advance()
|
if (tok.kind == ",") advance()
|
||||||
else break
|
else break
|
||||||
}
|
}
|
||||||
@@ -830,7 +830,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
before = cursor
|
before = cursor
|
||||||
stmt = parse_statement()
|
stmt = parse_statement()
|
||||||
if (stmt != null) {
|
if (stmt != null) {
|
||||||
push(stmts, stmt)
|
stmts[] = stmt
|
||||||
} else if (cursor == before) {
|
} else if (cursor == before) {
|
||||||
sync_to_statement()
|
sync_to_statement()
|
||||||
}
|
}
|
||||||
@@ -872,14 +872,14 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
param.name = tok.value
|
param.name = tok.value
|
||||||
pname = tok.value
|
pname = tok.value
|
||||||
if (find(prev_names, pname) != null) parse_error(tok, "duplicate parameter name '" + pname + "'")
|
if (find(prev_names, pname) != null) parse_error(tok, "duplicate parameter name '" + pname + "'")
|
||||||
push(prev_names, pname)
|
prev_names[] = pname
|
||||||
advance()
|
advance()
|
||||||
ast_node_end(param)
|
ast_node_end(param)
|
||||||
if (tok.kind == "=" || tok.kind == "|") {
|
if (tok.kind == "=" || tok.kind == "|") {
|
||||||
advance()
|
advance()
|
||||||
param.expression = parse_assign_expr()
|
param.expression = parse_assign_expr()
|
||||||
}
|
}
|
||||||
push(params, param)
|
params[] = param
|
||||||
} else {
|
} else {
|
||||||
parse_error(tok, "expected parameter name")
|
parse_error(tok, "expected parameter name")
|
||||||
break
|
break
|
||||||
@@ -959,7 +959,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
param.name = tok.value
|
param.name = tok.value
|
||||||
advance()
|
advance()
|
||||||
ast_node_end(param)
|
ast_node_end(param)
|
||||||
push(params, param)
|
params[] = param
|
||||||
} else if (tok.kind == "(") {
|
} else if (tok.kind == "(") {
|
||||||
advance()
|
advance()
|
||||||
prev_names = []
|
prev_names = []
|
||||||
@@ -969,14 +969,14 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
param.name = tok.value
|
param.name = tok.value
|
||||||
pname = tok.value
|
pname = tok.value
|
||||||
if (find(prev_names, pname) != null) parse_error(tok, "duplicate parameter name '" + pname + "'")
|
if (find(prev_names, pname) != null) parse_error(tok, "duplicate parameter name '" + pname + "'")
|
||||||
push(prev_names, pname)
|
prev_names[] = pname
|
||||||
advance()
|
advance()
|
||||||
ast_node_end(param)
|
ast_node_end(param)
|
||||||
if (tok.kind == "=" || tok.kind == "|") {
|
if (tok.kind == "=" || tok.kind == "|") {
|
||||||
advance()
|
advance()
|
||||||
param.expression = parse_assign_expr()
|
param.expression = parse_assign_expr()
|
||||||
}
|
}
|
||||||
push(params, param)
|
params[] = param
|
||||||
} else {
|
} else {
|
||||||
parse_error(tok, "expected parameter name")
|
parse_error(tok, "expected parameter name")
|
||||||
break
|
break
|
||||||
@@ -1010,7 +1010,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
expr = parse_assign_expr()
|
expr = parse_assign_expr()
|
||||||
ret.expression = expr
|
ret.expression = expr
|
||||||
ast_node_end(ret)
|
ast_node_end(ret)
|
||||||
push(stmts, ret)
|
stmts[] = ret
|
||||||
node.statements = stmts
|
node.statements = stmts
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,7 +1110,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
parse_error(start, "'var' declarations must be initialized; use 'var " + var_name + " = null' if no value is needed")
|
parse_error(start, "'var' declarations must be initialized; use 'var " + var_name + " = null' if no value is needed")
|
||||||
}
|
}
|
||||||
ast_node_end(node)
|
ast_node_end(node)
|
||||||
push(decls, node)
|
decls[] = node
|
||||||
decl_count = decl_count + 1
|
decl_count = decl_count + 1
|
||||||
if (tok.kind == ",") advance()
|
if (tok.kind == ",") advance()
|
||||||
else break
|
else break
|
||||||
@@ -1142,7 +1142,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
_control_depth = _control_depth + 1
|
_control_depth = _control_depth + 1
|
||||||
_expecting_body = true
|
_expecting_body = true
|
||||||
body = parse_statement()
|
body = parse_statement()
|
||||||
if (body != null) push(then_stmts, body)
|
if (body != null) then_stmts[] = body
|
||||||
else_ifs = []
|
else_ifs = []
|
||||||
node.list = else_ifs
|
node.list = else_ifs
|
||||||
if (tok.kind == "else") {
|
if (tok.kind == "else") {
|
||||||
@@ -1151,7 +1151,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
_control_depth = saved_cd
|
_control_depth = saved_cd
|
||||||
_control_type = saved_ct
|
_control_type = saved_ct
|
||||||
elif = parse_statement()
|
elif = parse_statement()
|
||||||
if (elif != null) push(else_ifs, elif)
|
if (elif != null) else_ifs[] = elif
|
||||||
ast_node_end(node)
|
ast_node_end(node)
|
||||||
return node
|
return node
|
||||||
} else {
|
} else {
|
||||||
@@ -1159,7 +1159,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
node.else = else_stmts
|
node.else = else_stmts
|
||||||
_expecting_body = true
|
_expecting_body = true
|
||||||
body = parse_statement()
|
body = parse_statement()
|
||||||
if (body != null) push(else_stmts, body)
|
if (body != null) else_stmts[] = body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_control_depth = saved_cd
|
_control_depth = saved_cd
|
||||||
@@ -1185,7 +1185,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
_control_depth = _control_depth + 1
|
_control_depth = _control_depth + 1
|
||||||
_expecting_body = true
|
_expecting_body = true
|
||||||
body = parse_statement()
|
body = parse_statement()
|
||||||
if (body != null) push(stmts, body)
|
if (body != null) stmts[] = body
|
||||||
_control_depth = saved_cd
|
_control_depth = saved_cd
|
||||||
_control_type = saved_ct
|
_control_type = saved_ct
|
||||||
ast_node_end(node)
|
ast_node_end(node)
|
||||||
@@ -1203,7 +1203,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
_control_depth = _control_depth + 1
|
_control_depth = _control_depth + 1
|
||||||
_expecting_body = true
|
_expecting_body = true
|
||||||
body = parse_statement()
|
body = parse_statement()
|
||||||
if (body != null) push(stmts, body)
|
if (body != null) stmts[] = body
|
||||||
_control_depth = saved_cd
|
_control_depth = saved_cd
|
||||||
_control_type = saved_ct
|
_control_type = saved_ct
|
||||||
if (tok.kind == "while") advance()
|
if (tok.kind == "while") advance()
|
||||||
@@ -1256,7 +1256,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
_control_depth = _control_depth + 1
|
_control_depth = _control_depth + 1
|
||||||
_expecting_body = true
|
_expecting_body = true
|
||||||
body = parse_statement()
|
body = parse_statement()
|
||||||
if (body != null) push(stmts, body)
|
if (body != null) stmts[] = body
|
||||||
_control_depth = saved_cd
|
_control_depth = saved_cd
|
||||||
_control_type = saved_ct
|
_control_type = saved_ct
|
||||||
ast_node_end(node)
|
ast_node_end(node)
|
||||||
@@ -1402,9 +1402,9 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
stmt = parse_statement()
|
stmt = parse_statement()
|
||||||
if (stmt != null) {
|
if (stmt != null) {
|
||||||
if (stmt.kind == "function") {
|
if (stmt.kind == "function") {
|
||||||
push(functions, stmt)
|
functions[] = stmt
|
||||||
} else {
|
} else {
|
||||||
push(statements, stmt)
|
statements[] = stmt
|
||||||
}
|
}
|
||||||
} else if (cursor == before) {
|
} else if (cursor == before) {
|
||||||
sync_to_statement()
|
sync_to_statement()
|
||||||
@@ -1426,7 +1426,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
var err = {message: msg}
|
var err = {message: msg}
|
||||||
if (node.from_row != null) err.line = node.from_row + 1
|
if (node.from_row != null) err.line = node.from_row + 1
|
||||||
if (node.from_column != null) err.column = node.from_column + 1
|
if (node.from_column != null) err.column = node.from_column + 1
|
||||||
push(sem_errors, err)
|
sem_errors[] = err
|
||||||
}
|
}
|
||||||
|
|
||||||
var make_scope = function(parent, fn_nr, opts) {
|
var make_scope = function(parent, fn_nr, opts) {
|
||||||
@@ -1452,7 +1452,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
}
|
}
|
||||||
if (make_opts.reached == false) entry.reached = false
|
if (make_opts.reached == false) entry.reached = false
|
||||||
if (make_opts.decl_line != null) entry.decl_line = make_opts.decl_line
|
if (make_opts.decl_line != null) entry.decl_line = make_opts.decl_line
|
||||||
push(scope.vars, entry)
|
scope.vars[] = entry
|
||||||
}
|
}
|
||||||
|
|
||||||
var sem_lookup_var = function(scope, name) {
|
var sem_lookup_var = function(scope, name) {
|
||||||
@@ -1503,7 +1503,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var sem_add_intrinsic = function(name) {
|
var sem_add_intrinsic = function(name) {
|
||||||
if (find(intrinsics, name) == null) push(intrinsics, name)
|
if (find(intrinsics, name) == null) intrinsics[] = name
|
||||||
}
|
}
|
||||||
|
|
||||||
var functino_names = {
|
var functino_names = {
|
||||||
@@ -1828,7 +1828,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sr = sem_build_scope_record(fn_scope)
|
sr = sem_build_scope_record(fn_scope)
|
||||||
push(scopes_array, sr.rec)
|
scopes_array[] = sr.rec
|
||||||
expr.nr_slots = sr.nr_slots
|
expr.nr_slots = sr.nr_slots
|
||||||
expr.nr_close_slots = sr.nr_close
|
expr.nr_close_slots = sr.nr_close
|
||||||
return null
|
return null
|
||||||
@@ -1858,9 +1858,9 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
r.v.nr_uses = r.v.nr_uses + 1
|
r.v.nr_uses = r.v.nr_uses + 1
|
||||||
if (r.level > 0) r.v.closure = 1
|
if (r.level > 0) r.v.closure = 1
|
||||||
if (r.v.reached == false && r.v.decl_line != null && expr.from_row != null && expr.from_row + 1 < r.v.decl_line) {
|
if (r.v.reached == false && r.v.decl_line != null && expr.from_row != null && expr.from_row + 1 < r.v.decl_line) {
|
||||||
push(hoisted_fn_refs, {name: name, line: expr.from_row + 1,
|
hoisted_fn_refs[] = {name: name, line: expr.from_row + 1,
|
||||||
col: expr.from_column != null ? expr.from_column + 1 : null,
|
col: expr.from_column != null ? expr.from_column + 1 : null,
|
||||||
decl_line: r.v.decl_line})
|
decl_line: r.v.decl_line}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
expr.level = -1
|
expr.level = -1
|
||||||
@@ -2110,7 +2110,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sr = sem_build_scope_record(fn_scope)
|
sr = sem_build_scope_record(fn_scope)
|
||||||
push(scopes_array, sr.rec)
|
scopes_array[] = sr.rec
|
||||||
stmt.nr_slots = sr.nr_slots
|
stmt.nr_slots = sr.nr_slots
|
||||||
stmt.nr_close_slots = sr.nr_close
|
stmt.nr_close_slots = sr.nr_close
|
||||||
return null
|
return null
|
||||||
@@ -2153,7 +2153,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
new_scopes = [sr.rec]
|
new_scopes = [sr.rec]
|
||||||
i = 0
|
i = 0
|
||||||
while (i < length(scopes_array)) {
|
while (i < length(scopes_array)) {
|
||||||
push(new_scopes, scopes_array[i])
|
new_scopes[] = scopes_array[i]
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
scopes_array = new_scopes
|
scopes_array = new_scopes
|
||||||
@@ -2183,7 +2183,7 @@ var parse = function(tokens, src, filename, tokenizer) {
|
|||||||
if (ast.errors != null) {
|
if (ast.errors != null) {
|
||||||
_mi = 0
|
_mi = 0
|
||||||
while (_mi < length(errors)) {
|
while (_mi < length(errors)) {
|
||||||
push(ast.errors, errors[_mi])
|
ast.errors[] = errors[_mi]
|
||||||
_mi = _mi + 1
|
_mi = _mi + 1
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
14
qbe_emit.cm
14
qbe_emit.cm
@@ -948,7 +948,7 @@ var qbe_emit = function(ir, qbe, export_name) {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
var emit = function(s) {
|
var emit = function(s) {
|
||||||
push(out, s)
|
out[] = s
|
||||||
}
|
}
|
||||||
|
|
||||||
var fresh = function() {
|
var fresh = function() {
|
||||||
@@ -982,9 +982,9 @@ var qbe_emit = function(ir, qbe, export_name) {
|
|||||||
escaped = replace(escaped, "\r", "\\r")
|
escaped = replace(escaped, "\r", "\\r")
|
||||||
escaped = replace(escaped, "\t", "\\t")
|
escaped = replace(escaped, "\t", "\\t")
|
||||||
var line = "data " + label + ' = ' + '{ b "' + escaped + '", b 0 }'
|
var line = "data " + label + ' = ' + '{ b "' + escaped + '", b 0 }'
|
||||||
push(data_out, line)
|
data_out[] = line
|
||||||
var entry = { label: label, idx: length(str_entries) }
|
var entry = { label: label, idx: length(str_entries) }
|
||||||
push(str_entries, entry)
|
str_entries[] = entry
|
||||||
str_table[val] = entry
|
str_table[val] = entry
|
||||||
return entry
|
return entry
|
||||||
}
|
}
|
||||||
@@ -2909,16 +2909,16 @@ var qbe_emit = function(ir, qbe, export_name) {
|
|||||||
|
|
||||||
// Export nr_slots for main function so the module loader can use right-sized frames
|
// Export nr_slots for main function so the module loader can use right-sized frames
|
||||||
var main_name = export_name ? sanitize(export_name) : "cell_main"
|
var main_name = export_name ? sanitize(export_name) : "cell_main"
|
||||||
push(data_out, "export data $" + main_name + "_nr_slots = { w " + text(ir.main.nr_slots) + " }")
|
data_out[] = "export data $" + main_name + "_nr_slots = { w " + text(ir.main.nr_slots) + " }"
|
||||||
push(data_out, "export data $cell_lit_count = { w " + text(length(str_entries)) + " }")
|
data_out[] = "export data $cell_lit_count = { w " + text(length(str_entries)) + " }"
|
||||||
if (length(str_entries) > 0) {
|
if (length(str_entries) > 0) {
|
||||||
lit_data = []
|
lit_data = []
|
||||||
si = 0
|
si = 0
|
||||||
while (si < length(str_entries)) {
|
while (si < length(str_entries)) {
|
||||||
push(lit_data, `l ${str_entries[si].label}`)
|
lit_data[] = `l ${str_entries[si].label}`
|
||||||
si = si + 1
|
si = si + 1
|
||||||
}
|
}
|
||||||
push(data_out, "export data $cell_lit_table = { " + text(lit_data, ", ") + " }")
|
data_out[] = "export data $cell_lit_table = { " + text(lit_data, ", ") + " }"
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ if (!is_array(args) || length(args) < 1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (; i < length(args) - 1; i++) {
|
for (; i < length(args) - 1; i++) {
|
||||||
push(sources, args[i])
|
sources[] = args[i]
|
||||||
}
|
}
|
||||||
archive = args[length(args) - 1]
|
archive = args[length(args) - 1]
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ var run = function() {
|
|||||||
arrfor(all_packages, function(p) {
|
arrfor(all_packages, function(p) {
|
||||||
if (p == 'core') return
|
if (p == 'core') return
|
||||||
if (!needed[p] && find(packages_to_remove, p) == null) {
|
if (!needed[p] && find(packages_to_remove, p) == null) {
|
||||||
push(packages_to_remove, p)
|
packages_to_remove[] = p
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
10
resolve.ce
10
resolve.ce
@@ -165,11 +165,11 @@ for (i = 0; i < length(sorted); i++) {
|
|||||||
|
|
||||||
// Format output
|
// Format output
|
||||||
status_parts = []
|
status_parts = []
|
||||||
if (is_linked) push(status_parts, "linked")
|
if (is_linked) status_parts[] = "linked"
|
||||||
if (is_local) push(status_parts, "local")
|
if (is_local) status_parts[] = "local"
|
||||||
if (!is_in_lock) push(status_parts, "not in lock")
|
if (!is_in_lock) status_parts[] = "not in lock"
|
||||||
if (!is_fetched) push(status_parts, "not fetched")
|
if (!is_fetched) status_parts[] = "not fetched"
|
||||||
if (has_c_files) push(status_parts, "has C modules")
|
if (has_c_files) status_parts[] = "has C modules"
|
||||||
|
|
||||||
commit_str = ""
|
commit_str = ""
|
||||||
if (lock_entry && lock_entry.commit) {
|
if (lock_entry && lock_entry.commit) {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ var packages = shop.list_packages()
|
|||||||
arrfor(packages, function(package_name) {
|
arrfor(packages, function(package_name) {
|
||||||
// Check if package name matches
|
// Check if package name matches
|
||||||
if (search(package_name, query) != null) {
|
if (search(package_name, query) != null) {
|
||||||
push(found_packages, package_name)
|
found_packages[] = package_name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search modules and actors within the package
|
// Search modules and actors within the package
|
||||||
@@ -29,14 +29,14 @@ arrfor(packages, function(package_name) {
|
|||||||
var modules = pkg.list_modules(package_name)
|
var modules = pkg.list_modules(package_name)
|
||||||
arrfor(modules, function(mod) {
|
arrfor(modules, function(mod) {
|
||||||
if (search(mod, query) != null) {
|
if (search(mod, query) != null) {
|
||||||
push(found_modules, package_name + ':' + mod)
|
found_modules[] = package_name + ':' + mod
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
var actors = pkg.list_programs(package_name)
|
var actors = pkg.list_programs(package_name)
|
||||||
arrfor(actors, function(actor) {
|
arrfor(actors, function(actor) {
|
||||||
if (search(actor, query) != null) {
|
if (search(actor, query) != null) {
|
||||||
push(found_actors, package_name + ':' + actor)
|
found_actors[] = package_name + ':' + actor
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} disruption {
|
} disruption {
|
||||||
|
|||||||
6
slots.ce
6
slots.ce
@@ -179,7 +179,7 @@ var run = function() {
|
|||||||
first_def[slot_num] = pc
|
first_def[slot_num] = pc
|
||||||
first_def_op[slot_num] = op
|
first_def_op[slot_num] = op
|
||||||
}
|
}
|
||||||
push(events, {kind: "DEF", slot: operand_val, pc: pc, instr: instr})
|
events[] = {kind: "DEF", slot: operand_val, pc: pc, instr: instr}
|
||||||
}
|
}
|
||||||
di = di + 1
|
di = di + 1
|
||||||
}
|
}
|
||||||
@@ -191,7 +191,7 @@ var run = function() {
|
|||||||
slot_num = text(operand_val)
|
slot_num = text(operand_val)
|
||||||
if (!uses[slot_num]) uses[slot_num] = 0
|
if (!uses[slot_num]) uses[slot_num] = 0
|
||||||
uses[slot_num] = uses[slot_num] + 1
|
uses[slot_num] = uses[slot_num] + 1
|
||||||
push(events, {kind: "USE", slot: operand_val, pc: pc, instr: instr})
|
events[] = {kind: "USE", slot: operand_val, pc: pc, instr: instr}
|
||||||
}
|
}
|
||||||
ui = ui + 1
|
ui = ui + 1
|
||||||
}
|
}
|
||||||
@@ -219,7 +219,7 @@ var run = function() {
|
|||||||
parts = []
|
parts = []
|
||||||
j = 1
|
j = 1
|
||||||
while (j < n - 2) {
|
while (j < n - 2) {
|
||||||
push(parts, fmt_val(evt.instr[j]))
|
parts[] = fmt_val(evt.instr[j])
|
||||||
j = j + 1
|
j = j + 1
|
||||||
}
|
}
|
||||||
operands = text(parts, ", ")
|
operands = text(parts, ", ")
|
||||||
|
|||||||
@@ -313,6 +313,26 @@ void actor_disrupt(JSContext *ctx)
|
|||||||
JSValue js_core_internal_os_use(JSContext *js);
|
JSValue js_core_internal_os_use(JSContext *js);
|
||||||
JSValue js_core_json_use(JSContext *js);
|
JSValue js_core_json_use(JSContext *js);
|
||||||
|
|
||||||
|
/* Engine-env log proxy: routes log("channel", [msg]) through JS_Log.
|
||||||
|
Before set_log is called, JS_Log falls back to stderr.
|
||||||
|
After set_log, JS_Log forwards to the engine's JS log function.
|
||||||
|
This exists so mcode-generated type-check error paths (which always
|
||||||
|
access 'log' as an intrinsic) work inside engine.cm itself. */
|
||||||
|
static JSValue js_engine_log(JSContext *js, JSValue self,
|
||||||
|
int argc, JSValue *argv) {
|
||||||
|
if (argc < 2) return JS_NULL;
|
||||||
|
const char *channel = JS_ToCString(js, argv[0]);
|
||||||
|
if (!channel) return JS_NULL;
|
||||||
|
JSValue msg_val = JS_GetPropertyNumber(js, argv[1], 0);
|
||||||
|
const char *msg = JS_ToCString(js, msg_val);
|
||||||
|
if (msg) {
|
||||||
|
JS_Log(js, channel, "%s", msg);
|
||||||
|
JS_FreeCString(js, msg);
|
||||||
|
}
|
||||||
|
JS_FreeCString(js, channel);
|
||||||
|
return JS_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void script_startup(JSContext *js)
|
void script_startup(JSContext *js)
|
||||||
{
|
{
|
||||||
if (!g_runtime) {
|
if (!g_runtime) {
|
||||||
@@ -414,6 +434,8 @@ void script_startup(JSContext *js)
|
|||||||
}
|
}
|
||||||
tmp = shop_path ? JS_NewString(js, shop_path) : JS_NULL;
|
tmp = shop_path ? JS_NewString(js, shop_path) : JS_NULL;
|
||||||
JS_SetPropertyStr(js, env_ref.val, "shop_path", tmp);
|
JS_SetPropertyStr(js, env_ref.val, "shop_path", tmp);
|
||||||
|
tmp = JS_NewCFunction(js, js_engine_log, "log", 2);
|
||||||
|
JS_SetPropertyStr(js, env_ref.val, "log", tmp);
|
||||||
|
|
||||||
// Stone the environment
|
// Stone the environment
|
||||||
JSValue hidden_env = JS_Stone(js, env_ref.val);
|
JSValue hidden_env = JS_Stone(js, env_ref.val);
|
||||||
@@ -761,6 +783,8 @@ int cell_init(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
JS_SetPropertyStr(ctx, env_ref.val, "args", args_ref.val);
|
JS_SetPropertyStr(ctx, env_ref.val, "args", args_ref.val);
|
||||||
JS_DeleteGCRef(ctx, &args_ref);
|
JS_DeleteGCRef(ctx, &args_ref);
|
||||||
|
tmp = JS_NewCFunction(ctx, js_engine_log, "log", 2);
|
||||||
|
JS_SetPropertyStr(ctx, env_ref.val, "log", tmp);
|
||||||
JSValue hidden_env = JS_Stone(ctx, env_ref.val);
|
JSValue hidden_env = JS_Stone(ctx, env_ref.val);
|
||||||
|
|
||||||
g_crash_ctx = ctx;
|
g_crash_ctx = ctx;
|
||||||
|
|||||||
@@ -876,7 +876,7 @@ typedef struct {
|
|||||||
#define ACTOR_SLOW 5
|
#define ACTOR_SLOW 5
|
||||||
#define ACTOR_REFRESHED 6
|
#define ACTOR_REFRESHED 6
|
||||||
|
|
||||||
#define ACTOR_FAST_TIMER_NS (10ULL * 1000000)
|
#define ACTOR_FAST_TIMER_NS (1000ULL * 1000000)
|
||||||
#define ACTOR_SLOW_TIMER_NS (60000ULL * 1000000)
|
#define ACTOR_SLOW_TIMER_NS (60000ULL * 1000000)
|
||||||
#define ACTOR_SLOW_STRIKES_MAX 3
|
#define ACTOR_SLOW_STRIKES_MAX 3
|
||||||
#define ACTOR_MEMORY_LIMIT (1024ULL * 1024 * 1024)
|
#define ACTOR_MEMORY_LIMIT (1024ULL * 1024 * 1024)
|
||||||
|
|||||||
@@ -1915,12 +1915,13 @@ int ctx_gc (JSContext *ctx, int allow_grow, size_t alloc_size) {
|
|||||||
if (ctx->trace_hook && (ctx->trace_type & JS_HOOK_GC))
|
if (ctx->trace_hook && (ctx->trace_type & JS_HOOK_GC))
|
||||||
ctx->trace_hook(ctx, JS_HOOK_GC, NULL, ctx->trace_data);
|
ctx->trace_hook(ctx, JS_HOOK_GC, NULL, ctx->trace_data);
|
||||||
|
|
||||||
/* Check memory limit — kill actor if heap exceeds cap */
|
/* Check memory limit — kill actor if heap exceeds cap.
|
||||||
|
Use JS_Log "memory" channel which always fprintf's (safe during GC). */
|
||||||
if (ctx->heap_memory_limit > 0 && ctx->current_block_size > ctx->heap_memory_limit) {
|
if (ctx->heap_memory_limit > 0 && ctx->current_block_size > ctx->heap_memory_limit) {
|
||||||
#ifdef ACTOR_TRACE
|
JS_Log(ctx, "memory", "%s: heap %zuKB exceeds limit %zuMB, killing",
|
||||||
fprintf(stderr, "[ACTOR_TRACE] heap %zu > limit %zu, OOM\n",
|
ctx->name ? ctx->name : ctx->id,
|
||||||
ctx->current_block_size, ctx->heap_memory_limit);
|
ctx->current_block_size / 1024,
|
||||||
#endif
|
ctx->heap_memory_limit / (1024 * 1024));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3283,19 +3284,18 @@ JS_RaiseDisrupt (JSContext *ctx, const char *fmt, ...) {
|
|||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Log to "memory" channel + disrupt. Skips JS callback (can't allocate). */
|
/* Log to "memory" channel + disrupt. Skips JS callback (can't allocate).
|
||||||
|
Uses fprintf directly — safe even during OOM. */
|
||||||
JSValue JS_RaiseOOM (JSContext *ctx) {
|
JSValue JS_RaiseOOM (JSContext *ctx) {
|
||||||
size_t used = (size_t)((uint8_t *)ctx->heap_free - (uint8_t *)ctx->heap_base);
|
size_t used = (size_t)((uint8_t *)ctx->heap_free - (uint8_t *)ctx->heap_base);
|
||||||
size_t block = ctx->current_block_size;
|
size_t block = ctx->current_block_size;
|
||||||
size_t limit = ctx->heap_memory_limit;
|
size_t limit = ctx->heap_memory_limit;
|
||||||
|
const char *name = ctx->name ? ctx->name : ctx->id;
|
||||||
const char *label = ctx->actor_label;
|
const char *label = ctx->actor_label;
|
||||||
if (limit > 0) {
|
fprintf(stderr, "[memory] %s: out of memory — heap %zuKB / %zuKB block",
|
||||||
fprintf(stderr, "out of memory: heap %zuKB / %zuKB block, limit %zuMB",
|
name ? name : "?", used / 1024, block / 1024);
|
||||||
used / 1024, block / 1024, limit / (1024 * 1024));
|
if (limit > 0)
|
||||||
} else {
|
fprintf(stderr, ", limit %zuMB", limit / (1024 * 1024));
|
||||||
fprintf(stderr, "out of memory: heap %zuKB / %zuKB block, no limit",
|
|
||||||
used / 1024, block / 1024);
|
|
||||||
}
|
|
||||||
if (label)
|
if (label)
|
||||||
fprintf(stderr, " [%s]", label);
|
fprintf(stderr, " [%s]", label);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
@@ -12009,7 +12009,7 @@ void JS_CrashPrintStack(JSContext *ctx) {
|
|||||||
if (!ctx) return;
|
if (!ctx) return;
|
||||||
if (JS_IsNull(ctx->reg_current_frame)) return;
|
if (JS_IsNull(ctx->reg_current_frame)) return;
|
||||||
|
|
||||||
static const char hdr[] = "\n--- JS Stack at crash ---\n";
|
static const char hdr[] = "\n--- JS Stack ---\n";
|
||||||
write(STDERR_FILENO, hdr, sizeof(hdr) - 1);
|
write(STDERR_FILENO, hdr, sizeof(hdr) - 1);
|
||||||
|
|
||||||
JSFrameRegister *frame = (JSFrameRegister *)JS_VALUE_GET_PTR(ctx->reg_current_frame);
|
JSFrameRegister *frame = (JSFrameRegister *)JS_VALUE_GET_PTR(ctx->reg_current_frame);
|
||||||
|
|||||||
@@ -293,9 +293,15 @@ void *timer_thread_func(void *arg) {
|
|||||||
/* Only fire if turn_gen still matches (stale timers are ignored) */
|
/* Only fire if turn_gen still matches (stale timers are ignored) */
|
||||||
uint32_t cur = atomic_load_explicit(&t.actor->turn_gen, memory_order_relaxed);
|
uint32_t cur = atomic_load_explicit(&t.actor->turn_gen, memory_order_relaxed);
|
||||||
if (cur == t.turn_gen) {
|
if (cur == t.turn_gen) {
|
||||||
|
/* Can't call JS_Log from timer thread — use fprintf */
|
||||||
|
const char *name = t.actor->name ? t.actor->name : t.actor->id;
|
||||||
if (t.type == TIMER_PAUSE) {
|
if (t.type == TIMER_PAUSE) {
|
||||||
|
fprintf(stderr, "[slow] %s: pausing (turn exceeded %llums)\n",
|
||||||
|
name, (unsigned long long)(ACTOR_FAST_TIMER_NS / 1000000));
|
||||||
JS_SetPauseFlag(t.actor, 1);
|
JS_SetPauseFlag(t.actor, 1);
|
||||||
} else {
|
} else {
|
||||||
|
fprintf(stderr, "[slow] %s: kill timer fired (turn exceeded %llus)\n",
|
||||||
|
name, (unsigned long long)(ACTOR_SLOW_TIMER_NS / 1000000000));
|
||||||
t.actor->disrupt = 1;
|
t.actor->disrupt = 1;
|
||||||
JS_SetPauseFlag(t.actor, 2);
|
JS_SetPauseFlag(t.actor, 2);
|
||||||
}
|
}
|
||||||
@@ -577,17 +583,11 @@ int actor_exists(const char *id)
|
|||||||
void set_actor_state(JSContext *actor)
|
void set_actor_state(JSContext *actor)
|
||||||
{
|
{
|
||||||
if (actor->disrupt) {
|
if (actor->disrupt) {
|
||||||
#ifdef SCHEDULER_DEBUG
|
|
||||||
fprintf(stderr, "set_actor_state: %s disrupted, freeing\n", actor->name ? actor->name : actor->id);
|
|
||||||
#endif
|
|
||||||
actor_free(actor);
|
actor_free(actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(actor->msg_mutex);
|
pthread_mutex_lock(actor->msg_mutex);
|
||||||
|
|
||||||
#ifdef SCHEDULER_DEBUG
|
|
||||||
fprintf(stderr, "set_actor_state: %s state=%d letters=%ld\n", actor->name ? actor->name : actor->id, actor->state, (long)arrlen(actor->letters));
|
|
||||||
#endif
|
|
||||||
switch(actor->state) {
|
switch(actor->state) {
|
||||||
case ACTOR_RUNNING:
|
case ACTOR_RUNNING:
|
||||||
case ACTOR_READY:
|
case ACTOR_READY:
|
||||||
@@ -601,9 +601,6 @@ void set_actor_state(JSContext *actor)
|
|||||||
actor->is_quiescent = 0;
|
actor->is_quiescent = 0;
|
||||||
atomic_fetch_sub(&engine.quiescent_count, 1);
|
atomic_fetch_sub(&engine.quiescent_count, 1);
|
||||||
}
|
}
|
||||||
#ifdef SCHEDULER_DEBUG
|
|
||||||
fprintf(stderr, "set_actor_state: %s IDLE->READY, enqueueing (main=%d)\n", actor->name ? actor->name : actor->id, actor->main_thread_only);
|
|
||||||
#endif
|
|
||||||
actor->state = ACTOR_READY;
|
actor->state = ACTOR_READY;
|
||||||
actor->ar = 0;
|
actor->ar = 0;
|
||||||
enqueue_actor_priority(actor);
|
enqueue_actor_priority(actor);
|
||||||
@@ -846,6 +843,8 @@ void actor_turn(JSContext *actor)
|
|||||||
|
|
||||||
if (JS_IsSuspended(result)) {
|
if (JS_IsSuspended(result)) {
|
||||||
/* Still suspended after kill timer — shouldn't happen, kill it */
|
/* Still suspended after kill timer — shouldn't happen, kill it */
|
||||||
|
fprintf(stderr, "[slow] %s: still suspended after resume, killing\n",
|
||||||
|
actor->name ? actor->name : actor->id);
|
||||||
actor->disrupt = 1;
|
actor->disrupt = 1;
|
||||||
goto ENDTURN;
|
goto ENDTURN;
|
||||||
}
|
}
|
||||||
@@ -854,16 +853,12 @@ void actor_turn(JSContext *actor)
|
|||||||
actor->disrupt = 1;
|
actor->disrupt = 1;
|
||||||
}
|
}
|
||||||
actor->slow_strikes++;
|
actor->slow_strikes++;
|
||||||
#ifdef ACTOR_TRACE
|
JS_Log(actor, "slow", "%s: slow strike %d/%d",
|
||||||
fprintf(stderr, "[ACTOR_TRACE] %s: slow strike %d/%d\n",
|
actor->name ? actor->name : actor->id,
|
||||||
actor->name ? actor->name : actor->id,
|
actor->slow_strikes, ACTOR_SLOW_STRIKES_MAX);
|
||||||
actor->slow_strikes, ACTOR_SLOW_STRIKES_MAX);
|
|
||||||
#endif
|
|
||||||
if (actor->slow_strikes >= ACTOR_SLOW_STRIKES_MAX) {
|
if (actor->slow_strikes >= ACTOR_SLOW_STRIKES_MAX) {
|
||||||
#ifdef ACTOR_TRACE
|
JS_Log(actor, "slow", "%s: killed after %d consecutive slow turns",
|
||||||
fprintf(stderr, "[ACTOR_TRACE] %s: %d slow strikes, killing\n",
|
actor->name ? actor->name : actor->id, actor->slow_strikes);
|
||||||
actor->name ? actor->name : actor->id, actor->slow_strikes);
|
|
||||||
#endif
|
|
||||||
actor->disrupt = 1;
|
actor->disrupt = 1;
|
||||||
}
|
}
|
||||||
goto ENDTURN;
|
goto ENDTURN;
|
||||||
@@ -876,10 +871,6 @@ void actor_turn(JSContext *actor)
|
|||||||
pthread_mutex_unlock(actor->msg_mutex);
|
pthread_mutex_unlock(actor->msg_mutex);
|
||||||
goto ENDTURN;
|
goto ENDTURN;
|
||||||
}
|
}
|
||||||
#ifdef SCHEDULER_DEBUG
|
|
||||||
fprintf(stderr, "actor_turn: %s has %d letters, type=%d\n",
|
|
||||||
actor->name ? actor->name : actor->id, pending, actor->letters[0].type);
|
|
||||||
#endif
|
|
||||||
letter l = actor->letters[0];
|
letter l = actor->letters[0];
|
||||||
arrdel(actor->letters, 0);
|
arrdel(actor->letters, 0);
|
||||||
pthread_mutex_unlock(actor->msg_mutex);
|
pthread_mutex_unlock(actor->msg_mutex);
|
||||||
@@ -937,29 +928,22 @@ ENDTURN:
|
|||||||
actor->actor_trace_hook(actor, CELL_HOOK_EXIT);
|
actor->actor_trace_hook(actor, CELL_HOOK_EXIT);
|
||||||
|
|
||||||
if (actor->disrupt) {
|
if (actor->disrupt) {
|
||||||
#ifdef SCHEDULER_DEBUG
|
|
||||||
fprintf(stderr, "actor_turn ENDTURN: %s disrupted, freeing\n",
|
|
||||||
actor->name ? actor->name : actor->id);
|
|
||||||
#endif
|
|
||||||
pthread_mutex_unlock(actor->mutex);
|
pthread_mutex_unlock(actor->mutex);
|
||||||
actor_free(actor);
|
actor_free(actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SCHEDULER_DEBUG
|
|
||||||
fprintf(stderr, "actor_turn ENDTURN: %s has %ld letters, calling set_actor_state\n",
|
|
||||||
actor->name ? actor->name : actor->id, (long)arrlen(actor->letters));
|
|
||||||
#endif
|
|
||||||
set_actor_state(actor);
|
set_actor_state(actor);
|
||||||
pthread_mutex_unlock(actor->mutex);
|
pthread_mutex_unlock(actor->mutex);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ENDTURN_SLOW:
|
ENDTURN_SLOW:
|
||||||
g_crash_ctx = NULL;
|
g_crash_ctx = NULL;
|
||||||
#ifdef ACTOR_TRACE
|
/* VM suspended mid-turn — can't call JS_Log, use fprintf.
|
||||||
fprintf(stderr, "[ACTOR_TRACE] %s: suspended mid-turn -> SLOW\n",
|
Print stack trace while frames are still intact. */
|
||||||
actor->name ? actor->name : actor->id);
|
fprintf(stderr, "[slow] %s: suspended mid-turn, entering slow queue (strike %d/%d)\n",
|
||||||
#endif
|
actor->name ? actor->name : actor->id,
|
||||||
|
actor->slow_strikes + 1, ACTOR_SLOW_STRIKES_MAX);
|
||||||
if (actor->actor_trace_hook)
|
if (actor->actor_trace_hook)
|
||||||
actor->actor_trace_hook(actor, CELL_HOOK_EXIT);
|
actor->actor_trace_hook(actor, CELL_HOOK_EXIT);
|
||||||
enqueue_actor_priority(actor);
|
enqueue_actor_priority(actor);
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ var type_annotation = function(slot_types, instr) {
|
|||||||
if (is_number(v)) {
|
if (is_number(v)) {
|
||||||
t = slot_types[text(v)]
|
t = slot_types[text(v)]
|
||||||
if (t != null && t != T_UNKNOWN) {
|
if (t != null && t != T_UNKNOWN) {
|
||||||
push(parts, `s${text(v)}:${t}`)
|
parts[] = `s${text(v)}:${t}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
j = j + 1
|
j = j + 1
|
||||||
@@ -290,7 +290,7 @@ var dump_function_typed = function(func, name) {
|
|||||||
operand_parts = []
|
operand_parts = []
|
||||||
j = 1
|
j = 1
|
||||||
while (j < n - 2) {
|
while (j < n - 2) {
|
||||||
push(operand_parts, fmt_val(instr[j]))
|
operand_parts[] = fmt_val(instr[j])
|
||||||
j = j + 1
|
j = j + 1
|
||||||
}
|
}
|
||||||
operands = text(operand_parts, ", ")
|
operands = text(operand_parts, ", ")
|
||||||
|
|||||||
40
test.ce
40
test.ce
@@ -62,7 +62,7 @@ function parse_args() {
|
|||||||
} else if (_args[i] == '--diff') {
|
} else if (_args[i] == '--diff') {
|
||||||
diff_mode = true
|
diff_mode = true
|
||||||
} else {
|
} else {
|
||||||
push(cleaned_args, _args[i])
|
cleaned_args[] = _args[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_args = cleaned_args
|
_args = cleaned_args
|
||||||
@@ -247,11 +247,11 @@ function collect_actor_tests(package_name, specific_test) {
|
|||||||
if (test_base != match_base) continue
|
if (test_base != match_base) continue
|
||||||
}
|
}
|
||||||
|
|
||||||
push(actor_tests, {
|
actor_tests[] = {
|
||||||
package: package_name || "local",
|
package: package_name || "local",
|
||||||
file: f,
|
file: f,
|
||||||
path: prefix + '/' + f
|
path: prefix + '/' + f
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return actor_tests
|
return actor_tests
|
||||||
@@ -296,16 +296,16 @@ function spawn_actor_test(test_info) {
|
|||||||
entry.error = { message: event.reason || "Actor disrupted" }
|
entry.error = { message: event.reason || "Actor disrupted" }
|
||||||
log.console(` FAIL ${test_name}: ${entry.error.message}`)
|
log.console(` FAIL ${test_name}: ${entry.error.message}`)
|
||||||
}
|
}
|
||||||
push(actor_test_results, entry)
|
actor_test_results[] = entry
|
||||||
if (gc_after_each_test) dbg.gc()
|
if (gc_after_each_test) dbg.gc()
|
||||||
check_completion()
|
check_completion()
|
||||||
}, actor_path)
|
}, actor_path)
|
||||||
push(pending_actor_tests, entry)
|
pending_actor_tests[] = entry
|
||||||
} disruption {
|
} disruption {
|
||||||
entry.status = "failed"
|
entry.status = "failed"
|
||||||
entry.error = { message: "Failed to spawn actor" }
|
entry.error = { message: "Failed to spawn actor" }
|
||||||
entry.duration_ns = 0
|
entry.duration_ns = 0
|
||||||
push(actor_test_results, entry)
|
actor_test_results[] = entry
|
||||||
log.console(` FAIL ${test_name}: Failed to spawn`)
|
log.console(` FAIL ${test_name}: Failed to spawn`)
|
||||||
}
|
}
|
||||||
_spawn()
|
_spawn()
|
||||||
@@ -347,7 +347,7 @@ function run_tests(package_name, specific_test) {
|
|||||||
match_base = ends_with(match_name, '.cm') ? text(match_name, 0, -3) : match_name
|
match_base = ends_with(match_name, '.cm') ? text(match_name, 0, -3) : match_name
|
||||||
if (test_name != match_base) continue
|
if (test_name != match_base) continue
|
||||||
}
|
}
|
||||||
push(test_files, f)
|
test_files[] = f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,14 +408,14 @@ function run_tests(package_name, specific_test) {
|
|||||||
var first_null_key = null
|
var first_null_key = null
|
||||||
var first_other_key = null
|
var first_other_key = null
|
||||||
if (is_function(test_mod)) {
|
if (is_function(test_mod)) {
|
||||||
push(tests, {name: 'main', fn: test_mod})
|
tests[] = {name: 'main', fn: test_mod}
|
||||||
} else if (is_object(test_mod)) {
|
} else if (is_object(test_mod)) {
|
||||||
all_keys = array(test_mod)
|
all_keys = array(test_mod)
|
||||||
log.console(` Found ${length(all_keys)} test entries`)
|
log.console(` Found ${length(all_keys)} test entries`)
|
||||||
arrfor(all_keys, function(k) {
|
arrfor(all_keys, function(k) {
|
||||||
if (is_function(test_mod[k])) {
|
if (is_function(test_mod[k])) {
|
||||||
fn_count = fn_count + 1
|
fn_count = fn_count + 1
|
||||||
push(tests, {name: k, fn: test_mod[k]})
|
tests[] = {name: k, fn: test_mod[k]}
|
||||||
} else if (is_null(test_mod[k])) {
|
} else if (is_null(test_mod[k])) {
|
||||||
null_count = null_count + 1
|
null_count = null_count + 1
|
||||||
if (!first_null_key) first_null_key = k
|
if (!first_null_key) first_null_key = k
|
||||||
@@ -494,7 +494,7 @@ function run_tests(package_name, specific_test) {
|
|||||||
file_result.failed = file_result.failed + 1
|
file_result.failed = file_result.failed + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
push(file_result.tests, test_entry)
|
file_result.tests[] = test_entry
|
||||||
pkg_result.total = pkg_result.total + 1
|
pkg_result.total = pkg_result.total + 1
|
||||||
if (gc_after_each_test) {
|
if (gc_after_each_test) {
|
||||||
dbg.gc()
|
dbg.gc()
|
||||||
@@ -512,7 +512,7 @@ function run_tests(package_name, specific_test) {
|
|||||||
file_result.failed = file_result.failed + 1
|
file_result.failed = file_result.failed + 1
|
||||||
pkg_result.total = pkg_result.total + 1
|
pkg_result.total = pkg_result.total + 1
|
||||||
}
|
}
|
||||||
push(pkg_result.files, file_result)
|
pkg_result.files[] = file_result
|
||||||
}
|
}
|
||||||
return pkg_result
|
return pkg_result
|
||||||
}
|
}
|
||||||
@@ -525,18 +525,18 @@ var i = 0
|
|||||||
if (all_pkgs) {
|
if (all_pkgs) {
|
||||||
// Run local first if we're in a valid package
|
// Run local first if we're in a valid package
|
||||||
if (is_valid_package('.')) {
|
if (is_valid_package('.')) {
|
||||||
push(all_results, run_tests(null, null))
|
all_results[] = run_tests(null, null)
|
||||||
all_actor_tests = array(all_actor_tests, collect_actor_tests(null, null))
|
all_actor_tests = array(all_actor_tests, collect_actor_tests(null, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then all packages in lock
|
// Then all packages in lock
|
||||||
packages = shop.list_packages()
|
packages = shop.list_packages()
|
||||||
for (i = 0; i < length(packages); i++) {
|
for (i = 0; i < length(packages); i++) {
|
||||||
push(all_results, run_tests(packages[i], null))
|
all_results[] = run_tests(packages[i], null)
|
||||||
all_actor_tests = array(all_actor_tests, collect_actor_tests(packages[i], null))
|
all_actor_tests = array(all_actor_tests, collect_actor_tests(packages[i], null))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
push(all_results, run_tests(target_pkg, target_test))
|
all_results[] = run_tests(target_pkg, target_test)
|
||||||
all_actor_tests = array(all_actor_tests, collect_actor_tests(target_pkg, target_test))
|
all_actor_tests = array(all_actor_tests, collect_actor_tests(target_pkg, target_test))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,7 +561,7 @@ function check_timeouts() {
|
|||||||
entry = pending_actor_tests[i]
|
entry = pending_actor_tests[i]
|
||||||
elapsed_ms = (now - entry.start_time) * 1000
|
elapsed_ms = (now - entry.start_time) * 1000
|
||||||
if (elapsed_ms > ACTOR_TEST_TIMEOUT) {
|
if (elapsed_ms > ACTOR_TEST_TIMEOUT) {
|
||||||
push(timed_out, i)
|
timed_out[] = i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,7 +573,7 @@ function check_timeouts() {
|
|||||||
entry.status = "failed"
|
entry.status = "failed"
|
||||||
entry.error = { message: "Test timed out" }
|
entry.error = { message: "Test timed out" }
|
||||||
entry.duration_ns = ACTOR_TEST_TIMEOUT * 1000000
|
entry.duration_ns = ACTOR_TEST_TIMEOUT * 1000000
|
||||||
push(actor_test_results, entry)
|
actor_test_results[] = entry
|
||||||
log.console(` TIMEOUT ${entry.test}`)
|
log.console(` TIMEOUT ${entry.test}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,7 +612,7 @@ function finalize_results() {
|
|||||||
}
|
}
|
||||||
if (!pkg_result) {
|
if (!pkg_result) {
|
||||||
pkg_result = { package: r.package, files: [], total: 0, passed: 0, failed: 0 }
|
pkg_result = { package: r.package, files: [], total: 0, passed: 0, failed: 0 }
|
||||||
push(all_results, pkg_result)
|
all_results[] = pkg_result
|
||||||
}
|
}
|
||||||
|
|
||||||
file_result = null
|
file_result = null
|
||||||
@@ -624,10 +624,10 @@ function finalize_results() {
|
|||||||
}
|
}
|
||||||
if (!file_result) {
|
if (!file_result) {
|
||||||
file_result = { name: r.file, tests: [], passed: 0, failed: 0 }
|
file_result = { name: r.file, tests: [], passed: 0, failed: 0 }
|
||||||
push(pkg_result.files, file_result)
|
pkg_result.files[] = file_result
|
||||||
}
|
}
|
||||||
|
|
||||||
push(file_result.tests, r)
|
file_result.tests[] = r
|
||||||
pkg_result.total = pkg_result.total + 1
|
pkg_result.total = pkg_result.total + 1
|
||||||
if (r.status == "passed") {
|
if (r.status == "passed") {
|
||||||
pkg_result.passed = pkg_result.passed + 1
|
pkg_result.passed = pkg_result.passed + 1
|
||||||
@@ -760,7 +760,7 @@ Total: ${totals.total}, Passed: ${totals.passed}, Failed: ${totals.failed}
|
|||||||
for (j = 0; j < length(pkg_res.files); j++) {
|
for (j = 0; j < length(pkg_res.files); j++) {
|
||||||
f = pkg_res.files[j]
|
f = pkg_res.files[j]
|
||||||
for (k = 0; k < length(f.tests); k++) {
|
for (k = 0; k < length(f.tests); k++) {
|
||||||
push(pkg_tests, f.tests[k])
|
pkg_tests[] = f.tests[k]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ var testarr = []
|
|||||||
var i = 0
|
var i = 0
|
||||||
var t = null
|
var t = null
|
||||||
for (i = 0; i < 500; i++) {
|
for (i = 0; i < 500; i++) {
|
||||||
push(testarr, 1)
|
testarr[] = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var testCases = [
|
var testCases = [
|
||||||
|
|||||||
@@ -2918,7 +2918,7 @@ return {
|
|||||||
test_arrfor_with_index: function() {
|
test_arrfor_with_index: function() {
|
||||||
var arr = ["a", "b", "c"]
|
var arr = ["a", "b", "c"]
|
||||||
var indices = []
|
var indices = []
|
||||||
arrfor(arr, (x, i) => { push(indices, i) })
|
arrfor(arr, (x, i) => { indices[] = i })
|
||||||
if (indices[0] != 0 || indices[2] != 2) return "arrfor with index failed"
|
if (indices[0] != 0 || indices[2] != 2) return "arrfor with index failed"
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -2931,7 +2931,7 @@ return {
|
|||||||
test_arrfor_mutation: function() {
|
test_arrfor_mutation: function() {
|
||||||
var arr = [1, 2, 3]
|
var arr = [1, 2, 3]
|
||||||
var results = []
|
var results = []
|
||||||
arrfor(arr, x => { push(results, x * 2) })
|
arrfor(arr, x => { results[] = x * 2 })
|
||||||
if (results[0] != 2 || results[1] != 4 || results[2] != 6) return "arrfor mutation failed"
|
if (results[0] != 2 || results[1] != 4 || results[2] != 6) return "arrfor mutation failed"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ var testarr = []
|
|||||||
var i = 0
|
var i = 0
|
||||||
var t = null
|
var t = null
|
||||||
var name = null
|
var name = null
|
||||||
for (i = 0; i < 500; i++) { push(testarr, 1) }
|
for (i = 0; i < 500; i++) { testarr[] = 1 }
|
||||||
|
|
||||||
var testCases = [
|
var testCases = [
|
||||||
{ name: 'zero', input: 0 },
|
{ name: 'zero', input: 0 },
|
||||||
|
|||||||
60
tokenize.cm
60
tokenize.cm
@@ -103,26 +103,26 @@ var tokenize = function(src, filename) {
|
|||||||
run_start = pos
|
run_start = pos
|
||||||
while (pos < len && pk() != quote) {
|
while (pos < len && pk() != quote) {
|
||||||
if (pk() == "\\") {
|
if (pk() == "\\") {
|
||||||
if (pos > run_start) push(parts, text(src, run_start, pos))
|
if (pos > run_start) parts[] = text(src, run_start, pos)
|
||||||
adv()
|
adv()
|
||||||
esc = adv()
|
esc = adv()
|
||||||
esc_val = escape_map[esc]
|
esc_val = escape_map[esc]
|
||||||
if (esc_val != null) { push(parts, esc_val) }
|
if (esc_val != null) { parts[] = esc_val }
|
||||||
else if (esc == "u") { push(parts, read_unicode_escape()) }
|
else if (esc == "u") { parts[] = read_unicode_escape() }
|
||||||
else { push(parts, esc) }
|
else { parts[] = esc }
|
||||||
run_start = pos
|
run_start = pos
|
||||||
} else {
|
} else {
|
||||||
adv()
|
adv()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos > run_start) push(parts, text(src, run_start, pos))
|
if (pos > run_start) parts[] = text(src, run_start, pos)
|
||||||
if (pos < len) adv() // skip closing quote
|
if (pos < len) adv() // skip closing quote
|
||||||
push(tokens, {
|
tokens[] = {
|
||||||
kind: "text", at: start,
|
kind: "text", at: start,
|
||||||
from_row: start_row, from_column: start_col,
|
from_row: start_row, from_column: start_col,
|
||||||
to_row: row, to_column: col,
|
to_row: row, to_column: col,
|
||||||
value: text(parts)
|
value: text(parts)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var read_template = function() {
|
var read_template = function() {
|
||||||
@@ -139,12 +139,12 @@ var tokenize = function(src, filename) {
|
|||||||
run_start = pos
|
run_start = pos
|
||||||
while (pos < len && pk() != "`") {
|
while (pos < len && pk() != "`") {
|
||||||
if (pk() == "\\" && pos + 1 < len) {
|
if (pk() == "\\" && pos + 1 < len) {
|
||||||
if (pos > run_start) push(parts, text(src, run_start, pos))
|
if (pos > run_start) parts[] = text(src, run_start, pos)
|
||||||
push(parts, text(src, pos, pos + 2))
|
parts[] = text(src, pos, pos + 2)
|
||||||
adv(); adv()
|
adv(); adv()
|
||||||
run_start = pos
|
run_start = pos
|
||||||
} else if (pk() == "$" && pos + 1 < len && pk_at(1) == "{") {
|
} else if (pk() == "$" && pos + 1 < len && pk_at(1) == "{") {
|
||||||
if (pos > run_start) push(parts, text(src, run_start, pos))
|
if (pos > run_start) parts[] = text(src, run_start, pos)
|
||||||
interp_start = pos
|
interp_start = pos
|
||||||
adv(); adv() // $ {
|
adv(); adv() // $ {
|
||||||
depth = 1
|
depth = 1
|
||||||
@@ -164,20 +164,20 @@ var tokenize = function(src, filename) {
|
|||||||
if (pos < len) adv()
|
if (pos < len) adv()
|
||||||
} else { adv() }
|
} else { adv() }
|
||||||
}
|
}
|
||||||
push(parts, text(src, interp_start, pos))
|
parts[] = text(src, interp_start, pos)
|
||||||
run_start = pos
|
run_start = pos
|
||||||
} else {
|
} else {
|
||||||
adv()
|
adv()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos > run_start) push(parts, text(src, run_start, pos))
|
if (pos > run_start) parts[] = text(src, run_start, pos)
|
||||||
if (pos < len) adv() // skip closing backtick
|
if (pos < len) adv() // skip closing backtick
|
||||||
push(tokens, {
|
tokens[] = {
|
||||||
kind: "text", at: start,
|
kind: "text", at: start,
|
||||||
from_row: start_row, from_column: start_col,
|
from_row: start_row, from_column: start_col,
|
||||||
to_row: row, to_column: col,
|
to_row: row, to_column: col,
|
||||||
value: text(parts)
|
value: text(parts)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var read_number = function() {
|
var read_number = function() {
|
||||||
@@ -207,12 +207,12 @@ var tokenize = function(src, filename) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
raw = substr(start, pos)
|
raw = substr(start, pos)
|
||||||
push(tokens, {
|
tokens[] = {
|
||||||
kind: "number", at: start,
|
kind: "number", at: start,
|
||||||
from_row: start_row, from_column: start_col,
|
from_row: start_row, from_column: start_col,
|
||||||
to_row: row, to_column: col,
|
to_row: row, to_column: col,
|
||||||
value: raw, number: number(raw)
|
value: raw, number: number(raw)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var read_name = function() {
|
var read_name = function() {
|
||||||
@@ -225,18 +225,18 @@ var tokenize = function(src, filename) {
|
|||||||
name = substr(start, pos)
|
name = substr(start, pos)
|
||||||
kw = keywords[name]
|
kw = keywords[name]
|
||||||
if (kw != null) {
|
if (kw != null) {
|
||||||
push(tokens, {
|
tokens[] = {
|
||||||
kind: kw, at: start,
|
kind: kw, at: start,
|
||||||
from_row: start_row, from_column: start_col,
|
from_row: start_row, from_column: start_col,
|
||||||
to_row: row, to_column: col
|
to_row: row, to_column: col
|
||||||
})
|
}
|
||||||
} else {
|
} else {
|
||||||
push(tokens, {
|
tokens[] = {
|
||||||
kind: "name", at: start,
|
kind: "name", at: start,
|
||||||
from_row: start_row, from_column: start_col,
|
from_row: start_row, from_column: start_col,
|
||||||
to_row: row, to_column: col,
|
to_row: row, to_column: col,
|
||||||
value: name
|
value: name
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,12 +258,12 @@ var tokenize = function(src, filename) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
raw = substr(start, pos)
|
raw = substr(start, pos)
|
||||||
push(tokens, {
|
tokens[] = {
|
||||||
kind: "comment", at: start,
|
kind: "comment", at: start,
|
||||||
from_row: start_row, from_column: start_col,
|
from_row: start_row, from_column: start_col,
|
||||||
to_row: row, to_column: col,
|
to_row: row, to_column: col,
|
||||||
value: raw
|
value: raw
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var emit_op = function(kind, count) {
|
var emit_op = function(kind, count) {
|
||||||
@@ -272,11 +272,11 @@ var tokenize = function(src, filename) {
|
|||||||
var start_col = col
|
var start_col = col
|
||||||
var i = 0
|
var i = 0
|
||||||
while (i < count) { adv(); i = i + 1 }
|
while (i < count) { adv(); i = i + 1 }
|
||||||
push(tokens, {
|
tokens[] = {
|
||||||
kind: kind, at: start,
|
kind: kind, at: start,
|
||||||
from_row: start_row, from_column: start_col,
|
from_row: start_row, from_column: start_col,
|
||||||
to_row: row, to_column: col
|
to_row: row, to_column: col
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var emit_ident = function(count) {
|
var emit_ident = function(count) {
|
||||||
@@ -285,12 +285,12 @@ var tokenize = function(src, filename) {
|
|||||||
var start_col = col
|
var start_col = col
|
||||||
var i = 0
|
var i = 0
|
||||||
while (i < count) { adv(); i = i + 1 }
|
while (i < count) { adv(); i = i + 1 }
|
||||||
push(tokens, {
|
tokens[] = {
|
||||||
kind: "name", at: start,
|
kind: "name", at: start,
|
||||||
from_row: start_row, from_column: start_col,
|
from_row: start_row, from_column: start_col,
|
||||||
to_row: row, to_column: col,
|
to_row: row, to_column: col,
|
||||||
value: text(src, start, pos)
|
value: text(src, start, pos)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tokenize_one = function() {
|
var tokenize_one = function() {
|
||||||
@@ -304,21 +304,21 @@ var tokenize = function(src, filename) {
|
|||||||
if (c == "\n") {
|
if (c == "\n") {
|
||||||
start = pos; start_row = row; start_col = col
|
start = pos; start_row = row; start_col = col
|
||||||
adv()
|
adv()
|
||||||
push(tokens, { kind: "newline", at: start, from_row: start_row, from_column: start_col, to_row: row, to_column: col, value: "\n" })
|
tokens[] = { kind: "newline", at: start, from_row: start_row, from_column: start_col, to_row: row, to_column: col, value: "\n" }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (c == "\r") {
|
if (c == "\r") {
|
||||||
start = pos; start_row = row; start_col = col
|
start = pos; start_row = row; start_col = col
|
||||||
adv()
|
adv()
|
||||||
if (pos < len && pk() == "\n") adv()
|
if (pos < len && pk() == "\n") adv()
|
||||||
push(tokens, { kind: "newline", at: start, from_row: start_row, from_column: start_col, to_row: row, to_column: col, value: "\n" })
|
tokens[] = { kind: "newline", at: start, from_row: start_row, from_column: start_col, to_row: row, to_column: col, value: "\n" }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (c == " " || c == "\t") {
|
if (c == " " || c == "\t") {
|
||||||
start = pos; start_row = row; start_col = col
|
start = pos; start_row = row; start_col = col
|
||||||
while (pos < len && (pk() == " " || pk() == "\t")) adv()
|
while (pos < len && (pk() == " " || pk() == "\t")) adv()
|
||||||
raw = substr(start, pos)
|
raw = substr(start, pos)
|
||||||
push(tokens, { kind: "space", at: start, from_row: start_row, from_column: start_col, to_row: row, to_column: col, value: raw })
|
tokens[] = { kind: "space", at: start, from_row: start_row, from_column: start_col, to_row: row, to_column: col, value: raw }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (c == "'" || c == "\"") { read_string(c); return true }
|
if (c == "'" || c == "\"") { read_string(c); return true }
|
||||||
@@ -446,7 +446,7 @@ var tokenize = function(src, filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EOF token
|
// EOF token
|
||||||
push(tokens, { kind: "eof", at: pos, from_row: row, from_column: col, to_row: row, to_column: col })
|
tokens[] = { kind: "eof", at: pos, from_row: row, from_column: col, to_row: row, to_column: col }
|
||||||
|
|
||||||
return {filename: filename, tokens: tokens}
|
return {filename: filename, tokens: tokens}
|
||||||
}
|
}
|
||||||
|
|||||||
16
toml.cm
16
toml.cm
@@ -127,7 +127,7 @@ function parse_key_path(str) {
|
|||||||
} else if (c == '.' && !in_quote) {
|
} else if (c == '.' && !in_quote) {
|
||||||
piece = trim(current)
|
piece = trim(current)
|
||||||
if (piece == null) piece = trim(current)
|
if (piece == null) piece = trim(current)
|
||||||
push(parts, parse_key(piece))
|
parts[] = parse_key(piece)
|
||||||
current = ''
|
current = ''
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ function parse_key_path(str) {
|
|||||||
|
|
||||||
var tail = trim(current)
|
var tail = trim(current)
|
||||||
if (tail == null) tail = trim(current)
|
if (tail == null) tail = trim(current)
|
||||||
if (length(tail) > 0) push(parts, parse_key(tail))
|
if (length(tail) > 0) parts[] = parse_key(tail)
|
||||||
|
|
||||||
return parts
|
return parts
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ function parse_array(str) {
|
|||||||
} else if (ch == ',' && !in_quotes) {
|
} else if (ch == ',' && !in_quotes) {
|
||||||
piece = trim(current)
|
piece = trim(current)
|
||||||
if (piece == null) piece = trim(current)
|
if (piece == null) piece = trim(current)
|
||||||
push(items, parse_value(piece))
|
items[] = parse_value(piece)
|
||||||
current = ''
|
current = ''
|
||||||
} else {
|
} else {
|
||||||
current = current + ch
|
current = current + ch
|
||||||
@@ -174,7 +174,7 @@ function parse_array(str) {
|
|||||||
|
|
||||||
var last = trim(current)
|
var last = trim(current)
|
||||||
if (last == null) last = trim(current)
|
if (last == null) last = trim(current)
|
||||||
if (last) push(items, parse_value(last))
|
if (last) items[] = parse_value(last)
|
||||||
|
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ function encode_toml(obj) {
|
|||||||
if (is_number(value)) return text(value)
|
if (is_number(value)) return text(value)
|
||||||
if (is_array(value)) {
|
if (is_array(value)) {
|
||||||
items = []
|
items = []
|
||||||
for (i = 0; i < length(value); i++) push(items, encode_value(value[i]))
|
for (i = 0; i < length(value); i++) items[] = encode_value(value[i])
|
||||||
return '[' + text(items, ', ') + ']'
|
return '[' + text(items, ', ') + ']'
|
||||||
}
|
}
|
||||||
return text(value)
|
return text(value)
|
||||||
@@ -230,7 +230,7 @@ function encode_toml(obj) {
|
|||||||
for (i = 0; i < length(keys); i++) {
|
for (i = 0; i < length(keys); i++) {
|
||||||
key = keys[i]
|
key = keys[i]
|
||||||
value = obj[key]
|
value = obj[key]
|
||||||
if (!is_object(value)) push(result, quote_key(key) + ' = ' + encode_value(value))
|
if (!is_object(value)) result[] = quote_key(key) + ' = ' + encode_value(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second pass: encode nested objects
|
// Second pass: encode nested objects
|
||||||
@@ -252,14 +252,14 @@ function encode_toml(obj) {
|
|||||||
if (is_object(value)) {
|
if (is_object(value)) {
|
||||||
quoted = quote_key(key)
|
quoted = quote_key(key)
|
||||||
section_path = path ? path + '.' + quoted : quoted
|
section_path = path ? path + '.' + quoted : quoted
|
||||||
push(result, '[' + section_path + ']')
|
result[] = '[' + section_path + ']'
|
||||||
|
|
||||||
// Direct properties
|
// Direct properties
|
||||||
section_keys = array(value)
|
section_keys = array(value)
|
||||||
for (j = 0; j < length(section_keys); j++) {
|
for (j = 0; j < length(section_keys); j++) {
|
||||||
sk = section_keys[j]
|
sk = section_keys[j]
|
||||||
sv = value[sk]
|
sv = value[sk]
|
||||||
if (!is_object(sv)) push(result, quote_key(sk) + ' = ' + encode_value(sv))
|
if (!is_object(sv)) result[] = quote_key(sk) + ' = ' + encode_value(sv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nested sections
|
// Nested sections
|
||||||
|
|||||||
85
update.ce
85
update.ce
@@ -20,7 +20,6 @@ var target_triple = null
|
|||||||
var follow_links = false
|
var follow_links = false
|
||||||
var git_pull = false
|
var git_pull = false
|
||||||
var i = 0
|
var i = 0
|
||||||
var updated = 0
|
|
||||||
var packages = null
|
var packages = null
|
||||||
|
|
||||||
var run = function() {
|
var run = function() {
|
||||||
@@ -54,7 +53,14 @@ var run = function() {
|
|||||||
if (target_pkg)
|
if (target_pkg)
|
||||||
target_pkg = shop.resolve_locator(target_pkg)
|
target_pkg = shop.resolve_locator(target_pkg)
|
||||||
|
|
||||||
function update_one(pkg) {
|
if (target_pkg) {
|
||||||
|
update_single(target_pkg)
|
||||||
|
} else {
|
||||||
|
update_all()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_one(pkg) {
|
||||||
var effective_pkg = pkg
|
var effective_pkg = pkg
|
||||||
var link_target = null
|
var link_target = null
|
||||||
var lock = shop.load_lock()
|
var lock = shop.load_lock()
|
||||||
@@ -62,59 +68,84 @@ function update_one(pkg) {
|
|||||||
var old_commit = old_entry ? old_entry.commit : null
|
var old_commit = old_entry ? old_entry.commit : null
|
||||||
var info = shop.resolve_package_info(pkg)
|
var info = shop.resolve_package_info(pkg)
|
||||||
var new_entry = null
|
var new_entry = null
|
||||||
var old_str = null
|
|
||||||
|
|
||||||
if (follow_links) {
|
if (follow_links) {
|
||||||
link_target = link.get_target(pkg)
|
link_target = link.get_target(pkg)
|
||||||
if (link_target) {
|
if (link_target) {
|
||||||
effective_pkg = link_target
|
effective_pkg = link_target
|
||||||
log.console(" Following link: " + pkg + " -> " + effective_pkg)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For local packages with --git, pull first
|
|
||||||
if (git_pull && info == 'local' && fd.is_dir(effective_pkg + '/.git')) {
|
if (git_pull && info == 'local' && fd.is_dir(effective_pkg + '/.git')) {
|
||||||
log.console(" " + effective_pkg + " (git pull)")
|
log.build(" " + effective_pkg + " (git pull)")
|
||||||
os.system('git -C "' + effective_pkg + '" pull')
|
os.system('git -C "' + effective_pkg + '" pull')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for update (sets lock entry if changed)
|
|
||||||
new_entry = shop.update(effective_pkg)
|
new_entry = shop.update(effective_pkg)
|
||||||
|
|
||||||
if (new_entry && new_entry.commit) {
|
return {
|
||||||
old_str = old_commit ? text(old_commit, 0, 8) : "(new)"
|
pkg: pkg,
|
||||||
log.console(" " + effective_pkg + " " + old_str + " -> " + text(new_entry.commit, 0, 8))
|
effective: effective_pkg,
|
||||||
|
old_commit: old_commit,
|
||||||
|
new_entry: new_entry,
|
||||||
|
changed: new_entry != null && new_entry.commit != null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync: fetch, extract, build
|
|
||||||
shop.sync(effective_pkg, {target: target_triple})
|
|
||||||
|
|
||||||
return new_entry
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_pkg) {
|
function sync_one(effective_pkg) {
|
||||||
if (update_one(target_pkg)) {
|
shop.sync(effective_pkg, {target: target_triple})
|
||||||
log.console("Updated " + target_pkg + ".")
|
}
|
||||||
|
|
||||||
|
function update_single(pkg) {
|
||||||
|
var result = check_one(pkg)
|
||||||
|
var old_str = null
|
||||||
|
if (result.changed) {
|
||||||
|
old_str = result.old_commit ? text(result.old_commit, 0, 8) : "(new)"
|
||||||
|
log.console("==> Upgrading " + result.effective)
|
||||||
|
log.console(" " + old_str + " -> " + text(result.new_entry.commit, 0, 8))
|
||||||
|
log.console("==> Syncing " + result.effective)
|
||||||
|
sync_one(result.effective)
|
||||||
|
log.console("Updated " + result.effective + ".")
|
||||||
} else {
|
} else {
|
||||||
log.console(target_pkg + " is up to date.")
|
log.console(pkg + " is up to date.")
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
function update_all() {
|
||||||
|
var results = []
|
||||||
|
var changed = []
|
||||||
|
var result = null
|
||||||
|
|
||||||
packages = shop.list_packages()
|
packages = shop.list_packages()
|
||||||
log.console("Checking for updates (" + text(length(packages)) + " packages)...")
|
log.console("Checking for updates...")
|
||||||
|
|
||||||
arrfor(packages, function(pkg) {
|
arrfor(packages, function(pkg) {
|
||||||
if (pkg == 'core') return
|
if (pkg == 'core') return
|
||||||
if (update_one(pkg))
|
result = check_one(pkg)
|
||||||
updated = updated + 1
|
results[] = result
|
||||||
|
if (result.changed)
|
||||||
|
changed[] = result
|
||||||
})
|
})
|
||||||
|
|
||||||
if (updated > 0) {
|
if (length(changed) == 0) {
|
||||||
log.console("Updated " + text(updated) + " package(s).")
|
|
||||||
} else {
|
|
||||||
log.console("All packages are up to date.")
|
log.console("All packages are up to date.")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.console("==> Upgrading " + text(length(changed)) + " outdated package" + (length(changed) != 1 ? "s" : "") + ":")
|
||||||
|
arrfor(changed, function(r) {
|
||||||
|
var old_str = r.old_commit ? text(r.old_commit, 0, 8) : "(new)"
|
||||||
|
log.console(" " + r.effective + " " + old_str + " -> " + text(r.new_entry.commit, 0, 8))
|
||||||
|
})
|
||||||
|
|
||||||
|
arrfor(changed, function(r) {
|
||||||
|
log.console("==> Syncing " + r.effective)
|
||||||
|
sync_one(r.effective)
|
||||||
|
})
|
||||||
|
|
||||||
|
log.console("Updated " + text(length(changed)) + " package(s).")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
run()
|
run()
|
||||||
|
|
||||||
$stop()
|
$stop()
|
||||||
|
|||||||
10
verify.ce
10
verify.ce
@@ -67,11 +67,11 @@ var warnings = []
|
|||||||
var checked = 0
|
var checked = 0
|
||||||
|
|
||||||
function add_error(msg) {
|
function add_error(msg) {
|
||||||
push(errors, msg)
|
errors[] = msg
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_warning(msg) {
|
function add_warning(msg) {
|
||||||
push(warnings, msg)
|
warnings[] = msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify a single package
|
// Verify a single package
|
||||||
@@ -211,12 +211,12 @@ if (scope == 'shop') {
|
|||||||
if (deep) {
|
if (deep) {
|
||||||
// Gather all dependencies
|
// Gather all dependencies
|
||||||
all_deps = pkg.gather_dependencies(locator)
|
all_deps = pkg.gather_dependencies(locator)
|
||||||
push(packages_to_verify, locator)
|
packages_to_verify[] = locator
|
||||||
arrfor(all_deps, function(dep) {
|
arrfor(all_deps, function(dep) {
|
||||||
push(packages_to_verify, dep)
|
packages_to_verify[] = dep
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
push(packages_to_verify, locator)
|
packages_to_verify[] = locator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
28
verify_ir.cm
28
verify_ir.cm
@@ -172,7 +172,7 @@ var check_slot_bounds = function(func) {
|
|||||||
if (pos < length(instr) - 2) {
|
if (pos < length(instr) - 2) {
|
||||||
val = instr[pos]
|
val = instr[pos]
|
||||||
if (is_number(val) && (val < 0 || val >= nr_slots)) {
|
if (is_number(val) && (val < 0 || val >= nr_slots)) {
|
||||||
push(errors, `slot_bounds: instr ${text(i)} op=${op} slot[${text(positions[j])}]=${text(val)} out of range 0..${text(nr_slots - 1)}`)
|
errors[] = `slot_bounds: instr ${text(i)} op=${op} slot[${text(positions[j])}]=${text(val)} out of range 0..${text(nr_slots - 1)}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
j = j + 1
|
j = j + 1
|
||||||
@@ -217,7 +217,7 @@ var check_jump_targets = function(func) {
|
|||||||
if (label_pos != null) {
|
if (label_pos != null) {
|
||||||
target = instr[label_pos + 1]
|
target = instr[label_pos + 1]
|
||||||
if (is_text(target) && labels[target] != true) {
|
if (is_text(target) && labels[target] != true) {
|
||||||
push(errors, `jump_targets: instr ${text(i)} op=${op} target label "${target}" not found`)
|
errors[] = `jump_targets: instr ${text(i)} op=${op} target label "${target}" not found`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -301,46 +301,46 @@ var check_type_consistency = function(func) {
|
|||||||
s2 = text(instr[2])
|
s2 = text(instr[2])
|
||||||
t2 = slot_types[s2]
|
t2 = slot_types[s2]
|
||||||
if (t2 != null && t2 != T_INT && t2 != "unknown") {
|
if (t2 != null && t2 != T_INT && t2 != "unknown") {
|
||||||
push(errors, `type_consistency: instr ${text(i)} op=${op} src1 slot ${s2} has type ${t2}, expected int`)
|
errors[] = `type_consistency: instr ${text(i)} op=${op} src1 slot ${s2} has type ${t2}, expected int`
|
||||||
}
|
}
|
||||||
if (length(instr) >= 6) {
|
if (length(instr) >= 6) {
|
||||||
s3 = text(instr[3])
|
s3 = text(instr[3])
|
||||||
t3 = slot_types[s3]
|
t3 = slot_types[s3]
|
||||||
if (t3 != null && t3 != T_INT && t3 != "unknown") {
|
if (t3 != null && t3 != T_INT && t3 != "unknown") {
|
||||||
push(errors, `type_consistency: instr ${text(i)} op=${op} src2 slot ${s3} has type ${t3}, expected int`)
|
errors[] = `type_consistency: instr ${text(i)} op=${op} src2 slot ${s3} has type ${t3}, expected int`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (float_ops[op] == true && length(instr) >= 5) {
|
} else if (float_ops[op] == true && length(instr) >= 5) {
|
||||||
s2 = text(instr[2])
|
s2 = text(instr[2])
|
||||||
t2 = slot_types[s2]
|
t2 = slot_types[s2]
|
||||||
if (t2 != null && t2 != T_FLOAT && t2 != "unknown") {
|
if (t2 != null && t2 != T_FLOAT && t2 != "unknown") {
|
||||||
push(errors, `type_consistency: instr ${text(i)} op=${op} src1 slot ${s2} has type ${t2}, expected float`)
|
errors[] = `type_consistency: instr ${text(i)} op=${op} src1 slot ${s2} has type ${t2}, expected float`
|
||||||
}
|
}
|
||||||
if (length(instr) >= 6) {
|
if (length(instr) >= 6) {
|
||||||
s3 = text(instr[3])
|
s3 = text(instr[3])
|
||||||
t3 = slot_types[s3]
|
t3 = slot_types[s3]
|
||||||
if (t3 != null && t3 != T_FLOAT && t3 != "unknown") {
|
if (t3 != null && t3 != T_FLOAT && t3 != "unknown") {
|
||||||
push(errors, `type_consistency: instr ${text(i)} op=${op} src2 slot ${s3} has type ${t3}, expected float`)
|
errors[] = `type_consistency: instr ${text(i)} op=${op} src2 slot ${s3} has type ${t3}, expected float`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (text_ops[op] == true && length(instr) >= 5) {
|
} else if (text_ops[op] == true && length(instr) >= 5) {
|
||||||
s2 = text(instr[2])
|
s2 = text(instr[2])
|
||||||
t2 = slot_types[s2]
|
t2 = slot_types[s2]
|
||||||
if (t2 != null && t2 != T_TEXT && t2 != "unknown") {
|
if (t2 != null && t2 != T_TEXT && t2 != "unknown") {
|
||||||
push(errors, `type_consistency: instr ${text(i)} op=${op} src1 slot ${s2} has type ${t2}, expected text`)
|
errors[] = `type_consistency: instr ${text(i)} op=${op} src1 slot ${s2} has type ${t2}, expected text`
|
||||||
}
|
}
|
||||||
if (length(instr) >= 6) {
|
if (length(instr) >= 6) {
|
||||||
s3 = text(instr[3])
|
s3 = text(instr[3])
|
||||||
t3 = slot_types[s3]
|
t3 = slot_types[s3]
|
||||||
if (t3 != null && t3 != T_TEXT && t3 != "unknown") {
|
if (t3 != null && t3 != T_TEXT && t3 != "unknown") {
|
||||||
push(errors, `type_consistency: instr ${text(i)} op=${op} src2 slot ${s3} has type ${t3}, expected text`)
|
errors[] = `type_consistency: instr ${text(i)} op=${op} src2 slot ${s3} has type ${t3}, expected text`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (bool_ops[op] == true && length(instr) >= 5) {
|
} else if (bool_ops[op] == true && length(instr) >= 5) {
|
||||||
s2 = text(instr[2])
|
s2 = text(instr[2])
|
||||||
t2 = slot_types[s2]
|
t2 = slot_types[s2]
|
||||||
if (t2 != null && t2 != T_BOOL && t2 != "unknown") {
|
if (t2 != null && t2 != T_BOOL && t2 != "unknown") {
|
||||||
push(errors, `type_consistency: instr ${text(i)} op=${op} src1 slot ${s2} has type ${t2}, expected bool`)
|
errors[] = `type_consistency: instr ${text(i)} op=${op} src1 slot ${s2} has type ${t2}, expected bool`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,7 +394,7 @@ var check_nop_consistency = function(func) {
|
|||||||
if (label_pos != null) {
|
if (label_pos != null) {
|
||||||
target = instr[label_pos + 1]
|
target = instr[label_pos + 1]
|
||||||
if (is_text(target) && nops[target] == true) {
|
if (is_text(target) && nops[target] == true) {
|
||||||
push(errors, `nop_consistency: instr ${text(i)} op=${op} jumps to nop marker "${target}"`)
|
errors[] = `nop_consistency: instr ${text(i)} op=${op} jumps to nop marker "${target}"`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,28 +415,28 @@ var verify_all = function(func, pass_name) {
|
|||||||
check_errors = check_slot_bounds(func)
|
check_errors = check_slot_bounds(func)
|
||||||
i = 0
|
i = 0
|
||||||
while (i < length(check_errors)) {
|
while (i < length(check_errors)) {
|
||||||
push(all_errors, `${prefix}${fn_name}: ${check_errors[i]}`)
|
all_errors[] = `${prefix}${fn_name}: ${check_errors[i]}`
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
check_errors = check_jump_targets(func)
|
check_errors = check_jump_targets(func)
|
||||||
i = 0
|
i = 0
|
||||||
while (i < length(check_errors)) {
|
while (i < length(check_errors)) {
|
||||||
push(all_errors, `${prefix}${fn_name}: ${check_errors[i]}`)
|
all_errors[] = `${prefix}${fn_name}: ${check_errors[i]}`
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
check_errors = check_type_consistency(func)
|
check_errors = check_type_consistency(func)
|
||||||
i = 0
|
i = 0
|
||||||
while (i < length(check_errors)) {
|
while (i < length(check_errors)) {
|
||||||
push(all_errors, `${prefix}${fn_name}: ${check_errors[i]}`)
|
all_errors[] = `${prefix}${fn_name}: ${check_errors[i]}`
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
check_errors = check_nop_consistency(func)
|
check_errors = check_nop_consistency(func)
|
||||||
i = 0
|
i = 0
|
||||||
while (i < length(check_errors)) {
|
while (i < length(check_errors)) {
|
||||||
push(all_errors, `${prefix}${fn_name}: ${check_errors[i]}`)
|
all_errors[] = `${prefix}${fn_name}: ${check_errors[i]}`
|
||||||
i = i + 1
|
i = i + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
4
xref.ce
4
xref.ce
@@ -93,11 +93,11 @@ var run = function() {
|
|||||||
if (!creates[text(parent_idx)]) {
|
if (!creates[text(parent_idx)]) {
|
||||||
creates[text(parent_idx)] = []
|
creates[text(parent_idx)] = []
|
||||||
}
|
}
|
||||||
push(creates[text(parent_idx)], {child: child_idx, line: instr_line})
|
creates[text(parent_idx)][] = {child: child_idx, line: instr_line}
|
||||||
if (!created_by[text(child_idx)]) {
|
if (!created_by[text(child_idx)]) {
|
||||||
created_by[text(child_idx)] = []
|
created_by[text(child_idx)] = []
|
||||||
}
|
}
|
||||||
push(created_by[text(child_idx)], {parent: parent_idx, line: instr_line})
|
created_by[text(child_idx)][] = {parent: parent_idx, line: instr_line}
|
||||||
}
|
}
|
||||||
j = j + 1
|
j = j + 1
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user