diff options
-rw-r--r-- | interp/interpreter.go | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/interp/interpreter.go b/interp/interpreter.go index 0f2355a68..cccbe7b3b 100644 --- a/interp/interpreter.go +++ b/interp/interpreter.go @@ -81,12 +81,28 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent if inst.opcode != llvm.PHI { for _, v := range inst.operands { if v, ok := v.(localValue); ok { - if localVal := locals[fn.locals[v.value]]; localVal == nil { + index, ok := fn.locals[v.value] + if !ok { + // This is a localValue that is not local to the + // function. An example would be an inline assembly call + // operand. + isRuntimeInst = true + break + } + localVal := locals[index] + if localVal == nil { + // Trying to read a function-local value before it is + // set. return nil, mem, r.errorAt(inst, errors.New("interp: local not defined")) } else { operands = append(operands, localVal) if _, ok := localVal.(localValue); ok { + // The function-local value is still just a + // localValue (which can't be interpreted at compile + // time). Not sure whether this ever happens in + // practice. isRuntimeInst = true + break } continue } |