diff --git a/_demo/cgodefer/cgodefer.go b/_demo/cgodefer/cgodefer.go new file mode 100644 index 000000000..252aa45e5 --- /dev/null +++ b/_demo/cgodefer/cgodefer.go @@ -0,0 +1,11 @@ +package main + +/* +#include +*/ +import "C" + +func main() { + p := C.malloc(1024) + defer C.free(p) +} diff --git a/_demo/reflectfunc/reflectfunc.go b/_demo/reflectfunc/reflectfunc.go new file mode 100644 index 000000000..2cf5c378d --- /dev/null +++ b/_demo/reflectfunc/reflectfunc.go @@ -0,0 +1,37 @@ +package main + +import ( + "fmt" + "reflect" +) + +func add(a, b int) int { + return a + b +} + +func main() { + fn := func(a, b int) int { + return a + b + } + + v := reflect.ValueOf(fn) + fmt.Println(v.Type()) + fmt.Println(v.Kind()) + if v.Kind() != reflect.Func { + panic("not func") + } + + v = reflect.ValueOf(add) + fmt.Println(v.Type()) + fmt.Println(v.Kind()) + if v.Kind() != reflect.Func { + panic("not func") + } + + t := reflect.TypeOf(fn) + fmt.Println(t) + fmt.Println(t.Kind()) + if t.Kind() != reflect.Func { + panic("not func") + } +} diff --git a/cl/_testgo/closure2/in.go b/cl/_testgo/closure2/in.go new file mode 100644 index 000000000..33f0683b3 --- /dev/null +++ b/cl/_testgo/closure2/in.go @@ -0,0 +1,11 @@ +package main + +func main() { + x := 1 + f := func(i int) func(int) { + return func(i int) { + println("closure", i, x) + } + } + f(1)(2) +} diff --git a/cl/_testgo/closure2/out.ll b/cl/_testgo/closure2/out.ll new file mode 100644 index 000000000..9878e0f50 --- /dev/null +++ b/cl/_testgo/closure2/out.ll @@ -0,0 +1,96 @@ +; ModuleID = 'main' +source_filename = "main" + +%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } + +@"main.init$guard" = global i1 false, align 1 +@__llgo_argc = global i32 0, align 4 +@__llgo_argv = global ptr null, align 8 +@0 = private unnamed_addr constant [7 x i8] c"closure", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define i32 @main(i32 %0, ptr %1) { +_llgo_0: + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) + store i64 1, ptr %2, align 4 + %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) + %4 = getelementptr inbounds { ptr }, ptr %3, i32 0, i32 0 + store ptr %2, ptr %4, align 8 + %5 = alloca { ptr, ptr }, align 8 + %6 = getelementptr inbounds { ptr, ptr }, ptr %5, i32 0, i32 0 + store ptr @"main.main$1", ptr %6, align 8 + %7 = getelementptr inbounds { ptr, ptr }, ptr %5, i32 0, i32 1 + store ptr %3, ptr %7, align 8 + %8 = load { ptr, ptr }, ptr %5, align 8 + %9 = extractvalue { ptr, ptr } %8, 1 + %10 = extractvalue { ptr, ptr } %8, 0 + %11 = call { ptr, ptr } %10(ptr %9, i64 1) + %12 = extractvalue { ptr, ptr } %11, 1 + %13 = extractvalue { ptr, ptr } %11, 0 + call void %13(ptr %12, i64 2) + ret i32 0 +} + +define { ptr, ptr } @"main.main$1"(ptr %0, i64 %1) { +_llgo_0: + %2 = load { ptr }, ptr %0, align 8 + %3 = extractvalue { ptr } %2, 0 + %4 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) + %5 = getelementptr inbounds { ptr }, ptr %4, i32 0, i32 0 + store ptr %3, ptr %5, align 8 + %6 = alloca { ptr, ptr }, align 8 + %7 = getelementptr inbounds { ptr, ptr }, ptr %6, i32 0, i32 0 + store ptr @"main.main$1$1", ptr %7, align 8 + %8 = getelementptr inbounds { ptr, ptr }, ptr %6, i32 0, i32 1 + store ptr %4, ptr %8, align 8 + %9 = load { ptr, ptr }, ptr %6, align 8 + ret { ptr, ptr } %9 +} + +define void @"main.main$1$1"(ptr %0, i64 %1) { +_llgo_0: + %2 = load { ptr }, ptr %0, align 8 + %3 = extractvalue { ptr } %2, 0 + %4 = load i64, ptr %3, align 4 + %5 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 0 + store ptr @0, ptr %6, align 8 + %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 1 + store i64 7, ptr %7, align 4 + %8 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %5, align 8 + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %8) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %1) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %4) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) + ret void +} + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) + +declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") + +declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64) diff --git a/ssa/type_cvt.go b/ssa/type_cvt.go index cfefe2273..df54d0b8f 100644 --- a/ssa/type_cvt.go +++ b/ssa/type_cvt.go @@ -92,6 +92,9 @@ func (p goTypes) cvtType(typ types.Type) (raw types.Type, cvt bool) { return types.NewMap(key, elem), true } case *types.Struct: + if isClosure(t) { + return typ, false + } return p.cvtStruct(t) case *types.Named: if v, ok := p.typbg.Load(namedLinkname(t)); ok && v.(Background) == InC {