Skip to content

TranformerCPS mutable variable capture bug #1229

@dvdvgt

Description

@dvdvgt

Consider the following program

def motz(n: Int): Int = {
  if (n <= 1) {
    1
  } else {
    val limit = n - 2
    def product(i: Int): Int = {
      motz(i) * motz(limit - i)
    }
    motz(n - 1) + sum(0, limit) { product }
  }
}

which is translated to

function motz_0(n_23, ks_1706, k_937) {
  motz_1: while (true) {
    if ((n_23 <= (1))) {
      return () => k_937(1, ks_1706);
    } else {
      function product_2(i_45, ks_1707, k_938) {
        return motz_0(i_45, ks_1707, (v_r_846, ks_1708) =>
          motz_0((((n_23 - (2))) - i_45), ks_1708, (v_r_847, ks_1709) =>
            () => k_938((v_r_846 * v_r_847), ks_1709)));
      }
      /* prepare call */
      const tmp_n_1 = n_23;
      const tmp_k_6 = k_937;
      k_937 = (v_r_848, ks_1710) =>
        sum_4(0, (tmp_n_1 - (2)), product_2, ks_1710, (v_r_849, ks_1711) =>
          () => tmp_k_6((v_r_848 + v_r_849), ks_1711));
      n_23 = (tmp_n_1 - (1));
      continue motz_1;
    }
  }
}

if not using optimizations (no-optimize). When the continuation k_937 is overwritten, we call sum_4 and correctly rename n to tmp_n_1. However, in product_2 we still use n_23 which is mutated before the continuation is called, altering the semantics.

Doing this correctly might be difficult since by the time we apply the substitution, the binding product_2 has already been introduced and is not considered anymore.

(this issue has been split off from #1200)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:jsbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions