Add support for (zero-initialized) arrays
Этот коммит содержится в:
родитель
02332080e6
коммит
d812873e60
1 изменённых файлов: 50 добавлений и 2 удалений
52
tgo.go
52
tgo.go
|
@ -48,6 +48,7 @@ type Compiler struct {
|
|||
printbyteFunc llvm.Value
|
||||
printspaceFunc llvm.Value
|
||||
printnlFunc llvm.Value
|
||||
memsetIntrinsic llvm.Value
|
||||
itfTypeNumbers map[types.Type]uint64
|
||||
itfTypes []types.Type
|
||||
}
|
||||
|
@ -107,6 +108,16 @@ func NewCompiler(pkgName, triple string) (*Compiler, error) {
|
|||
printnlType := llvm.FunctionType(llvm.VoidType(), nil, false)
|
||||
c.printnlFunc = llvm.AddFunction(c.mod, "runtime.printnl", printnlType)
|
||||
|
||||
// Intrinsic functions
|
||||
memsetType := llvm.FunctionType(
|
||||
llvm.VoidType(), []llvm.Type{
|
||||
llvm.PointerType(llvm.Int8Type(), 0),
|
||||
llvm.Int8Type(),
|
||||
llvm.Int32Type(),
|
||||
llvm.Int1Type(),
|
||||
}, false)
|
||||
c.memsetIntrinsic = llvm.AddFunction(c.mod, "llvm.memset.p0i8.i32", memsetType)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
|
@ -244,6 +255,12 @@ func (c *Compiler) Parse(pkgName string) error {
|
|||
func (c *Compiler) getLLVMType(goType types.Type) (llvm.Type, error) {
|
||||
fmt.Println(" type:", goType)
|
||||
switch typ := goType.(type) {
|
||||
case *types.Array:
|
||||
elemType, err := c.getLLVMType(typ.Elem())
|
||||
if err != nil {
|
||||
return llvm.Type{}, err
|
||||
}
|
||||
return llvm.ArrayType(elemType, int(typ.Len())), nil
|
||||
case *types.Basic:
|
||||
switch typ.Kind() {
|
||||
case types.Bool:
|
||||
|
@ -563,12 +580,28 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
|||
if err != nil {
|
||||
return llvm.Value{}, err
|
||||
}
|
||||
var buf llvm.Value
|
||||
if expr.Heap {
|
||||
// TODO: escape analysis
|
||||
return c.builder.CreateMalloc(typ, expr.Comment), nil
|
||||
buf = c.builder.CreateMalloc(typ, expr.Comment)
|
||||
} else {
|
||||
return c.builder.CreateAlloca(typ, expr.Comment), nil
|
||||
buf = c.builder.CreateAlloca(typ, expr.Comment)
|
||||
}
|
||||
width := c.targetData.TypeAllocSize(typ)
|
||||
if err != nil {
|
||||
return llvm.Value{}, err
|
||||
}
|
||||
llvmWidth := llvm.ConstInt(llvm.Int32Type(), width, false)
|
||||
bufBytes := c.builder.CreateBitCast(buf, llvm.PointerType(llvm.Int8Type(), 0), "")
|
||||
c.builder.CreateCall(
|
||||
c.memsetIntrinsic,
|
||||
[]llvm.Value{
|
||||
bufBytes,
|
||||
llvm.ConstInt(llvm.Int8Type(), 0, false), // value to set (zero)
|
||||
llvmWidth, // size to zero
|
||||
llvm.ConstInt(llvm.Int1Type(), 0, false), // volatile
|
||||
}, "")
|
||||
return buf, nil
|
||||
case *ssa.BinOp:
|
||||
return c.parseBinOp(frame, expr)
|
||||
case *ssa.Call:
|
||||
|
@ -603,6 +636,21 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
|||
return llvm.Value{}, errors.New("global not found: " + expr.Name())
|
||||
}
|
||||
return value, nil
|
||||
case *ssa.IndexAddr:
|
||||
val, err := c.parseExpr(frame, expr.X)
|
||||
if err != nil {
|
||||
return llvm.Value{}, err
|
||||
}
|
||||
index, err := c.parseExpr(frame, expr.Index)
|
||||
if err != nil {
|
||||
return llvm.Value{}, err
|
||||
}
|
||||
// TODO: bounds check
|
||||
indices := []llvm.Value{
|
||||
llvm.ConstInt(llvm.Int32Type(), 0, false),
|
||||
index,
|
||||
}
|
||||
return c.builder.CreateGEP(val, indices, ""), nil
|
||||
case *ssa.Lookup:
|
||||
if expr.CommaOk {
|
||||
return llvm.Value{}, errors.New("todo: lookup with comma-ok")
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче