diff --git a/cl/_testdata/vargs/out.ll b/cl/_testdata/vargs/out.ll index 1c06f3f1..668d704b 100644 --- a/cl/_testdata/vargs/out.ll +++ b/cl/_testdata/vargs/out.ll @@ -12,6 +12,7 @@ source_filename = "main" @_llgo_int = linkonce global ptr null @0 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @1 = private unnamed_addr constant [22 x i8] c"type assertion failed\00", align 1 +@_llgo_string = linkonce global ptr null define void @main.init() { _llgo_0: @@ -123,7 +124,16 @@ _llgo_5: ; preds = %_llgo_2 %17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %15, i32 0, i32 1 store i64 21, ptr %17, align 4 %18 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.String" %18) + %19 = load ptr, ptr @_llgo_string, align 8 + %20 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) + store %"github.com/goplus/llgo/internal/runtime.String" %18, ptr %20, align 8 + %21 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %22 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %21, i32 0, i32 0 + store ptr %19, ptr %22, align 8 + %23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %21, i32 0, i32 1 + store ptr %20, ptr %23, align 8 + %24 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %21, align 8 + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %24) unreachable } @@ -143,6 +153,16 @@ _llgo_1: ; preds = %_llgo_0 br label %_llgo_2 _llgo_2: ; preds = %_llgo_1, %_llgo_0 + %3 = load ptr, ptr @_llgo_string, align 8 + %4 = icmp eq ptr %3, null + br i1 %4, label %_llgo_3, label %_llgo_4 + +_llgo_3: ; preds = %_llgo_2 + %5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 24) + store ptr %5, ptr @_llgo_string, align 8 + br label %_llgo_4 + +_llgo_4: ; preds = %_llgo_3, %_llgo_2 ret void } @@ -150,6 +170,8 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1) +declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) + declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") declare i32 @printf(ptr, ...) diff --git a/cl/_testgo/interface/in.go b/cl/_testgo/interface/in.go new file mode 100644 index 00000000..46b026e4 --- /dev/null +++ b/cl/_testgo/interface/in.go @@ -0,0 +1,27 @@ +package main + +import ( + "github.com/goplus/llgo/cl/internal/foo" +) + +type Game1 struct { + *foo.Game +} + +type Game2 struct { +} + +func (p *Game2) initGame() { +} + +func main() { + var g1 any = &Game1{&foo.Game{}} + var g2 any = &Game2{} + v1, ok := g1.(foo.Gamer) + println("OK", v1, ok) + if ok { + v1.Load() + } + v2, ok := g2.(foo.Gamer) + println("FAIL", v2, ok) +} diff --git a/cl/_testgo/interface/out.ll b/cl/_testgo/interface/out.ll new file mode 100644 index 00000000..63c1ea92 --- /dev/null +++ b/cl/_testgo/interface/out.ll @@ -0,0 +1,584 @@ +; ModuleID = 'main' +source_filename = "main" + +%main.Game1 = type { ptr } +%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr } +%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr } +%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } +%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } +%"github.com/goplus/llgo/internal/abi.Method" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, ptr, ptr } +%"github.com/goplus/llgo/internal/abi.Imethod" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr } +%"github.com/goplus/llgo/internal/abi.StructField" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1 } + +@"main.init$guard" = global ptr null +@__llgo_argc = global ptr null +@__llgo_argv = global ptr null +@"*_llgo_main.Game1" = linkonce global ptr null +@_llgo_main.Game1 = linkonce global ptr null +@_llgo_int = linkonce global ptr null +@0 = private unnamed_addr constant [5 x i8] c"main\00", align 1 +@1 = private unnamed_addr constant [11 x i8] c"main.Game1\00", align 1 +@"*_llgo_main.Game2" = linkonce global ptr null +@_llgo_main.Game2 = linkonce global ptr null +@"_llgo_struct$n1H8J_3prDN3firMwPxBLVTkE5hJ9Di-AqNvaC9jczw" = linkonce global ptr null +@2 = private unnamed_addr constant [5 x i8] c"main\00", align 1 +@3 = private unnamed_addr constant [9 x i8] c"initGame\00", align 1 +@4 = private unnamed_addr constant [14 x i8] c"main.initGame\00", align 1 +@"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac" = linkonce global ptr null +@5 = private unnamed_addr constant [5 x i8] c"main\00", align 1 +@6 = private unnamed_addr constant [11 x i8] c"main.Game2\00", align 1 +@"_llgo_github.com/goplus/llgo/cl/internal/foo.Gamer" = linkonce global ptr null +@7 = private unnamed_addr constant [5 x i8] c"Load\00", align 1 +@8 = private unnamed_addr constant [48 x i8] c"github.com/goplus/llgo/cl/internal/foo.initGame\00", align 1 +@9 = private unnamed_addr constant [39 x i8] c"github.com/goplus/llgo/cl/internal/foo\00", align 1 +@10 = private unnamed_addr constant [45 x i8] c"github.com/goplus/llgo/cl/internal/foo.Gamer\00", align 1 +@"main.iface$sO8a1LvuUsjXwiwaC6sR9-L4DiYgiOnZi7iosyShJXg" = global ptr null +@11 = private unnamed_addr constant [5 x i8] c"Load\00", align 1 +@12 = private unnamed_addr constant [48 x i8] c"github.com/goplus/llgo/cl/internal/foo.initGame\00", align 1 +@13 = private unnamed_addr constant [5 x i8] c"main\00", align 1 +@14 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 +@15 = private unnamed_addr constant [3 x i8] c"OK\00", align 1 +@16 = private unnamed_addr constant [5 x i8] c"FAIL\00", align 1 + +define void @main.Game1.Load(%main.Game1 %0) { +_llgo_0: + %1 = alloca %main.Game1, align 8 + %2 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %1, i64 8) + store %main.Game1 %0, ptr %2, align 8 + %3 = getelementptr inbounds %main.Game1, ptr %2, i32 0, i32 0 + %4 = load ptr, ptr %3, align 8 + call void @"github.com/goplus/llgo/cl/internal/foo.(*Game).Load"(ptr %4) + ret void +} + +define void @main.Game1.initGame(%main.Game1 %0) { +_llgo_0: + %1 = alloca %main.Game1, align 8 + %2 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %1, i64 8) + store %main.Game1 %0, ptr %2, align 8 + %3 = getelementptr inbounds %main.Game1, ptr %2, i32 0, i32 0 + %4 = load ptr, ptr %3, align 8 + call void @"github.com/goplus/llgo/cl/internal/foo.(*Game).initGame"(ptr %4) + ret void +} + +define void @"main.(*Game1).Load"(ptr %0) { +_llgo_0: + %1 = getelementptr inbounds %main.Game1, ptr %0, i32 0, i32 0 + %2 = load ptr, ptr %1, align 8 + call void @"github.com/goplus/llgo/cl/internal/foo.(*Game).Load"(ptr %2) + ret void +} + +define void @"main.(*Game1).initGame"(ptr %0) { +_llgo_0: + %1 = getelementptr inbounds %main.Game1, ptr %0, i32 0, i32 0 + %2 = load ptr, ptr %1, align 8 + call void @"github.com/goplus/llgo/cl/internal/foo.(*Game).initGame"(ptr %2) + ret void +} + +define void @"main.(*Game2).initGame"(ptr %0) { +_llgo_0: + ret void +} + +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 + call void @"github.com/goplus/llgo/cl/internal/foo.init"() + call void @"main.init$after"() + 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) + %3 = getelementptr inbounds %main.Game1, ptr %2, i32 0, i32 0 + %4 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 0) + store ptr %4, ptr %3, align 8 + %5 = load ptr, ptr @"*_llgo_main.Game1", align 8 + %6 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %6, i32 0, i32 0 + store ptr %5, ptr %7, align 8 + %8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %6, i32 0, i32 1 + store ptr %2, ptr %8, align 8 + %9 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %6, align 8 + %10 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 0) + %11 = load ptr, ptr @"*_llgo_main.Game2", align 8 + %12 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %12, i32 0, i32 0 + store ptr %11, ptr %13, align 8 + %14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %12, i32 0, i32 1 + store ptr %10, ptr %14, align 8 + %15 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %12, align 8 + %16 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %9, 0 + %17 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/internal/foo.Gamer", align 8 + %18 = call i1 @"github.com/goplus/llgo/internal/runtime.Implements"(ptr %17, ptr %16) + br i1 %18, label %_llgo_3, label %_llgo_4 + +_llgo_1: ; preds = %_llgo_5 + %19 = call ptr @"github.com/goplus/llgo/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/internal/runtime.iface" %48) + %20 = extractvalue %"github.com/goplus/llgo/internal/runtime.iface" %48, 0 + %21 = getelementptr ptr, ptr %20, i64 3 + %22 = load ptr, ptr %21, align 8 + %23 = alloca { ptr, ptr }, align 8 + %24 = getelementptr inbounds { ptr, ptr }, ptr %23, i32 0, i32 0 + store ptr %22, ptr %24, align 8 + %25 = getelementptr inbounds { ptr, ptr }, ptr %23, i32 0, i32 1 + store ptr %19, ptr %25, align 8 + %26 = load { ptr, ptr }, ptr %23, align 8 + %27 = extractvalue { ptr, ptr } %26, 1 + %28 = extractvalue { ptr, ptr } %26, 0 + call void %28(ptr %27) + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_5 + %29 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %15, 0 + %30 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/internal/foo.Gamer", align 8 + %31 = call i1 @"github.com/goplus/llgo/internal/runtime.Implements"(ptr %30, ptr %29) + br i1 %31, label %_llgo_6, label %_llgo_7 + +_llgo_3: ; preds = %_llgo_0 + %32 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %9, 1 + %33 = load ptr, ptr @"main.iface$sO8a1LvuUsjXwiwaC6sR9-L4DiYgiOnZi7iosyShJXg", align 8 + %34 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %33, ptr %16) + %35 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8 + %36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %35, i32 0, i32 0 + store ptr %34, ptr %36, align 8 + %37 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %35, i32 0, i32 1 + store ptr %32, ptr %37, align 8 + %38 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %35, align 8 + %39 = alloca { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, align 8 + %40 = getelementptr inbounds { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %39, i32 0, i32 0 + store %"github.com/goplus/llgo/internal/runtime.iface" %38, ptr %40, align 8 + %41 = getelementptr inbounds { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %39, i32 0, i32 1 + store i1 true, ptr %41, align 1 + %42 = load { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %39, align 8 + br label %_llgo_5 + +_llgo_4: ; preds = %_llgo_0 + %43 = alloca { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, align 8 + %44 = getelementptr inbounds { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %43, i32 0, i32 0 + store { ptr, ptr } zeroinitializer, ptr %44, align 8 + %45 = getelementptr inbounds { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %43, i32 0, i32 1 + store i1 false, ptr %45, align 1 + %46 = load { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %43, align 8 + br label %_llgo_5 + +_llgo_5: ; preds = %_llgo_4, %_llgo_3 + %47 = phi { %"github.com/goplus/llgo/internal/runtime.iface", i1 } [ %42, %_llgo_3 ], [ %46, %_llgo_4 ] + %48 = extractvalue { %"github.com/goplus/llgo/internal/runtime.iface", i1 } %47, 0 + %49 = extractvalue { %"github.com/goplus/llgo/internal/runtime.iface", i1 } %47, 1 + %50 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %51 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %50, i32 0, i32 0 + store ptr @15, ptr %51, align 8 + %52 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %50, i32 0, i32 1 + store i64 2, ptr %52, align 4 + %53 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %50, align 8 + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %53) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) + call void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface" %48) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) + call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %49) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) + br i1 %49, label %_llgo_1, label %_llgo_2 + +_llgo_6: ; preds = %_llgo_2 + %54 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %15, 1 + %55 = load ptr, ptr @"main.iface$sO8a1LvuUsjXwiwaC6sR9-L4DiYgiOnZi7iosyShJXg", align 8 + %56 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %55, ptr %29) + %57 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8 + %58 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %57, i32 0, i32 0 + store ptr %56, ptr %58, align 8 + %59 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %57, i32 0, i32 1 + store ptr %54, ptr %59, align 8 + %60 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %57, align 8 + %61 = alloca { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, align 8 + %62 = getelementptr inbounds { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %61, i32 0, i32 0 + store %"github.com/goplus/llgo/internal/runtime.iface" %60, ptr %62, align 8 + %63 = getelementptr inbounds { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %61, i32 0, i32 1 + store i1 true, ptr %63, align 1 + %64 = load { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %61, align 8 + br label %_llgo_8 + +_llgo_7: ; preds = %_llgo_2 + %65 = alloca { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, align 8 + %66 = getelementptr inbounds { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %65, i32 0, i32 0 + store { ptr, ptr } zeroinitializer, ptr %66, align 8 + %67 = getelementptr inbounds { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %65, i32 0, i32 1 + store i1 false, ptr %67, align 1 + %68 = load { %"github.com/goplus/llgo/internal/runtime.iface", i1 }, ptr %65, align 8 + br label %_llgo_8 + +_llgo_8: ; preds = %_llgo_7, %_llgo_6 + %69 = phi { %"github.com/goplus/llgo/internal/runtime.iface", i1 } [ %64, %_llgo_6 ], [ %68, %_llgo_7 ] + %70 = extractvalue { %"github.com/goplus/llgo/internal/runtime.iface", i1 } %69, 0 + %71 = extractvalue { %"github.com/goplus/llgo/internal/runtime.iface", i1 } %69, 1 + %72 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %73 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %72, i32 0, i32 0 + store ptr @16, ptr %73, align 8 + %74 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %72, i32 0, i32 1 + store i64 4, ptr %74, align 4 + %75 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %72, align 8 + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %75) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) + call void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface" %70) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) + call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %71) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) + ret i32 0 +} + +declare ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr, i64) + +declare void @"github.com/goplus/llgo/cl/internal/foo.(*Game).Load"(ptr) + +declare void @"github.com/goplus/llgo/cl/internal/foo.(*Game).initGame"(ptr) + +declare void @"github.com/goplus/llgo/cl/internal/foo.init"() + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) + +define void @"main.init$after"() { +_llgo_0: + %0 = load ptr, ptr @_llgo_main.Game1, align 8 + %1 = icmp eq ptr %0, null + br i1 %1, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %2 = call ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64 2, i64 0, i64 0) + store ptr %2, ptr @_llgo_main.Game1, align 8 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + %3 = load ptr, ptr @_llgo_int, align 8 + %4 = icmp eq ptr %3, null + br i1 %4, label %_llgo_3, label %_llgo_4 + +_llgo_3: ; preds = %_llgo_2 + %5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) + store ptr %5, ptr @_llgo_int, align 8 + br label %_llgo_4 + +_llgo_4: ; preds = %_llgo_3, %_llgo_2 + %6 = load ptr, ptr @_llgo_int, align 8 + br i1 %1, label %_llgo_5, label %_llgo_6 + +_llgo_5: ; preds = %_llgo_4 + %7 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 0 + store ptr @0, ptr %8, align 8 + %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 1 + store i64 4, ptr %9, align 4 + %10 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %7, align 8 + %11 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %11, i32 0, i32 0 + store ptr @1, ptr %12, align 8 + %13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %11, i32 0, i32 1 + store i64 10, ptr %13, align 4 + %14 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %11, align 8 + call void @"github.com/goplus/llgo/internal/runtime.InitNamed"(ptr %2, %"github.com/goplus/llgo/internal/runtime.String" %10, %"github.com/goplus/llgo/internal/runtime.String" %14, ptr %6, { ptr, i64, i64 } zeroinitializer, { ptr, i64, i64 } zeroinitializer) + br label %_llgo_6 + +_llgo_6: ; preds = %_llgo_5, %_llgo_4 + %15 = load ptr, ptr @_llgo_main.Game1, align 8 + %16 = load ptr, ptr @"*_llgo_main.Game1", align 8 + %17 = icmp eq ptr %16, null + br i1 %17, label %_llgo_7, label %_llgo_8 + +_llgo_7: ; preds = %_llgo_6 + %18 = call ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr %15) + store ptr %18, ptr @"*_llgo_main.Game1", align 8 + br label %_llgo_8 + +_llgo_8: ; preds = %_llgo_7, %_llgo_6 + %19 = load ptr, ptr @_llgo_main.Game2, align 8 + %20 = icmp eq ptr %19, null + br i1 %20, label %_llgo_9, label %_llgo_10 + +_llgo_9: ; preds = %_llgo_8 + %21 = call ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64 25, i64 0, i64 1) + store ptr %21, ptr @_llgo_main.Game2, align 8 + br label %_llgo_10 + +_llgo_10: ; preds = %_llgo_9, %_llgo_8 + %22 = load ptr, ptr @"_llgo_struct$n1H8J_3prDN3firMwPxBLVTkE5hJ9Di-AqNvaC9jczw", align 8 + %23 = icmp eq ptr %22, null + br i1 %23, label %_llgo_11, label %_llgo_12 + +_llgo_11: ; preds = %_llgo_10 + %24 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %24, i32 0, i32 0 + store ptr @2, ptr %25, align 8 + %26 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %24, i32 0, i32 1 + store i64 4, ptr %26, align 4 + %27 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %24, align 8 + %28 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0) + %29 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 + %30 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %29, i32 0, i32 0 + store ptr %28, ptr %30, align 8 + %31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %29, i32 0, i32 1 + store i64 0, ptr %31, align 4 + %32 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %29, i32 0, i32 2 + store i64 0, ptr %32, align 4 + %33 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %29, align 8 + %34 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %27, i64 0, %"github.com/goplus/llgo/internal/runtime.Slice" %33) + store ptr %34, ptr @"_llgo_struct$n1H8J_3prDN3firMwPxBLVTkE5hJ9Di-AqNvaC9jczw", align 8 + br label %_llgo_12 + +_llgo_12: ; preds = %_llgo_11, %_llgo_10 + %35 = load ptr, ptr @"_llgo_struct$n1H8J_3prDN3firMwPxBLVTkE5hJ9Di-AqNvaC9jczw", align 8 + br i1 %20, label %_llgo_13, label %_llgo_14 + +_llgo_13: ; preds = %_llgo_12 + %36 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %37 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %36, i32 0, i32 0 + store ptr @3, ptr %37, align 8 + %38 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %36, i32 0, i32 1 + store i64 8, ptr %38, align 4 + %39 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %36, align 8 + %40 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %41 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %40, i32 0, i32 0 + store ptr @4, ptr %41, align 8 + %42 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %40, i32 0, i32 1 + store i64 13, ptr %42, align 4 + %43 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %40, align 8 + %44 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8 + %45 = icmp eq ptr %44, null + br i1 %45, label %_llgo_15, label %_llgo_16 + +_llgo_14: ; preds = %_llgo_16, %_llgo_12 + %46 = load ptr, ptr @_llgo_main.Game2, align 8 + %47 = load ptr, ptr @"*_llgo_main.Game2", align 8 + %48 = icmp eq ptr %47, null + br i1 %48, label %_llgo_17, label %_llgo_18 + +_llgo_15: ; preds = %_llgo_13 + %49 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0) + %50 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 + %51 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %50, i32 0, i32 0 + store ptr %49, ptr %51, align 8 + %52 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %50, i32 0, i32 1 + store i64 0, ptr %52, align 4 + %53 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %50, i32 0, i32 2 + store i64 0, ptr %53, align 4 + %54 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %50, align 8 + %55 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0) + %56 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 + %57 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %56, i32 0, i32 0 + store ptr %55, ptr %57, align 8 + %58 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %56, i32 0, i32 1 + store i64 0, ptr %58, align 4 + %59 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %56, i32 0, i32 2 + store i64 0, ptr %59, align 4 + %60 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %56, align 8 + %61 = call ptr @"github.com/goplus/llgo/internal/runtime.Func"(%"github.com/goplus/llgo/internal/runtime.Slice" %54, %"github.com/goplus/llgo/internal/runtime.Slice" %60, i1 false) + store ptr %61, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8 + br label %_llgo_16 + +_llgo_16: ; preds = %_llgo_15, %_llgo_13 + %62 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8 + %63 = alloca %"github.com/goplus/llgo/internal/abi.Method", align 8 + %64 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %63, i32 0, i32 0 + store %"github.com/goplus/llgo/internal/runtime.String" %43, ptr %64, align 8 + %65 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %63, i32 0, i32 1 + store ptr %62, ptr %65, align 8 + %66 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %63, i32 0, i32 2 + store ptr @"main.(*Game2).initGame", ptr %66, align 8 + %67 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %63, i32 0, i32 3 + store ptr @"main.(*Game2).initGame", ptr %67, align 8 + %68 = load %"github.com/goplus/llgo/internal/abi.Method", ptr %63, align 8 + %69 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 40) + %70 = getelementptr %"github.com/goplus/llgo/internal/abi.Method", ptr %69, i64 0 + store %"github.com/goplus/llgo/internal/abi.Method" %68, ptr %70, align 8 + %71 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 + %72 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %71, i32 0, i32 0 + store ptr %69, ptr %72, align 8 + %73 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %71, i32 0, i32 1 + store i64 1, ptr %73, align 4 + %74 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %71, i32 0, i32 2 + store i64 1, ptr %74, align 4 + %75 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %71, align 8 + %76 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %77 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %76, i32 0, i32 0 + store ptr @5, ptr %77, align 8 + %78 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %76, i32 0, i32 1 + store i64 4, ptr %78, align 4 + %79 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %76, align 8 + %80 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %81 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %80, i32 0, i32 0 + store ptr @6, ptr %81, align 8 + %82 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %80, i32 0, i32 1 + store i64 10, ptr %82, align 4 + %83 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %80, align 8 + call void @"github.com/goplus/llgo/internal/runtime.InitNamed"(ptr %21, %"github.com/goplus/llgo/internal/runtime.String" %79, %"github.com/goplus/llgo/internal/runtime.String" %83, ptr %35, { ptr, i64, i64 } zeroinitializer, %"github.com/goplus/llgo/internal/runtime.Slice" %75) + br label %_llgo_14 + +_llgo_17: ; preds = %_llgo_14 + %84 = call ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr %46) + store ptr %84, ptr @"*_llgo_main.Game2", align 8 + br label %_llgo_18 + +_llgo_18: ; preds = %_llgo_17, %_llgo_14 + %85 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8 + %86 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8 + %87 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/internal/foo.Gamer", align 8 + %88 = icmp eq ptr %87, null + br i1 %88, label %_llgo_19, label %_llgo_20 + +_llgo_19: ; preds = %_llgo_18 + %89 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %90 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %89, i32 0, i32 0 + store ptr @7, ptr %90, align 8 + %91 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %89, i32 0, i32 1 + store i64 4, ptr %91, align 4 + %92 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %89, align 8 + %93 = alloca %"github.com/goplus/llgo/internal/abi.Imethod", align 8 + %94 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %93, i32 0, i32 0 + store %"github.com/goplus/llgo/internal/runtime.String" %92, ptr %94, align 8 + %95 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %93, i32 0, i32 1 + store ptr %85, ptr %95, align 8 + %96 = load %"github.com/goplus/llgo/internal/abi.Imethod", ptr %93, align 8 + %97 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %98 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %97, i32 0, i32 0 + store ptr @8, ptr %98, align 8 + %99 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %97, i32 0, i32 1 + store i64 47, ptr %99, align 4 + %100 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %97, align 8 + %101 = alloca %"github.com/goplus/llgo/internal/abi.Imethod", align 8 + %102 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %101, i32 0, i32 0 + store %"github.com/goplus/llgo/internal/runtime.String" %100, ptr %102, align 8 + %103 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %101, i32 0, i32 1 + store ptr %86, ptr %103, align 8 + %104 = load %"github.com/goplus/llgo/internal/abi.Imethod", ptr %101, align 8 + %105 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 48) + %106 = getelementptr %"github.com/goplus/llgo/internal/abi.Imethod", ptr %105, i64 0 + store %"github.com/goplus/llgo/internal/abi.Imethod" %96, ptr %106, align 8 + %107 = getelementptr %"github.com/goplus/llgo/internal/abi.Imethod", ptr %105, i64 1 + store %"github.com/goplus/llgo/internal/abi.Imethod" %104, ptr %107, align 8 + %108 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 + %109 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %108, i32 0, i32 0 + store ptr %105, ptr %109, align 8 + %110 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %108, i32 0, i32 1 + store i64 2, ptr %110, align 4 + %111 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %108, i32 0, i32 2 + store i64 2, ptr %111, align 4 + %112 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %108, align 8 + %113 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %114 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %113, i32 0, i32 0 + store ptr @9, ptr %114, align 8 + %115 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %113, i32 0, i32 1 + store i64 38, ptr %115, align 4 + %116 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %113, align 8 + %117 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %118 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %117, i32 0, i32 0 + store ptr @10, ptr %118, align 8 + %119 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %117, i32 0, i32 1 + store i64 44, ptr %119, align 4 + %120 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %117, align 8 + %121 = call ptr @"github.com/goplus/llgo/internal/runtime.Interface"(%"github.com/goplus/llgo/internal/runtime.String" %116, %"github.com/goplus/llgo/internal/runtime.String" %120, %"github.com/goplus/llgo/internal/runtime.Slice" %112) + store ptr %121, ptr @"_llgo_github.com/goplus/llgo/cl/internal/foo.Gamer", align 8 + br label %_llgo_20 + +_llgo_20: ; preds = %_llgo_19, %_llgo_18 + %122 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8 + %123 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8 + %124 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %125 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %124, i32 0, i32 0 + store ptr @11, ptr %125, align 8 + %126 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %124, i32 0, i32 1 + store i64 4, ptr %126, align 4 + %127 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %124, align 8 + %128 = alloca %"github.com/goplus/llgo/internal/abi.Imethod", align 8 + %129 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %128, i32 0, i32 0 + store %"github.com/goplus/llgo/internal/runtime.String" %127, ptr %129, align 8 + %130 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %128, i32 0, i32 1 + store ptr %122, ptr %130, align 8 + %131 = load %"github.com/goplus/llgo/internal/abi.Imethod", ptr %128, align 8 + %132 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %133 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %132, i32 0, i32 0 + store ptr @12, ptr %133, align 8 + %134 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %132, i32 0, i32 1 + store i64 47, ptr %134, align 4 + %135 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %132, align 8 + %136 = alloca %"github.com/goplus/llgo/internal/abi.Imethod", align 8 + %137 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %136, i32 0, i32 0 + store %"github.com/goplus/llgo/internal/runtime.String" %135, ptr %137, align 8 + %138 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %136, i32 0, i32 1 + store ptr %123, ptr %138, align 8 + %139 = load %"github.com/goplus/llgo/internal/abi.Imethod", ptr %136, align 8 + %140 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 48) + %141 = getelementptr %"github.com/goplus/llgo/internal/abi.Imethod", ptr %140, i64 0 + store %"github.com/goplus/llgo/internal/abi.Imethod" %131, ptr %141, align 8 + %142 = getelementptr %"github.com/goplus/llgo/internal/abi.Imethod", ptr %140, i64 1 + store %"github.com/goplus/llgo/internal/abi.Imethod" %139, ptr %142, align 8 + %143 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 + %144 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %143, i32 0, i32 0 + store ptr %140, ptr %144, align 8 + %145 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %143, i32 0, i32 1 + store i64 2, ptr %145, align 4 + %146 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %143, i32 0, i32 2 + store i64 2, ptr %146, align 4 + %147 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %143, align 8 + %148 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %149 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %148, i32 0, i32 0 + store ptr @13, ptr %149, align 8 + %150 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %148, i32 0, i32 1 + store i64 4, ptr %150, align 4 + %151 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %148, align 8 + %152 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %153 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %152, i32 0, i32 0 + store ptr @14, ptr %153, align 8 + %154 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %152, i32 0, i32 1 + store i64 0, ptr %154, align 4 + %155 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %152, align 8 + %156 = call ptr @"github.com/goplus/llgo/internal/runtime.Interface"(%"github.com/goplus/llgo/internal/runtime.String" %151, %"github.com/goplus/llgo/internal/runtime.String" %155, %"github.com/goplus/llgo/internal/runtime.Slice" %147) + store ptr %156, ptr @"main.iface$sO8a1LvuUsjXwiwaC6sR9-L4DiYgiOnZi7iosyShJXg", align 8 + ret void +} + +declare ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64, i64, i64) + +declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) + +declare void @"github.com/goplus/llgo/internal/runtime.InitNamed"(ptr, %"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String", ptr, %"github.com/goplus/llgo/internal/runtime.Slice", %"github.com/goplus/llgo/internal/runtime.Slice") + +declare ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr) + +declare ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String", i64, %"github.com/goplus/llgo/internal/runtime.Slice") + +declare %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1) + +declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) + +declare ptr @"github.com/goplus/llgo/internal/runtime.Func"(%"github.com/goplus/llgo/internal/runtime.Slice", %"github.com/goplus/llgo/internal/runtime.Slice", i1) + +declare ptr @"github.com/goplus/llgo/internal/runtime.Interface"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.Slice") + +declare i1 @"github.com/goplus/llgo/internal/runtime.Implements"(ptr, ptr) + +declare ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr, ptr) + +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.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface") + +declare void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1) + +declare ptr @"github.com/goplus/llgo/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/internal/runtime.iface") diff --git a/cl/_testgo/invoke/in.go b/cl/_testgo/invoke/in.go index a6716183..d4f9e93a 100644 --- a/cl/_testgo/invoke/in.go +++ b/cl/_testgo/invoke/in.go @@ -53,7 +53,10 @@ func main() { println(i, m) m = &t invoke(m) - // panic + var a any = T{"world"} + invoke(a.(I)) + invoke(a.(interface{}).(interface{ Invoke() int })) + //panic invoke(nil) } diff --git a/cl/_testgo/invoke/out.ll b/cl/_testgo/invoke/out.ll index 3397cae1..12c97a0c 100644 --- a/cl/_testgo/invoke/out.ll +++ b/cl/_testgo/invoke/out.ll @@ -5,6 +5,7 @@ source_filename = "main" %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/internal/runtime.String", ptr } +%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/abi.StructField" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1 } %"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } %"github.com/goplus/llgo/internal/abi.Method" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, ptr, ptr } @@ -58,6 +59,17 @@ source_filename = "main" @25 = private unnamed_addr constant [7 x i8] c"Method\00", align 1 @26 = private unnamed_addr constant [5 x i8] c"main\00", align 1 @27 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 +@28 = private unnamed_addr constant [6 x i8] c"world\00", align 1 +@_llgo_main.I = linkonce global ptr null +@29 = private unnamed_addr constant [7 x i8] c"Invoke\00", align 1 +@30 = private unnamed_addr constant [5 x i8] c"main\00", align 1 +@31 = private unnamed_addr constant [7 x i8] c"main.I\00", align 1 +@32 = private unnamed_addr constant [22 x i8] c"type assertion failed\00", align 1 +@_llgo_any = linkonce global ptr null +@33 = private unnamed_addr constant [5 x i8] c"main\00", align 1 +@34 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 +@35 = private unnamed_addr constant [22 x i8] c"type assertion failed\00", align 1 +@36 = private unnamed_addr constant [22 x i8] c"type assertion failed\00", align 1 define i64 @main.T.Invoke(%main.T %0) { _llgo_0: @@ -326,8 +338,129 @@ _llgo_0: store ptr %88, ptr %93, align 8 %94 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %91, align 8 call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %94) + %95 = alloca %main.T, align 8 + %96 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %95, i64 16) + %97 = getelementptr inbounds %main.T, ptr %96, i32 0, i32 0 + %98 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %99 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %98, i32 0, i32 0 + store ptr @28, ptr %99, align 8 + %100 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %98, i32 0, i32 1 + store i64 5, ptr %100, align 4 + %101 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %98, align 8 + store %"github.com/goplus/llgo/internal/runtime.String" %101, ptr %97, align 8 + %102 = load %main.T, ptr %96, align 8 + %103 = load ptr, ptr @_llgo_main.T, align 8 + %104 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) + store %main.T %102, ptr %104, align 8 + %105 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %106 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %105, i32 0, i32 0 + store ptr %103, ptr %106, align 8 + %107 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %105, i32 0, i32 1 + store ptr %104, ptr %107, align 8 + %108 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %105, align 8 + %109 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %108, 0 + %110 = load ptr, ptr @_llgo_main.I, align 8 + %111 = call i1 @"github.com/goplus/llgo/internal/runtime.Implements"(ptr %110, ptr %109) + br i1 %111, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %112 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %108, 1 + %113 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8 + %114 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %113, ptr %109) + %115 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8 + %116 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %115, i32 0, i32 0 + store ptr %114, ptr %116, align 8 + %117 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %115, i32 0, i32 1 + store ptr %112, ptr %117, align 8 + %118 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %115, align 8 + call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %118) + %119 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %108, 0 + %120 = load ptr, ptr @_llgo_any, align 8 + br i1 true, label %_llgo_3, label %_llgo_4 + +_llgo_2: ; preds = %_llgo_0 + %121 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %122 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %121, i32 0, i32 0 + store ptr @32, ptr %122, align 8 + %123 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %121, i32 0, i32 1 + store i64 21, ptr %123, align 4 + %124 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %121, align 8 + %125 = load ptr, ptr @_llgo_string, align 8 + %126 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) + store %"github.com/goplus/llgo/internal/runtime.String" %124, ptr %126, align 8 + %127 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %128 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %127, i32 0, i32 0 + store ptr %125, ptr %128, align 8 + %129 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %127, i32 0, i32 1 + store ptr %126, ptr %129, align 8 + %130 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %127, align 8 + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %130) + unreachable + +_llgo_3: ; preds = %_llgo_1 + %131 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %108, 1 + %132 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %133 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %132, i32 0, i32 0 + store ptr %119, ptr %133, align 8 + %134 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %132, i32 0, i32 1 + store ptr %131, ptr %134, align 8 + %135 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %132, align 8 + %136 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %135, 0 + %137 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8 + %138 = call i1 @"github.com/goplus/llgo/internal/runtime.Implements"(ptr %137, ptr %136) + br i1 %138, label %_llgo_5, label %_llgo_6 + +_llgo_4: ; preds = %_llgo_1 + %139 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %140 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %139, i32 0, i32 0 + store ptr @35, ptr %140, align 8 + %141 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %139, i32 0, i32 1 + store i64 21, ptr %141, align 4 + %142 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %139, align 8 + %143 = load ptr, ptr @_llgo_string, align 8 + %144 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) + store %"github.com/goplus/llgo/internal/runtime.String" %142, ptr %144, align 8 + %145 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %146 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %145, i32 0, i32 0 + store ptr %143, ptr %146, align 8 + %147 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %145, i32 0, i32 1 + store ptr %144, ptr %147, align 8 + %148 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %145, align 8 + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %148) + unreachable + +_llgo_5: ; preds = %_llgo_3 + %149 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %135, 1 + %150 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8 + %151 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %150, ptr %136) + %152 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8 + %153 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %152, i32 0, i32 0 + store ptr %151, ptr %153, align 8 + %154 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %152, i32 0, i32 1 + store ptr %149, ptr %154, align 8 + %155 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %152, align 8 + call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %155) call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" zeroinitializer) ret i32 0 + +_llgo_6: ; preds = %_llgo_3 + %156 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %157 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %156, i32 0, i32 0 + store ptr @36, ptr %157, align 8 + %158 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %156, i32 0, i32 1 + store i64 21, ptr %158, align 4 + %159 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %156, align 8 + %160 = load ptr, ptr @_llgo_string, align 8 + %161 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) + store %"github.com/goplus/llgo/internal/runtime.String" %159, ptr %161, align 8 + %162 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %163 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %162, i32 0, i32 0 + store ptr %160, ptr %163, align 8 + %164 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %162, i32 0, i32 1 + store ptr %161, ptr %164, align 8 + %165 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %162, align 8 + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %165) + unreachable } declare ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr, i64) @@ -945,6 +1078,83 @@ _llgo_39: ; preds = %_llgo_38 br label %_llgo_40 _llgo_40: ; preds = %_llgo_39, %_llgo_38 + %317 = load ptr, ptr @"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA", align 8 + %318 = load ptr, ptr @_llgo_main.I, align 8 + %319 = icmp eq ptr %318, null + br i1 %319, label %_llgo_41, label %_llgo_42 + +_llgo_41: ; preds = %_llgo_40 + %320 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %321 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %320, i32 0, i32 0 + store ptr @29, ptr %321, align 8 + %322 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %320, i32 0, i32 1 + store i64 6, ptr %322, align 4 + %323 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %320, align 8 + %324 = alloca %"github.com/goplus/llgo/internal/abi.Imethod", align 8 + %325 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %324, i32 0, i32 0 + store %"github.com/goplus/llgo/internal/runtime.String" %323, ptr %325, align 8 + %326 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %324, i32 0, i32 1 + store ptr %317, ptr %326, align 8 + %327 = load %"github.com/goplus/llgo/internal/abi.Imethod", ptr %324, align 8 + %328 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24) + %329 = getelementptr %"github.com/goplus/llgo/internal/abi.Imethod", ptr %328, i64 0 + store %"github.com/goplus/llgo/internal/abi.Imethod" %327, ptr %329, align 8 + %330 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 + %331 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %330, i32 0, i32 0 + store ptr %328, ptr %331, align 8 + %332 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %330, i32 0, i32 1 + store i64 1, ptr %332, align 4 + %333 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %330, i32 0, i32 2 + store i64 1, ptr %333, align 4 + %334 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %330, align 8 + %335 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %336 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %335, i32 0, i32 0 + store ptr @30, ptr %336, align 8 + %337 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %335, i32 0, i32 1 + store i64 4, ptr %337, align 4 + %338 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %335, align 8 + %339 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %340 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %339, i32 0, i32 0 + store ptr @31, ptr %340, align 8 + %341 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %339, i32 0, i32 1 + store i64 6, ptr %341, align 4 + %342 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %339, align 8 + %343 = call ptr @"github.com/goplus/llgo/internal/runtime.Interface"(%"github.com/goplus/llgo/internal/runtime.String" %338, %"github.com/goplus/llgo/internal/runtime.String" %342, %"github.com/goplus/llgo/internal/runtime.Slice" %334) + store ptr %343, ptr @_llgo_main.I, align 8 + br label %_llgo_42 + +_llgo_42: ; preds = %_llgo_41, %_llgo_40 + %344 = load ptr, ptr @_llgo_any, align 8 + %345 = icmp eq ptr %344, null + br i1 %345, label %_llgo_43, label %_llgo_44 + +_llgo_43: ; preds = %_llgo_42 + %346 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0) + %347 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 + %348 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %347, i32 0, i32 0 + store ptr %346, ptr %348, align 8 + %349 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %347, i32 0, i32 1 + store i64 0, ptr %349, align 4 + %350 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %347, i32 0, i32 2 + store i64 0, ptr %350, align 4 + %351 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %347, align 8 + %352 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %353 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %352, i32 0, i32 0 + store ptr @33, ptr %353, align 8 + %354 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %352, i32 0, i32 1 + store i64 4, ptr %354, align 4 + %355 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %352, align 8 + %356 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %357 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %356, i32 0, i32 0 + store ptr @34, ptr %357, align 8 + %358 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %356, i32 0, i32 1 + store i64 0, ptr %358, align 4 + %359 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %356, align 8 + %360 = call ptr @"github.com/goplus/llgo/internal/runtime.Interface"(%"github.com/goplus/llgo/internal/runtime.String" %355, %"github.com/goplus/llgo/internal/runtime.String" %359, %"github.com/goplus/llgo/internal/runtime.Slice" %351) + store ptr %360, ptr @_llgo_any, align 8 + br label %_llgo_44 + +_llgo_44: ; preds = %_llgo_43, %_llgo_42 ret void } @@ -971,3 +1181,7 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr) declare ptr @"github.com/goplus/llgo/internal/runtime.IfaceType"(%"github.com/goplus/llgo/internal/runtime.iface") declare void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface") + +declare i1 @"github.com/goplus/llgo/internal/runtime.Implements"(ptr, ptr) + +declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") diff --git a/cl/_testrt/any/out.ll b/cl/_testrt/any/out.ll index ff63980b..b55c4afc 100644 --- a/cl/_testrt/any/out.ll +++ b/cl/_testrt/any/out.ll @@ -9,6 +9,7 @@ source_filename = "main" @"*_llgo_int8" = linkonce global ptr null @_llgo_int8 = linkonce global ptr null @0 = private unnamed_addr constant [22 x i8] c"type assertion failed\00", align 1 +@_llgo_string = linkonce global ptr null @_llgo_int = linkonce global ptr null @1 = private unnamed_addr constant [22 x i8] c"type assertion failed\00", align 1 @__llgo_argc = global ptr null @@ -34,7 +35,16 @@ _llgo_2: ; preds = %_llgo_0 %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 1 store i64 21, 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.TracePanic"(%"github.com/goplus/llgo/internal/runtime.String" %8) + %9 = load ptr, ptr @_llgo_string, align 8 + %10 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) + store %"github.com/goplus/llgo/internal/runtime.String" %8, ptr %10, align 8 + %11 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %11, i32 0, i32 0 + store ptr %9, ptr %12, align 8 + %13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %11, i32 0, i32 1 + store ptr %10, ptr %13, align 8 + %14 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %11, align 8 + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %14) unreachable } @@ -58,7 +68,16 @@ _llgo_2: ; preds = %_llgo_0 %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 1 store i64 21, ptr %9, align 4 %10 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %7, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.String" %10) + %11 = load ptr, ptr @_llgo_string, align 8 + %12 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) + store %"github.com/goplus/llgo/internal/runtime.String" %10, ptr %12, align 8 + %13 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %13, i32 0, i32 0 + store ptr %11, ptr %14, align 8 + %15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %13, i32 0, i32 1 + store ptr %12, ptr %15, align 8 + %16 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %13, align 8 + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %16) unreachable } @@ -129,16 +148,26 @@ _llgo_3: ; preds = %_llgo_2 br label %_llgo_4 _llgo_4: ; preds = %_llgo_3, %_llgo_2 - %7 = load ptr, ptr @_llgo_int, align 8 + %7 = load ptr, ptr @_llgo_string, align 8 %8 = icmp eq ptr %7, null br i1 %8, label %_llgo_5, label %_llgo_6 _llgo_5: ; preds = %_llgo_4 - %9 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) - store ptr %9, ptr @_llgo_int, align 8 + %9 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 24) + store ptr %9, ptr @_llgo_string, align 8 br label %_llgo_6 _llgo_6: ; preds = %_llgo_5, %_llgo_4 + %10 = load ptr, ptr @_llgo_int, align 8 + %11 = icmp eq ptr %10, null + br i1 %11, label %_llgo_7, label %_llgo_8 + +_llgo_7: ; preds = %_llgo_6 + %12 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) + store ptr %12, ptr @_llgo_int, align 8 + br label %_llgo_8 + +_llgo_8: ; preds = %_llgo_7, %_llgo_6 ret void } @@ -146,6 +175,8 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) declare ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr) +declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) + declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") declare void @"github.com/goplus/llgo/internal/runtime.init"() diff --git a/cl/internal/foo/foo.go b/cl/internal/foo/foo.go index 0c4e7d33..c3a4cd4e 100644 --- a/cl/internal/foo/foo.go +++ b/cl/internal/foo/foo.go @@ -16,3 +16,18 @@ type Foo struct { func (v Foo) Pb() *byte { return v.pb } + +type Gamer interface { + initGame() + Load() +} + +type Game struct { +} + +func (g *Game) initGame() { +} + +func (g *Game) Load() { + println("load") +} diff --git a/internal/abi/llgo_autogen.lla b/internal/abi/llgo_autogen.lla index 55b79262..17d02dd3 100644 Binary files a/internal/abi/llgo_autogen.lla and b/internal/abi/llgo_autogen.lla differ diff --git a/internal/abi/type.go b/internal/abi/type.go index 2c866238..c3f0f9ed 100644 --- a/internal/abi/type.go +++ b/internal/abi/type.go @@ -246,7 +246,19 @@ type Method struct { // Exported reports whether the method is exported. func (p *Method) Exported() bool { - return IsExported(p.Name_) + return lastDot(p.Name_) == -1 +} + +// Name returns the tag string for method. +func (p *Method) Name() string { + _, name := splitName(p.Name_) + return name +} + +// PkgPath returns the pkgpath string for method, or empty if there is none. +func (p *Method) PkgPath() string { + pkg, _ := splitName(p.Name_) + return pkg } // UncommonType is present only for defined types or types with methods @@ -280,6 +292,23 @@ type Imethod struct { Typ_ *FuncType // .(*FuncType) underneath } +// Exported reports whether the imethod is exported. +func (p *Imethod) Exported() bool { + return lastDot(p.Name_) == -1 +} + +// Name returns the tag string for imethod. +func (p *Imethod) Name() string { + _, name := splitName(p.Name_) + return name +} + +// PkgPath returns the pkgpath string for imethod, or empty if there is none. +func (p *Imethod) PkgPath() string { + pkg, _ := splitName(p.Name_) + return pkg +} + func (t *Type) Kind() Kind { return Kind(t.Kind_ & KindMask) } // Size returns the size of data with type t. @@ -450,4 +479,20 @@ func addChecked(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { return unsafe.Pointer(uintptr(p) + x) } +func splitName(s string) (pkg string, name string) { + i := lastDot(s) + if i == -1 { + return s, "" + } + return s[:i], s[i+1:] +} + +func lastDot(s string) int { + i := len(s) - 1 + for i >= 0 && s[i] != '.' { + i-- + } + return i +} + // ----------------------------------------------------------------------------- diff --git a/internal/runtime/llgo_autogen.lla b/internal/runtime/llgo_autogen.lla index f66c4e86..4cb3ec4a 100644 Binary files a/internal/runtime/llgo_autogen.lla and b/internal/runtime/llgo_autogen.lla differ diff --git a/internal/runtime/z_face.go b/internal/runtime/z_face.go index ca546843..ea464e91 100644 --- a/internal/runtime/z_face.go +++ b/internal/runtime/z_face.go @@ -266,4 +266,60 @@ func IfacePtrData(i iface) unsafe.Pointer { return i.data } +// Implements reports whether the type V implements the interface type T. +func Implements(T, V *abi.Type) bool { + if T.Kind() != abi.Interface { + return false + } + t := (*abi.InterfaceType)(unsafe.Pointer(T)) + + if len(t.Methods) == 0 { + return true + } + + // The same algorithm applies in both cases, but the + // method tables for an interface type and a concrete type + // are different, so the code is duplicated. + // In both cases the algorithm is a linear scan over the two + // lists - T's methods and V's methods - simultaneously. + // Since method tables are stored in a unique sorted order + // (alphabetical, with no duplicate method names), the scan + // through V's methods must hit a match for each of T's + // methods along the way, or else V does not implement T. + // This lets us run the scan in overall linear time instead of + // the quadratic time a naive search would require. + // See also ../runtime/iface.go. + if V.Kind() == abi.Interface { + v := (*abi.InterfaceType)(unsafe.Pointer(V)) + i := 0 + for j := 0; j < len(v.Methods); j++ { + tm := &t.Methods[i] + vm := &v.Methods[j] + if vm.Name_ == tm.Name_ && vm.Typ_ == tm.Typ_ { + if i++; i >= len(t.Methods) { + return true + } + } + } + return false + } + + v := V.Uncommon() + if v == nil { + return false + } + i := 0 + vmethods := v.Methods() + for j := 0; j < int(v.Mcount); j++ { + tm := &t.Methods[i] + vm := vmethods[j] + if vm.Name_ == tm.Name_ && vm.Mtyp_ == tm.Typ_ { + if i++; i >= len(t.Methods) { + return true + } + } + } + return false +} + // ----------------------------------------------------------------------------- diff --git a/ssa/abitype.go b/ssa/abitype.go index 309f58da..e41fda58 100644 --- a/ssa/abitype.go +++ b/ssa/abitype.go @@ -22,6 +22,7 @@ import ( "github.com/goplus/llgo/ssa/abi" "github.com/goplus/llvm" + "golang.org/x/tools/go/types/typeutil" ) // ----------------------------------------------------------------------------- @@ -54,9 +55,13 @@ func (b Builder) abiTypeOf(t types.Type) func() Expr { case *types.Struct: return b.abiStructOf(t) case *types.Named: + if iface, ok := t.Underlying().(*types.Interface); ok { + obj := t.Obj() + return b.abiInterfaceOf(abi.PathOf(obj.Pkg()), abi.TypeName(obj), iface) + } return b.abiNamedOf(t) case *types.Interface: - return b.abiInterfaceOf("", t) + return b.abiInterfaceOf("", "", t) case *types.Signature: return b.abiFuncOf(t) case *types.Slice: @@ -100,15 +105,14 @@ func (b Builder) abiImethodOf(mName string, typ Expr) Expr { return b.aggregateValue(prog.rtType("Imethod"), name.impl, typ.impl) } -func (b Builder) abiMethods(t *types.Named) (ret int) { - n := t.NumMethods() - for i := 0; i < n; i++ { - m := t.Method(i) - mSig := m.Type().(*types.Signature) - recvType := mSig.Recv().Type() - if _, ok := recvType.(*types.Pointer); !ok { - ret++ +func (b Builder) abiMethods(t *types.Named) (ret, pret int) { + methods := typeutil.IntuitiveMethodSet(t, nil) + pret = len(methods) + for _, m := range methods { + if _, ok := m.Recv().(*types.Pointer); ok { + continue } + ret++ } return } @@ -120,6 +124,9 @@ func (b Builder) abiMethodOf(m *types.Func /*, bg Background = InGo */) (mthd, p mSig := m.Type().(*types.Signature) name := b.Str(mName).impl + if !token.IsExported(mName) { + name = b.Str(abi.FullName(mPkg, m.Name())).impl + } abiSigGo := types.NewSignatureType(nil, nil, nil, mSig.Params(), mSig.Results(), mSig.Variadic()) abiSig := prog.FuncDecl(abiSigGo, InGo).raw.Type abiTyp := b.abiType(abiSig) @@ -149,7 +156,7 @@ func (b Builder) abiMthd(mPkg *types.Package, mName string, mSig *types.Signatur } // func Interface(pkgPath, name string, methods []abi.Imethod) -func (b Builder) abiInterfaceOf(name string, t *types.Interface) func() Expr { +func (b Builder) abiInterfaceOf(pkgPath string, name string, t *types.Interface) func() Expr { n := t.NumMethods() typs := make([]Expr, n) for i := 0; i < n; i++ { @@ -161,11 +168,17 @@ func (b Builder) abiInterfaceOf(name string, t *types.Interface) func() Expr { methods := make([]Expr, n) for i := 0; i < n; i++ { m := t.Method(i) - methods[i] = b.abiImethodOf(m.Name(), typs[i]) + mName := m.Name() + if !token.IsExported(mName) { + mName = abi.FullName(m.Pkg(), mName) + } + methods[i] = b.abiImethodOf(mName, typs[i]) } pkg := b.Pkg fn := pkg.rtFunc("Interface") - pkgPath := pkg.Path() + if pkgPath == "" { + pkgPath = pkg.Path() + } tSlice := lastParamType(prog, fn) methodSlice := b.SliceLit(tSlice, methods...) return b.Call(fn, b.Str(pkgPath), b.Str(name), methodSlice) @@ -178,8 +191,7 @@ func (b Builder) abiNamedOf(t *types.Named) func() Expr { pkg := b.Pkg tunder := t.Underlying() kind := int(abi.UnderlyingKind(tunder)) - numMethods := b.abiMethods(t) - numPtrMethods := t.NumMethods() + numMethods, numPtrMethods := b.abiMethods(t) newNamed := pkg.rtFunc("NewNamed") return b.Call(newNamed, b.Prog.Val(kind), b.Prog.Val(numMethods), b.Prog.Val(numPtrMethods)) } @@ -193,10 +205,10 @@ func (b Builder) abiInitNamed(ret Expr, t *types.Named) func() Expr { prog := b.Prog path := abi.PathOf(t.Obj().Pkg()) name := NameOf(t) - var initNamed = pkg.rtFunc("InitNamed") var tSlice = lastParamType(prog, initNamed) - var n = t.NumMethods() + mset := typeutil.IntuitiveMethodSet(t, nil) + n := len(mset) var methods, ptrMethods Expr if n == 0 { methods = prog.Zero(tSlice) @@ -205,7 +217,7 @@ func (b Builder) abiInitNamed(ret Expr, t *types.Named) func() Expr { var mthds []Expr var ptrMthds = make([]Expr, 0, n) for i := 0; i < n; i++ { - m := t.Method(i) + m := mset[i].Obj().(*types.Func) mthd, ptrMthd := b.abiMethodOf(m) if !mthd.IsNil() { mthds = append(mthds, mthd) @@ -304,6 +316,10 @@ func (p Package) abiTypeInit(g Global, t types.Type, pub bool) { b.blk.last = blks[1].last } if t, ok := t.(*types.Named); ok { + // skip interface + if _, ok := t.Underlying().(*types.Interface); ok { + return + } tabi = b.abiInitNamed(vexpr, t) if pub { blks = b.Func.MakeBlocks(2) diff --git a/ssa/expr.go b/ssa/expr.go index c085054d..960f1cde 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -113,7 +113,6 @@ func (p Program) Zero(t Type) Expr { ret = llvm.ConstStruct(flds, false) case *types.Slice: ret = p.Zero(p.rtType("Slice")).impl - /* TODO(xsw): case *types.Interface: var name string if u.Empty() { @@ -122,7 +121,6 @@ func (p Program) Zero(t Type) Expr { name = "Iface" } ret = p.Zero(p.rtType(name)).impl - */ default: log.Panicln("todo:", u) } diff --git a/ssa/interface.go b/ssa/interface.go index 39da9775..67d1ca34 100644 --- a/ssa/interface.go +++ b/ssa/interface.go @@ -234,7 +234,21 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr { } tx := b.faceAbiType(x) tabi := b.abiType(assertedTyp.raw.Type) - eq := b.BinOp(token.EQL, tx, tabi) + + var eq Expr + var val func() Expr + if rawIntf, ok := assertedTyp.raw.Type.Underlying().(*types.Interface); ok { + if rawIntf.Empty() { + eq = b.Prog.BoolVal(true) + } else { + eq = b.InlineCall(b.Pkg.rtFunc("Implements"), tabi, tx) + } + val = func() Expr { return Expr{b.unsafeInterface(rawIntf, tx, b.faceData(x.impl)), assertedTyp} } + } else { + eq = b.BinOp(token.EQL, tx, tabi) + val = func() Expr { return b.valFromData(assertedTyp, b.faceData(x.impl)) } + } + if commaOk { prog := b.Prog t := prog.Struct(assertedTyp, prog.Bool()) @@ -246,8 +260,7 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr { phi.AddIncoming(b, blks[:2], func(i int, blk BasicBlock) Expr { b.SetBlockEx(blk, AtEnd, false) if i == 0 { - val := b.valFromData(assertedTyp, b.faceData(x.impl)) - valTrue := aggregateValue(b.impl, t.ll, val.impl, prog.BoolVal(true).impl) + valTrue := aggregateValue(b.impl, t.ll, val().impl, prog.BoolVal(true).impl) b.Jump(blks[2]) return Expr{valTrue, t} } @@ -263,10 +276,10 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr { blks := b.Func.MakeBlocks(2) b.If(eq, blks[0], blks[1]) b.SetBlockEx(blks[1], AtEnd, false) - b.Panic(b.Str("type assertion failed")) + b.Panic(b.MakeInterface(b.Prog.Any(), b.Str("type assertion failed"))) b.SetBlockEx(blks[0], AtEnd, false) b.blk.last = blks[0].last - return b.valFromData(assertedTyp, b.faceData(x.impl)) + return val() } // ChangeInterface constructs a value of one interface type from a