Browse Source

compiler: Do not pre-define runtime functions by the compiler

pull/6/head
Ayke van Laethem 7 years ago
parent
commit
b0cb51bdd8
  1. 59
      tgo.go

59
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

Loading…
Cancel
Save