Set internal linkage and keeping default visibility for anonymous functions

Этот коммит содержится в:
Phil Kedy 2022-07-28 10:34:27 -04:00 коммит произвёл Ron Evans
родитель 25c8d3ec3a
коммит 05cdde162c
10 изменённых файлов: 123 добавлений и 9 удалений

Просмотреть файл

@ -1039,9 +1039,17 @@ func (b *builder) createFunctionStart() {
b.addError(b.fn.Pos(), errValue) b.addError(b.fn.Pos(), errValue)
return return
} }
b.addStandardDefinedAttributes(b.llvmFn) b.addStandardDefinedAttributes(b.llvmFn)
if !b.info.exported { if !b.info.exported {
b.llvmFn.SetVisibility(llvm.HiddenVisibility) // Do not set visibility for local linkage (internal or private).
// Otherwise a "local linkage requires default visibility"
// assertion error in llvm-project/llvm/include/llvm/IR/GlobalValue.h:236
// is thrown.
if b.llvmFn.Linkage() != llvm.InternalLinkage &&
b.llvmFn.Linkage() != llvm.PrivateLinkage {
b.llvmFn.SetVisibility(llvm.HiddenVisibility)
}
b.llvmFn.SetUnnamedAddr(true) b.llvmFn.SetUnnamedAddr(true)
} }
if b.info.section != "" { if b.info.section != "" {
@ -1265,6 +1273,7 @@ func (b *builder) createFunction() {
// Create anonymous functions (closures etc.). // Create anonymous functions (closures etc.).
for _, sub := range b.fn.AnonFuncs { for _, sub := range b.fn.AnonFuncs {
b := newBuilder(b.compilerContext, b.Builder, sub) b := newBuilder(b.compilerContext, b.Builder, sub)
b.llvmFn.SetLinkage(llvm.InternalLinkage)
b.createFunction() b.createFunction()
} }
} }

2
compiler/testdata/basic.ll предоставленный
Просмотреть файл

@ -196,7 +196,7 @@ entry:
} }
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden void @"main.foo$1"(%main.kv.0* dereferenceable_or_null(1) %b, i8* %context) unnamed_addr #1 { define internal void @"main.foo$1"(%main.kv.0* dereferenceable_or_null(1) %b, i8* %context) unnamed_addr #1 {
entry: entry:
ret void ret void
} }

6
compiler/testdata/defer-cortex-m-qemu.ll предоставленный
Просмотреть файл

@ -115,7 +115,7 @@ declare i8* @llvm.stacksave() #2
declare void @runtime.setupDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*, i8*) #0 declare void @runtime.setupDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*, i8*) #0
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden void @"main.deferSimple$1"(i8* %context) unnamed_addr #1 { define internal void @"main.deferSimple$1"(i8* %context) unnamed_addr #1 {
entry: entry:
call void @runtime.printint32(i32 3, i8* undef) #3 call void @runtime.printint32(i32 3, i8* undef) #3
ret void ret void
@ -246,14 +246,14 @@ rundefers.end9: ; preds = %rundefers.loophead1
} }
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden void @"main.deferMultiple$1"(i8* %context) unnamed_addr #1 { define internal void @"main.deferMultiple$1"(i8* %context) unnamed_addr #1 {
entry: entry:
call void @runtime.printint32(i32 3, i8* undef) #3 call void @runtime.printint32(i32 3, i8* undef) #3
ret void ret void
} }
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden void @"main.deferMultiple$2"(i8* %context) unnamed_addr #1 { define internal void @"main.deferMultiple$2"(i8* %context) unnamed_addr #1 {
entry: entry:
call void @runtime.printint32(i32 5, i8* undef) #3 call void @runtime.printint32(i32 5, i8* undef) #3
ret void ret void

4
compiler/testdata/goroutine-cortex-m-qemu-tasks.ll предоставленный
Просмотреть файл

@ -51,7 +51,7 @@ entry:
} }
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 { define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
entry: entry:
ret void ret void
} }
@ -84,7 +84,7 @@ entry:
} }
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 { define internal void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
entry: entry:
%unpack.ptr = bitcast i8* %context to i32* %unpack.ptr = bitcast i8* %context to i32*
store i32 7, i32* %unpack.ptr, align 4 store i32 7, i32* %unpack.ptr, align 4

4
compiler/testdata/goroutine-wasm-asyncify.ll предоставленный
Просмотреть файл

@ -53,7 +53,7 @@ entry:
} }
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 { define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
entry: entry:
ret void ret void
} }
@ -90,7 +90,7 @@ entry:
} }
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 { define internal void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 {
entry: entry:
%unpack.ptr = bitcast i8* %context to i32* %unpack.ptr = bitcast i8* %context to i32*
store i32 7, i32* %unpack.ptr, align 4 store i32 7, i32* %unpack.ptr, align 4

8
testdata/generics.go предоставленный
Просмотреть файл

@ -1,11 +1,19 @@
package main package main
import (
"github.com/tinygo-org/tinygo/testdata/generics/testa"
"github.com/tinygo-org/tinygo/testdata/generics/testb"
)
func main() { func main() {
println("add:", Add(3, 5)) println("add:", Add(3, 5))
println("add:", Add(int8(3), 5)) println("add:", Add(int8(3), 5))
var c C[int] var c C[int]
c.F() // issue 2951 c.F() // issue 2951
testa.Test()
testb.Test()
} }
type Integer interface { type Integer interface {

4
testdata/generics.txt предоставленный
Просмотреть файл

@ -1,2 +1,6 @@
add: 8 add: 8
add: 8 add: 8
value: 101
value: 101
value: 501
value: 501

20
testdata/generics/testa/testa.go предоставленный Обычный файл
Просмотреть файл

@ -0,0 +1,20 @@
package testa
import (
"github.com/tinygo-org/tinygo/testdata/generics/value"
)
func Test() {
v := value.New(1)
vm := value.Map(v, Plus100)
vm.Get(callback, callback)
}
func callback(v int) {
println("value:", v)
}
// Plus100 is a `Transform` that adds 100 to `value`.
func Plus100(value int) int {
return value + 100
}

20
testdata/generics/testb/testb.go предоставленный Обычный файл
Просмотреть файл

@ -0,0 +1,20 @@
package testb
import (
"github.com/tinygo-org/tinygo/testdata/generics/value"
)
func Test() {
v := value.New(1)
vm := value.Map(v, Plus500)
vm.Get(callback, callback)
}
func callback(v int) {
println("value:", v)
}
// Plus500 is a `Transform` that adds 500 to `value`.
func Plus500(value int) int {
return value + 500
}

53
testdata/generics/value/value.go предоставленный Обычный файл
Просмотреть файл

@ -0,0 +1,53 @@
package value
type (
Value[T any] interface {
Get(Callback[T], Callback[T])
}
Callback[T any] func(T)
Transform[S any, D any] func(S) D
)
func New[T any](v T) Value[T] {
return &value[T]{
v: v,
}
}
type value[T any] struct {
v T
}
func (v *value[T]) Get(fn1, fn2 Callback[T]) {
// For example purposes.
// Normally would be asynchronous callback.
fn1(v.v)
fn2(v.v)
}
func Map[S, D any](v Value[S], tx Transform[S, D]) Value[D] {
return &mapper[S, D]{
v: v,
tx: tx,
}
}
type mapper[S, D any] struct {
v Value[S]
tx Transform[S, D]
}
func (m *mapper[S, D]) Get(fn1, fn2 Callback[D]) {
// two callbacks are passed to generate more than
// one anonymous function symbol name.
m.v.Get(func(v S) {
// anonymous function inside of anonymous function.
func() {
fn1(m.tx(v))
}()
}, func(v S) {
fn2(m.tx(v))
})
}