Implement panic()
Этот коммит содержится в:
родитель
d812873e60
коммит
db66039dfe
2 изменённых файлов: 29 добавлений и 0 удалений
|
@ -2,6 +2,7 @@
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
// #include <stdio.h>
|
// #include <stdio.h>
|
||||||
|
// #include <stdlib.h>
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
const Compiler = "tgo"
|
const Compiler = "tgo"
|
||||||
|
@ -39,3 +40,19 @@ func printspace() {
|
||||||
func printnl() {
|
func printnl() {
|
||||||
C.putchar('\n')
|
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)
|
||||||
|
}
|
||||||
|
|
12
tgo.go
12
tgo.go
|
@ -43,6 +43,7 @@ type Compiler struct {
|
||||||
stringType llvm.Type
|
stringType llvm.Type
|
||||||
interfaceType llvm.Type
|
interfaceType llvm.Type
|
||||||
typeassertType llvm.Type
|
typeassertType llvm.Type
|
||||||
|
panicFunc llvm.Value
|
||||||
printstringFunc llvm.Value
|
printstringFunc llvm.Value
|
||||||
printintFunc llvm.Value
|
printintFunc llvm.Value
|
||||||
printbyteFunc llvm.Value
|
printbyteFunc llvm.Value
|
||||||
|
@ -97,6 +98,9 @@ func NewCompiler(pkgName, triple string) (*Compiler, error) {
|
||||||
// Go typeassert result: tuple of (ptr, bool)
|
// Go typeassert result: tuple of (ptr, bool)
|
||||||
c.typeassertType = llvm.StructType([]llvm.Type{llvm.PointerType(llvm.Int8Type(), 0), llvm.Int1Type()}, false)
|
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)
|
printstringType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.stringType}, false)
|
||||||
c.printstringFunc = llvm.AddFunction(c.mod, "runtime.printstring", printstringType)
|
c.printstringFunc = llvm.AddFunction(c.mod, "runtime.printstring", printstringType)
|
||||||
printintType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.intType}, false)
|
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]]
|
blockJump := frame.blocks[instr.Block().Succs[0]]
|
||||||
c.builder.CreateBr(blockJump)
|
c.builder.CreateBr(blockJump)
|
||||||
return nil
|
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:
|
case *ssa.Return:
|
||||||
if len(instr.Results) == 0 {
|
if len(instr.Results) == 0 {
|
||||||
c.builder.CreateRetVoid()
|
c.builder.CreateRetVoid()
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче