Support zero-initialized pointers in globals
Этот коммит содержится в:
родитель
5edf94ea10
коммит
a5252d07f0
2 изменённых файлов: 12 добавлений и 4 удалений
|
@ -866,6 +866,13 @@ func (c *Compiler) getInterpretedValue(value Value) (llvm.Value, error) {
|
||||||
return llvm.ConstPtrToInt(elem, c.uintptrType), nil
|
return llvm.ConstPtrToInt(elem, c.uintptrType), nil
|
||||||
|
|
||||||
case *PointerValue:
|
case *PointerValue:
|
||||||
|
if value.Elem == nil {
|
||||||
|
typ, err := c.getLLVMType(value.Type)
|
||||||
|
if err != nil {
|
||||||
|
return llvm.Value{}, err
|
||||||
|
}
|
||||||
|
return llvm.ConstPointerNull(typ), nil
|
||||||
|
}
|
||||||
elem, err := c.getInterpretedValue(*value.Elem)
|
elem, err := c.getInterpretedValue(*value.Elem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return llvm.Value{}, err
|
return llvm.Value{}, err
|
||||||
|
|
|
@ -39,7 +39,7 @@ func (p *Program) interpret(instrs []ssa.Instruction) (int, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
locals[instr] = &PointerValue{&alloc}
|
locals[instr] = &PointerValue{nil, &alloc}
|
||||||
case *ssa.Convert:
|
case *ssa.Convert:
|
||||||
x, err := p.getValue(instr.X, locals)
|
x, err := p.getValue(instr.X, locals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -77,7 +77,7 @@ func (p *Program) interpret(instrs []ssa.Instruction) (int, error) {
|
||||||
default:
|
default:
|
||||||
panic("expected a pointer")
|
panic("expected a pointer")
|
||||||
}
|
}
|
||||||
locals[instr] = &PointerValue{&structVal.Fields[instr.Field]}
|
locals[instr] = &PointerValue{nil, &structVal.Fields[instr.Field]}
|
||||||
case *ssa.IndexAddr:
|
case *ssa.IndexAddr:
|
||||||
x, err := p.getValue(instr.X, locals)
|
x, err := p.getValue(instr.X, locals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -95,7 +95,7 @@ func (p *Program) interpret(instrs []ssa.Instruction) (int, error) {
|
||||||
}
|
}
|
||||||
switch x := x.(type) {
|
switch x := x.(type) {
|
||||||
case *ArrayValue:
|
case *ArrayValue:
|
||||||
locals[instr] = &PointerValue{&x.Elems[index]}
|
locals[instr] = &PointerValue{nil, &x.Elems[index]}
|
||||||
default:
|
default:
|
||||||
return i, errors.New("todo: init IndexAddr not on an array or struct")
|
return i, errors.New("todo: init IndexAddr not on an array or struct")
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ func (p *Program) getZeroValue(t types.Type) (Value, error) {
|
||||||
case *types.Map:
|
case *types.Map:
|
||||||
return &MapValue{typ, nil, nil}, nil
|
return &MapValue{typ, nil, nil}, nil
|
||||||
case *types.Pointer:
|
case *types.Pointer:
|
||||||
return &PointerValue{nil}, nil
|
return &PointerValue{typ, nil}, nil
|
||||||
case *types.Struct:
|
case *types.Struct:
|
||||||
elems := make([]Value, typ.NumFields())
|
elems := make([]Value, typ.NumFields())
|
||||||
for i := range elems {
|
for i := range elems {
|
||||||
|
@ -265,6 +265,7 @@ type ZeroBasicValue struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PointerValue struct {
|
type PointerValue struct {
|
||||||
|
Type types.Type
|
||||||
Elem *Value
|
Elem *Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче