From db66039dfe6a813e647c4044211890385fc47664 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 20 Apr 2018 23:59:55 +0200 Subject: [PATCH] Implement panic() --- src/runtime/runtime.go | 17 +++++++++++++++++ tgo.go | 12 ++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go index c891641c..944325e7 100644 --- a/src/runtime/runtime.go +++ b/src/runtime/runtime.go @@ -2,6 +2,7 @@ package runtime // #include +// #include import "C" const Compiler = "tgo" @@ -39,3 +40,19 @@ func printspace() { func printnl() { C.putchar('\n') } + +func printitf(msg interface{}) { + switch msg := msg.(type) { + case string: + print(msg) + default: + print("???") + } +} + +func _panic(message interface{}) { + printstring("panic: ") + printitf(message) + printnl() + C.exit(1) +} diff --git a/tgo.go b/tgo.go index ab53ab5d..c2a615e2 100644 --- a/tgo.go +++ b/tgo.go @@ -43,6 +43,7 @@ type Compiler struct { stringType llvm.Type interfaceType llvm.Type typeassertType llvm.Type + panicFunc llvm.Value printstringFunc llvm.Value printintFunc llvm.Value printbyteFunc llvm.Value @@ -97,6 +98,9 @@ func NewCompiler(pkgName, triple string) (*Compiler, error) { // Go typeassert result: tuple of (ptr, bool) c.typeassertType = llvm.StructType([]llvm.Type{llvm.PointerType(llvm.Int8Type(), 0), llvm.Int1Type()}, false) + panicType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.interfaceType}, false) + c.panicFunc = llvm.AddFunction(c.mod, "runtime._panic", panicType) + printstringType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.stringType}, false) c.printstringFunc = llvm.AddFunction(c.mod, "runtime.printstring", printstringType) printintType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.intType}, false) @@ -434,6 +438,14 @@ func (c *Compiler) parseInstr(frame *Frame, instr ssa.Instruction) error { blockJump := frame.blocks[instr.Block().Succs[0]] c.builder.CreateBr(blockJump) return nil + case *ssa.Panic: + value, err := c.parseExpr(frame, instr.X) + if err != nil { + return err + } + c.builder.CreateCall(c.panicFunc, []llvm.Value{value}, "") + c.builder.CreateUnreachable() + return nil case *ssa.Return: if len(instr.Results) == 0 { c.builder.CreateRetVoid()