interp: don't ignore array indices for untyped objects
This fixes https://github.com/tinygo-org/tinygo/issues/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.
Этот коммит содержится в:
родитель
0565b7c0e0
коммит
cdba4fa8cc
4 изменённых файлов: 29 добавлений и 1 удалений
|
@ -15,7 +15,7 @@ import (
|
||||||
// package is changed in a way that affects the output so that cached package
|
// package is changed in a way that affects the output so that cached package
|
||||||
// builds will be invalidated.
|
// builds will be invalidated.
|
||||||
// This version is independent of the TinyGo version number.
|
// This version is independent of the TinyGo version number.
|
||||||
const Version = 1
|
const Version = 2 // last change: fix GEP on untyped pointers
|
||||||
|
|
||||||
// Enable extra checks, which should be disabled by default.
|
// Enable extra checks, which should be disabled by default.
|
||||||
// This may help track down bugs by adding a few more sanity checks.
|
// This may help track down bugs by adding a few more sanity checks.
|
||||||
|
|
|
@ -572,6 +572,17 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val
|
||||||
}
|
}
|
||||||
|
|
||||||
if llvmType.IsNil() {
|
if llvmType.IsNil() {
|
||||||
|
if v.offset() != 0 {
|
||||||
|
// If there is an offset, make sure to use a GEP to index into the
|
||||||
|
// pointer. Because there is no expected type, we use whatever is
|
||||||
|
// most convenient: an *i8 type. It is trivial to index byte-wise.
|
||||||
|
if llvmValue.Type() != mem.r.i8ptrType {
|
||||||
|
llvmValue = llvm.ConstBitCast(llvmValue, mem.r.i8ptrType)
|
||||||
|
}
|
||||||
|
llvmValue = llvm.ConstInBoundsGEP(llvmValue, []llvm.Value{
|
||||||
|
llvm.ConstInt(llvmValue.Type().Context().Int32Type(), uint64(v.offset()), false),
|
||||||
|
})
|
||||||
|
}
|
||||||
return llvmValue, nil
|
return llvmValue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
testdata/init.go
предоставленный
15
testdata/init.go
предоставленный
|
@ -13,6 +13,8 @@ func main() {
|
||||||
println("v5:", len(v5), v5 == nil)
|
println("v5:", len(v5), v5 == nil)
|
||||||
println("v6:", v6)
|
println("v6:", v6)
|
||||||
println("v7:", cap(v7), string(v7))
|
println("v7:", cap(v7), string(v7))
|
||||||
|
println("v8:", v8)
|
||||||
|
println("v9:", len(v9), v9[0], v9[1], v9[2])
|
||||||
|
|
||||||
println(uint8SliceSrc[0])
|
println(uint8SliceSrc[0])
|
||||||
println(uint8SliceDst[0])
|
println(uint8SliceDst[0])
|
||||||
|
@ -35,6 +37,8 @@ var (
|
||||||
v5 = map[string]int{}
|
v5 = map[string]int{}
|
||||||
v6 = float64(v1) < 2.6
|
v6 = float64(v1) < 2.6
|
||||||
v7 = []byte("foo")
|
v7 = []byte("foo")
|
||||||
|
v8 string
|
||||||
|
v9 []int
|
||||||
|
|
||||||
uint8SliceSrc = []uint8{3, 100}
|
uint8SliceSrc = []uint8{3, 100}
|
||||||
uint8SliceDst []uint8
|
uint8SliceDst []uint8
|
||||||
|
@ -48,4 +52,15 @@ func init() {
|
||||||
|
|
||||||
intSliceDst = make([]int16, len(intSliceSrc))
|
intSliceDst = make([]int16, len(intSliceSrc))
|
||||||
copy(intSliceDst, intSliceSrc)
|
copy(intSliceDst, intSliceSrc)
|
||||||
|
|
||||||
|
v8 = sliceString("foobarbaz", 3, 8)
|
||||||
|
v9 = sliceSlice([]int{0, 1, 2, 3, 4, 5}, 2, 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sliceString(s string, start, end int) string {
|
||||||
|
return s[start:end]
|
||||||
|
}
|
||||||
|
|
||||||
|
func sliceSlice(s []int, start, end int) []int {
|
||||||
|
return s[start:end]
|
||||||
}
|
}
|
||||||
|
|
2
testdata/init.txt
предоставленный
2
testdata/init.txt
предоставленный
|
@ -7,6 +7,8 @@ v4: 0 true
|
||||||
v5: 0 false
|
v5: 0 false
|
||||||
v6: false
|
v6: false
|
||||||
v7: 3 foo
|
v7: 3 foo
|
||||||
|
v8: barba
|
||||||
|
v9: 3 2 3 4
|
||||||
3
|
3
|
||||||
3
|
3
|
||||||
5
|
5
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче