From 3e6410f323620e963ed100b4f48060e0fcf8801c Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 10 Dec 2021 22:17:17 +0100 Subject: [PATCH] interp: work around AVR function pointers in globals Not sure how to test this, since we don't really have any AVR tests configured. --- interp/interp.go | 2 ++ interp/memory.go | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/interp/interp.go b/interp/interp.go index ba3583842..78896179e 100644 --- a/interp/interp.go +++ b/interp/interp.go @@ -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 } diff --git a/interp/memory.go b/interp/memory.go index e358124e7..c7828997d 100644 --- a/interp/memory.go +++ b/interp/memory.go @@ -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 }