@@ -197,8 +197,7 @@ object Evaluator {
197197 stack : List [Value ],
198198 frame : Frame ,
199199 kont : Cont [Ans ],
200- trail : List [Cont [Ans ]],
201- ret : Int ): Ans = {
200+ trail : List [Cont [Ans ]]): Ans = {
202201 if (insts.isEmpty) return kont(stack)
203202
204203 val inst = insts.head
@@ -207,23 +206,23 @@ object Evaluator {
207206 // println(s"inst: ${inst} \t | ${frame.locals} | ${stack.reverse}" )
208207
209208 inst match {
210- case Drop => eval(rest, stack.tail, frame, kont, trail, ret )
209+ case Drop => eval(rest, stack.tail, frame, kont, trail)
211210 case Select (_) =>
212211 val I32V (cond) :: v2 :: v1 :: newStack = stack
213212 val value = if (cond == 0 ) v1 else v2
214- eval(rest, value :: newStack, frame, kont, trail, ret )
213+ eval(rest, value :: newStack, frame, kont, trail)
215214 case LocalGet (i) =>
216- eval(rest, frame.locals(i) :: stack, frame, kont, trail, ret )
215+ eval(rest, frame.locals(i) :: stack, frame, kont, trail)
217216 case LocalSet (i) =>
218217 val value :: newStack = stack
219218 frame.locals(i) = value
220- eval(rest, newStack, frame, kont, trail, ret )
219+ eval(rest, newStack, frame, kont, trail)
221220 case LocalTee (i) =>
222221 val value :: newStack = stack
223222 frame.locals(i) = value
224- eval(rest, stack, frame, kont, trail, ret )
223+ eval(rest, stack, frame, kont, trail)
225224 case GlobalGet (i) =>
226- eval(rest, frame.module.globals(i).value :: stack, frame, kont, trail, ret )
225+ eval(rest, frame.module.globals(i).value :: stack, frame, kont, trail)
227226 case GlobalSet (i) =>
228227 val value :: newStack = stack
229228 frame.module.globals(i).ty match {
@@ -232,112 +231,112 @@ object Evaluator {
232231 case GlobalType (_, true ) => throw new Exception (" Invalid type" )
233232 case _ => throw new Exception (" Cannot set immutable global" )
234233 }
235- eval(rest, newStack, frame, kont, trail, ret )
234+ eval(rest, newStack, frame, kont, trail)
236235 case MemorySize =>
237- eval(rest, I32V (frame.module.memory.head.size) :: stack, frame, kont, trail, ret )
236+ eval(rest, I32V (frame.module.memory.head.size) :: stack, frame, kont, trail)
238237 case MemoryGrow =>
239238 val I32V (delta) :: newStack = stack
240239 val mem = frame.module.memory.head
241240 val oldSize = mem.size
242241 mem.grow(delta) match {
243242 case Some (e) =>
244- eval(rest, I32V (- 1 ) :: newStack, frame, kont, trail, ret )
243+ eval(rest, I32V (- 1 ) :: newStack, frame, kont, trail)
245244 case _ =>
246- eval(rest, I32V (oldSize) :: newStack, frame, kont, trail, ret )
245+ eval(rest, I32V (oldSize) :: newStack, frame, kont, trail)
247246 }
248247 case MemoryFill =>
249248 val I32V (value) :: I32V (offset) :: I32V (size) :: newStack = stack
250249 if (memOutOfBound(frame, 0 , offset, size))
251250 throw new Exception (" Out of bounds memory access" ) // GW: turn this into a `trap`?
252251 else {
253252 frame.module.memory.head.fill(offset, size, value.toByte)
254- eval(rest, newStack, frame, kont, trail, ret )
253+ eval(rest, newStack, frame, kont, trail)
255254 }
256255 case MemoryCopy =>
257256 val I32V (n) :: I32V (src) :: I32V (dest) :: newStack = stack
258257 if (memOutOfBound(frame, 0 , src, n) || memOutOfBound(frame, 0 , dest, n))
259258 throw new Exception (" Out of bounds memory access" )
260259 else {
261260 frame.module.memory.head.copy(dest, src, n)
262- eval(rest, newStack, frame, kont, trail, ret )
261+ eval(rest, newStack, frame, kont, trail)
263262 }
264- case Const (n) => eval(rest, n :: stack, frame, kont, trail, ret )
263+ case Const (n) => eval(rest, n :: stack, frame, kont, trail)
265264 case Binary (op) =>
266265 val v2 :: v1 :: newStack = stack
267- eval(rest, evalBinOp(op, v1, v2) :: newStack, frame, kont, trail, ret )
266+ eval(rest, evalBinOp(op, v1, v2) :: newStack, frame, kont, trail)
268267 case Unary (op) =>
269268 val v :: newStack = stack
270- eval(rest, evalUnaryOp(op, v) :: newStack, frame, kont, trail, ret )
269+ eval(rest, evalUnaryOp(op, v) :: newStack, frame, kont, trail)
271270 case Compare (op) =>
272271 val v2 :: v1 :: newStack = stack
273- eval(rest, evalRelOp(op, v1, v2) :: newStack, frame, kont, trail, ret )
272+ eval(rest, evalRelOp(op, v1, v2) :: newStack, frame, kont, trail)
274273 case Test (op) =>
275274 val v :: newStack = stack
276- eval(rest, evalTestOp(op, v) :: newStack, frame, kont, trail, ret )
275+ eval(rest, evalTestOp(op, v) :: newStack, frame, kont, trail)
277276 case Store (StoreOp (align, offset, ty, None )) =>
278277 val I32V (v) :: I32V (addr) :: newStack = stack
279278 frame.module.memory(0 ).storeInt(addr + offset, v)
280- eval(rest, newStack, frame, kont, trail, ret )
279+ eval(rest, newStack, frame, kont, trail)
281280 case Load (LoadOp (align, offset, ty, None , None )) =>
282281 val I32V (addr) :: newStack = stack
283282 val value = frame.module.memory(0 ).loadInt(addr + offset)
284- eval(rest, I32V (value) :: newStack, frame, kont, trail, ret )
283+ eval(rest, I32V (value) :: newStack, frame, kont, trail)
285284 case Nop =>
286- eval(rest, stack, frame, kont, trail, ret )
285+ eval(rest, stack, frame, kont, trail)
287286 case Unreachable => throw Trap ()
288287 case Block (ty, inner) =>
289288 val funcTy = getFuncType(frame.module, ty)
290289 val (inputs, restStack) = stack.splitAt(funcTy.inps.size)
291290 val restK : Cont [Ans ] = (retStack) =>
292- eval(rest, retStack.take(funcTy.out.size) ++ restStack, frame, kont, trail, ret )
293- eval(inner, inputs, frame, restK, restK :: trail, ret + 1 )
291+ eval(rest, retStack.take(funcTy.out.size) ++ restStack, frame, kont, trail)
292+ eval(inner, inputs, frame, restK, restK :: trail)
294293 case Loop (ty, inner) =>
295294 // We construct two continuations, one for the break (to the begining of the loop),
296295 // and one for fall-through to the next instruction following the syntactic structure
297296 // of the program.
298297 val funcTy = getFuncType(frame.module, ty)
299298 val (inputs, restStack) = stack.splitAt(funcTy.inps.size)
300299 val restK : Cont [Ans ] = (retStack) =>
301- eval(rest, retStack.take(funcTy.out.size) ++ restStack, frame, kont, trail, ret )
300+ eval(rest, retStack.take(funcTy.out.size) ++ restStack, frame, kont, trail)
302301 def loop (retStack : List [Value ]): Ans =
303- eval(inner, retStack.take(funcTy.inps.size), frame, restK, loop _ :: trail, ret + 1 )
302+ eval(inner, retStack.take(funcTy.inps.size), frame, restK, loop _ :: trail)
304303 loop(inputs)
305304 case If (ty, thn, els) =>
306305 val funcTy = getFuncType(frame.module, ty)
307306 val I32V (cond) :: newStack = stack
308307 val inner = if (cond != 0 ) thn else els
309308 val (inputs, restStack) = newStack.splitAt(funcTy.inps.size)
310309 val restK : Cont [Ans ] = (retStack) =>
311- eval(rest, retStack.take(funcTy.out.size) ++ restStack, frame, kont, trail, ret )
312- eval(inner, inputs, frame, restK, restK :: trail, ret + 1 )
310+ eval(rest, retStack.take(funcTy.out.size) ++ restStack, frame, kont, trail)
311+ eval(inner, inputs, frame, restK, restK :: trail)
313312 case Br (label) =>
314313 trail(label)(stack)
315314 case BrIf (label) =>
316315 val I32V (cond) :: newStack = stack
317316 if (cond != 0 ) trail(label)(newStack)
318- else eval(rest, newStack, frame, kont, trail, ret )
317+ else eval(rest, newStack, frame, kont, trail)
319318 case BrTable (labels, default) =>
320319 val I32V (cond) :: newStack = stack
321320 val goto = if (cond < labels.length) labels(cond) else default
322321 trail(goto)(newStack)
323- case Return => trail(ret) (stack)
322+ case Return => trail.last (stack)
324323 case Call (f) if frame.module.funcs(f).isInstanceOf [FuncDef ] =>
325324 val FuncDef (_, FuncBodyDef (ty, _, locals, body)) = frame.module.funcs(f)
326325 val args = stack.take(ty.inps.size).reverse
327326 val newStack = stack.drop(ty.inps.size)
328327 val frameLocals = args ++ locals.map(zero(_))
329328 val newFrame = Frame (frame.module, ArrayBuffer (frameLocals : _* ))
330- val newK : Cont [Ans ] = (retStack) => eval(rest, retStack.take(ty.out.size) ++ newStack, frame, kont, trail, ret )
329+ val newK : Cont [Ans ] = (retStack) => eval(rest, retStack.take(ty.out.size) ++ newStack, frame, kont, trail)
331330 // We push newK on the trail since function creates a new block to escape
332331 // (more or less like `return`)
333- eval(body, List (), newFrame, newK, List (newK), 0 )
332+ eval(body, List (), newFrame, newK, List (newK))
334333 case Call (f) if frame.module.funcs(f).isInstanceOf [Import ] =>
335334 frame.module.funcs(f) match {
336335 case Import (" console" , " log" , _) =>
337336 // println(s"[DEBUG] current stack: $stack")
338337 val I32V (v) :: newStack = stack
339338 println(v)
340- eval(rest, newStack, frame, kont, trail, ret )
339+ eval(rest, newStack, frame, kont, trail)
341340 case f => throw new Exception (s " Unknown import $f" )
342341 }
343342 case _ =>
@@ -404,7 +403,7 @@ object Evaluator {
404403
405404 val moduleInst = ModuleInstance (types, module.funcEnv, memory, globals)
406405
407- Evaluator .eval(instrs, List (), Frame (moduleInst, ArrayBuffer (I32V (0 ))), halt, List (halt), 0 )
406+ Evaluator .eval(instrs, List (), Frame (moduleInst, ArrayBuffer (I32V (0 ))), halt, List (halt))
408407 }
409408
410409 def evalTop (m : Module ): Unit = evalTop(m, stack => ())
0 commit comments