aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/image.zc
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-14 15:54:04 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-14 15:54:04 +0330
commit0879d0a42d137054057cd2a1e37437e6be78ed0b (patch)
treefcb16d3185c1f80fae8d54cd9062bd68d6c0c88d /src/compiler/image.zc
parentmerge spec conformance suite (diff)
parentmerge main into work/line-tables (diff)
merge line tables
Diffstat (limited to 'src/compiler/image.zc')
-rw-r--r--src/compiler/image.zc23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/compiler/image.zc b/src/compiler/image.zc
index dfe5f77..45cd928 100644
--- a/src/compiler/image.zc
+++ b/src/compiler/image.zc
@@ -62,25 +62,48 @@ int blob_load(word p, int hide) {
}
return 0;
}
+// the name of the function whose code holds address a, for the frames of a backtrace that have
+// no line table (rt.frame_namer is set to this when the compiler starts). the nearest function
+// at or below a, or 0.
+char* frame_symbol(int a) {
+ int i = 0, best = 0 - 1;
+ while (i < nsym) {
+ if (skind[i] == K_FN && (sflag[i] & F_DEF) && sval[i] <= a && sval[i] > 0 && (best < 0 || sval[i] > sval[best])) best = i;
+ i++;
+ }
+ if (best < 0) return 0;
+ return sname[best];
+}
+// an image built with line tables gets the head of its chain in its own rt.line_blocks, the
+// global the runtime reads, as that global's initial value.
+int lt_image_head() {
+ int s = lookup(intern("rt.line_blocks"));
+ if (lt_head && s >= 0 && skind[s] == K_GVAR) *(sval[s] + hdelta) = lt_head;
+ return 0;
+}
// compile the rest of stdin for org into a growing output buffer. the image's
// addresses remain logical addresses at org while its temporary storage grows.
// image_words and image_size expose the finished image; initial is its first
// buffer reservation. the matching host layout must still fit the finished image.
int build_image_grow(int org, int initial) {
int sh = here, sd = hdelta, sl = hlimit, sub = ubase, svl = vislo, sns = nsym, sen = nenh, n;
+ word saved_head = lt_head; char* saved_file = lt_file; word saved_file_at = lt_file_at; char* saved_mark = lt_mark_file; int saved_base = lt_mark_base, saved_nm = lt_next_mark, saved_nmarks = lt_nmarks;
word saved_buffer = image_buffer; int saved_active = image_active, saved_org = image_org, saved_capacity = image_capacity;
if (org < 0 || initial < 7 || initial > 0x7fffffff - org) fatal("bad image reservation");
image_buffer = chk_resize(0, 0, initial); image_active = 1; image_org = org; image_capacity = initial;
ubase = nsym; vislo = nsym; nenh = 0;
here = org; hdelta = image_buffer - org; hlimit = org + initial;
+ lt_head = 0; lt_file_at = 0; lt_mark_file = 0; lt_mark_base = 0; lt_next_mark = 0; lt_nmarks = 0;
lit(rt.FTOP); lit(rt.ZFP); op(O_ST); fnref(fwdfn(s_start)); op(O_JMP); emit(0); emit(0);
unit_stdin();
+ lt_image_head();
n = blob_emit(ubase);
image_buffer[5] = n;
image_buffer[6] = here;
n = here - org; image_words = image_buffer; image_size = n;
popsyms(sns);
ubase = sub; vislo = svl; here = sh; hdelta = sd; hlimit = sl; nenh = sen;
+ lt_head = saved_head; lt_file = saved_file; lt_file_at = saved_file_at; lt_mark_file = saved_mark; lt_mark_base = saved_base; lt_next_mark = saved_nm; lt_nmarks = saved_nmarks;
image_buffer = saved_buffer; image_active = saved_active; image_org = saved_org; image_capacity = saved_capacity;
return n;
}