Merge pull request #235 from xushiwei/q
runtime: iface; llgo/ssa: phi refactor; remove abi.Name
This commit is contained in:
@@ -3,8 +3,7 @@ source_filename = "main"
|
|||||||
|
|
||||||
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
|
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
|
||||||
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
||||||
%"github.com/goplus/llgo/internal/abi.StructField" = type { %"github.com/goplus/llgo/internal/abi.Name", ptr, i64 }
|
%"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/abi.Name" = type { ptr }
|
|
||||||
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
|
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
|
||||||
|
|
||||||
@"main.init$guard" = global ptr null
|
@"main.init$guard" = global ptr null
|
||||||
@@ -270,14 +269,14 @@ _llgo_0:
|
|||||||
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 1
|
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 1
|
||||||
store i64 0, ptr %7, align 4
|
store i64 0, ptr %7, align 4
|
||||||
%8 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %5, align 8
|
%8 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %5, align 8
|
||||||
%9 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %3, ptr %4, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %8, i1 false, i1 false)
|
%9 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %3, ptr %4, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %8, i1 false)
|
||||||
%10 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%10 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %10, i32 0, i32 0
|
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %10, i32 0, i32 0
|
||||||
store ptr @5, ptr %11, align 8
|
store ptr @5, ptr %11, align 8
|
||||||
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %10, i32 0, i32 1
|
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %10, i32 0, i32 1
|
||||||
store i64 4, ptr %12, align 4
|
store i64 4, ptr %12, align 4
|
||||||
%13 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %10, align 8
|
%13 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %10, align 8
|
||||||
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24)
|
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 56)
|
||||||
%15 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %14, i64 0
|
%15 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %14, i64 0
|
||||||
store %"github.com/goplus/llgo/internal/abi.StructField" %9, ptr %15, align 8
|
store %"github.com/goplus/llgo/internal/abi.StructField" %9, ptr %15, align 8
|
||||||
%16 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
|
%16 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
|
||||||
@@ -288,7 +287,7 @@ _llgo_0:
|
|||||||
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %16, i32 0, i32 2
|
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %16, i32 0, i32 2
|
||||||
store i64 1, ptr %19, align 4
|
store i64 1, ptr %19, align 4
|
||||||
%20 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %16, align 8
|
%20 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %16, align 8
|
||||||
%21 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %13, %"github.com/goplus/llgo/internal/runtime.Slice" %20)
|
%21 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %13, i64 8, %"github.com/goplus/llgo/internal/runtime.Slice" %20)
|
||||||
store ptr %21, ptr @"main.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88", align 8
|
store ptr %21, ptr @"main.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88", align 8
|
||||||
%22 = load ptr, ptr @"_llgo_struct$K-dZ9QotZfVPz2a0YdRa9vmZUuDXPTqZOlMShKEDJtk", align 8
|
%22 = load ptr, ptr @"_llgo_struct$K-dZ9QotZfVPz2a0YdRa9vmZUuDXPTqZOlMShKEDJtk", align 8
|
||||||
%23 = icmp eq ptr %22, null
|
%23 = icmp eq ptr %22, null
|
||||||
@@ -308,14 +307,14 @@ _llgo_1: ; preds = %_llgo_0
|
|||||||
%31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %29, i32 0, i32 1
|
%31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %29, i32 0, i32 1
|
||||||
store i64 0, ptr %31, align 4
|
store i64 0, ptr %31, align 4
|
||||||
%32 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %29, align 8
|
%32 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %29, align 8
|
||||||
%33 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %27, ptr %28, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %32, i1 true, i1 false)
|
%33 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %27, ptr %28, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %32, i1 false)
|
||||||
%34 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%34 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
%35 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %34, i32 0, i32 0
|
%35 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %34, i32 0, i32 0
|
||||||
store ptr @8, ptr %35, align 8
|
store ptr @8, ptr %35, align 8
|
||||||
%36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %34, i32 0, i32 1
|
%36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %34, i32 0, i32 1
|
||||||
store i64 4, ptr %36, align 4
|
store i64 4, ptr %36, align 4
|
||||||
%37 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %34, align 8
|
%37 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %34, align 8
|
||||||
%38 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24)
|
%38 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 56)
|
||||||
%39 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %38, i64 0
|
%39 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %38, i64 0
|
||||||
store %"github.com/goplus/llgo/internal/abi.StructField" %33, ptr %39, align 8
|
store %"github.com/goplus/llgo/internal/abi.StructField" %33, ptr %39, align 8
|
||||||
%40 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
|
%40 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
|
||||||
@@ -326,7 +325,7 @@ _llgo_1: ; preds = %_llgo_0
|
|||||||
%43 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %40, i32 0, i32 2
|
%43 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %40, i32 0, i32 2
|
||||||
store i64 1, ptr %43, align 4
|
store i64 1, ptr %43, align 4
|
||||||
%44 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %40, align 8
|
%44 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %40, align 8
|
||||||
%45 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %37, %"github.com/goplus/llgo/internal/runtime.Slice" %44)
|
%45 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %37, i64 8, %"github.com/goplus/llgo/internal/runtime.Slice" %44)
|
||||||
store ptr %45, ptr @"_llgo_struct$K-dZ9QotZfVPz2a0YdRa9vmZUuDXPTqZOlMShKEDJtk", align 8
|
store ptr %45, ptr @"_llgo_struct$K-dZ9QotZfVPz2a0YdRa9vmZUuDXPTqZOlMShKEDJtk", align 8
|
||||||
br label %_llgo_2
|
br label %_llgo_2
|
||||||
|
|
||||||
@@ -334,9 +333,9 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.Struct"(i64, %"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.Slice")
|
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, i1)
|
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.Basic"(i64)
|
declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64)
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ func Bar(v any) (ret foo.Foo, ok bool) {
|
|||||||
func main() {
|
func main() {
|
||||||
ret, ok := Foo(nil)
|
ret, ok := Foo(nil)
|
||||||
println(ret.pb, ret.f, "notOk:", !ok)
|
println(ret.pb, ret.f, "notOk:", !ok)
|
||||||
|
|
||||||
ret2, ok2 := Bar(foo.Foo{})
|
ret2, ok2 := Bar(foo.Foo{})
|
||||||
println(ret2.Pb(), ret2.F, ok2)
|
println(ret2.Pb(), ret2.F, ok2)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ source_filename = "main"
|
|||||||
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
|
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
|
||||||
%main.bar = type { ptr, float }
|
%main.bar = type { ptr, float }
|
||||||
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
||||||
%"github.com/goplus/llgo/internal/abi.StructField" = type { %"github.com/goplus/llgo/internal/abi.Name", ptr, i64 }
|
%"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/abi.Name" = type { ptr }
|
|
||||||
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
|
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
|
||||||
|
|
||||||
@"main.init$guard" = global ptr null
|
@"main.init$guard" = global ptr null
|
||||||
@@ -21,13 +20,15 @@ source_filename = "main"
|
|||||||
@3 = private unnamed_addr constant [2 x i8] c"F\00", align 1
|
@3 = private unnamed_addr constant [2 x i8] c"F\00", align 1
|
||||||
@4 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
@4 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
||||||
@5 = private unnamed_addr constant [5 x i8] c"main\00", align 1
|
@5 = private unnamed_addr constant [5 x i8] c"main\00", align 1
|
||||||
@6 = private unnamed_addr constant [43 x i8] c"github.com/goplus/llgo/cl/internal/foo.Foo\00", align 1
|
@6 = private unnamed_addr constant [5 x i8] c"main\00", align 1
|
||||||
@7 = private unnamed_addr constant [3 x i8] c"pb\00", align 1
|
@7 = private unnamed_addr constant [43 x i8] c"github.com/goplus/llgo/cl/internal/foo.Foo\00", align 1
|
||||||
@8 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
@8 = private unnamed_addr constant [3 x i8] c"pb\00", align 1
|
||||||
@9 = private unnamed_addr constant [2 x i8] c"f\00", align 1
|
@9 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
||||||
@10 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
@10 = private unnamed_addr constant [2 x i8] c"f\00", align 1
|
||||||
@11 = private unnamed_addr constant [5 x i8] c"main\00", align 1
|
@11 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
||||||
@12 = private unnamed_addr constant [9 x i8] c"main.bar\00", align 1
|
@12 = private unnamed_addr constant [5 x i8] c"main\00", align 1
|
||||||
|
@13 = private unnamed_addr constant [5 x i8] c"main\00", align 1
|
||||||
|
@14 = private unnamed_addr constant [9 x i8] c"main.bar\00", align 1
|
||||||
|
|
||||||
define { %"github.com/goplus/llgo/cl/internal/foo.Foo", i1 } @main.Bar(%"github.com/goplus/llgo/internal/runtime.eface" %0) {
|
define { %"github.com/goplus/llgo/cl/internal/foo.Foo", i1 } @main.Bar(%"github.com/goplus/llgo/internal/runtime.eface" %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
@@ -217,7 +218,7 @@ _llgo_1: ; preds = %_llgo_0
|
|||||||
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 1
|
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 1
|
||||||
store i64 0, ptr %9, align 4
|
store i64 0, ptr %9, align 4
|
||||||
%10 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %7, align 8
|
%10 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %7, align 8
|
||||||
%11 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %5, ptr %6, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %10, i1 false, i1 false)
|
%11 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %5, ptr %6, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %10, i1 false)
|
||||||
%12 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%12 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
%13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %12, i32 0, i32 0
|
%13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %12, i32 0, i32 0
|
||||||
store ptr @3, ptr %13, align 8
|
store ptr @3, ptr %13, align 8
|
||||||
@@ -231,14 +232,14 @@ _llgo_1: ; preds = %_llgo_0
|
|||||||
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %17, i32 0, i32 1
|
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %17, i32 0, i32 1
|
||||||
store i64 0, ptr %19, align 4
|
store i64 0, ptr %19, align 4
|
||||||
%20 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %17, align 8
|
%20 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %17, align 8
|
||||||
%21 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %15, ptr %16, i64 8, %"github.com/goplus/llgo/internal/runtime.String" %20, i1 true, i1 false)
|
%21 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %15, ptr %16, i64 8, %"github.com/goplus/llgo/internal/runtime.String" %20, i1 false)
|
||||||
%22 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%22 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
%23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 0
|
%23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 0
|
||||||
store ptr @5, ptr %23, align 8
|
store ptr @5, ptr %23, align 8
|
||||||
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 1
|
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 1
|
||||||
store i64 4, ptr %24, align 4
|
store i64 4, ptr %24, align 4
|
||||||
%25 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %22, align 8
|
%25 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %22, align 8
|
||||||
%26 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 48)
|
%26 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 112)
|
||||||
%27 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %26, i64 0
|
%27 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %26, i64 0
|
||||||
store %"github.com/goplus/llgo/internal/abi.StructField" %11, ptr %27, align 8
|
store %"github.com/goplus/llgo/internal/abi.StructField" %11, ptr %27, align 8
|
||||||
%28 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %26, i64 1
|
%28 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %26, i64 1
|
||||||
@@ -251,81 +252,93 @@ _llgo_1: ; preds = %_llgo_0
|
|||||||
%32 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %29, i32 0, i32 2
|
%32 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %29, i32 0, i32 2
|
||||||
store i64 2, ptr %32, align 4
|
store i64 2, ptr %32, align 4
|
||||||
%33 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %29, align 8
|
%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" %25, %"github.com/goplus/llgo/internal/runtime.Slice" %33)
|
%34 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %25, i64 16, %"github.com/goplus/llgo/internal/runtime.Slice" %33)
|
||||||
%35 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%35 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
%36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %35, i32 0, i32 0
|
%36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %35, i32 0, i32 0
|
||||||
store ptr @6, ptr %36, align 8
|
store ptr @6, ptr %36, align 8
|
||||||
%37 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %35, i32 0, i32 1
|
%37 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %35, i32 0, i32 1
|
||||||
store i64 42, ptr %37, align 4
|
store i64 4, ptr %37, align 4
|
||||||
%38 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %35, align 8
|
%38 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %35, align 8
|
||||||
%39 = call ptr @"github.com/goplus/llgo/internal/runtime.Named"(%"github.com/goplus/llgo/internal/runtime.String" %38, ptr %34)
|
%39 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
store ptr %39, ptr @"github.com/goplus/llgo/cl/internal/foo.Foo", align 8
|
%40 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %39, i32 0, i32 0
|
||||||
|
store ptr @7, ptr %40, align 8
|
||||||
|
%41 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %39, i32 0, i32 1
|
||||||
|
store i64 42, ptr %41, align 4
|
||||||
|
%42 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %39, align 8
|
||||||
|
%43 = call ptr @"github.com/goplus/llgo/internal/runtime.Named"(%"github.com/goplus/llgo/internal/runtime.String" %38, %"github.com/goplus/llgo/internal/runtime.String" %42, ptr %34, { ptr, i64, i64 } zeroinitializer)
|
||||||
|
store ptr %43, ptr @"github.com/goplus/llgo/cl/internal/foo.Foo", align 8
|
||||||
br label %_llgo_2
|
br label %_llgo_2
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
%40 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%44 = 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
|
%45 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %44, i32 0, i32 0
|
||||||
store ptr @7, ptr %41, align 8
|
store ptr @8, ptr %45, align 8
|
||||||
%42 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %40, i32 0, i32 1
|
%46 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %44, i32 0, i32 1
|
||||||
store i64 2, ptr %42, align 4
|
store i64 2, ptr %46, align 4
|
||||||
%43 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %40, align 8
|
%47 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %44, align 8
|
||||||
%44 = load ptr, ptr @"*_llgo_byte", align 8
|
%48 = load ptr, ptr @"*_llgo_byte", align 8
|
||||||
%45 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%49 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
%46 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %45, i32 0, i32 0
|
%50 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %49, i32 0, i32 0
|
||||||
store ptr @8, ptr %46, align 8
|
store ptr @9, ptr %50, align 8
|
||||||
%47 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %45, i32 0, i32 1
|
%51 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %49, i32 0, i32 1
|
||||||
store i64 0, ptr %47, align 4
|
store i64 0, ptr %51, align 4
|
||||||
%48 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %45, align 8
|
%52 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %49, align 8
|
||||||
%49 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %43, ptr %44, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %48, i1 false, i1 false)
|
%53 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %47, ptr %48, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %52, i1 false)
|
||||||
%50 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%54 = 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
|
%55 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %54, i32 0, i32 0
|
||||||
store ptr @9, ptr %51, align 8
|
store ptr @10, ptr %55, align 8
|
||||||
%52 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %50, i32 0, i32 1
|
%56 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %54, i32 0, i32 1
|
||||||
store i64 1, ptr %52, align 4
|
store i64 1, ptr %56, align 4
|
||||||
%53 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %50, align 8
|
%57 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %54, align 8
|
||||||
%54 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
|
%58 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
|
||||||
%55 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%59 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
%56 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %55, i32 0, i32 0
|
%60 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %59, i32 0, i32 0
|
||||||
store ptr @10, ptr %56, align 8
|
store ptr @11, ptr %60, align 8
|
||||||
%57 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %55, i32 0, i32 1
|
%61 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %59, i32 0, i32 1
|
||||||
store i64 0, ptr %57, align 4
|
store i64 0, ptr %61, align 4
|
||||||
%58 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %55, align 8
|
%62 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %59, align 8
|
||||||
%59 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %53, ptr %54, i64 8, %"github.com/goplus/llgo/internal/runtime.String" %58, i1 false, i1 false)
|
%63 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %57, ptr %58, i64 8, %"github.com/goplus/llgo/internal/runtime.String" %62, i1 false)
|
||||||
%60 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%64 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
%61 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %60, i32 0, i32 0
|
%65 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %64, i32 0, i32 0
|
||||||
store ptr @11, ptr %61, align 8
|
store ptr @12, ptr %65, align 8
|
||||||
%62 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %60, i32 0, i32 1
|
%66 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %64, i32 0, i32 1
|
||||||
store i64 4, ptr %62, align 4
|
store i64 4, ptr %66, align 4
|
||||||
%63 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %60, align 8
|
%67 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %64, align 8
|
||||||
%64 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 48)
|
%68 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 112)
|
||||||
%65 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %64, i64 0
|
%69 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %68, i64 0
|
||||||
store %"github.com/goplus/llgo/internal/abi.StructField" %49, ptr %65, align 8
|
store %"github.com/goplus/llgo/internal/abi.StructField" %53, ptr %69, align 8
|
||||||
%66 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %64, i64 1
|
%70 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %68, i64 1
|
||||||
store %"github.com/goplus/llgo/internal/abi.StructField" %59, ptr %66, align 8
|
store %"github.com/goplus/llgo/internal/abi.StructField" %63, ptr %70, align 8
|
||||||
%67 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
|
%71 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
|
||||||
%68 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %67, i32 0, i32 0
|
%72 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %71, i32 0, i32 0
|
||||||
store ptr %64, ptr %68, align 8
|
store ptr %68, ptr %72, align 8
|
||||||
%69 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %67, i32 0, i32 1
|
%73 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %71, i32 0, i32 1
|
||||||
store i64 2, ptr %69, align 4
|
store i64 2, ptr %73, align 4
|
||||||
%70 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %67, i32 0, i32 2
|
%74 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %71, i32 0, i32 2
|
||||||
store i64 2, ptr %70, align 4
|
store i64 2, ptr %74, align 4
|
||||||
%71 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %67, align 8
|
%75 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %71, align 8
|
||||||
%72 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %63, %"github.com/goplus/llgo/internal/runtime.Slice" %71)
|
%76 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %67, i64 16, %"github.com/goplus/llgo/internal/runtime.Slice" %75)
|
||||||
%73 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%77 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
%74 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %73, i32 0, i32 0
|
%78 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %77, i32 0, i32 0
|
||||||
store ptr @12, ptr %74, align 8
|
store ptr @13, ptr %78, align 8
|
||||||
%75 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %73, i32 0, i32 1
|
%79 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %77, i32 0, i32 1
|
||||||
store i64 8, ptr %75, align 4
|
store i64 4, ptr %79, align 4
|
||||||
%76 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %73, align 8
|
%80 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %77, align 8
|
||||||
%77 = call ptr @"github.com/goplus/llgo/internal/runtime.Named"(%"github.com/goplus/llgo/internal/runtime.String" %76, ptr %72)
|
%81 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
store ptr %77, ptr @main.bar, align 8
|
%82 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %81, i32 0, i32 0
|
||||||
|
store ptr @14, ptr %82, align 8
|
||||||
|
%83 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %81, i32 0, i32 1
|
||||||
|
store i64 8, ptr %83, align 4
|
||||||
|
%84 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %81, align 8
|
||||||
|
%85 = call ptr @"github.com/goplus/llgo/internal/runtime.Named"(%"github.com/goplus/llgo/internal/runtime.String" %80, %"github.com/goplus/llgo/internal/runtime.String" %84, ptr %76, { ptr, i64, i64 } zeroinitializer)
|
||||||
|
store ptr %85, ptr @main.bar, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.Struct"(i64, %"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.Slice")
|
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, i1)
|
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.Basic"(i64)
|
declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64)
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.Named"(%"github.com/goplus/llgo/internal/runtime.String", ptr)
|
declare ptr @"github.com/goplus/llgo/internal/runtime.Named"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String", ptr, %"github.com/goplus/llgo/internal/runtime.Slice")
|
||||||
|
|||||||
@@ -25,37 +25,26 @@ _llgo_0:
|
|||||||
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1
|
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1
|
||||||
store i64 0, ptr %4, align 4
|
store i64 0, ptr %4, align 4
|
||||||
%5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8
|
%5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8
|
||||||
%6 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %5, 0
|
|
||||||
%7 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %5, 1
|
|
||||||
br label %_llgo_1
|
br label %_llgo_1
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||||
%8 = phi ptr [ %6, %_llgo_0 ], [ %22, %_llgo_2 ]
|
%6 = phi %"github.com/goplus/llgo/internal/runtime.String" [ %5, %_llgo_0 ], [ %14, %_llgo_2 ]
|
||||||
%9 = phi i64 [ %7, %_llgo_0 ], [ %23, %_llgo_2 ]
|
%7 = phi i64 [ -1, %_llgo_0 ], [ %8, %_llgo_2 ]
|
||||||
%10 = phi i64 [ -1, %_llgo_0 ], [ %15, %_llgo_2 ]
|
%8 = add i64 %7, 1
|
||||||
%11 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
%9 = icmp slt i64 %8, %1
|
||||||
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %11, i32 0, i32 0
|
br i1 %9, label %_llgo_2, label %_llgo_3
|
||||||
store ptr %8, ptr %12, align 8
|
|
||||||
%13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %11, i32 0, i32 1
|
|
||||||
store i64 %9, ptr %13, align 4
|
|
||||||
%14 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %11, align 8
|
|
||||||
%15 = add i64 %10, 1
|
|
||||||
%16 = icmp slt i64 %15, %1
|
|
||||||
br i1 %16, label %_llgo_2, label %_llgo_3
|
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_1
|
_llgo_2: ; preds = %_llgo_1
|
||||||
%17 = icmp slt i64 %15, 0
|
%10 = icmp slt i64 %8, 0
|
||||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %17)
|
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %10)
|
||||||
%18 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
|
%11 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
|
||||||
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i64 %15
|
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %11, i64 %8
|
||||||
%20 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %19, align 8
|
%13 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %12, align 8
|
||||||
%21 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %14, %"github.com/goplus/llgo/internal/runtime.String" %20)
|
%14 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %6, %"github.com/goplus/llgo/internal/runtime.String" %13)
|
||||||
%22 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %21, 0
|
|
||||||
%23 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %21, 1
|
|
||||||
br label %_llgo_1
|
br label %_llgo_1
|
||||||
|
|
||||||
_llgo_3: ; preds = %_llgo_1
|
_llgo_3: ; preds = %_llgo_1
|
||||||
ret %"github.com/goplus/llgo/internal/runtime.String" %14
|
ret %"github.com/goplus/llgo/internal/runtime.String" %6
|
||||||
}
|
}
|
||||||
|
|
||||||
define %"github.com/goplus/llgo/internal/runtime.String" @main.info(%"github.com/goplus/llgo/internal/runtime.String" %0) {
|
define %"github.com/goplus/llgo/internal/runtime.String" @main.info(%"github.com/goplus/llgo/internal/runtime.String" %0) {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
; ModuleID = 'main'
|
; ModuleID = 'main'
|
||||||
source_filename = "main"
|
source_filename = "main"
|
||||||
|
|
||||||
%"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/internal/abi.Name", 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/abi.Name" = type { ptr }
|
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
||||||
|
|
||||||
@main.basicTypes = global [25 x ptr] undef
|
@main.basicTypes = global [25 x ptr] undef
|
||||||
@"main.init$guard" = global ptr null
|
@"main.init$guard" = global ptr null
|
||||||
@@ -20,7 +20,7 @@ _llgo_0:
|
|||||||
|
|
||||||
define ptr @main.basicType(i64 %0) {
|
define ptr @main.basicType(i64 %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 64)
|
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 72)
|
||||||
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %1, i32 0, i32 0
|
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %1, i32 0, i32 0
|
||||||
%3 = getelementptr inbounds i64, ptr @main.sizeBasicTypes, i64 %0
|
%3 = getelementptr inbounds i64, ptr @main.sizeBasicTypes, i64 %0
|
||||||
%4 = load i64, ptr %3, align 4
|
%4 = load i64, ptr %3, align 4
|
||||||
|
|||||||
@@ -522,7 +522,7 @@ func (p *context) compilePhis(b llssa.Builder, block *ssa.BasicBlock) int {
|
|||||||
}
|
}
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
iv := block.Instrs[i].(*ssa.Phi)
|
iv := block.Instrs[i].(*ssa.Phi)
|
||||||
p.bvals[iv] = rets[i].Do(b)
|
p.bvals[iv] = rets[i]
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
@@ -540,7 +540,8 @@ func (p *context) compilePhi(b llssa.Builder, v *ssa.Phi) (ret llssa.Expr) {
|
|||||||
bblks[i] = p.fn.Block(pred.Index)
|
bblks[i] = p.fn.Block(pred.Index)
|
||||||
}
|
}
|
||||||
edges := v.Edges
|
edges := v.Edges
|
||||||
phi.AddIncoming(b, bblks, func(i int) llssa.Expr {
|
phi.AddIncoming(b, bblks, func(i int, blk llssa.BasicBlock) llssa.Expr {
|
||||||
|
b.SetBlockEx(blk, llssa.BeforeLast, false)
|
||||||
return p.compileValue(b, edges[i])
|
return p.compileValue(b, edges[i])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -784,7 +785,7 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
|
|||||||
val := p.compileValue(b, v.Value)
|
val := p.compileValue(b, v.Value)
|
||||||
b.MapUpdate(m, key, val)
|
b.MapUpdate(m, key, val)
|
||||||
case *ssa.Panic:
|
case *ssa.Panic:
|
||||||
arg := p.compileValue(b, v.X).Do(b)
|
arg := p.compileValue(b, v.X)
|
||||||
b.Panic(arg)
|
b.Panic(arg)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("compileInstr: unknown instr - %T\n", instr))
|
panic(fmt.Sprintf("compileInstr: unknown instr - %T\n", instr))
|
||||||
@@ -856,7 +857,7 @@ func (p *context) compileValues(b llssa.Builder, vals []ssa.Value, hasVArg int)
|
|||||||
n := len(vals) - hasVArg
|
n := len(vals) - hasVArg
|
||||||
ret := make([]llssa.Expr, n)
|
ret := make([]llssa.Expr, n)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
ret[i] = p.compileValue(b, vals[i]).Do(b)
|
ret[i] = p.compileValue(b, vals[i])
|
||||||
}
|
}
|
||||||
if hasVArg > 0 {
|
if hasVArg > 0 {
|
||||||
ret = p.compileVArg(ret, b, vals[n])
|
ret = p.compileVArg(ret, b, vals[n])
|
||||||
|
|||||||
Binary file not shown.
@@ -20,6 +20,15 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// IsExported reports whether name starts with an upper-case letter.
|
||||||
|
func IsExported(name string) bool {
|
||||||
|
if len(name) > 0 {
|
||||||
|
c := name[0]
|
||||||
|
return 'A' <= c && c <= 'Z'
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Type is the runtime representation of a Go type.
|
// Type is the runtime representation of a Go type.
|
||||||
@@ -46,8 +55,8 @@ type Type struct {
|
|||||||
// If the KindGCProg bit is set in kind, GCData is a GC program.
|
// If the KindGCProg bit is set in kind, GCData is a GC program.
|
||||||
// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
|
// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
|
||||||
GCData *byte
|
GCData *byte
|
||||||
Str_ Name // string form
|
Str_ string // string form
|
||||||
PtrToThis_ *Type // type for pointer to this type, may be nil
|
PtrToThis_ *Type // type for pointer to this type, may be nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Kind represents the specific kind of type that a Type represents.
|
// A Kind represents the specific kind of type that a Type represents.
|
||||||
@@ -209,43 +218,57 @@ func (p *FuncType) Variadic() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StructField struct {
|
type StructField struct {
|
||||||
Name Name // name is always non-empty
|
Name_ string // name is always non-empty
|
||||||
Typ *Type // type of field
|
Typ *Type // type of field
|
||||||
Offset uintptr // byte offset of field
|
Offset uintptr // byte offset of field
|
||||||
|
|
||||||
|
Tag_ string
|
||||||
|
Embedded_ bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Embedded reports whether the field is embedded.
|
||||||
func (f *StructField) Embedded() bool {
|
func (f *StructField) Embedded() bool {
|
||||||
return f.Name.IsEmbedded()
|
return f.Embedded_
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exported reports whether the field is exported.
|
||||||
|
func (f *StructField) Exported() bool {
|
||||||
|
return IsExported(f.Name_)
|
||||||
}
|
}
|
||||||
|
|
||||||
type StructType struct {
|
type StructType struct {
|
||||||
Type
|
Type
|
||||||
PkgPath Name
|
PkgPath_ string
|
||||||
Fields []StructField
|
Fields []StructField
|
||||||
}
|
}
|
||||||
|
|
||||||
type InterfaceType struct {
|
type InterfaceType struct {
|
||||||
Type
|
Type
|
||||||
PkgPath Name // import path
|
PkgPath_ string // import path
|
||||||
Methods []Imethod // sorted by hash
|
Methods []Imethod // sorted by hash
|
||||||
}
|
}
|
||||||
|
|
||||||
type Text = unsafe.Pointer // TODO(xsw): to be confirmed
|
type Text = unsafe.Pointer // TODO(xsw): to be confirmed
|
||||||
|
|
||||||
// Method on non-interface type
|
// Method on non-interface type
|
||||||
type Method struct {
|
type Method struct {
|
||||||
Name_ Name // name of method
|
Name_ string // name of method
|
||||||
Mtyp_ *FuncType // method type (without receiver)
|
Mtyp_ *FuncType // method type (without receiver)
|
||||||
Ifn_ Text // fn used in interface call (one-word receiver)
|
Ifn_ Text // fn used in interface call (one-word receiver)
|
||||||
Tfn_ Text // fn used for normal method call
|
Tfn_ Text // fn used for normal method call
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exported reports whether the method is exported.
|
||||||
|
func (p *Method) Exported() bool {
|
||||||
|
return IsExported(p.Name_)
|
||||||
|
}
|
||||||
|
|
||||||
// UncommonType is present only for defined types or types with methods
|
// UncommonType is present only for defined types or types with methods
|
||||||
// (if T is a defined type, the uncommonTypes for T and *T have methods).
|
// (if T is a defined type, the uncommonTypes for T and *T have methods).
|
||||||
// Using a pointer to this struct reduces the overall size required
|
// Using a pointer to this struct reduces the overall size required
|
||||||
// to describe a non-defined type with no methods.
|
// to describe a non-defined type with no methods.
|
||||||
type UncommonType struct {
|
type UncommonType struct {
|
||||||
PkgPath_ Name // import path; empty for built-in types like int, string
|
PkgPath_ string // import path; empty for built-in types like int, string
|
||||||
Mcount uint16 // number of methods
|
Mcount uint16 // number of methods
|
||||||
Xcount uint16 // number of exported methods
|
Xcount uint16 // number of exported methods
|
||||||
Moff uint32 // offset from this uncommontype to [mcount]Method
|
Moff uint32 // offset from this uncommontype to [mcount]Method
|
||||||
@@ -267,7 +290,7 @@ func (t *UncommonType) ExportedMethods() []Method {
|
|||||||
|
|
||||||
// Imethod represents a method on an interface type
|
// Imethod represents a method on an interface type
|
||||||
type Imethod struct {
|
type Imethod struct {
|
||||||
Name_ Name // name of method
|
Name_ string // name of method
|
||||||
Typ_ *FuncType // .(*FuncType) underneath
|
Typ_ *FuncType // .(*FuncType) underneath
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,6 +308,70 @@ func (t *Type) Common() *Type {
|
|||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type structTypeUncommon struct {
|
||||||
|
StructType
|
||||||
|
u UncommonType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uncommon returns a pointer to T's "uncommon" data if there is any, otherwise nil
|
||||||
|
func (t *Type) Uncommon() *UncommonType {
|
||||||
|
if t.TFlag&TFlagUncommon == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
switch t.Kind() {
|
||||||
|
case Struct:
|
||||||
|
return &(*structTypeUncommon)(unsafe.Pointer(t)).u
|
||||||
|
case Pointer:
|
||||||
|
type u struct {
|
||||||
|
PtrType
|
||||||
|
u UncommonType
|
||||||
|
}
|
||||||
|
return &(*u)(unsafe.Pointer(t)).u
|
||||||
|
case Func:
|
||||||
|
type u struct {
|
||||||
|
FuncType
|
||||||
|
u UncommonType
|
||||||
|
}
|
||||||
|
return &(*u)(unsafe.Pointer(t)).u
|
||||||
|
case Slice:
|
||||||
|
type u struct {
|
||||||
|
SliceType
|
||||||
|
u UncommonType
|
||||||
|
}
|
||||||
|
return &(*u)(unsafe.Pointer(t)).u
|
||||||
|
case Array:
|
||||||
|
type u struct {
|
||||||
|
ArrayType
|
||||||
|
u UncommonType
|
||||||
|
}
|
||||||
|
return &(*u)(unsafe.Pointer(t)).u
|
||||||
|
case Chan:
|
||||||
|
type u struct {
|
||||||
|
ChanType
|
||||||
|
u UncommonType
|
||||||
|
}
|
||||||
|
return &(*u)(unsafe.Pointer(t)).u
|
||||||
|
case Map:
|
||||||
|
type u struct {
|
||||||
|
MapType
|
||||||
|
u UncommonType
|
||||||
|
}
|
||||||
|
return &(*u)(unsafe.Pointer(t)).u
|
||||||
|
case Interface:
|
||||||
|
type u struct {
|
||||||
|
InterfaceType
|
||||||
|
u UncommonType
|
||||||
|
}
|
||||||
|
return &(*u)(unsafe.Pointer(t)).u
|
||||||
|
default:
|
||||||
|
type u struct {
|
||||||
|
Type
|
||||||
|
u UncommonType
|
||||||
|
}
|
||||||
|
return &(*u)(unsafe.Pointer(t)).u
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Len returns the length of t if t is an array type, otherwise 0
|
// Len returns the length of t if t is an array type, otherwise 0
|
||||||
func (t *Type) Len() int {
|
func (t *Type) Len() int {
|
||||||
if t.Kind() == Array {
|
if t.Kind() == Array {
|
||||||
@@ -369,6 +456,7 @@ func addChecked(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
|
|||||||
return unsafe.Pointer(uintptr(p) + x)
|
return unsafe.Pointer(uintptr(p) + x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// Name is an encoded type Name with optional extra data.
|
// Name is an encoded type Name with optional extra data.
|
||||||
//
|
//
|
||||||
// The first byte is a bit field containing:
|
// The first byte is a bit field containing:
|
||||||
@@ -519,5 +607,6 @@ func NewName(n, tag string, exported, embedded bool) Name {
|
|||||||
|
|
||||||
return Name{Bytes: &b[0]}
|
return Name{Bytes: &b[0]}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ var Stderr FilePtr
|
|||||||
//go:linkname Str llgo.cstr
|
//go:linkname Str llgo.cstr
|
||||||
func Str(string) *Char
|
func Str(string) *Char
|
||||||
|
|
||||||
//go:linkname Advance llgo.advance
|
// llgo:link Advance llgo.advance
|
||||||
func Advance(ptr Pointer, offset int) Pointer
|
func Advance[PtrT any](ptr PtrT, offset int) PtrT { return ptr }
|
||||||
|
|
||||||
//go:linkname Alloca llgo.alloca
|
//go:linkname Alloca llgo.alloca
|
||||||
func Alloca(size uintptr) Pointer
|
func Alloca(size uintptr) Pointer
|
||||||
|
|||||||
Binary file not shown.
@@ -1,44 +0,0 @@
|
|||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
type eface struct {
|
|
||||||
_type *_type
|
|
||||||
data unsafe.Pointer
|
|
||||||
}
|
|
||||||
|
|
||||||
type iface struct {
|
|
||||||
tab *itab
|
|
||||||
data unsafe.Pointer
|
|
||||||
}
|
|
||||||
|
|
||||||
// layout of Itab known to compilers
|
|
||||||
// allocated in non-garbage-collected memory
|
|
||||||
// Needs to be in sync with
|
|
||||||
// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
|
|
||||||
type itab struct {
|
|
||||||
inter *interfacetype
|
|
||||||
_type *_type
|
|
||||||
hash uint32 // copy of _type.hash. Used for type switches.
|
|
||||||
_ [4]byte
|
|
||||||
fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func efaceOf(ep *any) *eface {
|
|
||||||
return (*eface)(unsafe.Pointer(ep))
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeInterface(inter *InterfaceType, typ *Type, data unsafe.Pointer) Interface {
|
|
||||||
tab := &itab{inter: inter, _type: typ, hash: 0, fun: [1]uintptr{0}}
|
|
||||||
return Interface{
|
|
||||||
tab: tab, data: data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -12,11 +12,9 @@ import (
|
|||||||
|
|
||||||
type _type = abi.Type
|
type _type = abi.Type
|
||||||
|
|
||||||
type interfacetype = abi.InterfaceType
|
/*
|
||||||
|
|
||||||
type maptype = abi.MapType
|
type maptype = abi.MapType
|
||||||
|
|
||||||
/*
|
|
||||||
type arraytype = abi.ArrayType
|
type arraytype = abi.ArrayType
|
||||||
|
|
||||||
type chantype = abi.ChanType
|
type chantype = abi.ChanType
|
||||||
|
|||||||
205
internal/runtime/z_face.go
Normal file
205
internal/runtime/z_face.go
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/internal/abi"
|
||||||
|
"github.com/goplus/llgo/internal/runtime/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
type eface struct {
|
||||||
|
_type *_type
|
||||||
|
data unsafe.Pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
type iface struct {
|
||||||
|
tab *itab
|
||||||
|
data unsafe.Pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
type interfacetype = abi.InterfaceType
|
||||||
|
|
||||||
|
// layout of Itab known to compilers
|
||||||
|
// allocated in non-garbage-collected memory
|
||||||
|
// Needs to be in sync with
|
||||||
|
// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
|
||||||
|
type itab struct {
|
||||||
|
inter *interfacetype
|
||||||
|
_type *_type
|
||||||
|
hash uint32 // copy of _type.hash. Used for type switches.
|
||||||
|
_ [4]byte
|
||||||
|
fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type (
|
||||||
|
Eface = eface
|
||||||
|
Iface = iface
|
||||||
|
Itab = itab
|
||||||
|
)
|
||||||
|
|
||||||
|
type FuncType = abi.FuncType
|
||||||
|
type InterfaceType = abi.InterfaceType
|
||||||
|
|
||||||
|
// ToEface converts an iface to an eface.
|
||||||
|
func ToEface(i Iface) Eface {
|
||||||
|
return Eface{i.tab._type, i.data}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const (
|
||||||
|
typeHdrSize = unsafe.Sizeof(abi.Type{})
|
||||||
|
funcTypeHdrSize = unsafe.Sizeof(abi.FuncType{})
|
||||||
|
uncommonTypeHdrSize = unsafe.Sizeof(abi.UncommonType{})
|
||||||
|
methodSize = unsafe.Sizeof(abi.Method{})
|
||||||
|
pointerSize = unsafe.Sizeof(uintptr(0))
|
||||||
|
itabHdrSize = unsafe.Sizeof(itab{}) - pointerSize
|
||||||
|
)
|
||||||
|
|
||||||
|
// Func returns a function type.
|
||||||
|
func Func(in, out []*Type, variadic bool) *FuncType {
|
||||||
|
n := len(in) + len(out)
|
||||||
|
ptr := AllocU(funcTypeHdrSize + uintptr(n)*pointerSize)
|
||||||
|
c.Memset(ptr, 0, funcTypeHdrSize)
|
||||||
|
|
||||||
|
ret := (*abi.FuncType)(ptr)
|
||||||
|
ret.Size_ = pointerSize
|
||||||
|
ret.Hash = uint32(abi.Func) // TODO(xsw): hash
|
||||||
|
ret.Kind_ = uint8(abi.Func)
|
||||||
|
ret.InCount = uint16(len(in))
|
||||||
|
ret.OutCount = uint16(len(out))
|
||||||
|
if variadic {
|
||||||
|
ret.OutCount |= 1 << 15
|
||||||
|
}
|
||||||
|
|
||||||
|
data := (**Type)(c.Advance(ptr, int(funcTypeHdrSize)))
|
||||||
|
params := unsafe.Slice(data, n)
|
||||||
|
copy(params, in)
|
||||||
|
copy(params[len(in):], out)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// Imethod returns an interface method.
|
||||||
|
func Imethod(name string, typ *FuncType) abi.Imethod {
|
||||||
|
return abi.Imethod{
|
||||||
|
Name_: name,
|
||||||
|
Typ_: typ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method returns a method.
|
||||||
|
func Method(name string, typ *FuncType, ifn, tfn abi.Text) abi.Method {
|
||||||
|
return abi.Method{
|
||||||
|
Name_: name,
|
||||||
|
Mtyp_: typ,
|
||||||
|
Ifn_: ifn,
|
||||||
|
Tfn_: tfn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Named returns a named type.
|
||||||
|
func Named(pkgPath, name string, underlying *Type, methods []abi.Method) *Type {
|
||||||
|
tflag := underlying.TFlag
|
||||||
|
size := typeHdrSize
|
||||||
|
n := len(methods)
|
||||||
|
if n > 0 || pkgPath != "" {
|
||||||
|
size += uncommonTypeHdrSize + uintptr(n)*methodSize
|
||||||
|
tflag |= abi.TFlagUncommon
|
||||||
|
}
|
||||||
|
ptr := AllocU(size)
|
||||||
|
|
||||||
|
ret := (*Type)(ptr)
|
||||||
|
*ret = *underlying
|
||||||
|
ret.TFlag = tflag | abi.TFlagNamed
|
||||||
|
ret.Str_ = name
|
||||||
|
|
||||||
|
xcount := 0
|
||||||
|
for _, m := range methods {
|
||||||
|
if !m.Exported() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
xcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
uncommon := (*abi.UncommonType)(c.Advance(ptr, int(typeHdrSize)))
|
||||||
|
uncommon.PkgPath_ = pkgPath
|
||||||
|
uncommon.Mcount = uint16(n)
|
||||||
|
uncommon.Xcount = uint16(xcount)
|
||||||
|
uncommon.Moff = uint32(uncommonTypeHdrSize)
|
||||||
|
|
||||||
|
data := (*abi.Method)(c.Advance(ptr, int(typeHdrSize+uncommonTypeHdrSize)))
|
||||||
|
copy(unsafe.Slice(data, n), methods)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface returns an interface type.
|
||||||
|
func Interface(pkgPath string, methods []abi.Imethod) *Type {
|
||||||
|
ret := &abi.InterfaceType{
|
||||||
|
Type: Type{
|
||||||
|
Size_: unsafe.Sizeof(eface{}),
|
||||||
|
Hash: uint32(abi.Interface), // TODO(xsw): hash
|
||||||
|
Kind_: uint8(abi.Interface),
|
||||||
|
},
|
||||||
|
PkgPath_: pkgPath,
|
||||||
|
Methods: methods,
|
||||||
|
}
|
||||||
|
return &ret.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewItab returns a new itab.
|
||||||
|
func NewItab(inter *InterfaceType, typ *Type) *Itab {
|
||||||
|
n := len(inter.Methods)
|
||||||
|
size := itabHdrSize + uintptr(n)*pointerSize
|
||||||
|
ptr := AllocU(size)
|
||||||
|
|
||||||
|
ret := (*Itab)(ptr)
|
||||||
|
ret.inter = inter
|
||||||
|
ret._type = typ
|
||||||
|
ret.hash = typ.Hash
|
||||||
|
|
||||||
|
u := typ.Uncommon()
|
||||||
|
if u == nil {
|
||||||
|
ret.fun[0] = 0
|
||||||
|
} else {
|
||||||
|
data := (*uintptr)(c.Advance(ptr, int(itabHdrSize)))
|
||||||
|
mthds := methods(u, inter.PkgPath_)
|
||||||
|
for i, m := range inter.Methods {
|
||||||
|
fn := findMethod(mthds, m)
|
||||||
|
if fn == nil {
|
||||||
|
ret.fun[0] = 0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
*c.Advance(data, i) = uintptr(fn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func findMethod(mthds []abi.Method, im abi.Imethod) abi.Text {
|
||||||
|
imName := im.Name_
|
||||||
|
for _, m := range mthds {
|
||||||
|
mName := m.Name_
|
||||||
|
if mName >= imName {
|
||||||
|
if mName == imName && m.Mtyp_ == im.Typ_ {
|
||||||
|
return m.Ifn_
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func methods(u *abi.UncommonType, from string) []abi.Method {
|
||||||
|
if u.PkgPath_ == from {
|
||||||
|
return u.Methods()
|
||||||
|
}
|
||||||
|
return u.ExportedMethods()
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
@@ -20,104 +20,29 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goplus/llgo/internal/abi"
|
"github.com/goplus/llgo/internal/abi"
|
||||||
"github.com/goplus/llgo/internal/runtime/c"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
Eface = eface
|
|
||||||
Iface = iface
|
|
||||||
Itab = itab
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Kind = abi.Kind
|
type Kind = abi.Kind
|
||||||
type Type = abi.Type
|
type Type = abi.Type
|
||||||
|
|
||||||
type FuncType = abi.FuncType
|
|
||||||
type InterfaceType = abi.InterfaceType
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Func returns a function type.
|
/*
|
||||||
func Func(in, out []*Type, variadic bool) *FuncType {
|
type Name = abi.Name
|
||||||
const (
|
|
||||||
funcTypeHdrSize = unsafe.Sizeof(abi.FuncType{})
|
|
||||||
pointerSize = unsafe.Sizeof(uintptr(0))
|
|
||||||
)
|
|
||||||
|
|
||||||
n := len(in) + len(out)
|
// NewName creates a new name.
|
||||||
ptr := AllocU(funcTypeHdrSize + uintptr(n)*pointerSize)
|
func NewName(name string, exported bool) Name {
|
||||||
c.Memset(ptr, 0, funcTypeHdrSize)
|
return abi.NewName(name, "", exported, false)
|
||||||
|
}
|
||||||
|
|
||||||
ret := (*abi.FuncType)(ptr)
|
// NewPkgName creates a package name.
|
||||||
ret.Size_ = pointerSize
|
func NewPkgName(pkgPath string) (ret Name) {
|
||||||
ret.Hash = uint32(abi.Func) // TODO(xsw): hash
|
if len(pkgPath) > 0 {
|
||||||
ret.Kind_ = uint8(abi.Func)
|
ret = abi.NewName(pkgPath, "", false, false)
|
||||||
ret.InCount = uint16(len(in))
|
|
||||||
ret.OutCount = uint16(len(out))
|
|
||||||
if variadic {
|
|
||||||
ret.OutCount |= 1 << 15
|
|
||||||
}
|
|
||||||
|
|
||||||
data := (**Type)(c.Advance(ptr, int(funcTypeHdrSize)))
|
|
||||||
params := unsafe.Slice(data, n)
|
|
||||||
copy(params, in)
|
|
||||||
copy(params[len(in):], out)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// Imethod returns an interface method.
|
|
||||||
func Imethod(name string, typ *FuncType, exported bool) abi.Imethod {
|
|
||||||
n := abi.NewName(name, "", exported, false)
|
|
||||||
return abi.Imethod{
|
|
||||||
Name_: n,
|
|
||||||
Typ_: typ,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method returns a method.
|
|
||||||
func Method(name string, typ *FuncType, fn abi.Text, exported bool) abi.Method {
|
|
||||||
n := abi.NewName(name, "", exported, false)
|
|
||||||
return abi.Method{
|
|
||||||
Name_: n,
|
|
||||||
Mtyp_: typ,
|
|
||||||
Ifn_: fn,
|
|
||||||
Tfn_: fn,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Named returns a named type.
|
|
||||||
func Named(name string, typ *Type) *Type {
|
|
||||||
ret := *typ // TODO(xsw): named type
|
|
||||||
return &ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interface returns an interface type.
|
|
||||||
func Interface(pkgPath string) *Type {
|
|
||||||
// TODO(xsw): pkgPath
|
|
||||||
// npkg := abi.NewName(pkgPath, "", false, false)
|
|
||||||
ret := &abi.InterfaceType{
|
|
||||||
Type: Type{
|
|
||||||
Size_: unsafe.Sizeof(eface{}),
|
|
||||||
Hash: uint32(abi.Interface), // TODO(xsw): hash
|
|
||||||
Kind_: uint8(abi.Interface),
|
|
||||||
},
|
|
||||||
//PkgPath: npkg,
|
|
||||||
Methods: nil,
|
|
||||||
}
|
|
||||||
return &ret.Type
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewItab returns a new itab.
|
|
||||||
func NewItab(inter *InterfaceType, typ *Type) *Itab {
|
|
||||||
return &itab{
|
|
||||||
inter: inter,
|
|
||||||
_type: typ,
|
|
||||||
hash: typ.Hash,
|
|
||||||
//fun: nil, TODO(xsw)
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -180,31 +105,32 @@ func basicType(kind abi.Kind) *Type {
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// StructField returns a struct field.
|
// StructField returns a struct field.
|
||||||
func StructField(name string, typ *Type, off uintptr, tag string, exported, embedded bool) abi.StructField {
|
func StructField(name string, typ *Type, off uintptr, tag string, embedded bool) abi.StructField {
|
||||||
n := abi.NewName(name, tag, exported, embedded)
|
|
||||||
return abi.StructField{
|
return abi.StructField{
|
||||||
Name: n,
|
Name_: name,
|
||||||
Typ: typ,
|
Typ: typ,
|
||||||
Offset: off,
|
Offset: off,
|
||||||
|
Tag_: tag,
|
||||||
|
Embedded_: embedded,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Struct returns a struct type.
|
// Struct returns a struct type.
|
||||||
func Struct(size uintptr, pkgPath string, fields ...abi.StructField) *Type {
|
func Struct(pkgPath string, size uintptr, fields ...abi.StructField) *Type {
|
||||||
// TODO(xsw): pkgPath
|
|
||||||
// npkg := abi.NewName(pkgPath, "", false, false)
|
|
||||||
ret := &abi.StructType{
|
ret := &abi.StructType{
|
||||||
Type: Type{
|
Type: Type{
|
||||||
Size_: size,
|
Size_: size,
|
||||||
Hash: uint32(abi.Struct), // TODO(xsw): hash
|
Hash: uint32(abi.Struct), // TODO(xsw): hash
|
||||||
Kind_: uint8(abi.Struct),
|
Kind_: uint8(abi.Struct),
|
||||||
},
|
},
|
||||||
// PkgPath: npkg,
|
PkgPath_: pkgPath,
|
||||||
Fields: fields,
|
Fields: fields,
|
||||||
}
|
}
|
||||||
return &ret.Type
|
return &ret.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Pointer returns a pointer type.
|
// Pointer returns a pointer type.
|
||||||
func Pointer(elem *Type) *Type {
|
func Pointer(elem *Type) *Type {
|
||||||
ret := &abi.PtrType{
|
ret := &abi.PtrType{
|
||||||
|
|||||||
175
ssa/expr.go
175
ssa/expr.go
@@ -41,16 +41,6 @@ func (v Expr) IsNil() bool {
|
|||||||
return v.Type == nil
|
return v.Type == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do evaluates the delay expression and returns the result.
|
|
||||||
func (v Expr) Do(b Builder) Expr { // TODO(xsw): can we remove this method?
|
|
||||||
switch vt := v.Type; vt.kind {
|
|
||||||
case vkPhisExpr:
|
|
||||||
e := vt.raw.Type.(*phisExprTy)
|
|
||||||
return b.aggregateValue(e.Type, e.phis...)
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
type pyVarTy struct {
|
type pyVarTy struct {
|
||||||
@@ -73,26 +63,6 @@ func pyVarExpr(mod Expr, name string) Expr {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
type phisExprTy struct {
|
|
||||||
phis []llvm.Value
|
|
||||||
Type
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p phisExprTy) Underlying() types.Type {
|
|
||||||
panic("don't call")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p phisExprTy) String() string {
|
|
||||||
return "phisExpr"
|
|
||||||
}
|
|
||||||
|
|
||||||
func phisExpr(t Type, phis []llvm.Value) Expr {
|
|
||||||
tphi := &aType{raw: rawType{&phisExprTy{phis, t}}, kind: vkPhisExpr}
|
|
||||||
return Expr{Type: tphi}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
func (p Program) Zero(t Type) Expr {
|
func (p Program) Zero(t Type) Expr {
|
||||||
var ret llvm.Value
|
var ret llvm.Value
|
||||||
switch u := t.raw.Type.Underlying().(type) {
|
switch u := t.raw.Type.Underlying().(type) {
|
||||||
@@ -121,6 +91,8 @@ func (p Program) Zero(t Type) Expr {
|
|||||||
flds[i] = p.Zero(p.rawType(u.Field(i).Type())).impl
|
flds[i] = p.Zero(p.rawType(u.Field(i).Type())).impl
|
||||||
}
|
}
|
||||||
ret = llvm.ConstStruct(flds, false)
|
ret = llvm.ConstStruct(flds, false)
|
||||||
|
case *types.Slice:
|
||||||
|
ret = p.Zero(p.rtType("Slice")).impl
|
||||||
default:
|
default:
|
||||||
log.Panicln("todo:", u)
|
log.Panicln("todo:", u)
|
||||||
}
|
}
|
||||||
@@ -221,6 +193,12 @@ func (b Builder) Str(v string) (ret Expr) {
|
|||||||
return Expr{aggregateValue(b.impl, prog.rtString(), data, size), prog.String()}
|
return Expr{aggregateValue(b.impl, prog.rtString(), data, size), prog.String()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b Builder) pkgName(pkgPath string) Expr {
|
||||||
|
// TODO(xsw): use a global cache
|
||||||
|
// return b.Call(b.Pkg.rtFunc("NewPkgName"), b.Str(pkgPath))
|
||||||
|
return b.Str(pkgPath)
|
||||||
|
}
|
||||||
|
|
||||||
// unsafeString(data *byte, size int) string
|
// unsafeString(data *byte, size int) string
|
||||||
func (b Builder) unsafeString(data, size llvm.Value) Expr {
|
func (b Builder) unsafeString(data, size llvm.Value) Expr {
|
||||||
prog := b.Prog
|
prog := b.Prog
|
||||||
@@ -528,14 +506,6 @@ func llvmFields(vals []Expr, t *types.Struct, b Builder) (ret []llvm.Value) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func llvmDelayValues(f func(i int) Expr, n int) []llvm.Value {
|
|
||||||
ret := make([]llvm.Value, n)
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ret[i] = f(i).impl
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func llvmPredBlocks(preds []BasicBlock) []llvm.BasicBlock {
|
func llvmPredBlocks(preds []BasicBlock) []llvm.BasicBlock {
|
||||||
ret := make([]llvm.BasicBlock, len(preds))
|
ret := make([]llvm.BasicBlock, len(preds))
|
||||||
for i, v := range preds {
|
for i, v := range preds {
|
||||||
@@ -544,60 +514,115 @@ func llvmPredBlocks(preds []BasicBlock) []llvm.BasicBlock {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phi represents a phi node.
|
type aPhi struct {
|
||||||
type Phi struct {
|
|
||||||
Expr
|
Expr
|
||||||
|
// phis []llvm.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Phi represents a phi node.
|
||||||
|
type Phi = *aPhi
|
||||||
|
|
||||||
|
/*
|
||||||
|
func (b Builder) newPhi(t Type, phis []llvm.Value) Phi {
|
||||||
|
ret := b.aggregateValue(t, phis...)
|
||||||
|
return &aPhi{ret, phis}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// AddIncoming adds incoming values to a phi node.
|
// AddIncoming adds incoming values to a phi node.
|
||||||
func (p Phi) AddIncoming(b Builder, preds []BasicBlock, f func(i int) Expr) {
|
func (p Phi) AddIncoming(b Builder, preds []BasicBlock, f func(i int, blk BasicBlock) Expr) {
|
||||||
bs := llvmPredBlocks(preds)
|
bs := llvmPredBlocks(preds)
|
||||||
if p.kind != vkPhisExpr { // normal phi node
|
/*
|
||||||
vs := llvmDelayValues(f, len(preds))
|
phis := p.phis
|
||||||
p.impl.AddIncoming(vs, bs)
|
if phis != nil {
|
||||||
return
|
vals := make([][]llvm.Value, len(phis))
|
||||||
}
|
for iblk, blk := range preds {
|
||||||
e := p.raw.Type.(*phisExprTy)
|
val := f(iblk, blk).impl
|
||||||
phis := e.phis
|
impl := b.impl
|
||||||
vals := make([][]llvm.Value, len(phis))
|
b.SetBlockEx(blk, BeforeLast, false)
|
||||||
for iblk, blk := range preds {
|
for i := range phis {
|
||||||
last := blk.last.LastInstruction()
|
if iblk == 0 {
|
||||||
b.impl.SetInsertPointBefore(last)
|
vals[i] = make([]llvm.Value, len(preds))
|
||||||
impl := b.impl
|
}
|
||||||
val := f(iblk).impl
|
vals[i][iblk] = llvm.CreateExtractValue(impl, val, i)
|
||||||
for i := range phis {
|
}
|
||||||
if iblk == 0 {
|
|
||||||
vals[i] = make([]llvm.Value, len(preds))
|
|
||||||
}
|
}
|
||||||
vals[i][iblk] = llvm.CreateExtractValue(impl, val, i)
|
for i, phi := range phis {
|
||||||
|
phi.AddIncoming(vals[i], bs)
|
||||||
|
}
|
||||||
|
} else */
|
||||||
|
{
|
||||||
|
vals := make([]llvm.Value, len(preds))
|
||||||
|
for iblk, blk := range preds {
|
||||||
|
vals[iblk] = f(iblk, blk).impl
|
||||||
}
|
}
|
||||||
}
|
p.impl.AddIncoming(vals, bs)
|
||||||
for i, phi := range phis {
|
|
||||||
phi.AddIncoming(vals[i], bs)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phi returns a phi node.
|
// Phi returns a phi node.
|
||||||
func (b Builder) Phi(t Type) Phi {
|
func (b Builder) Phi(t Type) Phi {
|
||||||
impl := b.impl
|
impl := b.impl
|
||||||
switch tund := t.raw.Type.Underlying().(type) {
|
/*
|
||||||
case *types.Basic:
|
switch tund := t.raw.Type.Underlying().(type) {
|
||||||
kind := tund.Kind()
|
case *types.Basic:
|
||||||
switch kind {
|
kind := tund.Kind()
|
||||||
case types.String:
|
switch kind {
|
||||||
prog := b.Prog
|
case types.String:
|
||||||
phis := make([]llvm.Value, 2)
|
phis := createStringPhis(impl, make([]llvm.Value, 0, 2), b.Prog)
|
||||||
phis[0] = llvm.CreatePHI(impl, prog.tyVoidPtr())
|
return b.newPhi(t, phis)
|
||||||
phis[1] = llvm.CreatePHI(impl, prog.tyInt())
|
}
|
||||||
return Phi{phisExpr(t, phis)}
|
case *types.Struct:
|
||||||
|
phis := createStrucPhis(impl, nil, tund, b.Prog)
|
||||||
|
return b.newPhi(t, phis)
|
||||||
|
default:
|
||||||
|
log.Panicf("todo: %T\n", tund)
|
||||||
}
|
}
|
||||||
case *types.Struct:
|
*/
|
||||||
panic("todo")
|
|
||||||
}
|
|
||||||
phi := llvm.CreatePHI(impl, t.ll)
|
phi := llvm.CreatePHI(impl, t.ll)
|
||||||
return Phi{Expr{phi, t}}
|
return &aPhi{Expr{phi, t}} //, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func createStringPhis(b llvm.Builder, phis []llvm.Value, prog Program) []llvm.Value {
|
||||||
|
phis = append(phis, llvm.CreatePHI(b, prog.tyVoidPtr()))
|
||||||
|
return append(phis, llvm.CreatePHI(b, prog.tyInt()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func createStrucPhis(b llvm.Builder, phis []llvm.Value, t *types.Struct, prog Program) []llvm.Value {
|
||||||
|
n := t.NumFields()
|
||||||
|
if phis == nil {
|
||||||
|
phis = make([]llvm.Value, 0, n)
|
||||||
|
}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
fld := t.Field(i)
|
||||||
|
switch tfld := fld.Type().Underlying().(type) {
|
||||||
|
case *types.Basic:
|
||||||
|
kind := tfld.Kind()
|
||||||
|
switch kind {
|
||||||
|
case types.String:
|
||||||
|
phis = createStringPhis(b, phis, prog)
|
||||||
|
default:
|
||||||
|
phis = createBasicPhi(b, phis, tfld, prog)
|
||||||
|
}
|
||||||
|
case *types.Pointer:
|
||||||
|
phis = createBasicPhi(b, phis, tfld, prog)
|
||||||
|
case *types.Struct:
|
||||||
|
phis = createStrucPhis(b, phis, tfld, prog)
|
||||||
|
default:
|
||||||
|
panic("todo")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return phis
|
||||||
|
}
|
||||||
|
|
||||||
|
func createBasicPhi(b llvm.Builder, phis []llvm.Value, t types.Type, prog Program) []llvm.Value {
|
||||||
|
tll := prog.rawType(t).ll
|
||||||
|
phi := llvm.CreatePHI(b, tll)
|
||||||
|
return append(phis, phi)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Advance returns the pointer ptr advanced by offset.
|
// Advance returns the pointer ptr advanced by offset.
|
||||||
|
|||||||
@@ -59,10 +59,19 @@ func (b Builder) abiTypeOf(t types.Type) Expr {
|
|||||||
panic("todo")
|
panic("todo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func Named(pkgPath, name string, underlying *Type, methods []abi.Method)
|
||||||
func (b Builder) abiNamedOf(t *types.Named) Expr {
|
func (b Builder) abiNamedOf(t *types.Named) Expr {
|
||||||
under := b.abiTypeOf(t.Underlying())
|
under := b.abiTypeOf(t.Underlying())
|
||||||
name := NameOf(t)
|
name := NameOf(t)
|
||||||
return b.Call(b.Pkg.rtFunc("Named"), b.Str(name), under)
|
|
||||||
|
prog := b.Prog
|
||||||
|
pkg := b.Pkg
|
||||||
|
pkgPath := b.pkgName(pkg.Path())
|
||||||
|
fn := pkg.rtFunc("Named")
|
||||||
|
tSlice := lastParamType(prog, fn)
|
||||||
|
// TODO(xsw): methods
|
||||||
|
methods := prog.Zero(tSlice)
|
||||||
|
return b.Call(fn, pkgPath, b.Str(name), under, methods)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Builder) abiPointerOf(t *types.Pointer) Expr {
|
func (b Builder) abiPointerOf(t *types.Pointer) Expr {
|
||||||
@@ -70,7 +79,7 @@ func (b Builder) abiPointerOf(t *types.Pointer) Expr {
|
|||||||
return b.Call(b.Pkg.rtFunc("Pointer"), elem)
|
return b.Call(b.Pkg.rtFunc("Pointer"), elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
// func Struct(size uintptr, pkgPath string, fields []abi.StructField) *abi.Type
|
// func Struct(pkgPath string, size uintptr, fields []abi.StructField)
|
||||||
func (b Builder) abiStructOf(t *types.Struct) Expr {
|
func (b Builder) abiStructOf(t *types.Struct) Expr {
|
||||||
pkg := b.Pkg
|
pkg := b.Pkg
|
||||||
prog := b.Prog
|
prog := b.Prog
|
||||||
@@ -84,20 +93,24 @@ func (b Builder) abiStructOf(t *types.Struct) Expr {
|
|||||||
off := uintptr(prog.OffsetOf(typ, i))
|
off := uintptr(prog.OffsetOf(typ, i))
|
||||||
flds[i] = b.structField(sfAbi, prog, f, off, t.Tag(i))
|
flds[i] = b.structField(sfAbi, prog, f, off, t.Tag(i))
|
||||||
}
|
}
|
||||||
pkgPath := b.Str(pkg.Path())
|
pkgPath := b.pkgName(pkg.Path())
|
||||||
params := strucAbi.raw.Type.(*types.Signature).Params()
|
tSlice := lastParamType(prog, strucAbi)
|
||||||
tSlice := prog.rawType(params.At(params.Len() - 1).Type().(*types.Slice))
|
|
||||||
fldSlice := b.SliceLit(tSlice, flds...)
|
fldSlice := b.SliceLit(tSlice, flds...)
|
||||||
return b.Call(strucAbi, pkgPath, fldSlice)
|
size := prog.IntVal(prog.SizeOf(typ), prog.Uintptr())
|
||||||
|
return b.Call(strucAbi, pkgPath, size, fldSlice)
|
||||||
}
|
}
|
||||||
|
|
||||||
// func StructField(name string, typ *abi.Type, off uintptr, tag string, exported, embedded bool) abi.StructField
|
func lastParamType(prog Program, fn Expr) Type {
|
||||||
|
params := fn.raw.Type.(*types.Signature).Params()
|
||||||
|
return prog.rawType(params.At(params.Len() - 1).Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
// func StructField(name string, typ *abi.Type, off uintptr, tag string, embedded bool) abi.StructField
|
||||||
func (b Builder) structField(sfAbi Expr, prog Program, f *types.Var, offset uintptr, tag string) Expr {
|
func (b Builder) structField(sfAbi Expr, prog Program, f *types.Var, offset uintptr, tag string) Expr {
|
||||||
name := b.Str(f.Name())
|
name := b.Str(f.Name())
|
||||||
typ := b.abiType(f.Type())
|
typ := b.abiType(f.Type())
|
||||||
exported := prog.Val(f.Exported())
|
|
||||||
embedded := prog.Val(f.Embedded())
|
embedded := prog.Val(f.Embedded())
|
||||||
return b.Call(sfAbi, name, typ, prog.Val(offset), b.Str(tag), exported, embedded)
|
return b.Call(sfAbi, name, typ, prog.Val(offset), b.Str(tag), embedded)
|
||||||
}
|
}
|
||||||
|
|
||||||
// abiType returns the abi type of the specified type.
|
// abiType returns the abi type of the specified type.
|
||||||
@@ -296,21 +309,20 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr {
|
|||||||
eq := b.BinOp(token.EQL, tx, tabi)
|
eq := b.BinOp(token.EQL, tx, tabi)
|
||||||
if commaOk {
|
if commaOk {
|
||||||
prog := b.Prog
|
prog := b.Prog
|
||||||
t := prog.Tuple(assertedTyp, prog.Bool())
|
t := prog.Struct(assertedTyp, prog.Bool())
|
||||||
blks := b.Func.MakeBlocks(3)
|
blks := b.Func.MakeBlocks(3)
|
||||||
b.If(eq, blks[0], blks[1])
|
b.If(eq, blks[0], blks[1])
|
||||||
|
|
||||||
b.SetBlockEx(blks[2], AtEnd, false)
|
b.SetBlockEx(blks[2], AtEnd, false)
|
||||||
phi := b.Phi(t)
|
phi := b.Phi(t)
|
||||||
phi.AddIncoming(b, blks[:2], func(i int) Expr {
|
phi.AddIncoming(b, blks[:2], func(i int, blk BasicBlock) Expr {
|
||||||
|
b.SetBlockEx(blk, AtEnd, false)
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
b.SetBlockEx(blks[0], AtEnd, false)
|
|
||||||
val := b.valFromData(assertedTyp, b.faceData(x.impl))
|
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])
|
b.Jump(blks[2])
|
||||||
return Expr{valTrue, t}
|
return Expr{valTrue, t}
|
||||||
}
|
}
|
||||||
b.SetBlockEx(blks[1], AtEnd, false)
|
|
||||||
zero := prog.Zero(assertedTyp)
|
zero := prog.Zero(assertedTyp)
|
||||||
valFalse := aggregateValue(b.impl, t.ll, zero.impl, prog.BoolVal(false).impl)
|
valFalse := aggregateValue(b.impl, t.ll, zero.impl, prog.BoolVal(false).impl)
|
||||||
b.Jump(blks[2])
|
b.Jump(blks[2])
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package ssa
|
|||||||
import (
|
import (
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
"strconv"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goplus/llgo/ssa/abi"
|
"github.com/goplus/llgo/ssa/abi"
|
||||||
@@ -296,13 +297,13 @@ func (p Program) NewPackage(name, pkgPath string) Package {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tuple returns a tuple type.
|
// Struct returns a struct type.
|
||||||
func (p Program) Tuple(typs ...Type) Type {
|
func (p Program) Struct(typs ...Type) Type {
|
||||||
els := make([]*types.Var, len(typs))
|
els := make([]*types.Var, len(typs))
|
||||||
for i, t := range typs {
|
for i, t := range typs {
|
||||||
els[i] = types.NewParam(token.NoPos, nil, "", t.raw.Type)
|
els[i] = types.NewParam(token.NoPos, nil, "_llgo_f"+strconv.Itoa(i), t.raw.Type)
|
||||||
}
|
}
|
||||||
return p.rawType(types.NewTuple(els...))
|
return p.rawType(types.NewStruct(els, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -109,9 +109,7 @@ func TestCvtType(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUserdefExpr(t *testing.T) {
|
func TestUserdefExpr(t *testing.T) {
|
||||||
b := &phisExprTy{}
|
|
||||||
c := &pyVarTy{}
|
c := &pyVarTy{}
|
||||||
_ = b.String()
|
|
||||||
_ = c.String()
|
_ = c.String()
|
||||||
test := func(a types.Type) {
|
test := func(a types.Type) {
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -121,7 +119,6 @@ func TestUserdefExpr(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
a.Underlying()
|
a.Underlying()
|
||||||
}
|
}
|
||||||
test(b)
|
|
||||||
test(c)
|
test(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ type InsertPoint int
|
|||||||
const (
|
const (
|
||||||
AtEnd InsertPoint = iota
|
AtEnd InsertPoint = iota
|
||||||
AtStart
|
AtStart
|
||||||
|
BeforeLast
|
||||||
afterInit
|
afterInit
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -93,6 +94,8 @@ func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint, setBlk bool) Builde
|
|||||||
b.impl.SetInsertPointAtEnd(blk.last)
|
b.impl.SetInsertPointAtEnd(blk.last)
|
||||||
case AtStart:
|
case AtStart:
|
||||||
b.impl.SetInsertPointBefore(blk.first.FirstInstruction())
|
b.impl.SetInsertPointBefore(blk.first.FirstInstruction())
|
||||||
|
case BeforeLast:
|
||||||
|
b.impl.SetInsertPointBefore(blk.last.LastInstruction())
|
||||||
case afterInit:
|
case afterInit:
|
||||||
b.impl.SetInsertPointBefore(instrAfterInit(blk.first))
|
b.impl.SetInsertPointBefore(instrAfterInit(blk.first))
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ const (
|
|||||||
vkEface
|
vkEface
|
||||||
vkIface
|
vkIface
|
||||||
vkStruct
|
vkStruct
|
||||||
vkPhisExpr = -1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user