- Modules: `use`/`pub`, directory-as-module, per-module symbol resolution (a
flat first-wins merge silently ran the wrong `pub fn` body), six reserved
stdlib namespaces typed UNKNOWN-BUT-RESERVED.
- Surface: `and`/`or` (own precedence tier, short-circuit, Bool-only), `${}`
interpolation desugared at parse time, `const`, break/continue with
drop-correct exits, do-while, inline-fn rejection.
- switch expr/stmt: required `default` over scalars/Text, arm unification,
EQ/EQS+JZ lowering, per-arm drop scopes with N-way JOIN-DROP; `default`
sorted last by a shared lowering order (textual order made arms dead).
- typedef records: structural, same shape = one class entry; `?name: T`
nullable-by-shape; emit_ctor fills omitted defaults; `type` as field name.
- Enum variants: all-bare unions = int ordinals; any-payload = one class
entry per variant, tag IS the header class_id (no header field, no format
bump); exhaustive switch without `default`; arity checked both directions.
- Payload escape modeled as move-out (pointer-kind fields only — a scalar
escape is a copy); caller reaps owned heap temps passed by borrow: two
unbounded LSan-blind leaks, 10.5 MB -> 1.5 MB flat over 300k iterations.
- Fixed en route, each with a RED repro: dead E209 builtin-arg check and
`int_to_text` missing from both types.ml builtin tables (both segfaulted
wovm), multi-file phantom double-report, emit_ctor's field temp clobbering
dst in tail position (pre-existing), warnings swallowed without an error.
- Two fenced VM builtins: `int_to_text` (13), `variant_tag` (14).
- 14+565 unit (was 14+401), corpus 71 (was 32) plain and under wovm_asan,
wovm-test + cli_smoke green. Log-watcher 307 -> 93 diagnostics (85 E101 /
4 E207 / 1 E208 / 3 W202); the 5 non-E101 residuals await Task 7 grammar.
159 lines
3.5 KiB
Text
159 lines
3.5 KiB
Text
-- haxe-parity Task 2: break/continue drop-set correctness.
|
|
-- `Big` has 130 Int fields (runtime/test's own malloc-path trick,
|
|
-- test_rc.c's doc comment: field_cnt*8 bytes exceeds the arena's
|
|
-- 1024-byte size-class ceiling, so a missed DROP is a hard ASan leak,
|
|
-- not a silent, unobservable miss). At i == 1, `big` is still live
|
|
-- (never returned or moved) when `break` fires -- this is the DROP
|
|
-- under test: owner.ml's DBreak table entry, emitted at the break site
|
|
-- itself, must destroy it there, not leave it to leak. Verified under
|
|
-- `runtime/build/wovm_asan` (see task-2-report.md for the RED/GREEN
|
|
-- ASan evidence); this fixture's own oop-e2e.sh check (plain wovm)
|
|
-- pins the *output*, not the leak-freedom -- the two are complementary,
|
|
-- not redundant (a correct DROP is also silently correct output-wise;
|
|
-- only ASan's leak checker actually proves the destructor ran).
|
|
class Big {
|
|
f0: Int
|
|
f1: Int
|
|
f2: Int
|
|
f3: Int
|
|
f4: Int
|
|
f5: Int
|
|
f6: Int
|
|
f7: Int
|
|
f8: Int
|
|
f9: Int
|
|
f10: Int
|
|
f11: Int
|
|
f12: Int
|
|
f13: Int
|
|
f14: Int
|
|
f15: Int
|
|
f16: Int
|
|
f17: Int
|
|
f18: Int
|
|
f19: Int
|
|
f20: Int
|
|
f21: Int
|
|
f22: Int
|
|
f23: Int
|
|
f24: Int
|
|
f25: Int
|
|
f26: Int
|
|
f27: Int
|
|
f28: Int
|
|
f29: Int
|
|
f30: Int
|
|
f31: Int
|
|
f32: Int
|
|
f33: Int
|
|
f34: Int
|
|
f35: Int
|
|
f36: Int
|
|
f37: Int
|
|
f38: Int
|
|
f39: Int
|
|
f40: Int
|
|
f41: Int
|
|
f42: Int
|
|
f43: Int
|
|
f44: Int
|
|
f45: Int
|
|
f46: Int
|
|
f47: Int
|
|
f48: Int
|
|
f49: Int
|
|
f50: Int
|
|
f51: Int
|
|
f52: Int
|
|
f53: Int
|
|
f54: Int
|
|
f55: Int
|
|
f56: Int
|
|
f57: Int
|
|
f58: Int
|
|
f59: Int
|
|
f60: Int
|
|
f61: Int
|
|
f62: Int
|
|
f63: Int
|
|
f64: Int
|
|
f65: Int
|
|
f66: Int
|
|
f67: Int
|
|
f68: Int
|
|
f69: Int
|
|
f70: Int
|
|
f71: Int
|
|
f72: Int
|
|
f73: Int
|
|
f74: Int
|
|
f75: Int
|
|
f76: Int
|
|
f77: Int
|
|
f78: Int
|
|
f79: Int
|
|
f80: Int
|
|
f81: Int
|
|
f82: Int
|
|
f83: Int
|
|
f84: Int
|
|
f85: Int
|
|
f86: Int
|
|
f87: Int
|
|
f88: Int
|
|
f89: Int
|
|
f90: Int
|
|
f91: Int
|
|
f92: Int
|
|
f93: Int
|
|
f94: Int
|
|
f95: Int
|
|
f96: Int
|
|
f97: Int
|
|
f98: Int
|
|
f99: Int
|
|
f100: Int
|
|
f101: Int
|
|
f102: Int
|
|
f103: Int
|
|
f104: Int
|
|
f105: Int
|
|
f106: Int
|
|
f107: Int
|
|
f108: Int
|
|
f109: Int
|
|
f110: Int
|
|
f111: Int
|
|
f112: Int
|
|
f113: Int
|
|
f114: Int
|
|
f115: Int
|
|
f116: Int
|
|
f117: Int
|
|
f118: Int
|
|
f119: Int
|
|
f120: Int
|
|
f121: Int
|
|
f122: Int
|
|
f123: Int
|
|
f124: Int
|
|
f125: Int
|
|
f126: Int
|
|
f127: Int
|
|
f128: Int
|
|
f129: Int
|
|
}
|
|
|
|
fn main() -> Int {
|
|
let i = 0
|
|
while i < 3 {
|
|
let big = Big { f0: 1, f1: 1, f2: 1, f3: 1, f4: 1, f5: 1, f6: 1, f7: 1, f8: 1, f9: 1, f10: 1, f11: 1, f12: 1, f13: 1, f14: 1, f15: 1, f16: 1, f17: 1, f18: 1, f19: 1, f20: 1, f21: 1, f22: 1, f23: 1, f24: 1, f25: 1, f26: 1, f27: 1, f28: 1, f29: 1, f30: 1, f31: 1, f32: 1, f33: 1, f34: 1, f35: 1, f36: 1, f37: 1, f38: 1, f39: 1, f40: 1, f41: 1, f42: 1, f43: 1, f44: 1, f45: 1, f46: 1, f47: 1, f48: 1, f49: 1, f50: 1, f51: 1, f52: 1, f53: 1, f54: 1, f55: 1, f56: 1, f57: 1, f58: 1, f59: 1, f60: 1, f61: 1, f62: 1, f63: 1, f64: 1, f65: 1, f66: 1, f67: 1, f68: 1, f69: 1, f70: 1, f71: 1, f72: 1, f73: 1, f74: 1, f75: 1, f76: 1, f77: 1, f78: 1, f79: 1, f80: 1, f81: 1, f82: 1, f83: 1, f84: 1, f85: 1, f86: 1, f87: 1, f88: 1, f89: 1, f90: 1, f91: 1, f92: 1, f93: 1, f94: 1, f95: 1, f96: 1, f97: 1, f98: 1, f99: 1, f100: 1, f101: 1, f102: 1, f103: 1, f104: 1, f105: 1, f106: 1, f107: 1, f108: 1, f109: 1, f110: 1, f111: 1, f112: 1, f113: 1, f114: 1, f115: 1, f116: 1, f117: 1, f118: 1, f119: 1, f120: 1, f121: 1, f122: 1, f123: 1, f124: 1, f125: 1, f126: 1, f127: 1, f128: 1, f129: 1 }
|
|
if i == 1 {
|
|
break
|
|
}
|
|
print_int(big.f0)
|
|
i = i + 1
|
|
}
|
|
print("done")
|
|
return 0
|
|
}
|