131 lines
3.5 KiB
Plaintext
131 lines
3.5 KiB
Plaintext
// compare_aot.ce — compile a .ce/.cm file via both paths and compare results
|
|
//
|
|
// Usage:
|
|
// cell --dev compare_aot.ce <file.ce>
|
|
|
|
var build = use('build')
|
|
var fd_mod = use('fd')
|
|
var os = use('internal/os')
|
|
var json = use('json')
|
|
var time = use('time')
|
|
|
|
var show = function(v) {
|
|
if (v == null) return "null"
|
|
return json.encode(v)
|
|
}
|
|
|
|
if (length(args) < 1) {
|
|
log.compile('usage: cell --dev compare_aot.ce <file>')
|
|
return
|
|
}
|
|
|
|
var file = args[0]
|
|
if (!fd_mod.is_file(file)) {
|
|
if (!ends_with(file, '.ce') && fd_mod.is_file(file + '.ce'))
|
|
file = file + '.ce'
|
|
else if (!ends_with(file, '.cm') && fd_mod.is_file(file + '.cm'))
|
|
file = file + '.cm'
|
|
else {
|
|
log.error('file not found: ' + file)
|
|
return
|
|
}
|
|
}
|
|
|
|
var abs = fd_mod.realpath(file)
|
|
|
|
// Shared compilation front-end — uses raw modules for per-stage timing
|
|
var tokenize = use('tokenize')
|
|
var parse_mod = use('parse')
|
|
var fold = use('fold')
|
|
var mcode_mod = use('mcode')
|
|
var streamline_mod = use('streamline')
|
|
|
|
var t0 = time.number()
|
|
var src = text(fd_mod.slurp(abs))
|
|
var t1 = time.number()
|
|
var tok = tokenize(src, abs)
|
|
var t2 = time.number()
|
|
var ast = parse_mod(tok.tokens, src, abs, tokenize)
|
|
var t3 = time.number()
|
|
var folded = fold(ast)
|
|
var t4 = time.number()
|
|
var compiled = mcode_mod(folded)
|
|
var t5 = time.number()
|
|
var optimized = streamline_mod(compiled)
|
|
var t6 = time.number()
|
|
|
|
log.compile('--- front-end timing ---')
|
|
log.compile(' read: ' + text(t1 - t0) + 's')
|
|
log.compile(' tokenize: ' + text(t2 - t1) + 's')
|
|
log.compile(' parse: ' + text(t3 - t2) + 's')
|
|
log.compile(' fold: ' + text(t4 - t3) + 's')
|
|
log.compile(' mcode: ' + text(t5 - t4) + 's')
|
|
log.compile(' streamline: ' + text(t6 - t5) + 's')
|
|
log.compile(' total: ' + text(t6 - t0) + 's')
|
|
|
|
// Shared env for both paths — only non-intrinsic runtime functions.
|
|
// Intrinsics (starts_with, ends_with, logical, some, every, etc.) live on
|
|
// the stoned global and are found via GETINTRINSIC/cell_rt_get_intrinsic.
|
|
var env = stone({
|
|
log: log,
|
|
fallback: fallback,
|
|
parallel: parallel,
|
|
race: race,
|
|
sequence: sequence,
|
|
use
|
|
})
|
|
|
|
// --- Interpreted (mach VM) ---
|
|
var result_interp = null
|
|
var interp_ok = false
|
|
var run_interp = function() {
|
|
log.compile('--- interpreted ---')
|
|
var mcode_json = json.encode(optimized)
|
|
var mach_blob = mach_compile_mcode_bin(abs, mcode_json)
|
|
result_interp = mach_load(mach_blob, env)
|
|
interp_ok = true
|
|
log.compile('result: ' + show(result_interp))
|
|
} disruption {
|
|
interp_ok = true
|
|
log.compile('(disruption escaped from interpreted run)')
|
|
}
|
|
run_interp()
|
|
|
|
// --- Native (AOT via QBE) ---
|
|
var result_native = null
|
|
var native_ok = false
|
|
var run_native = function() {
|
|
log.compile('\n--- native ---')
|
|
var dylib_path = build.compile_native_ir(optimized, abs, null)
|
|
log.compile('dylib: ' + dylib_path)
|
|
var handle = os.dylib_open(dylib_path)
|
|
if (!handle) {
|
|
log.error('failed to open dylib')
|
|
return
|
|
}
|
|
result_native = os.native_module_load(handle, env)
|
|
native_ok = true
|
|
log.compile('result: ' + show(result_native))
|
|
} disruption {
|
|
native_ok = true
|
|
log.compile('(disruption escaped from native run)')
|
|
}
|
|
run_native()
|
|
|
|
// --- Comparison ---
|
|
log.compile('\n--- comparison ---')
|
|
var s_interp = show(result_interp)
|
|
var s_native = show(result_native)
|
|
if (interp_ok && native_ok) {
|
|
if (s_interp == s_native) {
|
|
log.compile('MATCH')
|
|
} else {
|
|
log.error('MISMATCH')
|
|
log.error(' interp: ' + s_interp)
|
|
log.error(' native: ' + s_native)
|
|
}
|
|
} else {
|
|
if (!interp_ok) log.error('interpreted run failed')
|
|
if (!native_ok) log.error('native run failed')
|
|
}
|