Skip to content

Commit

Permalink
some tweaks, no impl for fx yet
Browse files Browse the repository at this point in the history
  • Loading branch information
ahuoguo committed Nov 20, 2024
1 parent 93a4464 commit 0607ac9
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 42 deletions.
6 changes: 3 additions & 3 deletions src/main/scala/wasm/AST.scala
Original file line number Diff line number Diff line change
Expand Up @@ -328,9 +328,9 @@ case class RefFuncV(funcAddr: Int) extends Ref {
}
}
// RefContV refers to a delimited continuation
case class RefContV(cont: List[Value] => List[Value]) extends Ref {
def tipe(implicit m: ModuleInstance): ValueType = ???
}
// case class RefContV(cont: List[Value] => List[Value]) extends Ref {
// def tipe(implicit m: ModuleInstance): ValueType = ???
// }
case class RefExternV(externAddr: Int) extends Ref {
def tipe(implicit m: ModuleInstance): ValueType = ???
}
Expand Down
17 changes: 14 additions & 3 deletions src/main/scala/wasm/MiniWasm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ case class Trap() extends Exception

case class ModuleInstance(
defs: List[Definition],
types: List[FuncType],
types: List[FuncLikeType],
tags: List[FuncType],
funcs: HashMap[Int, Callable],
memory: List[RTMemory] = List(RTMemory()),
globals: List[RTGlobal] = List(),
Expand All @@ -21,7 +22,17 @@ case class ModuleInstance(

object ModuleInstance {
def apply(module: Module): ModuleInstance = {
val types = List()
val types = module.definitions
.collect({
case TypeDef(_, ft) => ft
})
.toList
val tags = module.definitions
.collect({
case Tag(id, ty) => ty
})
.toList

val funcs = module.definitions
.collect({
case FuncDef(_, fndef @ FuncBodyDef(_, _, _, _)) => fndef
Expand Down Expand Up @@ -53,7 +64,7 @@ object ModuleInstance {
})
.toList

ModuleInstance(module.definitions, types, module.funcEnv, memory, globals, exports)
ModuleInstance(module.definitions, types, tags, module.funcEnv, memory, globals, exports)
}
}

Expand Down
93 changes: 57 additions & 36 deletions src/main/scala/wasm/MiniWasmFX.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ case class EvaluatorFX(module: ModuleInstance) {
val inst = insts.head
val rest = insts.tail

// TODO: uncommenting this will fail try-catch
// println(s"inst: ${inst} \t | ${frame.locals} | ${stack.reverse}" )

inst match {
Expand Down Expand Up @@ -195,30 +196,13 @@ case class EvaluatorFX(module: ModuleInstance) {
case Return => trail.last(stack, mkont)
case Call(f) => evalCall(f, rest, stack, frame, kont, mkont, trail, h, false)
case ReturnCall(f) => evalCall(f, rest, stack, frame, kont, mkont, trail, h, true)
// XXX (GW): consider implementing call_ref too
case RefFunc(f) =>
// TODO: RefFuncV stores an applicable function, instead of a syntactic structure
eval(rest, RefFuncV(f) :: stack, frame, kont, mkont, trail, h)
case ContNew(ty) =>
// val RefFuncV(f) :: newStack = stack
// DH(calling for a review):
// create a function works like a delimited continuation,
// but it's still a function in essensial, make our interpreter not in pure CPS
// val cont: List[Value] => List[Value] =
// (stack) => evalCall(List(), stack, frame, (s) => s, List(), f, false)
// eval(rest, RefContV(cont) :: newStack, frame, kont, trail)
throw new Exception("Unimplemented")
// TODO: implement the following
// case Suspend(tag_id) => {
// println(s"${RED}Unimplimented Suspending tag $tag_id")
// eval(rest, stack, frame, kont, trail)
// }

// TODO: resume should create a list of handlers to capture suspend
// TODO: The current implementation doesn't not deal with suspend at all
case CallRef(ty) =>
val RefFuncV(f) :: newStack = stack
evalCall(f, rest, newStack, frame, kont, mkont, trail, h, false)

// resumable try-catch exception handling:
case TryCatch(es1, es2) =>
val join: MCont[Ans] = (newStack) => eval(rest, stack, frame, kont, mkont, trail, h)
Expand All @@ -242,29 +226,61 @@ case class EvaluatorFX(module: ModuleInstance) {
eval(rest, newStack/*!*/, frame, kontK, m/*vs mkont?*/, trail, h)
}
h(List(err, TCContV(kr)))
// XXX (GW): consider implementing call_ref too
case RefFunc(f) =>
// TODO: RefFuncV stores an applicable function, instead of a syntactic structure
eval(rest, RefFuncV(f) :: stack, frame, kont, mkont, trail, h)

// WasmFX effect handlers:
case ContNew(ty) =>
val RefFuncV(f) :: newStack = stack
// DH(calling for a review):
// create a function works like a delimited continuation,
// but it's still a function in essensial, make our interpreter not in pure CPS
// val cont: List[Value] => List[Value] =
// (stack) => evalCall(f, List(), stack, frame, mkont, (s) => s, List(), h, false)
// eval(rest, RefContV(cont) :: newStack, frame, kont, mkont, trail, h)
throw new Exception("Unimplemented")
// should be similar to the contiuantion thrown by `throw`

// TODO: what is the justification for idK here?
val idK: Cont[Ans] = (s, m) => m(s)
// val k: Cont[Ans] = (s, mk) => evalCall(f, List(), s, frame, idK, mk, trail, h, false)

def kr(s: Stack, k1: Cont[Ans], mk: MCont[Ans]): Ans = {
val kontK: Cont[Ans] = (s1, m1) => kont(s1, s2 => k1(s2, m1))
eval(rest, s, frame, kontK, mk, trail, h)
}

eval(rest, TCContV(kr) :: newStack, frame, kont, mkont, trail, h)
// TODO: implement the following
// case Suspend(tag_id) => {
// println(s"${RED}Unimplimented Suspending tag $tag_id")
// eval(rest, stack, frame, kont, trail)
// }
case Suspend(tag_id) => {
// println(s"${RED}Unimplimented Suspending tag $tag_id")
// eval(rest, stack, frame, kont, mkont, trail, h)
h(stack)
}

// TODO: resume should create a list of handlers to capture suspend
// TODO: The current implementation doesn't not deal with suspend at all
case Resume(ty, _handlers) => {
val RefContV(cont) :: newStack = stack
case Resume(kty_id, handler) => {
val (resume: TCContV[Ans]) :: newStack = stack
val contTy = module.types(kty_id)
val ContType(funcTypeId) = contTy
val FuncType(_, inps, out) = module.types(funcTypeId)
val (inputs, restStack) = newStack.splitAt(inps.size)

if (handler.length == 0) {
val k: Cont[Ans] = (s, m) => eval(rest, newStack, frame, kont, m, trail, h)
resume.k(inputs, k, mkont)
} else {

handler(0) match {
case Handler(tag_id, hanblk) => {
val newHandler: Handler[Ans] = (newStack) => {
// TODO: make sure this hanblk id is actually in the scope of resume
trail(hanblk)(newStack, mkont)
}
val m: MCont[Ans] = (s) => eval(rest, s ++ restStack, frame, kont, mkont, trail, h)
resume.k(inputs, kont, m)
}
}

}

// val newEhs: List[(Int, Handler[Ans])] = handlers.map {
// case Handler(tag_id, handler) => (tag_id, (s) => trail(handler)(s, ehs, mkont))
// }
// resume with new effect handlers installed each time

// val cont = module.funcs(contAddr) match {
// case FuncDef(_, f) => f
// case _ => throw new Exception("Continuation is not a function")
Expand All @@ -281,7 +297,6 @@ case class EvaluatorFX(module: ModuleInstance) {
// }

// val (inputs, restStack) = newStack.splitAt(inps.size)
throw new Exception("Unimplemented")
// val restK: Cont[Ans] = (retStack) =>
// eval(rest, retStack.take(out.size) ++ restStack, frame, kont, mkont, trail, h)
// // DH(calling for a review): Here introduce a mix between direct-style and cps
Expand All @@ -303,6 +318,12 @@ case class EvaluatorFX(module: ModuleInstance) {
// // TODO: finish this



case CallRef(ty) =>
val RefFuncV(f) :: newStack = stack
evalCall(f, rest, newStack, frame, kont, mkont, trail, h, false)


case CallRef(ty) =>
val RefFuncV(f) :: newStack = stack
evalCall(f, rest, newStack, frame, kont, mkont, trail, h, false)
Expand Down

0 comments on commit 0607ac9

Please sign in to comment.