From b0cb51bdd875dfb895b1d6d39a33a825d3652291 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 3 May 2018 21:15:29 +0200 Subject: [PATCH] compiler: Do not pre-define runtime functions by the compiler --- tgo.go | 59 ++++++++++++++++------------------------------------------ 1 file changed, 16 insertions(+), 43 deletions(-) diff --git a/tgo.go b/tgo.go index d4586b29..5a6aa8cc 100644 --- a/tgo.go +++ b/tgo.go @@ -43,16 +43,6 @@ type Compiler struct { stringType llvm.Type interfaceType llvm.Type typeassertType llvm.Type - panicFunc llvm.Value - boundsCheckFunc llvm.Value - printstringFunc llvm.Value - printint32Func llvm.Value - printuint32Func llvm.Value - printint64Func llvm.Value - printuint64Func llvm.Value - printbyteFunc llvm.Value - printspaceFunc llvm.Value - printnlFunc llvm.Value itfTypeNumbers map[types.Type]uint64 itfTypes []types.Type initFuncs []llvm.Value @@ -109,27 +99,6 @@ 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) - - boundsCheckType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{llvm.Int1Type()}, false) - c.boundsCheckFunc = llvm.AddFunction(c.mod, "runtime.boundsCheck", boundsCheckType) - - printstringType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.stringType}, false) - c.printstringFunc = llvm.AddFunction(c.mod, "runtime.printstring", printstringType) - printi32Type := llvm.FunctionType(llvm.VoidType(), []llvm.Type{llvm.Int32Type()}, false) - c.printint32Func = llvm.AddFunction(c.mod, "runtime.printint32", printi32Type) - c.printuint32Func = llvm.AddFunction(c.mod, "runtime.printuint32", printi32Type) - printi64Type := llvm.FunctionType(llvm.VoidType(), []llvm.Type{llvm.Int64Type()}, false) - c.printint64Func = llvm.AddFunction(c.mod, "runtime.printint64", printi64Type) - c.printuint64Func = llvm.AddFunction(c.mod, "runtime.printuint64", printi64Type) - printbyteType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{llvm.Int8Type()}, false) - c.printbyteFunc = llvm.AddFunction(c.mod, "runtime.printbyte", printbyteType) - printspaceType := llvm.FunctionType(llvm.VoidType(), nil, false) - c.printspaceFunc = llvm.AddFunction(c.mod, "runtime.printspace", printspaceType) - printnlType := llvm.FunctionType(llvm.VoidType(), nil, false) - c.printnlFunc = llvm.AddFunction(c.mod, "runtime.printnl", printnlType) - return c, nil } @@ -183,7 +152,11 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error { } unsatisfiedImports := make([]string, 0) - for _, pkg := range pkg.Pkg.Imports() { + imports := pkg.Pkg.Imports() + if pkgPath != "runtime" && pkgPath != "unsafe" && pkgPath != "runtime/cgo" && pkgPath != "syscall" { + imports = append(imports, program.ImportedPackage("runtime").Pkg) + } + for _, pkg := range imports { if _, ok := packageSet[pkg.Path()]; ok { continue } @@ -557,7 +530,7 @@ func (c *Compiler) parseInstr(frame *Frame, instr ssa.Instruction) error { if err != nil { return err } - c.builder.CreateCall(c.panicFunc, []llvm.Value{value}, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime._panic"), []llvm.Value{value}, "") c.builder.CreateUnreachable() return nil case *ssa.Return: @@ -601,7 +574,7 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string) case "print", "println": for i, arg := range args { if i >= 1 { - c.builder.CreateCall(c.printspaceFunc, nil, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime.printspace"), nil, "") } fmt.Printf(" arg: %s\n", arg); value, err := c.parseExpr(frame, arg) @@ -616,17 +589,17 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string) case *types.Basic: switch typ.Kind() { case types.Uint8: - c.builder.CreateCall(c.printbyteFunc, []llvm.Value{value}, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime.printbyte"), []llvm.Value{value}, "") case types.Int, types.Int32: // TODO: assumes a 32-bit int type - c.builder.CreateCall(c.printint32Func, []llvm.Value{value}, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime.printint32"), []llvm.Value{value}, "") case types.Uint, types.Uint32: - c.builder.CreateCall(c.printuint32Func, []llvm.Value{value}, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime.printuint32"), []llvm.Value{value}, "") case types.Int64: - c.builder.CreateCall(c.printint64Func, []llvm.Value{value}, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime.printint64"), []llvm.Value{value}, "") case types.Uint64: - c.builder.CreateCall(c.printuint64Func, []llvm.Value{value}, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime.printuint64"), []llvm.Value{value}, "") case types.String: - c.builder.CreateCall(c.printstringFunc, []llvm.Value{value}, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime.printstring"), []llvm.Value{value}, "") default: return llvm.Value{}, errors.New("unknown basic arg type: " + fmt.Sprintf("%#v", typ)) } @@ -635,7 +608,7 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string) } } if callName == "println" { - c.builder.CreateCall(c.printnlFunc, nil, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime.printnl"), nil, "") } return llvm.Value{}, nil // print() or println() returns void case "len": @@ -792,7 +765,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { isNegative := c.builder.CreateICmp(llvm.IntSLT, index, constZero, "") // index < 0 isTooBig := c.builder.CreateICmp(llvm.IntSGE, index, buflen, "") // index >= len(value) isOverflow := c.builder.CreateOr(isNegative, isTooBig, "") - c.builder.CreateCall(c.boundsCheckFunc, []llvm.Value{isOverflow}, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime.boundsCheck"), []llvm.Value{isOverflow}, "") indices := []llvm.Value{ llvm.ConstInt(llvm.Int32Type(), 0, false), @@ -830,7 +803,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { } isTooBig := c.builder.CreateICmp(llvm.IntSGE, index, strlen, "") // index >= len(value) isOverflow := c.builder.CreateOr(isNegative, isTooBig, "") - c.builder.CreateCall(c.boundsCheckFunc, []llvm.Value{isOverflow}, "") + c.builder.CreateCall(c.mod.NamedFunction("runtime.boundsCheck"), []llvm.Value{isOverflow}, "") } // Lookup byte