compiler: Implement initializers for arrays in global structs
Этот коммит содержится в:
родитель
db8b6c6900
коммит
84b45a33f1
1 изменённых файлов: 24 добавлений и 7 удалений
31
tgo.go
31
tgo.go
|
@ -471,14 +471,13 @@ func (c *Compiler) parseInitFunc(frame *Frame, f *ssa.Function) error {
|
||||||
for _, instr := range block.Instrs {
|
for _, instr := range block.Instrs {
|
||||||
var err error
|
var err error
|
||||||
switch instr := instr.(type) {
|
switch instr := instr.(type) {
|
||||||
case *ssa.Convert:
|
case *ssa.Call, *ssa.Return:
|
||||||
// ignore: CGo pointer conversion
|
|
||||||
case *ssa.Return:
|
|
||||||
err = c.parseInstr(frame, instr)
|
err = c.parseInstr(frame, instr)
|
||||||
case *ssa.FieldAddr:
|
case *ssa.Convert:
|
||||||
// ignore
|
// Ignore: CGo pointer conversion.
|
||||||
|
case *ssa.FieldAddr, *ssa.IndexAddr:
|
||||||
|
// Ignore: handled below with *ssa.Store.
|
||||||
case *ssa.Store:
|
case *ssa.Store:
|
||||||
var llvmAddr llvm.Value
|
|
||||||
switch addr := instr.Addr.(type) {
|
switch addr := instr.Addr.(type) {
|
||||||
case *ssa.Global:
|
case *ssa.Global:
|
||||||
// Regular store, like a global int variable.
|
// Regular store, like a global int variable.
|
||||||
|
@ -491,7 +490,7 @@ func (c *Compiler) parseInitFunc(frame *Frame, f *ssa.Function) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fullName := pkgPrefix(addr.Pkg) + "." + addr.Name()
|
fullName := pkgPrefix(addr.Pkg) + "." + addr.Name()
|
||||||
llvmAddr = c.mod.NamedGlobal(fullName)
|
llvmAddr := c.mod.NamedGlobal(fullName)
|
||||||
llvmAddr.SetInitializer(val)
|
llvmAddr.SetInitializer(val)
|
||||||
case *ssa.FieldAddr:
|
case *ssa.FieldAddr:
|
||||||
// Initialize field of a global struct.
|
// Initialize field of a global struct.
|
||||||
|
@ -508,6 +507,24 @@ func (c *Compiler) parseInitFunc(frame *Frame, f *ssa.Function) error {
|
||||||
llvmValue := llvmAddr.Initializer()
|
llvmValue := llvmAddr.Initializer()
|
||||||
llvmValue = c.builder.CreateInsertValue(llvmValue, val, addr.Field, "")
|
llvmValue = c.builder.CreateInsertValue(llvmValue, val, addr.Field, "")
|
||||||
llvmAddr.SetInitializer(llvmValue)
|
llvmAddr.SetInitializer(llvmValue)
|
||||||
|
case *ssa.IndexAddr:
|
||||||
|
val, err := c.parseExpr(frame, instr.Val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
constIndex := addr.Index.(*ssa.Const)
|
||||||
|
index, exact := constant.Int64Val(constIndex.Value)
|
||||||
|
if !exact {
|
||||||
|
return errors.New("could not get store index: " + constIndex.Value.ExactString())
|
||||||
|
}
|
||||||
|
fieldAddr := addr.X.(*ssa.FieldAddr)
|
||||||
|
global := fieldAddr.X.(*ssa.Global)
|
||||||
|
llvmAddr := c.mod.NamedGlobal(pkgPrefix(global.Pkg) + "." + global.Name())
|
||||||
|
llvmValue := c.mod.NamedGlobal(pkgPrefix(global.Pkg) + "." + global.Name()).Initializer()
|
||||||
|
llvmFieldValue := c.builder.CreateExtractValue(llvmValue, fieldAddr.Field, "")
|
||||||
|
llvmFieldValue = c.builder.CreateInsertValue(llvmFieldValue, val, int(index), "")
|
||||||
|
llvmValue = c.builder.CreateInsertValue(llvmValue, llvmFieldValue, fieldAddr.Field, "")
|
||||||
|
llvmAddr.SetInitializer(llvmValue)
|
||||||
default:
|
default:
|
||||||
return errors.New("unknown init store: " + fmt.Sprintf("%#v", addr))
|
return errors.New("unknown init store: " + fmt.Sprintf("%#v", addr))
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче