wcc/ww: cgtypeassert gains the nullable arm
'as' on a nullable value compared the pointer itself to a tag (the missing arm). Mirror cgtypetest's nullable fold and the cstage twin (cgen.c:10694). Review item #17.
This commit is contained in:
@@ -24019,8 +24019,32 @@ fn cgtypeassert(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
let want: i32 = cgtagvariantidx(c, scrutt, n.rhs);
|
||||
if (want < 0) { want = 0; };
|
||||
let okl: str = mklabel(c, "asrt_ok");
|
||||
// Nullable `(*T | void)`: the slot word IS the pointer, not a tag.
|
||||
// The *T variant asserts non-null, the void variant asserts null;
|
||||
// AX keeps the pointer on the ok path (no slot+8 unwrap — the 8B
|
||||
// nullable slot has no second word). The pre-fix path compared the
|
||||
// POINTER against `want` (so a real pointer aborted, null passed)
|
||||
// and unwrapped a frame word past the slot. `want` stays RAW (no
|
||||
// clamp), mirroring cstage cgen.c N_TYPEASSERT nullable arm and
|
||||
// ww's own cgtypetest nullable fold (cgenexpr.ww). (task #17/F4)
|
||||
if (isnullabletype(scrutt)) {
|
||||
let ptrtag: i32 = nullableptrtag(scrutt);
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff(scrutoff: i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tCMPQ\t$0, AX\n");
|
||||
if (want == ptrtag) {
|
||||
emitline("\tJNE\t");
|
||||
} else {
|
||||
emitline("\tJE\t");
|
||||
};
|
||||
emitline(okl);
|
||||
emitline("\n\tMOVQ\t$1, DI\n\tMOVQ\t$60, AX\n\tSYSCALL\n");
|
||||
emitlabel(okl);
|
||||
return;
|
||||
};
|
||||
if (want < 0) { want = 0; };
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff(scrutoff: i64);
|
||||
emitline("(BP), AX\n");
|
||||
|
||||
@@ -868,8 +868,32 @@ fn cgtypeassert(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
let want: i32 = cgtagvariantidx(c, scrutt, n.rhs);
|
||||
if (want < 0) { want = 0; };
|
||||
let okl: str = mklabel(c, "asrt_ok");
|
||||
// Nullable `(*T | void)`: the slot word IS the pointer, not a tag.
|
||||
// The *T variant asserts non-null, the void variant asserts null;
|
||||
// AX keeps the pointer on the ok path (no slot+8 unwrap — the 8B
|
||||
// nullable slot has no second word). The pre-fix path compared the
|
||||
// POINTER against `want` (so a real pointer aborted, null passed)
|
||||
// and unwrapped a frame word past the slot. `want` stays RAW (no
|
||||
// clamp), mirroring cstage cgen.c N_TYPEASSERT nullable arm and
|
||||
// ww's own cgtypetest nullable fold (cgenexpr.ww). (task #17/F4)
|
||||
if (isnullabletype(scrutt)) {
|
||||
let ptrtag: i32 = nullableptrtag(scrutt);
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff(scrutoff: i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tCMPQ\t$0, AX\n");
|
||||
if (want == ptrtag) {
|
||||
emitline("\tJNE\t");
|
||||
} else {
|
||||
emitline("\tJE\t");
|
||||
};
|
||||
emitline(okl);
|
||||
emitline("\n\tMOVQ\t$1, DI\n\tMOVQ\t$60, AX\n\tSYSCALL\n");
|
||||
emitlabel(okl);
|
||||
return;
|
||||
};
|
||||
if (want < 0) { want = 0; };
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff(scrutoff: i64);
|
||||
emitline("(BP), AX\n");
|
||||
|
||||
@@ -24019,8 +24019,32 @@ fn cgtypeassert(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
let want: i32 = cgtagvariantidx(c, scrutt, n.rhs);
|
||||
if (want < 0) { want = 0; };
|
||||
let okl: str = mklabel(c, "asrt_ok");
|
||||
// Nullable `(*T | void)`: the slot word IS the pointer, not a tag.
|
||||
// The *T variant asserts non-null, the void variant asserts null;
|
||||
// AX keeps the pointer on the ok path (no slot+8 unwrap — the 8B
|
||||
// nullable slot has no second word). The pre-fix path compared the
|
||||
// POINTER against `want` (so a real pointer aborted, null passed)
|
||||
// and unwrapped a frame word past the slot. `want` stays RAW (no
|
||||
// clamp), mirroring cstage cgen.c N_TYPEASSERT nullable arm and
|
||||
// ww's own cgtypetest nullable fold (cgenexpr.ww). (task #17/F4)
|
||||
if (isnullabletype(scrutt)) {
|
||||
let ptrtag: i32 = nullableptrtag(scrutt);
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff(scrutoff: i64);
|
||||
emitline("(BP), AX\n");
|
||||
emitline("\tCMPQ\t$0, AX\n");
|
||||
if (want == ptrtag) {
|
||||
emitline("\tJNE\t");
|
||||
} else {
|
||||
emitline("\tJE\t");
|
||||
};
|
||||
emitline(okl);
|
||||
emitline("\n\tMOVQ\t$1, DI\n\tMOVQ\t$60, AX\n\tSYSCALL\n");
|
||||
emitlabel(okl);
|
||||
return;
|
||||
};
|
||||
if (want < 0) { want = 0; };
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff(scrutoff: i64);
|
||||
emitline("(BP), AX\n");
|
||||
|
||||
Reference in New Issue
Block a user