Rearrange cgen temporary assignment for =?
diff --git a/internal/cgen/statement.go b/internal/cgen/statement.go
index 9e96cfe..d0252aa 100644
--- a/internal/cgen/statement.go
+++ b/internal/cgen/statement.go
@@ -81,28 +81,49 @@
}
depth++
- hack, err := g.writeStatementAssign0(b, op, lhs, rhs)
- if err != nil {
- return err
+ needWriteLoadExprDerivedVars := false
+ if (len(g.currFunk.derivedVars) > 0) &&
+ (rhs.Operator() == t.IDOpenParen) {
+ method := rhs.LHS().AsExpr()
+ recvTyp := method.LHS().MType().Pointee()
+ if (recvTyp.Decorator() == 0) && (recvTyp.QID()[0] != t.IDBase) {
+ n := len(*b)
+ if err := g.writeSaveExprDerivedVars(b, rhs); err != nil {
+ return err
+ }
+ needWriteLoadExprDerivedVars = n != len(*b)
+ }
}
+
+ couldSuspend := false
+ if err := g.writeBuiltinQuestionCall(b, rhs, 0); err == nil {
+ // No-op.
+ } else if err != errNoSuchBuiltin {
+ return err
+ } else {
+ if _, err := g.writeStatementAssign0(b, op, lhs, rhs); err != nil {
+ return err
+ }
+ couldSuspend = (op != t.IDEqQuestion) && rhs.Effect().Coroutine()
+ }
+
if lhs != nil {
if err := g.writeStatementAssign1(b, op, lhs, rhs); err != nil {
return err
}
}
- if hack {
+ if needWriteLoadExprDerivedVars {
if err := g.writeLoadExprDerivedVars(b, rhs); err != nil {
return err
}
}
+ if couldSuspend {
+ b.writes("if (status.repr) {\ngoto suspend;\n}\n")
+ }
return nil
}
func (g *gen) writeStatementAssign0(b *buffer, op t.ID, lhs *a.Expr, rhs *a.Expr) (bool, error) {
- if err := g.writeBuiltinQuestionCall(b, rhs, 0); err != errNoSuchBuiltin {
- return false, err
- }
-
doWork, hack := (lhs == nil) || rhs.Effect().Coroutine(), false
if !doWork && (rhs.Operator() == t.IDOpenParen) && (len(g.currFunk.derivedVars) > 0) {
// TODO: tighten this heuristic for filtering out all but user-defined
@@ -129,10 +150,6 @@
}
if doWork {
- if err := g.writeSaveExprDerivedVars(b, rhs); err != nil {
- return false, err
- }
-
if op == t.IDEqQuestion {
if g.currFunk.tempW > maxTemp {
return false, fmt.Errorf("too many temporary variables required")
@@ -153,14 +170,6 @@
return false, err
}
b.writes(";\n")
-
- if err := g.writeLoadExprDerivedVars(b, rhs); err != nil {
- return false, err
- }
- }
-
- if op != t.IDEqQuestion && rhs.Effect().Coroutine() {
- b.writes("if (status.repr) {\ngoto suspend;\n}\n")
}
}
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index b446d4b..1ab7a05 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -18448,10 +18448,10 @@
a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
}
wuffs_base__status t_0 = wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src);
+ v_status = t_0;
if (a_dst) {
iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
}
- v_status = t_0;
}
if ( ! wuffs_base__status__is_suspension(&v_status)) {
status = v_status;
@@ -24726,8 +24726,8 @@
{
u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
wuffs_base__status t_1 = wuffs_lzw__decoder__transform_io(&self->private_data.f_lzw, &empty_io_buffer, v_r, wuffs_base__utility__empty_slice_u8());
- iop_v_r = u_r.data.ptr + u_r.meta.ri;
v_lzw_status = t_1;
+ iop_v_r = u_r.data.ptr + u_r.meta.ri;
}
wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_ri, wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_v_r - io0_v_r))));
v_r = o_0_v_r;
@@ -25327,13 +25327,13 @@
a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
}
wuffs_base__status t_7 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
+ v_status = t_7;
if (a_dst) {
iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
}
if (a_src) {
iop_a_src = a_src->data.ptr + a_src->meta.ri;
}
- v_status = t_7;
}
if ( ! self->private_impl.f_ignore_checksum) {
v_checksum_got = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
@@ -28849,13 +28849,13 @@
a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
}
wuffs_base__status t_2 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
+ v_status = t_2;
if (a_dst) {
iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
}
if (a_src) {
iop_a_src = a_src->data.ptr + a_src->meta.ri;
}
- v_status = t_2;
}
if ( ! self->private_impl.f_ignore_checksum) {
v_checksum_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));