While I was porting apps from Imba 1 to Imba 2 I encountered a bug in Imba 2, but I was too busy to deal with it. Let's take a step back, try to reproduce a bug with minimal case, and then submit it.
The Bug
The bug was that when I'd put debugger
statement in the code, depending on where it was, Imba would stack overflow.
Getting to replication
I don't remember which apps had this issue, so I'll try it first with imba2-game-of-life
. Fortunately if it works I won't even need to run it, it will be obvious on the terminal.
So I opened client.imba
and started adding debugger
in various places.
It took zero time to get a crash, in any function where I use it after a block, here's an example:
def countNeighbours(cells, x, y)
let count = 0
for cell of cells
if !cell.state
continue
let dx = Math.abs(cell.x - x)
let dy = Math.abs(cell.y - y)
if Math.max(dx, dy) == 1
count += 1
count
def runStep(cells)
let nextCells = []
for cell of cells
let n = countNeighbours(cells, cell.x, cell.y)
let nextState = (n == 3 || (cell.state && n == 2))
nextCells.push({x: cell.x, y: cell.y, state: nextState})
nextCells
tag cell
prop data
def onclick
data.state = !data.state
emit("pause")
def render
let visualStartX = 20 * data.x + 1
let visualStartY = 20 * data.y + 1
<self[left:{visualStartX}px top:{visualStartY}px] .alive=(data.state) .dead=(!data.state) @click.onclick>
css
position: absolute
width: 18px
height: 18px
&.dead
background-color: #864
&.alive
background-color: #3f3
tag app
prop cells
prop playing = true
def setup
let sizex = 30
let sizey = 30
cells = []
for x in [0 ... sizex]
for y in [0 ... sizey]
cells.push({ x: x, y: y, state: Math.random() < 0.2 })
def step
cells = runStep(cells)
def mount
imba.setInterval(&,100) do
if playing
step()
debugger
def play
playing = true
def pause
playing = false
def render
<self>
<header>
"Game of Life"
<div.board>
for cell in cells
<cell data=cell @pause.pause>
<div.buttons>
if playing
<button @click.pause>
"Pause"
else
<button @click.step>
"Step"
<button @click.play>
"Play"
css
header
font-size: 64px
text-align: center
.board
position: relative
height: 600px
width: 600px
background-color: #aaa
margin: auto
.buttons
text-align: center
button
margin: 0.5em
imba.mount <app>
And error message in the terminal:
ERROR COMPILING IMBA RangeError: Maximum call stack size exceeded
at Yp.J.consume (~/imba2-game-of-life/node_modules/imba/compiler.imba.js:79:11138)
at Qe.c (~/imba2-game-of-life/node_modules/imba/compiler.imba.js:88:4768)
at Qe.c (~/imba2-game-of-life/node_modules/imba/compiler.imba.js:88:4782)
at Qe.c (~/imba2-game-of-life/node_modules/imba/compiler.imba.js:88:4782)
at Qe.c (~/imba2-game-of-life/node_modules/imba/compiler.imba.js:88:4782)
at Qe.c (~/imba2-game-of-life/node_modules/imba/compiler.imba.js:88:4782)
at Qe.c (~/imba2-game-of-life/node_modules/imba/compiler.imba.js:88:4782)
at Qe.c (~/imba2-game-of-life/node_modules/imba/compiler.imba.js:88:4782)
at Qe.c (~/imba2-game-of-life/node_modules/imba/compiler.imba.js:88:4782)
at Qe.c (~/imba2-game-of-life/node_modules/imba/compiler.imba.js:88:4782) app/client.imba
Removing irrelevant parts
OK, we don't need an app, we just need a clear test case. So time to remove all extra stuff. And step by step, after each one verifying that the crash is still there, I arrived at this:
def foo
debugger
Even that causes the same crash.
Exploring other ways to trigger the bug
OK, so right now a debugger
at the end of the method crashes Imba compiler. But I'm pretty sure I saw this in other contexts too.
Looks like putting debugger
at end of a block also does it:
def foo
imba.setInterval(&,1000) do
debugger
I think I saw this happen in some other contexts, but I can't reproduce it right now. So maybe I'm misremembering, and possibly a fix for this would also deal with more complex cases anyway.
Time to submit a bug
Next step is to go to GitHub issues for Imba and do a search for debugger
. It doesn't look like it was reported before, so time to submit it.
As usual, I deleted the pre-made template, as I find them more annoying than useful. So here's the bug report.
In retrospect I should have saved the failing code as I was coding, even if I didn't have time to write a bug report.
Coming next
In the next episode I'll give some thoughts about Imba 2.
Top comments (0)