Skip to content

Commit 4fa1fc6

Browse files
aykevldeadprogram
authored andcommitted
interp: don't panic in the Store method
Instead return an error, which indicates where it goes wrong. That's less user unfriendly than panicking.
1 parent ccb803e commit 4fa1fc6

File tree

2 files changed

+22
-15
lines changed

2 files changed

+22
-15
lines changed

interp/frame.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,10 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
111111
if inst.IsVolatile() {
112112
fr.builder.CreateStore(value.Value(), ptr.Value())
113113
} else {
114-
ptr.Store(value.Value())
114+
err := ptr.Store(value.Value())
115+
if err != nil {
116+
return nil, nil, fr.errorAt(inst, err)
117+
}
115118
}
116119
case !inst.IsAGetElementPtrInst().IsNil():
117120
value := fr.getLocal(inst.Operand(0))
@@ -422,7 +425,10 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
422425
if err != nil {
423426
return nil, nil, fr.errorAt(inst, err)
424427
}
425-
dstArray.Store(val)
428+
err = dstArray.Store(val)
429+
if err != nil {
430+
return nil, nil, fr.errorAt(inst, err)
431+
}
426432
// dst++
427433
dstArrayValue, err := dstArray.GetElementPtr([]uint32{1})
428434
if err != nil {

interp/values.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type Value interface {
1616
Type() llvm.Type // equal to Value().Type()
1717
IsConstant() bool // returns true if this value is a constant value
1818
Load() (llvm.Value, error) // dereference a pointer
19-
Store(llvm.Value) // store to a pointer
19+
Store(llvm.Value) error // store to a pointer
2020
GetElementPtr([]uint32) (Value, error) // returns an interior pointer
2121
String() string // string representation, for debugging
2222
}
@@ -68,38 +68,37 @@ func (v *LocalValue) Load() (llvm.Value, error) {
6868
}
6969

7070
// Store stores to the underlying value if the value type is a pointer type,
71-
// otherwise it panics.
72-
func (v *LocalValue) Store(value llvm.Value) {
71+
// otherwise it returns an error.
72+
func (v *LocalValue) Store(value llvm.Value) error {
7373
if !v.Underlying.IsAGlobalVariable().IsNil() {
7474
if !value.IsConstant() {
7575
v.MarkDirty()
7676
v.Eval.builder.CreateStore(value, v.Underlying)
7777
} else {
7878
v.Underlying.SetInitializer(value)
7979
}
80-
return
80+
return nil
8181
}
8282
if !value.IsConstant() {
8383
v.MarkDirty()
8484
v.Eval.builder.CreateStore(value, v.Underlying)
85-
return
85+
return nil
8686
}
8787
switch v.Underlying.Opcode() {
8888
case llvm.GetElementPtr:
8989
indices := v.getConstGEPIndices()
9090
if indices[0] != 0 {
91-
panic("invalid GEP")
91+
return errors.New("invalid GEP")
9292
}
9393
global := &LocalValue{v.Eval, v.Underlying.Operand(0)}
9494
agg, err := global.Load()
9595
if err != nil {
96-
panic(err) // TODO
96+
return err
9797
}
9898
agg = llvm.ConstInsertValue(agg, value, indices[1:])
99-
global.Store(agg)
100-
return
99+
return global.Store(agg)
101100
default:
102-
panic("interp: store on a constant")
101+
return errors.New("interp: store on a constant")
103102
}
104103
}
105104

@@ -313,9 +312,11 @@ func (v *MapValue) Load() (llvm.Value, error) {
313312
panic("interp: load from a map")
314313
}
315314

316-
// Store panics: maps are of reference type so cannot be stored to.
317-
func (v *MapValue) Store(value llvm.Value) {
318-
panic("interp: store on a map")
315+
// Store returns an error: maps are of reference type so cannot be stored to.
316+
func (v *MapValue) Store(value llvm.Value) error {
317+
// This must be a bug, but it might be helpful to indicate the location
318+
// anyway.
319+
return errors.New("interp: store on a map")
319320
}
320321

321322
// GetElementPtr panics: maps are of reference type so their (interior)

0 commit comments

Comments
 (0)