Skip to content

Commit cdba4fa

Browse files
aykevldeadprogram
authored andcommitted
interp: don't ignore array indices for untyped objects
This fixes #1884. My original plan to fix this was much more complicated, but then I realized that the output type doesn't matter anyway and I can simply cast the type to an *i8 and perform a GEP on that pointer.
1 parent 0565b7c commit cdba4fa

File tree

4 files changed

+29
-1
lines changed

4 files changed

+29
-1
lines changed

interp/interp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
// package is changed in a way that affects the output so that cached package
1616
// builds will be invalidated.
1717
// This version is independent of the TinyGo version number.
18-
const Version = 1
18+
const Version = 2 // last change: fix GEP on untyped pointers
1919

2020
// Enable extra checks, which should be disabled by default.
2121
// This may help track down bugs by adding a few more sanity checks.

interp/memory.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,17 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val
572572
}
573573

574574
if llvmType.IsNil() {
575+
if v.offset() != 0 {
576+
// If there is an offset, make sure to use a GEP to index into the
577+
// pointer. Because there is no expected type, we use whatever is
578+
// most convenient: an *i8 type. It is trivial to index byte-wise.
579+
if llvmValue.Type() != mem.r.i8ptrType {
580+
llvmValue = llvm.ConstBitCast(llvmValue, mem.r.i8ptrType)
581+
}
582+
llvmValue = llvm.ConstInBoundsGEP(llvmValue, []llvm.Value{
583+
llvm.ConstInt(llvmValue.Type().Context().Int32Type(), uint64(v.offset()), false),
584+
})
585+
}
575586
return llvmValue, nil
576587
}
577588

testdata/init.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ func main() {
1313
println("v5:", len(v5), v5 == nil)
1414
println("v6:", v6)
1515
println("v7:", cap(v7), string(v7))
16+
println("v8:", v8)
17+
println("v9:", len(v9), v9[0], v9[1], v9[2])
1618

1719
println(uint8SliceSrc[0])
1820
println(uint8SliceDst[0])
@@ -35,6 +37,8 @@ var (
3537
v5 = map[string]int{}
3638
v6 = float64(v1) < 2.6
3739
v7 = []byte("foo")
40+
v8 string
41+
v9 []int
3842

3943
uint8SliceSrc = []uint8{3, 100}
4044
uint8SliceDst []uint8
@@ -48,4 +52,15 @@ func init() {
4852

4953
intSliceDst = make([]int16, len(intSliceSrc))
5054
copy(intSliceDst, intSliceSrc)
55+
56+
v8 = sliceString("foobarbaz", 3, 8)
57+
v9 = sliceSlice([]int{0, 1, 2, 3, 4, 5}, 2, 5)
58+
}
59+
60+
func sliceString(s string, start, end int) string {
61+
return s[start:end]
62+
}
63+
64+
func sliceSlice(s []int, start, end int) []int {
65+
return s[start:end]
5166
}

testdata/init.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ v4: 0 true
77
v5: 0 false
88
v6: false
99
v7: 3 foo
10+
v8: barba
11+
v9: 3 2 3 4
1012
3
1113
3
1214
5

0 commit comments

Comments
 (0)