@@ -97,7 +97,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
97
97
value = operand .Load ()
98
98
}
99
99
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" )
101
101
}
102
102
fr .locals [inst ] = fr .getValue (value )
103
103
case ! inst .IsAStoreInst ().IsNil ():
@@ -121,15 +121,13 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
121
121
// Not a constant operation.
122
122
// This should be detected by the scanner, but isn't at the
123
123
// moment.
124
- panic ( "todo: non-const gep" )
124
+ return nil , nil , fr . errorAt ( inst , "todo: non-const gep" )
125
125
}
126
126
indices [i ] = uint32 (operand .Value ().ZExtValue ())
127
127
}
128
128
result := value .GetElementPtr (indices )
129
129
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" )
133
131
}
134
132
fr .locals [inst ] = result
135
133
@@ -184,7 +182,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
184
182
}
185
183
}
186
184
// 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" )
188
186
}
189
187
value := fr .getLocal (operand ).(* LocalValue )
190
188
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
397
395
typecode := fr .getLocal (inst .Operand (0 )).(* LocalValue ).Underlying
398
396
interfaceMethodSet := fr .getLocal (inst .Operand (1 )).(* LocalValue ).Underlying
399
397
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" )
401
399
}
402
400
typecode = typecode .Operand (0 )
403
401
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" )
405
403
}
406
404
interfaceMethodSet = interfaceMethodSet .Operand (0 ).Initializer ()
407
405
methodSet := llvm .ConstExtractValue (typecode .Initializer (), []uint32 {1 })
408
406
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" )
410
408
}
411
409
methodSet = methodSet .Operand (0 ).Initializer ()
412
410
@@ -476,7 +474,10 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
476
474
params = append (params , local )
477
475
}
478
476
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
+ }
480
481
if scanResult .severity == sideEffectLimited || dirtyParams && scanResult .severity != sideEffectAll {
481
482
// Side effect is bounded. This means the operation invokes
482
483
// side effects (like calling an external function) but it
@@ -545,7 +546,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
545
546
// conditional branch (if/then/else)
546
547
cond := fr .getLocal (inst .Operand (0 )).Value ()
547
548
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" )
549
550
}
550
551
thenBB := inst .Operand (1 )
551
552
elseBB := inst .Operand (2 )
@@ -563,7 +564,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
563
564
case llvm .ConstInt (fr .Mod .Context ().Int1Type (), 1 , false ): // true
564
565
return nil , []llvm.Value {elseBB }, nil // else
565
566
default :
566
- panic ( "branch was not true or false" )
567
+ return nil , nil , fr . errorAt ( inst , "branch was not true or false" )
567
568
}
568
569
case ! inst .IsABranchInst ().IsNil () && inst .OperandsCount () == 1 :
569
570
// unconditional branch (goto)
@@ -589,6 +590,7 @@ func (fr *frame) getLocal(v llvm.Value) Value {
589
590
} else if value := fr .getValue (v ); value != nil {
590
591
return value
591
592
} else {
593
+ // This should not happen under normal circumstances.
592
594
panic ("cannot find value" )
593
595
}
594
596
}
0 commit comments