build: fix unsafe.Sizeof for llgo:type C
This commit is contained in:
@@ -263,31 +263,25 @@ _llgo_0:
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = alloca { ptr, ptr }, align 8
|
||||
%8 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 0
|
||||
store ptr @"__llgo_stub.main.sort3a$1", ptr %8, align 8
|
||||
%9 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 1
|
||||
store ptr null, ptr %9, align 8
|
||||
%10 = load { ptr, ptr }, ptr %7, align 8
|
||||
%11 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %11, i64 5, i64 8, { ptr, ptr } %10)
|
||||
%12 = load [5 x i64], ptr %1, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %7, i64 5, i64 8, ptr @"main.sort3a$1")
|
||||
%8 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%13 = phi i64 [ -1, %_llgo_0 ], [ %14, %_llgo_2 ]
|
||||
%14 = add i64 %13, 1
|
||||
%15 = icmp slt i64 %14, 5
|
||||
br i1 %15, label %_llgo_2, label %_llgo_3
|
||||
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
|
||||
%10 = add i64 %9, 1
|
||||
%11 = icmp slt i64 %10, 5
|
||||
br i1 %11, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%16 = icmp slt i64 %14, 0
|
||||
%17 = icmp sge i64 %14, 5
|
||||
%18 = or i1 %17, %16
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %18)
|
||||
%19 = getelementptr inbounds i64, ptr %1, i64 %14
|
||||
%20 = load i64, ptr %19, align 4
|
||||
%21 = call i32 (ptr, ...) @printf(ptr @9, i64 %20)
|
||||
%12 = icmp slt i64 %10, 0
|
||||
%13 = icmp sge i64 %10, 5
|
||||
%14 = or i1 %13, %12
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
|
||||
%15 = getelementptr inbounds i64, ptr %1, i64 %10
|
||||
%16 = load i64, ptr %15, align 4
|
||||
%17 = call i32 (ptr, ...) @printf(ptr @9, i64 %16)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
@@ -318,30 +312,24 @@ _llgo_0:
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
%8 = alloca { ptr, ptr }, align 8
|
||||
%9 = getelementptr inbounds { ptr, ptr }, ptr %8, i32 0, i32 0
|
||||
store ptr @"__llgo_stub.main.sort3b$1", ptr %9, align 8
|
||||
%10 = getelementptr inbounds { ptr, ptr }, ptr %8, i32 0, i32 1
|
||||
store ptr null, ptr %10, align 8
|
||||
%11 = load { ptr, ptr }, ptr %8, align 8
|
||||
call void @qsort(ptr %7, i64 5, i64 8, { ptr, ptr } %11)
|
||||
%12 = load [5 x i64], ptr %1, align 4
|
||||
call void @qsort(ptr %7, i64 5, i64 8, ptr @"main.sort3b$1")
|
||||
%8 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%13 = phi i64 [ -1, %_llgo_0 ], [ %14, %_llgo_2 ]
|
||||
%14 = add i64 %13, 1
|
||||
%15 = icmp slt i64 %14, 5
|
||||
br i1 %15, label %_llgo_2, label %_llgo_3
|
||||
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
|
||||
%10 = add i64 %9, 1
|
||||
%11 = icmp slt i64 %10, 5
|
||||
br i1 %11, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%16 = icmp slt i64 %14, 0
|
||||
%17 = icmp sge i64 %14, 5
|
||||
%18 = or i1 %17, %16
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %18)
|
||||
%19 = getelementptr inbounds i64, ptr %1, i64 %14
|
||||
%20 = load i64, ptr %19, align 4
|
||||
%21 = call i32 (ptr, ...) @printf(ptr @11, i64 %20)
|
||||
%12 = icmp slt i64 %10, 0
|
||||
%13 = icmp sge i64 %10, 5
|
||||
%14 = or i1 %13, %12
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
|
||||
%15 = getelementptr inbounds i64, ptr %1, i64 %10
|
||||
%16 = load i64, ptr %15, align 4
|
||||
%17 = call i32 (ptr, ...) @printf(ptr @11, i64 %16)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
@@ -371,31 +359,25 @@ _llgo_0:
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = alloca { ptr, ptr }, align 8
|
||||
%8 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 0
|
||||
store ptr @"__llgo_stub.main.sort4a$1", ptr %8, align 8
|
||||
%9 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 1
|
||||
store ptr null, ptr %9, align 8
|
||||
%10 = load { ptr, ptr }, ptr %7, align 8
|
||||
%11 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %11, i64 5, i64 8, { ptr, ptr } %10)
|
||||
%12 = load [5 x i64], ptr %1, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %7, i64 5, i64 8, ptr @"main.sort4a$1")
|
||||
%8 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%13 = phi i64 [ -1, %_llgo_0 ], [ %14, %_llgo_2 ]
|
||||
%14 = add i64 %13, 1
|
||||
%15 = icmp slt i64 %14, 5
|
||||
br i1 %15, label %_llgo_2, label %_llgo_3
|
||||
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
|
||||
%10 = add i64 %9, 1
|
||||
%11 = icmp slt i64 %10, 5
|
||||
br i1 %11, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%16 = icmp slt i64 %14, 0
|
||||
%17 = icmp sge i64 %14, 5
|
||||
%18 = or i1 %17, %16
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %18)
|
||||
%19 = getelementptr inbounds i64, ptr %1, i64 %14
|
||||
%20 = load i64, ptr %19, align 4
|
||||
%21 = call i32 (ptr, ...) @printf(ptr @13, i64 %20)
|
||||
%12 = icmp slt i64 %10, 0
|
||||
%13 = icmp sge i64 %10, 5
|
||||
%14 = or i1 %13, %12
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
|
||||
%15 = getelementptr inbounds i64, ptr %1, i64 %10
|
||||
%16 = load i64, ptr %15, align 4
|
||||
%17 = call i32 (ptr, ...) @printf(ptr @13, i64 %16)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
@@ -473,31 +455,25 @@ _llgo_0:
|
||||
store i64 23, ptr %4, align 4
|
||||
store i64 2, ptr %5, align 4
|
||||
store i64 7, ptr %6, align 4
|
||||
%7 = alloca { ptr, ptr }, align 8
|
||||
%8 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 0
|
||||
store ptr @"__llgo_stub.main.sort5a$1", ptr %8, align 8
|
||||
%9 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 1
|
||||
store ptr null, ptr %9, align 8
|
||||
%10 = load { ptr, ptr }, ptr %7, align 8
|
||||
%11 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %11, i64 5, i64 8, { ptr, ptr } %10)
|
||||
%12 = load [5 x i64], ptr %1, align 4
|
||||
%7 = getelementptr inbounds i64, ptr %1, i64 0
|
||||
call void @qsort(ptr %7, i64 5, i64 8, ptr @"main.sort5a$1")
|
||||
%8 = load [5 x i64], ptr %1, align 4
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||
%13 = phi i64 [ -1, %_llgo_0 ], [ %14, %_llgo_2 ]
|
||||
%14 = add i64 %13, 1
|
||||
%15 = icmp slt i64 %14, 5
|
||||
br i1 %15, label %_llgo_2, label %_llgo_3
|
||||
%9 = phi i64 [ -1, %_llgo_0 ], [ %10, %_llgo_2 ]
|
||||
%10 = add i64 %9, 1
|
||||
%11 = icmp slt i64 %10, 5
|
||||
br i1 %11, label %_llgo_2, label %_llgo_3
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1
|
||||
%16 = icmp slt i64 %14, 0
|
||||
%17 = icmp sge i64 %14, 5
|
||||
%18 = or i1 %17, %16
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %18)
|
||||
%19 = getelementptr inbounds i64, ptr %1, i64 %14
|
||||
%20 = load i64, ptr %19, align 4
|
||||
%21 = call i32 (ptr, ...) @printf(ptr @17, i64 %20)
|
||||
%12 = icmp slt i64 %10, 0
|
||||
%13 = icmp sge i64 %10, 5
|
||||
%14 = or i1 %13, %12
|
||||
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
|
||||
%15 = getelementptr inbounds i64, ptr %1, i64 %10
|
||||
%16 = load i64, ptr %15, align 4
|
||||
%17 = call i32 (ptr, ...) @printf(ptr @17, i64 %16)
|
||||
br label %_llgo_1
|
||||
|
||||
_llgo_3: ; preds = %_llgo_1
|
||||
@@ -570,27 +546,3 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
||||
declare void @qsort(ptr, i64, i64, ptr)
|
||||
|
||||
declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)
|
||||
|
||||
define linkonce i32 @"__llgo_stub.main.sort3a$1"(ptr %0, ptr %1, ptr %2) {
|
||||
_llgo_0:
|
||||
%3 = tail call i32 @"main.sort3a$1"(ptr %1, ptr %2)
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
define linkonce i32 @"__llgo_stub.main.sort3b$1"(ptr %0, ptr %1, ptr %2) {
|
||||
_llgo_0:
|
||||
%3 = tail call i32 @"main.sort3b$1"(ptr %1, ptr %2)
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
define linkonce i32 @"__llgo_stub.main.sort4a$1"(ptr %0, ptr %1, ptr %2) {
|
||||
_llgo_0:
|
||||
%3 = tail call i32 @"main.sort4a$1"(ptr %1, ptr %2)
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
define linkonce i32 @"__llgo_stub.main.sort5a$1"(ptr %0, ptr %1, ptr %2) {
|
||||
_llgo_0:
|
||||
%3 = tail call i32 @"main.sort5a$1"(ptr %1, ptr %2)
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
30
cl/_testrt/unsafe/in.go
Normal file
30
cl/_testrt/unsafe/in.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//llgo:type C
|
||||
type T func()
|
||||
|
||||
type M struct {
|
||||
v int
|
||||
fn T
|
||||
}
|
||||
|
||||
type N struct {
|
||||
v int
|
||||
fn func()
|
||||
}
|
||||
|
||||
func main() {
|
||||
if unsafe.Sizeof(*(*T)(nil)) != unsafe.Sizeof(0) {
|
||||
panic("error")
|
||||
}
|
||||
if unsafe.Sizeof(*(*M)(nil)) != unsafe.Sizeof([2]int{}) {
|
||||
panic("error")
|
||||
}
|
||||
if unsafe.Sizeof(*(*N)(nil)) != unsafe.Sizeof([3]int{}) {
|
||||
panic("error")
|
||||
}
|
||||
}
|
||||
123
cl/_testrt/unsafe/out.ll
Normal file
123
cl/_testrt/unsafe/out.ll
Normal file
@@ -0,0 +1,123 @@
|
||||
; ModuleID = 'main'
|
||||
source_filename = "main"
|
||||
|
||||
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
||||
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
|
||||
|
||||
@"main.init$guard" = global i1 false, align 1
|
||||
@__llgo_argc = global i32 0, align 4
|
||||
@__llgo_argv = global ptr null, align 8
|
||||
@0 = private unnamed_addr constant [5 x i8] c"error", align 1
|
||||
@_llgo_string = linkonce global ptr null, align 8
|
||||
|
||||
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 @"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()
|
||||
br i1 false, label %_llgo_1, label %_llgo_2
|
||||
|
||||
_llgo_1: ; preds = %_llgo_0
|
||||
%2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 0
|
||||
store ptr @0, ptr %3, align 8
|
||||
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1
|
||||
store i64 5, ptr %4, align 4
|
||||
%5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8
|
||||
%6 = load ptr, ptr @_llgo_string, align 8
|
||||
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
|
||||
store %"github.com/goplus/llgo/internal/runtime.String" %5, ptr %7, align 8
|
||||
%8 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
|
||||
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, i32 0, i32 0
|
||||
store ptr %6, ptr %9, align 8
|
||||
%10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, i32 0, i32 1
|
||||
store ptr %7, ptr %10, align 8
|
||||
%11 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, align 8
|
||||
call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %11)
|
||||
unreachable
|
||||
|
||||
_llgo_2: ; preds = %_llgo_0
|
||||
br i1 false, label %_llgo_3, label %_llgo_4
|
||||
|
||||
_llgo_3: ; preds = %_llgo_2
|
||||
%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
|
||||
store ptr @0, ptr %13, align 8
|
||||
%14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %12, i32 0, i32 1
|
||||
store i64 5, ptr %14, align 4
|
||||
%15 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %12, align 8
|
||||
%16 = load ptr, ptr @_llgo_string, align 8
|
||||
%17 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
|
||||
store %"github.com/goplus/llgo/internal/runtime.String" %15, ptr %17, align 8
|
||||
%18 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
|
||||
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %18, i32 0, i32 0
|
||||
store ptr %16, ptr %19, align 8
|
||||
%20 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %18, i32 0, i32 1
|
||||
store ptr %17, ptr %20, align 8
|
||||
%21 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %18, align 8
|
||||
call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %21)
|
||||
unreachable
|
||||
|
||||
_llgo_4: ; preds = %_llgo_2
|
||||
br i1 false, label %_llgo_5, label %_llgo_6
|
||||
|
||||
_llgo_5: ; preds = %_llgo_4
|
||||
%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
|
||||
store ptr @0, ptr %23, align 8
|
||||
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 1
|
||||
store i64 5, ptr %24, align 4
|
||||
%25 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %22, align 8
|
||||
%26 = load ptr, ptr @_llgo_string, align 8
|
||||
%27 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
|
||||
store %"github.com/goplus/llgo/internal/runtime.String" %25, ptr %27, align 8
|
||||
%28 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
|
||||
%29 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %28, i32 0, i32 0
|
||||
store ptr %26, ptr %29, align 8
|
||||
%30 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %28, i32 0, i32 1
|
||||
store ptr %27, ptr %30, align 8
|
||||
%31 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %28, align 8
|
||||
call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %31)
|
||||
unreachable
|
||||
|
||||
_llgo_6: ; preds = %_llgo_4
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||
|
||||
define void @"main.init$after"() {
|
||||
_llgo_0:
|
||||
%0 = load ptr, ptr @_llgo_string, 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.Basic"(i64 24)
|
||||
store ptr %2, ptr @_llgo_string, align 8
|
||||
br label %_llgo_2
|
||||
|
||||
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||
ret void
|
||||
}
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64)
|
||||
|
||||
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64)
|
||||
|
||||
declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface")
|
||||
@@ -196,8 +196,6 @@ func (p *context) initFiles(pkgPath string, files []*ast.File) {
|
||||
p.collectSkipNames(line)
|
||||
}
|
||||
}
|
||||
case token.TYPE:
|
||||
handleTypeDecl(p.prog, p.goTyps, decl)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -568,9 +566,7 @@ func handleTypeDecl(prog llssa.Program, pkg *types.Package, decl *ast.GenDecl) {
|
||||
if len(decl.Specs) == 1 {
|
||||
if bg := typeBackground(decl.Doc); bg != "" {
|
||||
inPkgName := decl.Specs[0].(*ast.TypeSpec).Name.Name
|
||||
if obj := pkg.Scope().Lookup(inPkgName); obj != nil {
|
||||
prog.Type(obj.Type(), toBackground(bg))
|
||||
}
|
||||
prog.SetTypeBackground(pkg.Path()+"."+inPkgName, toBackground(bg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
"go/types"
|
||||
@@ -136,6 +137,12 @@ func Do(args []string, conf *Config) {
|
||||
prog := llssa.NewProgram(nil)
|
||||
sizes := prog.TypeSizes
|
||||
dedup := packages.NewDeduper()
|
||||
dedup.SetPreload(func(pkg *types.Package, files []*ast.File) {
|
||||
if canSkipToBuild(pkg.Path()) {
|
||||
return
|
||||
}
|
||||
cl.ParsePkgSyntax(prog, pkg, files)
|
||||
})
|
||||
|
||||
if patterns == nil {
|
||||
patterns = []string{"."}
|
||||
@@ -256,7 +263,6 @@ func buildAllPkgs(ctx *context, initial []*packages.Package, verbose bool) (pkgs
|
||||
case cl.PkgDeclOnly:
|
||||
// skip packages that only contain declarations
|
||||
// and set no export file
|
||||
cl.ParsePkgSyntax(ctx.prog, pkg.Types, pkg.Syntax)
|
||||
pkg.ExportFile = ""
|
||||
case cl.PkgLinkIR, cl.PkgLinkExtern, cl.PkgPyModule:
|
||||
if len(pkg.GoFiles) > 0 {
|
||||
|
||||
@@ -17,17 +17,10 @@
|
||||
package llgen
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"os"
|
||||
|
||||
"github.com/goplus/gogen/packages"
|
||||
"github.com/goplus/llgo/cl"
|
||||
"github.com/goplus/llgo/internal/mod"
|
||||
"golang.org/x/tools/go/ssa"
|
||||
"golang.org/x/tools/go/ssa/ssautil"
|
||||
|
||||
llssa "github.com/goplus/llgo/ssa"
|
||||
)
|
||||
@@ -45,51 +38,11 @@ func PkgPath(dir string) string {
|
||||
}
|
||||
|
||||
func Do(pkgPath, inFile, outFile string) {
|
||||
ret := Gen(pkgPath, inFile, nil)
|
||||
ret := genFrom(inFile, pkgPath)
|
||||
err := os.WriteFile(outFile, []byte(ret), 0644)
|
||||
check(err)
|
||||
}
|
||||
|
||||
func Gen(pkgPath, inFile string, src any) string {
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, inFile, src, parser.ParseComments)
|
||||
check(err)
|
||||
|
||||
files := []*ast.File{f}
|
||||
name := f.Name.Name
|
||||
if pkgPath == "" {
|
||||
pkgPath = name
|
||||
}
|
||||
pkg := types.NewPackage(pkgPath, name)
|
||||
imp := packages.NewImporter(fset)
|
||||
ssaPkg, _, err := ssautil.BuildPackage(
|
||||
&types.Config{Importer: imp}, fset, pkg, files, ssa.SanityCheckFunctions|ssa.InstantiateGenerics)
|
||||
check(err)
|
||||
|
||||
if Verbose {
|
||||
ssaPkg.WriteTo(os.Stderr)
|
||||
}
|
||||
|
||||
prog := llssa.NewProgram(nil)
|
||||
prog.SetRuntime(func() *types.Package {
|
||||
ret, _ := imp.Import(llssa.PkgRuntime)
|
||||
return ret
|
||||
})
|
||||
prog.SetPython(func() *types.Package {
|
||||
ret, _ := imp.Import(llssa.PkgPython)
|
||||
return ret
|
||||
})
|
||||
|
||||
ret, err := cl.NewPackage(prog, ssaPkg, files)
|
||||
check(err)
|
||||
|
||||
if prog.NeedPyInit { // call PyInit if needed
|
||||
ret.PyInit()
|
||||
}
|
||||
|
||||
return ret.String()
|
||||
}
|
||||
|
||||
func check(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package llgen
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/types"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -60,12 +61,32 @@ func initRtAndPy(prog llssa.Program, cfg *packages.Config) {
|
||||
}
|
||||
|
||||
func GenFrom(fileOrPkg string) string {
|
||||
return genFrom(fileOrPkg, "")
|
||||
}
|
||||
|
||||
func genFrom(fileOrPkg string, pkgPath string) string {
|
||||
prog := llssa.NewProgram(nil)
|
||||
|
||||
cfg := &packages.Config{
|
||||
Mode: loadSyntax | packages.NeedDeps,
|
||||
}
|
||||
initial, err := packages.LoadEx(nil, prog.TypeSizes, cfg, fileOrPkg)
|
||||
|
||||
dedup := packages.NewDeduper()
|
||||
dedup.SetPkgPath(func(path, name string) string {
|
||||
if path == "command-line-arguments" {
|
||||
if pkgPath != "" {
|
||||
path = pkgPath
|
||||
} else {
|
||||
path = name
|
||||
}
|
||||
}
|
||||
return path
|
||||
})
|
||||
dedup.SetPreload(func(pkg *types.Package, files []*ast.File) {
|
||||
cl.ParsePkgSyntax(prog, pkg, files)
|
||||
})
|
||||
|
||||
initial, err := packages.LoadEx(dedup, prog.TypeSizes, cfg, fileOrPkg)
|
||||
check(err)
|
||||
|
||||
_, pkgs := ssautil.AllPackages(initial, ssa.SanityCheckFunctions|ssa.InstantiateGenerics)
|
||||
|
||||
@@ -110,7 +110,9 @@ type Cached struct {
|
||||
}
|
||||
|
||||
type aDeduper struct {
|
||||
cache sync.Map
|
||||
cache sync.Map
|
||||
setpath func(path string, name string) string
|
||||
preload func(pkg *types.Package, syntax []*ast.File)
|
||||
}
|
||||
|
||||
type Deduper = *aDeduper
|
||||
@@ -119,6 +121,14 @@ func NewDeduper() Deduper {
|
||||
return &aDeduper{}
|
||||
}
|
||||
|
||||
func (p Deduper) SetPreload(fn func(pkg *types.Package, syntax []*ast.File)) {
|
||||
p.preload = fn
|
||||
}
|
||||
|
||||
func (p Deduper) SetPkgPath(fn func(path, name string) string) {
|
||||
p.setpath = fn
|
||||
}
|
||||
|
||||
func (p Deduper) Check(pkgPath string) *Cached {
|
||||
if v, ok := p.cache.Load(pkgPath); ok {
|
||||
return v.(*Cached)
|
||||
@@ -186,6 +196,9 @@ func loadPackageEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
|
||||
})
|
||||
}
|
||||
}()
|
||||
if dedup.setpath != nil {
|
||||
lpkg.PkgPath = dedup.setpath(lpkg.PkgPath, lpkg.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Call NewPackage directly with explicit name.
|
||||
@@ -369,6 +382,10 @@ func loadPackageEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
|
||||
panic("unreachable")
|
||||
})
|
||||
|
||||
if dedup != nil && dedup.preload != nil {
|
||||
dedup.preload(lpkg.Types, lpkg.Syntax)
|
||||
}
|
||||
|
||||
// type-check
|
||||
tc := &types.Config{
|
||||
Importer: importer,
|
||||
|
||||
@@ -236,6 +236,10 @@ func (p Program) SetRuntime(runtime any) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p Program) SetTypeBackground(fullName string, bg Background) {
|
||||
p.gocvt.typbg[fullName] = bg
|
||||
}
|
||||
|
||||
func (p Program) runtime() *types.Package {
|
||||
if p.rt == nil {
|
||||
p.rt = p.rtget()
|
||||
|
||||
22
ssa/type.go
22
ssa/type.go
@@ -103,7 +103,7 @@ func (p *goProgram) Offsetsof(fields []*types.Var) (ret []int64) {
|
||||
ret = p.sizes.Offsetsof(fields)
|
||||
for i, f := range fields {
|
||||
ret[i] += extra
|
||||
extra += extraSize(f.Type(), ptrSize)
|
||||
extra += p.extraSize(f.Type(), ptrSize)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -114,26 +114,34 @@ func (p *goProgram) Offsetsof(fields []*types.Var) (ret []int64) {
|
||||
func (p *goProgram) Sizeof(T types.Type) int64 {
|
||||
prog := Program(p)
|
||||
ptrSize := int64(prog.PointerSize())
|
||||
baseSize := prog.sizes.Sizeof(T) + extraSize(T, ptrSize)
|
||||
if _, ok := T.Underlying().(*types.Struct); ok {
|
||||
baseSize := prog.sizes.Sizeof(T) + p.extraSize(T, ptrSize)
|
||||
switch T.Underlying().(type) {
|
||||
case *types.Struct, *types.Array:
|
||||
return align(baseSize, prog.sizes.Alignof(T))
|
||||
}
|
||||
return baseSize
|
||||
}
|
||||
|
||||
func extraSize(t types.Type, ptrSize int64) (ret int64) {
|
||||
switch t := t.Underlying().(type) {
|
||||
func (p *goProgram) extraSize(typ types.Type, ptrSize int64) (ret int64) {
|
||||
retry:
|
||||
switch t := typ.(type) {
|
||||
case *types.Named:
|
||||
if p.gocvt.typbg[t.String()] == InC {
|
||||
return 0
|
||||
}
|
||||
typ = t.Underlying()
|
||||
goto retry
|
||||
case *types.Signature:
|
||||
return ptrSize
|
||||
case *types.Struct:
|
||||
n := t.NumFields()
|
||||
for i := 0; i < n; i++ {
|
||||
f := t.Field(i)
|
||||
ret += extraSize(f.Type(), ptrSize)
|
||||
ret += p.extraSize(f.Type(), ptrSize)
|
||||
}
|
||||
return
|
||||
case *types.Array:
|
||||
return extraSize(t.Elem(), ptrSize) * t.Len()
|
||||
return p.extraSize(t.Elem(), ptrSize) * t.Len()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -26,12 +26,14 @@ import (
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
type goTypes struct {
|
||||
typs map[unsafe.Pointer]unsafe.Pointer
|
||||
typs map[unsafe.Pointer]unsafe.Pointer
|
||||
typbg map[string]Background
|
||||
}
|
||||
|
||||
func newGoTypes() goTypes {
|
||||
typs := make(map[unsafe.Pointer]unsafe.Pointer)
|
||||
return goTypes{typs}
|
||||
typbk := make(map[string]Background)
|
||||
return goTypes{typs, typbk}
|
||||
}
|
||||
|
||||
type Background int
|
||||
@@ -93,6 +95,9 @@ func (p goTypes) cvtType(typ types.Type) (raw types.Type, cvt bool) {
|
||||
case *types.Struct:
|
||||
return p.cvtStruct(t)
|
||||
case *types.Named:
|
||||
if p.typbg[t.String()] == InC {
|
||||
break
|
||||
}
|
||||
return p.cvtNamed(t)
|
||||
case *types.Signature:
|
||||
return p.cvtClosure(t), true
|
||||
|
||||
Reference in New Issue
Block a user