Skip to content

Conversation

b-studios
Copy link
Collaborator

When not opimizing core, continuations are not inlined, complicating the direct-style analysis.

For the example in #842, this currently yields:

repro.js:365
  let v_r_0 = undefined;
      ^

SyntaxError: Identifier 'v_r_0' has already been declared

since the generated code looks like this:

function println_0(ans_0, ks_0, k_0) {
  let v_r_0 = undefined;
  let v_r_0 = undefined;
  switch (ans_0.__tag) {
    case 0:  return () => b_k_0(ks_0);
    case 1:  break;
  }
  const v_r_1 = $effekt.println("n");
  v_r_0 = v_r_1;
  return () => k_0(v_r_0, ks_0);
  const v_r_2 = $effekt.println("y");
  v_r_0 = v_r_2;
  return () => k_0(v_r_0, ks_0);
}

Disabling the direct style optimization by commenting out this

case cps.Stmt.LetCont(id, Cont.ContLam(params, ks, body), body2) if canBeDirect(id, body2) =>
Binding { k =>
params.map { p => js.Let(nameDef(p), js.Undefined) } :::
toJS(body2)(using markDirectStyle(id, params, ks)).stmts ++
toJS(maintainDirectStyle(ks, body)).run(k)
}

resolves the issue, but is slow.

@b-studios
Copy link
Collaborator Author

This is the CPS IR for println

let k3755 = { (v_r_27793745) | ks3756 =>
  jump k3754(v_r_27793745) @ ks3756
}
let b_k_27763741 = { () | ks3757 =>
  let v_r_27753743 = println1("y")
  jump k3755(v_r_27753743) @ ks3757
}
let k3753 = { (v_r_27793745) | ks3758 =>
  jump k3754(v_r_27793745) @ ks3758
}
let b_k_27783742 = { () | ks3759 =>
  let v_r_27773744 = println1("n")
  jump k3753(v_r_27773744) @ ks3759
}
ans2747 match {
  case Yes2753 () => {
    jump b_k_27763741() @ ks3760
  }
  case No2754 () => {
    jump b_k_27783742() @ ks3760
  }
}

which it believes is direct style in k3755.

@b-studios
Copy link
Collaborator Author

It also suffices to make the rhs of this

case Stmt.Jump(k2, vargs, ks2) => vargs.forall(notIn)

to always return false, which effectively requires all branches to return to the same continuation. This again might be too conservative since under certain conditions we can convert a program to direct style (for the fast path), but still keep non-local jumps to other continuations.

Comment on lines -253 to +256
stmts.last match {
case terminator : (js.Stmt.Return | js.Stmt.Break | js.Stmt.Continue) => (e, stmts)
stmts.lastOption match {
case Some(terminator : (js.Stmt.Return | js.Stmt.Break | js.Stmt.Continue)) => (e, stmts)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh this already fixed #842...

b-studios added a commit that referenced this pull request Mar 11, 2025
This PR fixes #861 by not contifying under reset. 

It also adds a pretty printer as a drive-by for easier debugging (the
one from #843).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant