@@ -97,7 +97,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
9797 value = operand .Load ()
9898 }
9999 if value .Type () != inst .Type () {
100- panic ( "interp: load: type does not match" )
100+ return nil , nil , fr . errorAt ( inst , "interp: load: type does not match" )
101101 }
102102 fr .locals [inst ] = fr .getValue (value )
103103 case ! inst .IsAStoreInst ().IsNil ():
@@ -121,15 +121,13 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
121121 // Not a constant operation.
122122 // This should be detected by the scanner, but isn't at the
123123 // moment.
124- panic ( "todo: non-const gep" )
124+ return nil , nil , fr . errorAt ( inst , "todo: non-const gep" )
125125 }
126126 indices [i ] = uint32 (operand .Value ().ZExtValue ())
127127 }
128128 result := value .GetElementPtr (indices )
129129 if result .Type () != inst .Type () {
130- println (" expected:" , inst .Type ().String ())
131- println (" actual: " , result .Type ().String ())
132- panic ("interp: gep: type does not match" )
130+ return nil , nil , fr .errorAt (inst , "interp: gep: type does not match" )
133131 }
134132 fr .locals [inst ] = result
135133
@@ -184,7 +182,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
184182 }
185183 }
186184 // It is not possible in Go to bitcast a map value to a pointer.
187- panic ( "unimplemented: bitcast of map" )
185+ return nil , nil , fr . errorAt ( inst , "unimplemented: bitcast of map" )
188186 }
189187 value := fr .getLocal (operand ).(* LocalValue )
190188 fr .locals [inst ] = & LocalValue {fr .Eval , fr .builder .CreateBitCast (value .Value (), inst .Type (), "" )}
@@ -397,16 +395,16 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
397395 typecode := fr .getLocal (inst .Operand (0 )).(* LocalValue ).Underlying
398396 interfaceMethodSet := fr .getLocal (inst .Operand (1 )).(* LocalValue ).Underlying
399397 if typecode .IsAConstantExpr ().IsNil () || typecode .Opcode () != llvm .PtrToInt {
400- panic ( "interp: expected typecode to be a ptrtoint" )
398+ return nil , nil , fr . errorAt ( inst , "interp: expected typecode to be a ptrtoint" )
401399 }
402400 typecode = typecode .Operand (0 )
403401 if interfaceMethodSet .IsAConstantExpr ().IsNil () || interfaceMethodSet .Opcode () != llvm .GetElementPtr {
404- panic ( "interp: expected method set in runtime.interfaceImplements to be a constant gep" )
402+ return nil , nil , fr . errorAt ( inst , "interp: expected method set in runtime.interfaceImplements to be a constant gep" )
405403 }
406404 interfaceMethodSet = interfaceMethodSet .Operand (0 ).Initializer ()
407405 methodSet := llvm .ConstExtractValue (typecode .Initializer (), []uint32 {1 })
408406 if methodSet .IsAConstantExpr ().IsNil () || methodSet .Opcode () != llvm .GetElementPtr {
409- panic ( "interp: expected method set to be a constant gep" )
407+ return nil , nil , fr . errorAt ( inst , "interp: expected method set to be a constant gep" )
410408 }
411409 methodSet = methodSet .Operand (0 ).Initializer ()
412410
@@ -476,7 +474,10 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
476474 params = append (params , local )
477475 }
478476 var ret Value
479- scanResult := fr .Eval .hasSideEffects (callee )
477+ scanResult , err := fr .hasSideEffects (callee )
478+ if err != nil {
479+ return nil , nil , err
480+ }
480481 if scanResult .severity == sideEffectLimited || dirtyParams && scanResult .severity != sideEffectAll {
481482 // Side effect is bounded. This means the operation invokes
482483 // side effects (like calling an external function) but it
@@ -545,7 +546,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
545546 // conditional branch (if/then/else)
546547 cond := fr .getLocal (inst .Operand (0 )).Value ()
547548 if cond .Type () != fr .Mod .Context ().Int1Type () {
548- panic ( "expected an i1 in a branch instruction" )
549+ return nil , nil , fr . errorAt ( inst , "expected an i1 in a branch instruction" )
549550 }
550551 thenBB := inst .Operand (1 )
551552 elseBB := inst .Operand (2 )
@@ -563,7 +564,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
563564 case llvm .ConstInt (fr .Mod .Context ().Int1Type (), 1 , false ): // true
564565 return nil , []llvm.Value {elseBB }, nil // else
565566 default :
566- panic ( "branch was not true or false" )
567+ return nil , nil , fr . errorAt ( inst , "branch was not true or false" )
567568 }
568569 case ! inst .IsABranchInst ().IsNil () && inst .OperandsCount () == 1 :
569570 // unconditional branch (goto)
@@ -589,6 +590,7 @@ func (fr *frame) getLocal(v llvm.Value) Value {
589590 } else if value := fr .getValue (v ); value != nil {
590591 return value
591592 } else {
593+ // This should not happen under normal circumstances.
592594 panic ("cannot find value" )
593595 }
594596}
0 commit comments