@@ -15,7 +15,7 @@ type Value interface {
1515 Value () llvm.Value // returns a LLVM value
1616 Type () llvm.Type // equal to Value().Type()
1717 IsConstant () bool // returns true if this value is a constant value
18- Load () llvm.Value // dereference a pointer
18+ Load () ( llvm.Value , error ) // dereference a pointer
1919 Store (llvm.Value ) // store to a pointer
2020 GetElementPtr ([]uint32 ) (Value , error ) // returns an interior pointer
2121 String () string // string representation, for debugging
@@ -44,23 +44,26 @@ func (v *LocalValue) IsConstant() bool {
4444}
4545
4646// Load loads a constant value if this is a constant pointer.
47- func (v * LocalValue ) Load () llvm.Value {
47+ func (v * LocalValue ) Load () ( llvm.Value , error ) {
4848 if ! v .Underlying .IsAGlobalVariable ().IsNil () {
49- return v .Underlying .Initializer ()
49+ return v .Underlying .Initializer (), nil
5050 }
5151 switch v .Underlying .Opcode () {
5252 case llvm .GetElementPtr :
5353 indices := v .getConstGEPIndices ()
5454 if indices [0 ] != 0 {
55- panic ("invalid GEP" )
55+ return llvm. Value {}, errors . New ("invalid GEP" )
5656 }
5757 global := v .Eval .getValue (v .Underlying .Operand (0 ))
58- agg := global .Load ()
59- return llvm .ConstExtractValue (agg , indices [1 :])
58+ agg , err := global .Load ()
59+ if err != nil {
60+ return llvm.Value {}, err
61+ }
62+ return llvm .ConstExtractValue (agg , indices [1 :]), nil
6063 case llvm .BitCast :
61- panic ("interp: load from a bitcast" )
64+ return llvm. Value {}, errors . New ("interp: load from a bitcast" )
6265 default :
63- panic ("interp: load from a constant" )
66+ return llvm. Value {}, errors . New ("interp: load from a constant" )
6467 }
6568}
6669
@@ -88,7 +91,10 @@ func (v *LocalValue) Store(value llvm.Value) {
8891 panic ("invalid GEP" )
8992 }
9093 global := & LocalValue {v .Eval , v .Underlying .Operand (0 )}
91- agg := global .Load ()
94+ agg , err := global .Load ()
95+ if err != nil {
96+ panic (err ) // TODO
97+ }
9298 agg = llvm .ConstInsertValue (agg , value , indices [1 :])
9399 global .Store (agg )
94100 return
@@ -225,7 +231,11 @@ func (v *MapValue) Value() llvm.Value {
225231 keyPtr := llvm .ConstExtractValue (llvmKey , []uint32 {0 })
226232 keyLen := llvm .ConstExtractValue (llvmKey , []uint32 {1 })
227233 keyPtrVal := v .Eval .getValue (keyPtr )
228- keyBuf = getStringBytes (keyPtrVal , keyLen )
234+ var err error
235+ keyBuf , err = getStringBytes (keyPtrVal , keyLen )
236+ if err != nil {
237+ panic (err ) // TODO
238+ }
229239 } else if key .Type ().TypeKind () == llvm .IntegerTypeKind {
230240 keyBuf = make ([]byte , v .Eval .TargetData .TypeAllocSize (key .Type ()))
231241 n := key .Value ().ZExtValue ()
@@ -299,7 +309,7 @@ func (v *MapValue) IsConstant() bool {
299309}
300310
301311// Load panics: maps are of reference type so cannot be dereferenced.
302- func (v * MapValue ) Load () llvm.Value {
312+ func (v * MapValue ) Load () ( llvm.Value , error ) {
303313 panic ("interp: load from a map" )
304314}
305315
@@ -316,23 +326,26 @@ func (v *MapValue) GetElementPtr(indices []uint32) (Value, error) {
316326
317327// PutString does a map assign operation, assuming that the map is of type
318328// map[string]T.
319- func (v * MapValue ) PutString (keyBuf , keyLen , valPtr * LocalValue ) {
329+ func (v * MapValue ) PutString (keyBuf , keyLen , valPtr * LocalValue ) error {
320330 if ! v .Underlying .IsNil () {
321- panic ("map already created" )
331+ return errors . New ("map already created" )
322332 }
323333
324334 if valPtr .Underlying .Opcode () == llvm .BitCast {
325335 valPtr = & LocalValue {v .Eval , valPtr .Underlying .Operand (0 )}
326336 }
327- value := valPtr .Load ()
337+ value , err := valPtr .Load ()
338+ if err != nil {
339+ return err
340+ }
328341 if v .ValueType .IsNil () {
329342 v .ValueType = value .Type ()
330343 if int (v .Eval .TargetData .TypeAllocSize (v .ValueType )) != v .ValueSize {
331- panic ("interp: map store value type has the wrong size" )
344+ return errors . New ("interp: map store value type has the wrong size" )
332345 }
333346 } else {
334347 if value .Type () != v .ValueType {
335- panic ("interp: map store value type is inconsistent" )
348+ return errors . New ("interp: map store value type is inconsistent" )
336349 }
337350 }
338351
@@ -345,26 +358,31 @@ func (v *MapValue) PutString(keyBuf, keyLen, valPtr *LocalValue) {
345358 // TODO: avoid duplicate keys
346359 v .Keys = append (v .Keys , & LocalValue {v .Eval , key })
347360 v .Values = append (v .Values , & LocalValue {v .Eval , value })
361+
362+ return nil
348363}
349364
350365// PutBinary does a map assign operation.
351- func (v * MapValue ) PutBinary (keyPtr , valPtr * LocalValue ) {
366+ func (v * MapValue ) PutBinary (keyPtr , valPtr * LocalValue ) error {
352367 if ! v .Underlying .IsNil () {
353- panic ("map already created" )
368+ return errors . New ("map already created" )
354369 }
355370
356371 if valPtr .Underlying .Opcode () == llvm .BitCast {
357372 valPtr = & LocalValue {v .Eval , valPtr .Underlying .Operand (0 )}
358373 }
359- value := valPtr .Load ()
374+ value , err := valPtr .Load ()
375+ if err != nil {
376+ return err
377+ }
360378 if v .ValueType .IsNil () {
361379 v .ValueType = value .Type ()
362380 if int (v .Eval .TargetData .TypeAllocSize (v .ValueType )) != v .ValueSize {
363- panic ("interp: map store value type has the wrong size" )
381+ return errors . New ("interp: map store value type has the wrong size" )
364382 }
365383 } else {
366384 if value .Type () != v .ValueType {
367- panic ("interp: map store value type is inconsistent" )
385+ return errors . New ("interp: map store value type is inconsistent" )
368386 }
369387 }
370388
@@ -375,21 +393,26 @@ func (v *MapValue) PutBinary(keyPtr, valPtr *LocalValue) {
375393 keyPtr = & LocalValue {v .Eval , keyPtr .Underlying .Operand (0 )}
376394 }
377395 }
378- key := keyPtr .Load ()
396+ key , err := keyPtr .Load ()
397+ if err != nil {
398+ return err
399+ }
379400 if v .KeyType .IsNil () {
380401 v .KeyType = key .Type ()
381402 if int (v .Eval .TargetData .TypeAllocSize (v .KeyType )) != v .KeySize {
382- panic ("interp: map store key type has the wrong size" )
403+ return errors . New ("interp: map store key type has the wrong size" )
383404 }
384405 } else {
385406 if key .Type () != v .KeyType {
386- panic ("interp: map store key type is inconsistent" )
407+ return errors . New ("interp: map store key type is inconsistent" )
387408 }
388409 }
389410
390411 // TODO: avoid duplicate keys
391412 v .Keys = append (v .Keys , & LocalValue {v .Eval , key })
392413 v .Values = append (v .Values , & LocalValue {v .Eval , value })
414+
415+ return nil
393416}
394417
395418// Get FNV-1a hash of this string.
0 commit comments