interp: work around AVR function pointers in globals
Not sure how to test this, since we don't really have any AVR tests configured.
Этот коммит содержится в:
родитель
0f69d016a0
коммит
3e6410f323
2 изменённых файлов: 10 добавлений и 1 удалений
|
@ -28,6 +28,7 @@ type runner struct {
|
|||
builder llvm.Builder
|
||||
pointerSize uint32 // cached pointer size from the TargetData
|
||||
i8ptrType llvm.Type // often used type so created in advance
|
||||
uintptrType llvm.Type // equivalent to uintptr in Go
|
||||
maxAlign int // maximum alignment of an object, alignment of runtime.alloc() result
|
||||
debug bool // log debug messages
|
||||
pkgName string // package name of the currently executing package
|
||||
|
@ -50,6 +51,7 @@ func newRunner(mod llvm.Module, debug bool) *runner {
|
|||
}
|
||||
r.pointerSize = uint32(r.targetData.PointerSize())
|
||||
r.i8ptrType = llvm.PointerType(mod.Context().Int8Type(), 0)
|
||||
r.uintptrType = mod.Context().IntType(r.targetData.PointerSize() * 8)
|
||||
r.maxAlign = r.targetData.PrefTypeAlignment(r.i8ptrType) // assume pointers are maximally aligned (this is not always the case)
|
||||
return &r
|
||||
}
|
||||
|
|
|
@ -903,7 +903,14 @@ func (v rawValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Value,
|
|||
return llvm.Value{}, err
|
||||
}
|
||||
if llvmValue.Type() != llvmType {
|
||||
llvmValue = llvm.ConstBitCast(llvmValue, llvmType)
|
||||
if llvmValue.Type().PointerAddressSpace() != llvmType.PointerAddressSpace() {
|
||||
// Special case for AVR function pointers.
|
||||
// Because go-llvm doesn't have addrspacecast at the moment,
|
||||
// do it indirectly with a ptrtoint/inttoptr pair.
|
||||
llvmValue = llvm.ConstIntToPtr(llvm.ConstPtrToInt(llvmValue, mem.r.uintptrType), llvmType)
|
||||
} else {
|
||||
llvmValue = llvm.ConstBitCast(llvmValue, llvmType)
|
||||
}
|
||||
}
|
||||
return llvmValue, nil
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче