compiler+runtime: codegen fixes for empty literal, == int idents, m.field; runtime body-loss fix and Linux feature macros
Three codegen bugs surfaced repeatedly across the parallel port-to-El
agents and were patched here:
1. Empty array literal '[]' was emitting el_list_new(0, ) — trailing
comma in a varargs call, fails the C parse. Special-cased: n==0
returns 'el_list_empty()' directly.
2. '==' between two identifiers both tracked in __int_names (typed
Int via 'let x: Int = ...') was miscompiling to str_eq. With the
tagged-pointer Int-as-int64 representation, str_eq strcmp's what
are integer values dressed as char* and segfaults on the first
non-printable byte. Added the int-name lookup, mirroring the
dispatch already present for '+' between Int idents. NotEq got
the same treatment.
3. 'm.field' codegen was passing the raw const char* field name to
el_get_field, which expects el_val_t. C compiler warned about int
conversion; runtime read garbage at the address. Wrapped in
EL_STR(...) so the field name lands as a proper el_val_t.
Runtime additions in the same pass:
- el_runtime.c http_read_request: the loop's boundary check was
'line_end >= hdr_end' which broke before processing the LAST
header line — its trailing \r\n IS hdr_end. Real curl clients
put Content-Length last, so POST bodies were silently arriving
as length 0. Changed to '> hdr_end' so the last line is processed.
soma-server agent surfaced this during smoke testing.
- _GNU_SOURCE feature macro: clock_gettime/CLOCK_REALTIME, strcasecmp,
and the dlfcn extensions (RTLD_DEFAULT) all gated behind it on
glibc/Debian. macOS is permissive without; the landing Docker
build needed these for linux/amd64. Adds <strings.h> for
strcasecmp.
- Refactored slot semantics in el_runtime.c (already in tree from
the morning ARC commit): magic-tagged ElHeader at offset 0,
ElList/ElMap with separate elems/keys/values payload allocations,
el_list_append and el_map_set mutate-in-place when refcount<=1
and copy-on-write when shared.
Self-host fixpoint reached at v3: elc → elc.c → cc → elc binary →
elc.c reproduced byte-for-byte. dist/platform/elc and dist/platform/elc.c
updated. The codegen.el and elc-combined.el changes are mirror-edits;
both flow through the bootstrap chain to keep self-hosting clean.
This commit is contained in:
Vendored
BIN
Binary file not shown.
Vendored
+26
-1
@@ -1898,6 +1898,17 @@ el_val_t cg_expr(el_val_t expr) {
|
||||
if (str_eq(right_kind, EL_STR("Bool"))) {
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")"));
|
||||
}
|
||||
if (str_eq(left_kind, EL_STR("Ident"))) {
|
||||
if (str_eq(right_kind, EL_STR("Ident"))) {
|
||||
el_val_t lname = el_get_field(left, EL_STR("name"));
|
||||
el_val_t rname = el_get_field(right, EL_STR("name"));
|
||||
if (is_int_name(lname)) {
|
||||
if (is_int_name(rname)) {
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" == ")), right_c), EL_STR(")"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (str_eq(left_kind, EL_STR("Str"))) {
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")"));
|
||||
}
|
||||
@@ -1930,6 +1941,17 @@ el_val_t cg_expr(el_val_t expr) {
|
||||
if (str_eq(right_kind, EL_STR("Bool"))) {
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")"));
|
||||
}
|
||||
if (str_eq(left_kind, EL_STR("Ident"))) {
|
||||
if (str_eq(right_kind, EL_STR("Ident"))) {
|
||||
el_val_t lname = el_get_field(left, EL_STR("name"));
|
||||
el_val_t rname = el_get_field(right, EL_STR("name"));
|
||||
if (is_int_name(lname)) {
|
||||
if (is_int_name(rname)) {
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("("), left_c), EL_STR(" != ")), right_c), EL_STR(")"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (str_eq(left_kind, EL_STR("Str"))) {
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("!str_eq("), left_c), EL_STR(", ")), right_c), EL_STR(")"));
|
||||
}
|
||||
@@ -1989,7 +2011,7 @@ el_val_t cg_expr(el_val_t expr) {
|
||||
el_val_t obj = el_get_field(expr, EL_STR("object"));
|
||||
el_val_t field = el_get_field(expr, EL_STR("field"));
|
||||
el_val_t obj_c = cg_expr(obj);
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", ")), c_str_lit(field)), EL_STR(")"));
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("el_get_field("), obj_c), EL_STR(", EL_STR(")), c_str_lit(field)), EL_STR("))"));
|
||||
}
|
||||
if (str_eq(kind, EL_STR("Index"))) {
|
||||
el_val_t obj = el_get_field(expr, EL_STR("object"));
|
||||
@@ -2005,6 +2027,9 @@ el_val_t cg_expr(el_val_t expr) {
|
||||
if (str_eq(kind, EL_STR("Array"))) {
|
||||
el_val_t elems = el_get_field(expr, EL_STR("elems"));
|
||||
el_val_t n = native_list_len(elems);
|
||||
if (n == 0) {
|
||||
return EL_STR("el_list_empty()");
|
||||
}
|
||||
el_val_t items = EL_STR("");
|
||||
el_val_t i = 0;
|
||||
while (i < n) {
|
||||
|
||||
Reference in New Issue
Block a user