cgen: load the full header for a wwstage global-dot slice field
let x: []T = g.buf on a module-global struct dispatched only str fields to the 3-word header load; a []T field fell to the scalar tail (ptr word only), so len/cap read stale registers and the shape was byteid-divergent against cstage's TY_STR||TY_SLICE arm (#263).
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
package wwfixture;
|
package wwfixture;
|
||||||
|
|
||||||
def protocolversion: i32 = 1;
|
def protocolversion: i32 = 1;
|
||||||
def corpuscount: i32 = 1229;
|
def corpuscount: i32 = 1230;
|
||||||
def errorcount: i32 = 314;
|
def errorcount: i32 = 314;
|
||||||
def compilecount: i32 = 12;
|
def compilecount: i32 = 12;
|
||||||
def runcount: i32 = 137;
|
def runcount: i32 = 138;
|
||||||
def runexitcount: i32 = 766;
|
def runexitcount: i32 = 766;
|
||||||
def nativecount: i32 = 2458;
|
def nativecount: i32 = 2460;
|
||||||
def corpushash: str = "9d1db4b4bdde1b7e2b1f2e2ae5ca6c6b91b0162df585fd877021d27ec6863d89";
|
def corpushash: str = "fd04059b05a19ae63f1bec3edaefedf1d8ce9a505302a153434457d0fb9b9eca";
|
||||||
|
|
||||||
type directive = enum i32 {
|
type directive = enum i32 {
|
||||||
ERROR = 0,
|
ERROR = 0,
|
||||||
|
|||||||
@@ -4242,7 +4242,12 @@ fn cgdot(c: *cgen, n: *syntax.node) void = {
|
|||||||
cgloadtaggedfield(c, "CX", foff, tsz, true);
|
cgloadtaggedfield(c, "CX", foff, tsz, true);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if (syntax.typeisstr(ftraw)) {
|
// slice joins the str header load (#263: cstage
|
||||||
|
// N_DOT chain arm keys TY_STR||TY_SLICE — the
|
||||||
|
// same 24B {ptr,len,cap}); the scalar tail below
|
||||||
|
// pulled ONLY .ptr, so len(g.buf) read garbage.
|
||||||
|
if (syntax.typeisstr(ftraw)
|
||||||
|
|| syntax.typeisslice(ftraw)) {
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
emitdispreg(foff: i64, "CX");
|
emitdispreg(foff: i64, "CX");
|
||||||
emitline(", AX\n");
|
emitline(", AX\n");
|
||||||
|
|||||||
25
test/wcc/data/globaldot_slicefield_hdr/case.ww
Normal file
25
test/wcc/data/globaldot_slicefield_hdr/case.ww
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//ww:run
|
||||||
|
// A module-global struct's slice field read BY VALUE must load the
|
||||||
|
// full 24B {ptr,len,cap} header. The pre-fix wwstage global-dot arm
|
||||||
|
// dispatched only str fields to the header load; a []T field fell to
|
||||||
|
// the scalar tail (ptr word only) and len(x) read stale registers.
|
||||||
|
package main;
|
||||||
|
|
||||||
|
type box = struct {
|
||||||
|
buf: []i32,
|
||||||
|
name: str,
|
||||||
|
};
|
||||||
|
|
||||||
|
let g: box = box{};
|
||||||
|
|
||||||
|
export fn main() int = {
|
||||||
|
let arr: [4]i32 = [10, 20, 30, 40];
|
||||||
|
g.buf = arr[:];
|
||||||
|
g.name = "globals";
|
||||||
|
let x: []i32 = g.buf;
|
||||||
|
if (len(x) != 4) { return 1; };
|
||||||
|
if (x[2] != 30) { return 2; };
|
||||||
|
let s: str = g.name;
|
||||||
|
if (len(s) != 7) { return 3; };
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user