cmd+selfhost+test: gate alloc builtin behind same-module fn alloc
Mirrors the existing abort/assert gates in cstage check.c (strict same-module lookup rather than scope_lookup_prefer, since lib/os.alloc under a `use os;` import must not suppress the bare-alloc builtin in client code). cgen.c shadows the resolution: only fire the rt_alloc path when the typer left N_CALL.lhs->type == ty_err. wwstage gets a new samemodfn helper for the matching gate. Test fixtures: package-main repair for the 3 alloc rows in 700_e2e.c that the parser was inheriting curmod="os" from the concat'd os.ww; new shadow-test row asserts a same-module `fn alloc(n: i64) i64` beats the builtin in cgen.
This commit is contained in:
@@ -274,8 +274,12 @@ static const struct row rows[] = {
|
||||
" os.write(1, s.ptr, len(s): u64);\n"
|
||||
" return len(s);\n"
|
||||
"};", 4 },
|
||||
/* alloc() builtin: heap-allocate a struct, init from struct-lit */
|
||||
{ "import os;\n"
|
||||
/* alloc() builtin: heap-allocate a struct, init from struct-lit.
|
||||
* `package main;` is required so the bare-alloc-builtin gate
|
||||
* (task #23) sees c->cur_mod=="main" and doesn't suppress the
|
||||
* builtin via the inherited os.alloc decl. */
|
||||
{ "package main;\n"
|
||||
"import os;\n"
|
||||
"type point = struct { x: i32, y: i32 };\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let p: *point = alloc(point { x = 3, y = 4 });\n"
|
||||
@@ -291,13 +295,32 @@ static const struct row rows[] = {
|
||||
" for (let b .. s) { total += b: i32; };\n"
|
||||
" return total;\n"
|
||||
"};", 100 },
|
||||
/* alloc([], n): fresh empty slice with cap n */
|
||||
{ "import os;\n"
|
||||
/* alloc([], n): fresh empty slice with cap n. `package main;` for
|
||||
* the same reason as the value-form test above (task #23 gate). */
|
||||
{ "package main;\n"
|
||||
"import os;\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let s: []u8 = alloc([], 16);\n"
|
||||
" append(s, 72u8, 105u8);\n"
|
||||
" return s.cap;\n"
|
||||
"};", 16 },
|
||||
/* alloc-builtin shadow (task #23): a non-main package declares
|
||||
* `fn alloc(n: i64) i64` and calls it bare. The same-module gate
|
||||
* must suppress the builtin and dispatch to the user fn so the
|
||||
* call returns n+100. Pre-gate this site lands in the typed-builtin
|
||||
* path: arg is i64 → returns *i64 → init-type fails against the
|
||||
* declared i64 (and would over-allocate against rt_alloc anyway).
|
||||
* Inline multi-`package` mirrors driver-concatenated layout; the
|
||||
* `import myos;` directive is silently skipped by locate_import
|
||||
* (no external module by that name). */
|
||||
{ "package myos;\n"
|
||||
"fn alloc(n: i64) i64 = { return n + 100; };\n"
|
||||
"fn run() i64 = { return alloc(7); };\n"
|
||||
"package main;\n"
|
||||
"import myos;\n"
|
||||
"fn main() i32 = {\n"
|
||||
" return myos.run(): i32;\n"
|
||||
"};", 107 },
|
||||
/* variadic spread: append(dst, src...) iterates src */
|
||||
{ "import os;\n"
|
||||
"fn main() i32 = {\n"
|
||||
@@ -334,8 +357,10 @@ static const struct row rows[] = {
|
||||
" let t: (i64, i64) = pair();\n"
|
||||
" return (t.0 + t.1): i32;\n"
|
||||
"};", 42 },
|
||||
/* Hare-style abort/assert + free() builtin */
|
||||
{ "import os;\n"
|
||||
/* Hare-style abort/assert + free() builtin. `package main;` for
|
||||
* the alloc-builtin gate (task #23). */
|
||||
{ "package main;\n"
|
||||
"import os;\n"
|
||||
"type point = struct { x: i64, y: i64 };\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let p: *point = alloc(point { x = 7, y = 35 });\n"
|
||||
|
||||
Reference in New Issue
Block a user