Skip to content

Commit 34b50ef

Browse files
aykevldeadprogram
authored andcommitted
interp: support GEP on fixed (MMIO) addresses
GetElementPtr would not work on values that weren't pointers. Because fixed addresses (often used in memory-mapped I/O) are integers rather than pointers in interp, it would return an error. This resulted in the teensy40 target not compiling correctly since the interp package rewrite. This commit should fix that.
1 parent 42088f9 commit 34b50ef

File tree

4 files changed

+21
-8
lines changed

4 files changed

+21
-8
lines changed

interp/errors.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,17 @@ import (
1111
"tinygo.org/x/go-llvm"
1212
)
1313

14-
var errLiteralToPointer = errors.New("interp: trying to convert literal value to pointer")
15-
1614
// These errors are expected during normal execution and can be recovered from
1715
// by running the affected function at runtime instead of compile time.
1816
var (
19-
errExpectedPointer = errors.New("interp: trying to use an integer as a pointer (memory-mapped I/O?)")
17+
errIntegerAsPointer = errors.New("interp: trying to use an integer as a pointer (memory-mapped I/O?)")
2018
errUnsupportedInst = errors.New("interp: unsupported instruction")
2119
errUnsupportedRuntimeInst = errors.New("interp: unsupported instruction (to be emitted at runtime)")
2220
errMapAlreadyCreated = errors.New("interp: map already created")
2321
)
2422

2523
func isRecoverableError(err error) bool {
26-
return err == errExpectedPointer || err == errUnsupportedInst || err == errUnsupportedRuntimeInst || err == errMapAlreadyCreated
24+
return err == errIntegerAsPointer || err == errUnsupportedInst || err == errUnsupportedRuntimeInst || err == errMapAlreadyCreated
2725
}
2826

2927
// ErrorLine is one line in a traceback. The position may be missing.

interp/interp.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func Run(mod llvm.Module, debug bool) error {
102102
if callErr != nil {
103103
if isRecoverableError(callErr.Err) {
104104
if r.debug {
105-
fmt.Fprintln(os.Stderr, "not interpretring", r.pkgName, "because of error:", callErr.Err)
105+
fmt.Fprintln(os.Stderr, "not interpreting", r.pkgName, "because of error:", callErr.Error())
106106
}
107107
mem.revert()
108108
continue

interp/interpreter.go

+16-1
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,22 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
550550
}
551551
ptr, err := operands[0].asPointer(r)
552552
if err != nil {
553-
return nil, mem, r.errorAt(inst, err)
553+
if err != errIntegerAsPointer {
554+
return nil, mem, r.errorAt(inst, err)
555+
}
556+
// GEP on fixed pointer value (for example, memory-mapped I/O).
557+
ptrValue := operands[0].Uint() + offset
558+
switch operands[0].len(r) {
559+
case 8:
560+
locals[inst.localIndex] = literalValue{uint64(ptrValue)}
561+
case 4:
562+
locals[inst.localIndex] = literalValue{uint32(ptrValue)}
563+
case 2:
564+
locals[inst.localIndex] = literalValue{uint16(ptrValue)}
565+
default:
566+
panic("pointer operand is not of a known pointer size")
567+
}
568+
continue
554569
}
555570
ptr = ptr.addOffset(uint32(offset))
556571
locals[inst.localIndex] = ptr

interp/memory.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ func (v literalValue) clone() value {
348348
}
349349

350350
func (v literalValue) asPointer(r *runner) (pointerValue, error) {
351-
return pointerValue{}, errLiteralToPointer
351+
return pointerValue{}, errIntegerAsPointer
352352
}
353353

354354
func (v literalValue) asRawValue(r *runner) rawValue {
@@ -949,7 +949,7 @@ func (v rawValue) clone() value {
949949
func (v rawValue) asPointer(r *runner) (pointerValue, error) {
950950
if v.buf[0] <= 255 {
951951
// Probably a null pointer or memory-mapped I/O.
952-
return pointerValue{}, errExpectedPointer
952+
return pointerValue{}, errIntegerAsPointer
953953
}
954954
return pointerValue{v.buf[0]}, nil
955955
}

0 commit comments

Comments
 (0)