fix: codegen O(n²) HTML memory leak + elb stderr surface + runtime dir path
This commit is contained in:
+26
-3
@@ -225,6 +225,7 @@ fn compile_module(src_path: String, out_dir: String, elc_bin: String, dry_run: B
|
||||
let bname: String = basename_noext(src_path)
|
||||
let c_out: String = out_dir + "/" + bname + ".c"
|
||||
let elh_out: String = out_dir + "/" + bname + ".elh"
|
||||
let err_tmp: String = "/tmp/elb-err-" + bname + ".txt"
|
||||
|
||||
// Check if recompile needed
|
||||
if !file_is_newer(src_path, c_out) {
|
||||
@@ -234,18 +235,26 @@ fn compile_module(src_path: String, out_dir: String, elc_bin: String, dry_run: B
|
||||
return true
|
||||
}
|
||||
|
||||
// elc streams C to stdout (collect mode not yet implemented); use
|
||||
// shell redirection so the output lands in the file, not the terminal.
|
||||
let cmd: String = elc_bin + " --emit-header " + src_path + " > " + c_out + " 2>&1"
|
||||
// elc streams C to stdout; redirect stderr to a temp file so we can
|
||||
// surface the actual error message on failure instead of swallowing it.
|
||||
let cmd: String = elc_bin + " --emit-header " + src_path + " > " + c_out + " 2>" + err_tmp
|
||||
println(" compile " + src_path)
|
||||
|
||||
if dry_run { return true }
|
||||
|
||||
let ret: Int = exec_command(cmd)
|
||||
if ret != 0 {
|
||||
// Surface the actual compiler error from stderr
|
||||
let err_msg: String = str_trim(fs_read(err_tmp))
|
||||
if !str_eq(err_msg, "") {
|
||||
println(err_msg)
|
||||
}
|
||||
// Remove partial output so a retry starts clean
|
||||
exec_command("rm -f " + c_out + " " + err_tmp)
|
||||
println("elb: compile failed: " + src_path)
|
||||
return false
|
||||
}
|
||||
exec_command("rm -f " + err_tmp)
|
||||
|
||||
// Move the generated .elh (written next to the source by elc) into
|
||||
// out_dir so that #include "module.elh" lines in the generated .c
|
||||
@@ -320,6 +329,20 @@ fn main() -> Void {
|
||||
runtime_path = elc_dir + "/../el-compiler/runtime/el_runtime.c"
|
||||
}
|
||||
}
|
||||
// If --runtime points to a directory, auto-locate el_runtime.c inside it.
|
||||
// This lets both forms work:
|
||||
// --runtime=/opt/el/el-compiler/runtime (directory form)
|
||||
// --runtime=/opt/el/el-compiler/runtime/el_runtime.c (file form)
|
||||
if !str_eq(runtime_path, "") {
|
||||
let is_dir: String = str_trim(exec_capture("test -d " + runtime_path + " && echo dir || echo file"))
|
||||
if str_eq(is_dir, "dir") {
|
||||
let candidate: String = runtime_path + "/el_runtime.c"
|
||||
let has_file: String = str_trim(exec_capture("test -f " + candidate + " && echo yes || echo no"))
|
||||
if str_eq(has_file, "yes") {
|
||||
let runtime_path = candidate
|
||||
}
|
||||
}
|
||||
}
|
||||
if str_eq(runtime_path, "") {
|
||||
println("elb: cannot locate el_runtime.c - use --runtime=PATH")
|
||||
exit(1)
|
||||
|
||||
Reference in New Issue
Block a user