Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vm: add Unreachable opcode #34

Merged
merged 1 commit into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion passes/pass0.nim
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ proc genExit(c; tree; exit: NodeIndex) =
c.instr(opcPopLocal, tree[exit, 1].id)
c.jump(opcJmp, tree[tree.child(exit, ^2), 0].imm)
of Unreachable:
discard "a no-op"
c.instr(opcUnreachable)
else:
unreachable()

Expand Down
2 changes: 1 addition & 1 deletion tests/pass0/t03_unreachable.expected
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.type t0 (Proc (Void))
.start t0 p0
Ret
Unreachable
.end
4 changes: 1 addition & 3 deletions tests/pass0/t03_unreachable.test
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
discard """
description: "An Unreachable exit translates to nothing"
output: "(Done)"
output: "(Error ecUnreachable)"
"""
(TypeDefs
(ProcTy (Void))
Expand All @@ -11,6 +10,5 @@ discard """
(Continuation (Params) 0
(Unreachable)
)
(Continuation (Params))
))
)
2 changes: 1 addition & 1 deletion vm/assembler.nim
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ proc parseOp(s: Stream, op: Opcode, a: var AssemblerState): Instr =
opcSubFloat, opcMulFloat, opcDivFloat, opcNegFloat, opcEqInt, opcLtInt,
opcLeInt, opcLtu, opcLeu, opcEqFloat, opcLtFloat, opcLeFloat, opcNot,
opcReinterpF32, opcReinterpF64, opcReinterpI32, opcReinterpI64,
opcExcept, opcRaise, opcMemCopy, opcMemClear, opcGrow:
opcExcept, opcUnreachable, opcRaise, opcMemCopy, opcMemClear, opcGrow:
Instr(op) # instruction with no immediate operands
of opcAddImm, opcLdConst, opcLdImmInt, opcOffset,
opcLdInt8, opcLdInt16, opcLdInt32, opcLdInt64, opcLdFlt32, opcLdFlt64,
Expand Down
3 changes: 3 additions & 0 deletions vm/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type
ecIllegalGrow ## improper grow operation
ecTypeError ## type error
ecCallbackError ## a fatal error ocurred within a callback
ecUnreachable ## an 'unreachable' instruction was executed

YieldReasonKind* = enum
yrkDone
Expand Down Expand Up @@ -428,6 +429,8 @@ proc run*(c: var VmEnv, t: var VmThread, cl: RootRef): YieldReason {.raises: [].

of opcExcept:
unreachable() # never executed
of opcUnreachable:
return YieldReason(kind: yrkError, error: ecUnreachable)

of opcStackAlloc:
let next = t.sp + cast[uint32](imm32())
Expand Down
1 change: 1 addition & 0 deletions vm/vmspec.nim
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ type
opcCall ## callee:imm32 num:imm16
opcIndCall ## callee:int typ:imm32 num:imm16
opcExcept ## val:int
opcUnreachable

# memory management
opcStackAlloc ## size:imm32
Expand Down
2 changes: 2 additions & 0 deletions vm/vmvalidation.nim
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ proc run(ctx: var ValidationState, env: VmEnv, pos: PrgCtr, instr: Instr
check not ctx.active, "control-flow reaches 'opcExcept'"
push(vtInt)
ctx.active = true
of opcUnreachable:
ctx.active = false
of opcStackAlloc:
push(vtInt)
of opcStackFree, opcGrow:
Expand Down