diff --git a/.github/workflows/cleanup.sh b/.github/workflows/cleanup.sh deleted file mode 100644 index 9153db88..00000000 --- a/.github/workflows/cleanup.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -e - -if pkg=$(brew list | grep -E "pkg-config"); then - brew uninstall "$pkg" || true -fi diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index e5f669a5..594bb059 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -16,10 +16,10 @@ jobs: uses: actions/setup-node@v4 with: node-version: '20' - + - name: Install embedme run: npm install -g embedme - + - name: Verify README.md embedded code run: npx embedme --verify README.md @@ -32,7 +32,7 @@ jobs: runs-on: ${{matrix.os}} steps: - uses: actions/checkout@v4 - + - name: Set up Go uses: actions/setup-go@v5 with: @@ -43,7 +43,6 @@ jobs: run: | set -e set -x - bash .github/workflows/cleanup.sh source doc/_readme/scripts/install_macos.sh - name: Install dependencies on Ubuntu diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 8c6873d6..488e73c3 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -41,11 +41,10 @@ jobs: - name: Install dependencies if: startsWith(matrix.os, 'macos') run: | - bash .github/workflows/cleanup.sh brew update - brew install llvm@${{matrix.llvm}} pkg-config bdw-gc openssl libffi + brew install llvm@${{matrix.llvm}} bdw-gc openssl libffi + brew link --force libffi echo "$(brew --prefix llvm@${{matrix.llvm}})/bin" >> $GITHUB_PATH - echo "PKG_CONFIG_PATH=/opt/homebrew/opt/libffi/lib/pkgconfig" >> $GITHUB_ENV # Install optional deps for demos. # diff --git a/.github/workflows/test_demo.sh b/.github/workflows/test_demo.sh index 8e947f6a..42232e2f 100644 --- a/.github/workflows/test_demo.sh +++ b/.github/workflows/test_demo.sh @@ -1,13 +1,13 @@ #!/bin/bash set -e -# llgo run subdirectories under _demo and _pydemo +# llgo run subdirectories under _demo and _pydemo that contain *.go files total=0 failed=0 failed_cases="" for d in ./_demo/* ./_pydemo/*; do - total=$((total+1)) - if [ -d "$d" ]; then + if [ -d "$d" ] && [ -n "$(ls "$d"/*.go 2>/dev/null)" ]; then + total=$((total+1)) echo "Testing $d" if ! (cd "$d" && llgo run .); then echo "FAIL" diff --git a/README.md b/README.md index 605f6a72..e5700d48 100644 --- a/README.md +++ b/README.md @@ -358,9 +358,11 @@ Follow these steps to generate the `llgo` command (its usage is the same as the ```sh brew update -brew install llvm@18 pkg-config bdw-gc openssl cjson +brew install llvm@18 bdw-gc openssl cjson libffi brew install python@3.12 # optional +brew link --force libffi go install -v github.com/goplus/llgo/cmd/llgo@latest + ``` ### on Linux (Debian/Ubuntu) @@ -371,7 +373,7 @@ go install -v github.com/goplus/llgo/cmd/llgo@latest echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-18 main" | sudo tee /etc/apt/sources.list.d/llvm.list wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - sudo apt-get update -sudo apt-get install -y llvm-18-dev clang-18 libclang-18-dev lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev libcjson-dev python3.12-dev +sudo apt-get install -y llvm-18-dev clang-18 libclang-18-dev lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev libcjson-dev libsqlite3-dev sudo apt-get install -y python3.12-dev # optional go install -v github.com/goplus/llgo/cmd/llgo@latest ``` diff --git a/chore/gentests/gentests.go b/chore/gentests/gentests.go index ea465748..6cd06ba5 100644 --- a/chore/gentests/gentests.go +++ b/chore/gentests/gentests.go @@ -21,9 +21,7 @@ import ( "os" "strings" - "github.com/goplus/llgo/cl" "github.com/goplus/llgo/internal/llgen" - "github.com/goplus/llgo/ssa" "github.com/goplus/mod" ) @@ -31,32 +29,15 @@ func main() { dir, _, err := mod.FindGoMod(".") check(err) - ssa.Initialize(ssa.InitAll | ssa.InitNative) - llgen.Verbose = false - llgenDir(dir + "/cl/_testlibc") llgenDir(dir + "/cl/_testlibgo") llgenDir(dir + "/cl/_testrt") llgenDir(dir + "/cl/_testgo") - llgenDir(dir+"/cl/_testpy", "") - llgenDir(dir+"/cl/_testdata", "") + llgenDir(dir + "/cl/_testpy") + llgenDir(dir + "/cl/_testdata") } -func isDbgSymEnabled(flagsFile string) bool { - data, err := os.ReadFile(flagsFile) - if err != nil { - return false - } - toks := strings.Split(strings.Join(strings.Split(string(data), "\n"), " "), " ") - for _, tok := range toks { - if tok == "-dbg" { - return true - } - } - return false -} - -func llgenDir(dir string, pkgPath ...string) { +func llgenDir(dir string) { fis, err := os.ReadDir(dir) check(err) for _, fi := range fis { @@ -67,10 +48,7 @@ func llgenDir(dir string, pkgPath ...string) { testDir := dir + "/" + name fmt.Fprintln(os.Stderr, "llgen", testDir) check(os.Chdir(testDir)) - dbg := isDbgSymEnabled("flags.txt") - cl.EnableDebugSymbols(dbg) - - llgen.SmartDoFile("in.go", pkgPath...) + llgen.SmartDoFile(testDir) } } diff --git a/chore/llgen/llgen.go b/chore/llgen/llgen.go index 4f14892b..50e9a89e 100644 --- a/chore/llgen/llgen.go +++ b/chore/llgen/llgen.go @@ -17,6 +17,7 @@ package main import ( + "flag" "fmt" "os" @@ -24,11 +25,10 @@ import ( ) func main() { - if len(os.Args) < 2 { - fmt.Fprintln(os.Stderr, "Usage: llgen [flags] [pkgPath]") + flag.Parse() + if len(flag.Args()) != 1 { + fmt.Fprintln(os.Stderr, "Usage: llgen [flags] ") return } - llgen.Init() - args := os.Args[1:] - llgen.SmartDoFile(args[0], args[1:]...) + llgen.SmartDoFile(flag.Args()[0]) } diff --git a/cl/_testdata/apkg/out.ll b/cl/_testdata/apkg/out.ll index 165eea6c..adaa6e28 100644 --- a/cl/_testdata/apkg/out.ll +++ b/cl/_testdata/apkg/out.ll @@ -1,9 +1,9 @@ -; ModuleID = 'apkg' -source_filename = "apkg" +; ModuleID = 'github.com/goplus/llgo/cl/_testdata/apkg' +source_filename = "github.com/goplus/llgo/cl/_testdata/apkg" -@"apkg.init$guard" = global i1 false, align 1 +@"github.com/goplus/llgo/cl/_testdata/apkg.init$guard" = global i1 false, align 1 -define double @apkg.Max(double %0, double %1) { +define double @"github.com/goplus/llgo/cl/_testdata/apkg.Max"(double %0, double %1) { _llgo_0: %2 = fcmp ogt double %0, %1 br i1 %2, label %_llgo_1, label %_llgo_2 @@ -15,13 +15,13 @@ _llgo_2: ; preds = %_llgo_0 ret double %1 } -define void @apkg.init() { +define void @"github.com/goplus/llgo/cl/_testdata/apkg.init"() { _llgo_0: - %0 = load i1, ptr @"apkg.init$guard", align 1 + %0 = load i1, ptr @"github.com/goplus/llgo/cl/_testdata/apkg.init$guard", align 1 br i1 %0, label %_llgo_2, label %_llgo_1 _llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"apkg.init$guard", align 1 + store i1 true, ptr @"github.com/goplus/llgo/cl/_testdata/apkg.init$guard", align 1 br label %_llgo_2 _llgo_2: ; preds = %_llgo_1, %_llgo_0 diff --git a/cl/_testdata/llgotag/out.ll b/cl/_testdata/llgotag/out.ll index 6eadd8e5..568edce1 100644 --- a/cl/_testdata/llgotag/out.ll +++ b/cl/_testdata/llgotag/out.ll @@ -1,20 +1,20 @@ -; ModuleID = 'llgotag' -source_filename = "llgotag" +; ModuleID = 'github.com/goplus/llgo/cl/_testdata/llgotag' +source_filename = "github.com/goplus/llgo/cl/_testdata/llgotag" -@"llgotag.init$guard" = global i1 false, align 1 +@"github.com/goplus/llgo/cl/_testdata/llgotag.init$guard" = global i1 false, align 1 -define void @llgotag.Foo() { +define void @"github.com/goplus/llgo/cl/_testdata/llgotag.Foo"() { _llgo_0: ret void } -define void @llgotag.init() { +define void @"github.com/goplus/llgo/cl/_testdata/llgotag.init"() { _llgo_0: - %0 = load i1, ptr @"llgotag.init$guard", align 1 + %0 = load i1, ptr @"github.com/goplus/llgo/cl/_testdata/llgotag.init$guard", align 1 br i1 %0, label %_llgo_2, label %_llgo_1 _llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"llgotag.init$guard", align 1 + store i1 true, ptr @"github.com/goplus/llgo/cl/_testdata/llgotag.init$guard", align 1 br label %_llgo_2 _llgo_2: ; preds = %_llgo_1, %_llgo_0 diff --git a/cl/_testdata/print/out.ll b/cl/_testdata/print/out.ll index bd2de8a7..85340317 100644 --- a/cl/_testdata/print/out.ll +++ b/cl/_testdata/print/out.ll @@ -24,7 +24,7 @@ source_filename = "main" @_llgo_int16 = linkonce global ptr null, align 8 @_llgo_int64 = linkonce global ptr null, align 8 @_llgo_int = linkonce global ptr null, align 8 -@_llgo_uint8 = linkonce global ptr null, align 8 +@_llgo_byte = linkonce global ptr null, align 8 @_llgo_uint16 = linkonce global ptr null, align 8 @_llgo_uint32 = linkonce global ptr null, align 8 @_llgo_uint64 = linkonce global ptr null, align 8 @@ -243,7 +243,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_3, %78 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %77, ptr inttoptr (i64 5 to ptr), 1 store %"github.com/goplus/llgo/internal/runtime.eface" %78, ptr %75, align 8 %79 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %38, i64 10 - %80 = load ptr, ptr @_llgo_uint8, align 8 + %80 = load ptr, ptr @_llgo_byte, align 8 %81 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %80, 0 %82 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %81, ptr inttoptr (i64 1 to ptr), 1 store %"github.com/goplus/llgo/internal/runtime.eface" %82, ptr %79, align 8 @@ -389,7 +389,7 @@ _llgo_14: ; preds = %_llgo_55 _llgo_15: ; preds = %_llgo_55 %25 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %0, 0 - %26 = load ptr, ptr @_llgo_uint8, align 8 + %26 = load ptr, ptr @_llgo_byte, align 8 %27 = icmp eq ptr %25, %26 br i1 %27, label %_llgo_56, label %_llgo_57 @@ -1273,13 +1273,13 @@ _llgo_17: ; preds = %_llgo_16 br label %_llgo_18 _llgo_18: ; preds = %_llgo_17, %_llgo_16 - %27 = load ptr, ptr @_llgo_uint8, align 8 + %27 = load ptr, ptr @_llgo_byte, align 8 %28 = icmp eq ptr %27, null br i1 %28, label %_llgo_19, label %_llgo_20 _llgo_19: ; preds = %_llgo_18 %29 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 40) - store ptr %29, ptr @_llgo_uint8, align 8 + store ptr %29, ptr @_llgo_byte, align 8 br label %_llgo_20 _llgo_20: ; preds = %_llgo_19, %_llgo_18 diff --git a/cl/_testgo/goroutine/out.ll b/cl/_testgo/goroutine/out.ll index bfc48cba..b91770c7 100644 --- a/cl/_testgo/goroutine/out.ll +++ b/cl/_testgo/goroutine/out.ll @@ -2,7 +2,6 @@ source_filename = "main" %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } -%"github.com/goplus/llgo/c/pthread.RoutineFunc" = type { ptr, ptr } @"main.init$guard" = global i1 false, align 1 @__llgo_argc = global i32 0, align 4 @@ -41,7 +40,7 @@ _llgo_0: %8 = getelementptr inbounds { { ptr, ptr }, %"github.com/goplus/llgo/internal/runtime.String" }, ptr %6, i32 0, i32 1 store %"github.com/goplus/llgo/internal/runtime.String" { ptr @0, i64 16 }, ptr %8, align 8 %9 = alloca i8, i64 8, align 1 - %10 = call i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr %9, ptr null, %"github.com/goplus/llgo/c/pthread.RoutineFunc" { ptr @"__llgo_stub.main._llgo_routine$1", ptr null }, ptr %6) + %10 = call i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr %9, ptr null, ptr @"main._llgo_routine$1", ptr %6) br label %_llgo_3 _llgo_1: ; preds = %_llgo_3 @@ -88,13 +87,7 @@ _llgo_0: declare void @free(ptr) -declare i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr, ptr, %"github.com/goplus/llgo/c/pthread.RoutineFunc", ptr) - -define linkonce ptr @"__llgo_stub.main._llgo_routine$1"(ptr %0, ptr %1) { -_llgo_0: - %2 = tail call ptr @"main._llgo_routine$1"(ptr %1) - ret ptr %2 -} +declare i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr, ptr, ptr, ptr) declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") diff --git a/cl/_testgo/selects/out.ll b/cl/_testgo/selects/out.ll index 595d2ce3..6196d5c7 100644 --- a/cl/_testgo/selects/out.ll +++ b/cl/_testgo/selects/out.ll @@ -1,7 +1,6 @@ ; ModuleID = 'main' source_filename = "main" -%"github.com/goplus/llgo/c/pthread.RoutineFunc" = type { ptr, ptr } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.ChanOp" = type { ptr, ptr, i32, i1 } %"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } @@ -61,7 +60,7 @@ _llgo_0: %15 = getelementptr inbounds { { ptr, ptr } }, ptr %14, i32 0, i32 0 store { ptr, ptr } %13, ptr %15, align 8 %16 = alloca i8, i64 8, align 1 - %17 = call i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr %16, ptr null, %"github.com/goplus/llgo/c/pthread.RoutineFunc" { ptr @"__llgo_stub.main._llgo_routine$1", ptr null }, ptr %14) + %17 = call i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr %16, ptr null, ptr @"main._llgo_routine$1", ptr %14) %18 = load ptr, ptr %2, align 8 %19 = alloca {}, align 8 call void @llvm.memset(ptr %19, i8 0, i64 0, i1 false) @@ -230,13 +229,7 @@ _llgo_0: declare void @free(ptr) -declare i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr, ptr, %"github.com/goplus/llgo/c/pthread.RoutineFunc", ptr) - -define linkonce ptr @"__llgo_stub.main._llgo_routine$1"(ptr %0, ptr %1) { -_llgo_0: - %2 = tail call ptr @"main._llgo_routine$1"(ptr %1) - ret ptr %2 -} +declare i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr, ptr, ptr, ptr) declare i1 @"github.com/goplus/llgo/internal/runtime.ChanSend"(ptr, ptr, i64) diff --git a/cl/_testgo/syncmap/out.ll b/cl/_testgo/syncmap/out.ll index b9327d67..1c8a0e79 100644 --- a/cl/_testgo/syncmap/out.ll +++ b/cl/_testgo/syncmap/out.ll @@ -1,161 +1 @@ -; ModuleID = 'main' -source_filename = "main" - -%"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.Slice" = type { ptr, i64, i64 } -%"github.com/goplus/llgo/internal/runtime.iface" = 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 -@_llgo_int = linkonce global ptr null, align 8 -@0 = private unnamed_addr constant [5 x i8] c"hello", align 1 -@_llgo_string = linkonce global ptr null, align 8 -@1 = private unnamed_addr constant [1 x i8] c"1", align 1 -@_llgo_bool = linkonce global ptr null, align 8 -@2 = private unnamed_addr constant [7 x i8] c"%#v %v\0A", align 1 - -define void @main.init() { -_llgo_0: - %0 = load i1, ptr @"main.init$guard", align 1 - br i1 %0, label %_llgo_2, label %_llgo_1 - -_llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"main.init$guard", align 1 - call void @fmt.init() - call void @sync.init() - call void @"main.init$after"() - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - ret void -} - -define i32 @main(i32 %0, ptr %1) { -_llgo_0: - store i32 %0, ptr @__llgo_argc, align 4 - store ptr %1, ptr @__llgo_argv, align 8 - call void @"github.com/goplus/llgo/internal/runtime.init"() - call void @main.init() - %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) - %3 = load ptr, ptr @_llgo_int, align 8 - %4 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %3, 0 - %5 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %4, ptr inttoptr (i64 1 to ptr), 1 - %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" { ptr @0, i64 5 }, ptr %7, align 8 - %8 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %6, 0 - %9 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %8, ptr %7, 1 - call void @"sync.(*Map).Store"(ptr %2, %"github.com/goplus/llgo/internal/runtime.eface" %5, %"github.com/goplus/llgo/internal/runtime.eface" %9) - %10 = load ptr, ptr @_llgo_string, align 8 - %11 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) - store %"github.com/goplus/llgo/internal/runtime.String" { ptr @1, i64 1 }, ptr %11, align 8 - %12 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %10, 0 - %13 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %12, ptr %11, 1 - %14 = load ptr, ptr @_llgo_int, align 8 - %15 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %14, 0 - %16 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %15, ptr inttoptr (i64 100 to ptr), 1 - call void @"sync.(*Map).Store"(ptr %2, %"github.com/goplus/llgo/internal/runtime.eface" %13, %"github.com/goplus/llgo/internal/runtime.eface" %16) - %17 = load ptr, ptr @_llgo_string, align 8 - %18 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) - store %"github.com/goplus/llgo/internal/runtime.String" { ptr @1, i64 1 }, ptr %18, align 8 - %19 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %17, 0 - %20 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %19, ptr %18, 1 - %21 = call { %"github.com/goplus/llgo/internal/runtime.eface", i1 } @"sync.(*Map).Load"(ptr %2, %"github.com/goplus/llgo/internal/runtime.eface" %20) - %22 = extractvalue { %"github.com/goplus/llgo/internal/runtime.eface", i1 } %21, 0 - %23 = extractvalue { %"github.com/goplus/llgo/internal/runtime.eface", i1 } %21, 1 - %24 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) - %25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %24, i64 0 - store %"github.com/goplus/llgo/internal/runtime.eface" %22, ptr %25, align 8 - %26 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %24, i64 1 - %27 = load ptr, ptr @_llgo_bool, align 8 - %28 = sext i1 %23 to i64 - %29 = inttoptr i64 %28 to ptr - %30 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %27, 0 - %31 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %30, ptr %29, 1 - store %"github.com/goplus/llgo/internal/runtime.eface" %31, ptr %26, align 8 - %32 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" undef, ptr %24, 0 - %33 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %32, i64 2, 1 - %34 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %33, i64 2, 2 - %35 = call { i64, %"github.com/goplus/llgo/internal/runtime.iface" } @fmt.Println(%"github.com/goplus/llgo/internal/runtime.Slice" %34) - call void @"sync.(*Map).Range"(ptr %2, { ptr, ptr } { ptr @"__llgo_stub.main.main$1", ptr null }) - ret i32 0 -} - -define i1 @"main.main$1"(%"github.com/goplus/llgo/internal/runtime.eface" %0, %"github.com/goplus/llgo/internal/runtime.eface" %1) { -_llgo_0: - %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) - %3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %2, i64 0 - store %"github.com/goplus/llgo/internal/runtime.eface" %0, ptr %3, align 8 - %4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %2, i64 1 - store %"github.com/goplus/llgo/internal/runtime.eface" %1, ptr %4, align 8 - %5 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" undef, ptr %2, 0 - %6 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %5, i64 2, 1 - %7 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %6, i64 2, 2 - %8 = call { i64, %"github.com/goplus/llgo/internal/runtime.iface" } @fmt.Printf(%"github.com/goplus/llgo/internal/runtime.String" { ptr @2, i64 7 }, %"github.com/goplus/llgo/internal/runtime.Slice" %7) - ret i1 true -} - -declare void @fmt.init() - -declare void @sync.init() - -declare void @"github.com/goplus/llgo/internal/runtime.init"() - -declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) - -declare void @"sync.(*Map).Store"(ptr, %"github.com/goplus/llgo/internal/runtime.eface", %"github.com/goplus/llgo/internal/runtime.eface") - -define void @"main.init$after"() { -_llgo_0: - %0 = load ptr, ptr @_llgo_int, 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 34) - store ptr %2, ptr @_llgo_int, align 8 - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - %3 = load ptr, ptr @_llgo_string, align 8 - %4 = icmp eq ptr %3, null - br i1 %4, label %_llgo_3, label %_llgo_4 - -_llgo_3: ; preds = %_llgo_2 - %5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 24) - store ptr %5, ptr @_llgo_string, align 8 - br label %_llgo_4 - -_llgo_4: ; preds = %_llgo_3, %_llgo_2 - %6 = load ptr, ptr @_llgo_bool, align 8 - %7 = icmp eq ptr %6, null - br i1 %7, label %_llgo_5, label %_llgo_6 - -_llgo_5: ; preds = %_llgo_4 - %8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 33) - store ptr %8, ptr @_llgo_bool, align 8 - br label %_llgo_6 - -_llgo_6: ; preds = %_llgo_5, %_llgo_4 - ret void -} - -declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) - -declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) - -declare { %"github.com/goplus/llgo/internal/runtime.eface", i1 } @"sync.(*Map).Load"(ptr, %"github.com/goplus/llgo/internal/runtime.eface") - -declare { i64, %"github.com/goplus/llgo/internal/runtime.iface" } @fmt.Println(%"github.com/goplus/llgo/internal/runtime.Slice") - -declare void @"sync.(*Map).Range"(ptr, { ptr, ptr }) - -define linkonce i1 @"__llgo_stub.main.main$1"(ptr %0, %"github.com/goplus/llgo/internal/runtime.eface" %1, %"github.com/goplus/llgo/internal/runtime.eface" %2) { -_llgo_0: - %3 = tail call i1 @"main.main$1"(%"github.com/goplus/llgo/internal/runtime.eface" %1, %"github.com/goplus/llgo/internal/runtime.eface" %2) - ret i1 %3 -} - -declare { i64, %"github.com/goplus/llgo/internal/runtime.iface" } @fmt.Printf(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.Slice") +; \ No newline at end of file diff --git a/cl/_testlibgo/atomic/out.ll b/cl/_testlibgo/atomic/out.ll index e206c8c2..765b0452 100644 --- a/cl/_testlibgo/atomic/out.ll +++ b/cl/_testlibgo/atomic/out.ll @@ -32,8 +32,8 @@ _llgo_0: call void @"github.com/goplus/llgo/internal/runtime.init"() call void @main.init() %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - call void @"sync/atomic.StoreInt64"(ptr %2, i64 100) - %3 = call i64 @"sync/atomic.LoadInt64"(ptr %2) + store atomic i64 100, ptr %2 seq_cst, align 4 + %3 = load atomic i64, ptr %2 seq_cst, align 4 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" { ptr @0, i64 6 }) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %3) @@ -87,10 +87,6 @@ declare void @"github.com/goplus/llgo/internal/runtime.init"() declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) -declare void @"sync/atomic.StoreInt64"(ptr, i64) - -declare i64 @"sync/atomic.LoadInt64"(ptr) - declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8) diff --git a/cl/_testlibgo/complex/out.ll b/cl/_testlibgo/complex/out.ll index d89ac2fb..a7c5af4e 100644 --- a/cl/_testlibgo/complex/out.ll +++ b/cl/_testlibgo/complex/out.ll @@ -12,7 +12,7 @@ source_filename = "main" define void @main.f({ double, double } %0, { double, double } %1) { _llgo_0: - %2 = call double @"math/cmplx.Abs"({ double, double } %0) + %2 = call double @cabs({ double, double } %0) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" { ptr @0, i64 10 }) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %2) @@ -54,7 +54,7 @@ _llgo_0: ret i32 0 } -declare double @"math/cmplx.Abs"({ double, double }) +declare double @cabs({ double, double }) declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") diff --git a/cl/_testlibgo/math/out.ll b/cl/_testlibgo/math/out.ll index e7ee0e64..deb4b57e 100644 --- a/cl/_testlibgo/math/out.ll +++ b/cl/_testlibgo/math/out.ll @@ -25,7 +25,7 @@ _llgo_0: store ptr %1, ptr @__llgo_argv, align 8 call void @"github.com/goplus/llgo/internal/runtime.init"() call void @main.init() - %2 = call double @math.Sqrt(double 2.000000e+00) + %2 = call double @sqrt(double 2.000000e+00) call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %2) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) %3 = call double @math.Abs(double -1.200000e+00) @@ -41,7 +41,7 @@ declare void @math.init() declare void @"github.com/goplus/llgo/internal/runtime.init"() -declare double @math.Sqrt(double) +declare double @sqrt(double) declare void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double) diff --git a/cl/_testpy/callpy/out.ll b/cl/_testpy/callpy/out.ll index 25ccfebb..484cf44e 100644 --- a/cl/_testpy/callpy/out.ll +++ b/cl/_testpy/callpy/out.ll @@ -40,7 +40,6 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define i32 @main(i32 %0, ptr %1) { _llgo_0: - call void @Py_Initialize() 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"() @@ -81,5 +80,3 @@ declare ptr @PyUnicode_FromString(ptr) declare ptr @PyObject_CallFunctionObjArgs(ptr, ...) declare void @llgoLoadPyModSyms(ptr, ...) - -declare void @Py_Initialize() diff --git a/cl/_testpy/gcd/out.ll b/cl/_testpy/gcd/out.ll index fbc24887..0fdec606 100644 --- a/cl/_testpy/gcd/out.ll +++ b/cl/_testpy/gcd/out.ll @@ -27,7 +27,6 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define i32 @main(i32 %0, ptr %1) { _llgo_0: - call void @Py_Initialize() 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"() @@ -55,5 +54,3 @@ declare i64 @PyLong_AsLong(ptr) declare i32 @printf(ptr, ...) declare void @llgoLoadPyModSyms(ptr, ...) - -declare void @Py_Initialize() diff --git a/cl/_testpy/math/out.ll b/cl/_testpy/math/out.ll index 746b550c..9eeddcbc 100644 --- a/cl/_testpy/math/out.ll +++ b/cl/_testpy/math/out.ll @@ -1,17 +1,17 @@ -; ModuleID = 'math' -source_filename = "math" +; ModuleID = 'github.com/goplus/llgo/cl/_testpy/math' +source_filename = "github.com/goplus/llgo/cl/_testpy/math" -@"math.init$guard" = global i1 false, align 1 +@"github.com/goplus/llgo/cl/_testpy/math.init$guard" = global i1 false, align 1 @__llgo_py.math = linkonce global ptr null, align 8 @0 = private unnamed_addr constant [5 x i8] c"math\00", align 1 -define void @math.init() { +define void @"github.com/goplus/llgo/cl/_testpy/math.init"() { _llgo_0: - %0 = load i1, ptr @"math.init$guard", align 1 + %0 = load i1, ptr @"github.com/goplus/llgo/cl/_testpy/math.init$guard", align 1 br i1 %0, label %_llgo_2, label %_llgo_1 _llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"math.init$guard", align 1 + store i1 true, ptr @"github.com/goplus/llgo/cl/_testpy/math.init$guard", align 1 %1 = load ptr, ptr @__llgo_py.math, align 8 %2 = icmp ne ptr %1, null br i1 %2, label %_llgo_2, label %_llgo_3 diff --git a/cl/_testpy/matrix/out.ll b/cl/_testpy/matrix/out.ll index 20548694..7fe94c57 100644 --- a/cl/_testpy/matrix/out.ll +++ b/cl/_testpy/matrix/out.ll @@ -29,7 +29,6 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define i32 @main(i32 %0, ptr %1) { _llgo_0: - call void @Py_Initialize() 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"() @@ -117,5 +116,3 @@ declare ptr @PyUnicode_AsUTF8(ptr) declare i32 @printf(ptr, ...) declare void @llgoLoadPyModSyms(ptr, ...) - -declare void @Py_Initialize() diff --git a/cl/_testpy/max/out.ll b/cl/_testpy/max/out.ll index 3eae5bed..46b66d48 100644 --- a/cl/_testpy/max/out.ll +++ b/cl/_testpy/max/out.ll @@ -30,7 +30,6 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define i32 @main(i32 %0, ptr %1) { _llgo_0: - call void @Py_Initialize() 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"() @@ -93,5 +92,3 @@ declare ptr @PyTuple_New(i64) declare i32 @PyTuple_SetItem(ptr, i64, ptr) declare void @llgoLoadPyModSyms(ptr, ...) - -declare void @Py_Initialize() diff --git a/cl/_testpy/pi/out.ll b/cl/_testpy/pi/out.ll index 0a6225de..083e6d54 100644 --- a/cl/_testpy/pi/out.ll +++ b/cl/_testpy/pi/out.ll @@ -24,7 +24,6 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define i32 @main(i32 %0, ptr %1) { _llgo_0: - call void @Py_Initialize() 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"() @@ -45,5 +44,3 @@ declare ptr @PyObject_GetAttrString(ptr, ptr) declare double @PyFloat_AsDouble(ptr) declare i32 @printf(ptr, ...) - -declare void @Py_Initialize() diff --git a/cl/_testpy/pow/out.ll b/cl/_testpy/pow/out.ll index 5807c6f3..29ee34d2 100644 --- a/cl/_testpy/pow/out.ll +++ b/cl/_testpy/pow/out.ll @@ -27,7 +27,6 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define i32 @main(i32 %0, ptr %1) { _llgo_0: - call void @Py_Initialize() 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"() @@ -54,5 +53,3 @@ declare double @PyFloat_AsDouble(ptr) declare i32 @printf(ptr, ...) declare void @llgoLoadPyModSyms(ptr, ...) - -declare void @Py_Initialize() diff --git a/cl/cltest/cltest.go b/cl/cltest/cltest.go index 821f51a8..5bfde54f 100644 --- a/cl/cltest/cltest.go +++ b/cl/cltest/cltest.go @@ -50,7 +50,7 @@ func InitDebug() { llssa.SetDebug(llssa.DbgFlagAll) } -func FromDir(t *testing.T, sel, relDir string, byLLGen bool) { +func FromDir(t *testing.T, sel, relDir string) { dir, err := os.Getwd() if err != nil { t.Fatal("Getwd failed:", err) @@ -66,7 +66,7 @@ func FromDir(t *testing.T, sel, relDir string, byLLGen bool) { continue } t.Run(name, func(t *testing.T) { - testFrom(t, dir+"/"+name, sel, byLLGen) + testFrom(t, dir+"/"+name, sel) }) } } @@ -107,44 +107,19 @@ func Pkg(t *testing.T, pkgPath, outFile string) { } } -func isDbgSymEnabled(flagsFile string) bool { - data, err := os.ReadFile(flagsFile) - if err != nil { - return false - } - toks := strings.Split(strings.Join(strings.Split(string(data), "\n"), " "), " ") - for _, tok := range toks { - if tok == "-dbg" { - return true - } - } - return false -} - -func testFrom(t *testing.T, pkgDir, sel string, byLLGen bool) { +func testFrom(t *testing.T, pkgDir, sel string) { if sel != "" && !strings.Contains(pkgDir, sel) { return } log.Println("Parsing", pkgDir) - in := pkgDir + "/in.go" out := pkgDir + "/out.ll" - dbg := isDbgSymEnabled(pkgDir + "/flags.txt") - if dbg { - cl.EnableDebugSymbols(true) - defer cl.EnableDebugSymbols(false) - cl.DebugSymbols() // just for coverage - } b, err := os.ReadFile(out) if err != nil { t.Fatal("ReadFile failed:", err) } expected := string(b) - if byLLGen { - if v := llgen.GenFrom(in); v != expected && expected != ";" { // expected == ";" means skipping out.ll - t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected) - } - } else { - TestCompileEx(t, nil, in, expected, dbg) + if v := llgen.GenFrom(pkgDir); v != expected && expected != ";" { // expected == ";" means skipping out.ll + t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected) } } diff --git a/cl/compile.go b/cl/compile.go index 305bf1cb..f4949b74 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -57,15 +57,10 @@ func SetDebug(dbgFlags dbgFlags) { debugGoSSA = (dbgFlags & DbgFlagGoSSA) != 0 } -// EnableDebugSymbols enables debug symbols. func EnableDebugSymbols(b bool) { debugSymbols = b } -func DebugSymbols() bool { - return debugSymbols -} - // ----------------------------------------------------------------------------- type instrOrValue interface { diff --git a/cl/compile_test.go b/cl/compile_test.go index 47f1773c..4618ffef 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -30,34 +30,37 @@ func testCompile(t *testing.T, src, expected string) { } func TestFromTestgo(t *testing.T) { - cltest.FromDir(t, "", "./_testgo", false) + cltest.FromDir(t, "", "./_testgo") } func TestFromTestpy(t *testing.T) { - cltest.FromDir(t, "", "./_testpy", false) + cltest.FromDir(t, "", "./_testpy") } func TestFromTestlibgo(t *testing.T) { - cltest.FromDir(t, "", "./_testlibgo", true) + cltest.FromDir(t, "", "./_testlibgo") } func TestFromTestlibc(t *testing.T) { - cltest.FromDir(t, "", "./_testlibc", true) + cltest.FromDir(t, "", "./_testlibc") } func TestFromTestrt(t *testing.T) { cl.SetDebug(cl.DbgFlagAll) - cltest.FromDir(t, "", "./_testrt", true) + cltest.FromDir(t, "", "./_testrt") cl.SetDebug(0) } func TestFromTestdata(t *testing.T) { - cltest.FromDir(t, "", "./_testdata", false) + cltest.FromDir(t, "", "./_testdata") } func TestGoPkgMath(t *testing.T) { conf := build.NewDefaultConf(build.ModeInstall) - build.Do([]string{"math"}, conf) + _, err := build.Do([]string{"math"}, conf) + if err != nil { + t.Fatal(err) + } } func TestVar(t *testing.T) { diff --git a/cmd/internal/build/build.go b/cmd/internal/build/build.go index 67915c4a..c578a8ee 100644 --- a/cmd/internal/build/build.go +++ b/cmd/internal/build/build.go @@ -18,6 +18,9 @@ package build import ( + "fmt" + "os" + "github.com/goplus/llgo/cmd/internal/base" "github.com/goplus/llgo/internal/build" ) @@ -41,5 +44,9 @@ func runCmd(cmd *base.Command, args []string) { conf.OutFile = args[1] args = args[2:] } - build.Do(args, conf) + _, err := build.Do(args, conf) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } } diff --git a/cmd/internal/install/install.go b/cmd/internal/install/install.go index c486abb3..5c0f5621 100644 --- a/cmd/internal/install/install.go +++ b/cmd/internal/install/install.go @@ -18,6 +18,9 @@ package install import ( + "fmt" + "os" + "github.com/goplus/llgo/cmd/internal/base" "github.com/goplus/llgo/internal/build" ) @@ -34,5 +37,9 @@ func init() { func runCmd(cmd *base.Command, args []string) { conf := build.NewDefaultConf(build.ModeInstall) - build.Do(args, conf) + _, err := build.Do(args, conf) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } } diff --git a/cmd/internal/run/run.go b/cmd/internal/run/run.go index 3317cfad..2b5ff2ad 100644 --- a/cmd/internal/run/run.go +++ b/cmd/internal/run/run.go @@ -19,6 +19,8 @@ package run import ( "errors" + "fmt" + "os" "path/filepath" "github.com/goplus/llgo/cmd/internal/base" @@ -63,7 +65,11 @@ func runCmdEx(_ *base.Command, args []string, mode build.Mode) { args, runArgs, err := parseRunArgs(args) check(err) conf.RunArgs = runArgs - build.Do(args, conf) + _, err = build.Do(args, conf) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } } func parseRunArgs(args []string) ([]string, []string, error) { diff --git a/cpp/llvm/llvm.go b/cpp/llvm/llvm.go index f43e9a93..f0b1ca6f 100644 --- a/cpp/llvm/llvm.go +++ b/cpp/llvm/llvm.go @@ -19,7 +19,7 @@ package llvm // ----------------------------------------------------------------------------- const ( - LLGoPackage = "link: -L$(llvm-config --libdir) -lLLVM; -lLLVM" + LLGoPackage = "link: -L$(llvm-config --libs) $(llvm-config --ldflags); -lLLVM" ) // StringView represents a C++ std::string_view object. diff --git a/doc/_readme/scripts/install_macos.sh b/doc/_readme/scripts/install_macos.sh index 9892979d..20cd3a47 100644 --- a/doc/_readme/scripts/install_macos.sh +++ b/doc/_readme/scripts/install_macos.sh @@ -1,5 +1,6 @@ # shellcheck disable=all brew update -brew install llvm@18 pkg-config bdw-gc openssl cjson +brew install llvm@18 bdw-gc openssl cjson libffi brew install python@3.12 # optional -go install -v github.com/goplus/llgo/cmd/llgo@latest \ No newline at end of file +brew link --force libffi +go install -v github.com/goplus/llgo/cmd/llgo@latest diff --git a/doc/_readme/scripts/install_ubuntu.sh b/doc/_readme/scripts/install_ubuntu.sh index 069e6170..b36e42d7 100644 --- a/doc/_readme/scripts/install_ubuntu.sh +++ b/doc/_readme/scripts/install_ubuntu.sh @@ -2,6 +2,6 @@ echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-18 main" | sudo tee /etc/apt/sources.list.d/llvm.list wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - sudo apt-get update -sudo apt-get install -y llvm-18-dev clang-18 libclang-18-dev lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev libcjson-dev python3.12-dev +sudo apt-get install -y llvm-18-dev clang-18 libclang-18-dev lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev libcjson-dev libsqlite3-dev sudo apt-get install -y python3.12-dev # optional go install -v github.com/goplus/llgo/cmd/llgo@latest \ No newline at end of file diff --git a/internal/build/build.go b/internal/build/build.go index 4eec5338..e12e57eb 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -53,6 +53,7 @@ const ( ModeInstall ModeRun ModeCmpTest + ModeGen ) const ( @@ -119,9 +120,8 @@ const ( loadSyntax = loadTypes | packages.NeedSyntax | packages.NeedTypesInfo ) -func Do(args []string, conf *Config) { +func Do(args []string, conf *Config) ([]Package, error) { flags, patterns, verbose := ParseArgs(args, buildFlags) - cl.EnableDebugSymbols(IsDebugEnabled()) flags = append(flags, "-tags", "llgo") cfg := &packages.Config{ Mode: loadSyntax | packages.NeedDeps | packages.NeedModule | packages.NeedExportFile, @@ -137,6 +137,7 @@ func Do(args []string, conf *Config) { } } + cl.EnableDebugSymbols(IsDebugEnabled()) llssa.Initialize(llssa.InitAll) target := &llssa.Target{ @@ -159,7 +160,6 @@ func Do(args []string, conf *Config) { } initial, err := packages.LoadEx(dedup, sizes, cfg, patterns...) check(err) - mode := conf.Mode if len(initial) == 1 && len(initial[0].CompiledGoFiles) > 0 { if mode == ModeBuild { @@ -167,11 +167,10 @@ func Do(args []string, conf *Config) { } } else if mode == ModeRun { if len(initial) > 1 { - fmt.Fprintln(os.Stderr, "cannot run multiple packages") + return nil, fmt.Errorf("cannot run multiple packages") } else { - fmt.Fprintln(os.Stderr, "no Go files in matched packages") + return nil, fmt.Errorf("no Go files in matched packages") } - return } altPkgPaths := altPkgs(initial, llssa.PkgRuntime) @@ -188,7 +187,7 @@ func Do(args []string, conf *Config) { }) buildMode := ssaBuildMode - if cl.DebugSymbols() { + if IsDebugEnabled() { buildMode |= ssa.GlobalDebug } if !IsOptimizeEnabled() { @@ -203,12 +202,21 @@ func Do(args []string, conf *Config) { ctx := &context{env, cfg, progSSA, prog, dedup, patches, make(map[string]none), initial, mode, 0} pkgs := buildAllPkgs(ctx, initial, verbose) + if mode == ModeGen { + for _, pkg := range pkgs { + if pkg.Package == initial[0] { + return []*aPackage{pkg}, nil + } + } + return nil, fmt.Errorf("initial package not found") + } dpkg := buildAllPkgs(ctx, altPkgs[noRt:], verbose) var linkArgs []string for _, pkg := range dpkg { linkArgs = append(linkArgs, pkg.LinkArgs...) } + if mode != ModeBuild { nErr := 0 for _, pkg := range initial { @@ -220,6 +228,7 @@ func Do(args []string, conf *Config) { os.Exit(nErr) } } + return dpkg, nil } func setNeedRuntimeOrPyInit(pkg *packages.Package, needRuntime, needPyInit bool) { @@ -451,7 +460,7 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, linkArgs } } args = append(args, exargs...) - if cl.DebugSymbols() { + if IsDebugEnabled() { args = append(args, "-gdwarf-4") } @@ -571,6 +580,8 @@ type aPackage struct { LinkArgs []string } +type Package = *aPackage + func allPkgs(ctx *context, initial []*packages.Package, verbose bool) (all []*aPackage, errs []*packages.Package) { prog := ctx.progSSA built := ctx.built diff --git a/internal/llgen/llgen.go b/internal/llgen/llgen.go index 14440c42..7401ebe5 100644 --- a/internal/llgen/llgen.go +++ b/internal/llgen/llgen.go @@ -16,41 +16,8 @@ package llgen -import ( - "os" - - "github.com/goplus/llgo/cl" - "github.com/goplus/llgo/internal/build" - "github.com/goplus/llgo/internal/mod" - - llssa "github.com/goplus/llgo/ssa" -) - -func Init() { - llssa.Initialize(llssa.InitAll) - llssa.SetDebug(llssa.DbgFlagAll) - cl.SetDebug(cl.DbgFlagAll) - cl.EnableDebugSymbols(build.IsDebugEnabled()) -} - -func PkgPath(dir string) string { - _, pkgPath, err := mod.Load(dir) - check(err) - return pkgPath -} - -func Do(pkgPath, inFile, outFile string) { - ret := genFrom(inFile, pkgPath) - err := os.WriteFile(outFile, []byte(ret), 0644) - check(err) -} - func check(err error) { if err != nil { panic(err) } } - -var ( - Verbose = true -) diff --git a/internal/llgen/llgenf.go b/internal/llgen/llgenf.go index cf55c856..e7f8cc83 100644 --- a/internal/llgen/llgenf.go +++ b/internal/llgen/llgenf.go @@ -17,107 +17,37 @@ package llgen import ( - "go/ast" - "go/types" "os" "os/exec" "path/filepath" "strings" - "github.com/goplus/llgo/cl" "github.com/goplus/llgo/internal/build" - "github.com/goplus/llgo/internal/packages" - "golang.org/x/tools/go/ssa" - "golang.org/x/tools/go/ssa/ssautil" - - llssa "github.com/goplus/llgo/ssa" ) -const ( - loadFiles = packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles - loadImports = loadFiles | packages.NeedImports - loadTypes = loadImports | packages.NeedTypes | packages.NeedTypesSizes - loadSyntax = loadTypes | packages.NeedSyntax | packages.NeedTypesInfo -) - -func initRtAndPy(prog llssa.Program, cfg *packages.Config) { - var pkgRtAndPy []*packages.Package - load := func() []*packages.Package { - if pkgRtAndPy == nil { - var err error - pkgRtAndPy, err = packages.LoadEx(nil, prog.TypeSizes, cfg, llssa.PkgRuntime, llssa.PkgPython) - check(err) - } - return pkgRtAndPy - } - - prog.SetRuntime(func() *types.Package { - rt := load() - return rt[0].Types - }) - prog.SetPython(func() *types.Package { - rt := load() - return rt[1].Types - }) -} - func GenFrom(fileOrPkg string) string { - return genFrom(fileOrPkg, "") + pkg, err := genFrom(fileOrPkg) + check(err) + return pkg.LPkg.String() } -func genFrom(fileOrPkg string, pkgPath string) string { - prog := llssa.NewProgram(nil) - - cfg := &packages.Config{ - Mode: loadSyntax | packages.NeedDeps, - BuildFlags: []string{"-tags", "llgo"}, +func genFrom(pkgPath string) (build.Package, error) { + oldDbg := os.Getenv("LLGO_DEBUG") + dbg := isDbgSymEnabled(filepath.Join(pkgPath, "flags.txt")) + if dbg { + os.Setenv("LLGO_DEBUG", "1") } + defer os.Setenv("LLGO_DEBUG", oldDbg) - 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) - - buildMode := ssa.SanityCheckFunctions | ssa.InstantiateGenerics - if build.IsDebugEnabled() { - buildMode |= ssa.GlobalDebug + conf := &build.Config{ + Mode: build.ModeGen, + AppExt: build.DefaultAppExt(), } - if !build.IsOptimizeEnabled() { - buildMode |= ssa.NaiveForm + pkgs, err := build.Do([]string{pkgPath}, conf) + if err != nil { + return nil, err } - _, pkgs := ssautil.AllPackages(initial, buildMode) - - pkg := initial[0] - ssaPkg := pkgs[0] - ssaPkg.Build() - - initRtAndPy(prog, cfg) - - if Verbose { - ssaPkg.WriteTo(os.Stderr) - } - - ret, err := cl.NewPackage(prog, ssaPkg, pkg.Syntax) - check(err) - - if prog.NeedPyInit { // call PyInit if needed - ret.PyInit() - } - - return ret.String() + return pkgs[0], nil } func DoFile(fileOrPkg, outFile string) { @@ -126,9 +56,26 @@ func DoFile(fileOrPkg, outFile string) { check(err) } -func SmartDoFile(inFile string, pkgPath ...string) { +func isDbgSymEnabled(flagsFile string) bool { + data, err := os.ReadFile(flagsFile) + if err != nil { + return false + } + toks := strings.Split(strings.Join(strings.Split(string(data), "\n"), " "), " ") + for _, tok := range toks { + if tok == "-dbg" { + return true + } + } + return false +} + +func SmartDoFile(pkgPath string) { + pkg, err := genFrom(pkgPath) + check(err) + const autgenFile = "llgo_autogen.ll" - dir, _ := filepath.Split(inFile) + dir, _ := filepath.Split(pkg.GoFiles[0]) absDir, _ := filepath.Abs(dir) absDir = filepath.ToSlash(absDir) fname := autgenFile @@ -142,10 +89,8 @@ func SmartDoFile(inFile string, pkgPath ...string) { return // skip to gen } - if len(pkgPath) > 0 { - Do(pkgPath[0], inFile, outFile) - } else { - DoFile(inFile, outFile) + if err = os.WriteFile(outFile, []byte(pkg.LPkg.String()), 0644); err != nil { + panic(err) } if false && fname == autgenFile { genZip(absDir, "llgo_autogen.lla", autgenFile) diff --git a/ssa/cl_test.go b/ssa/cl_test.go index 837a990a..86928f5f 100644 --- a/ssa/cl_test.go +++ b/ssa/cl_test.go @@ -30,27 +30,27 @@ func init() { } func TestFromTestlibgo(t *testing.T) { - cltest.FromDir(t, "", "../cl/_testlibgo", false) + cltest.FromDir(t, "", "../cl/_testlibgo") } func TestFromTestgo(t *testing.T) { - cltest.FromDir(t, "", "../cl/_testgo", false) + cltest.FromDir(t, "", "../cl/_testgo") } func TestFromTestpy(t *testing.T) { - cltest.FromDir(t, "", "../cl/_testpy", false) + cltest.FromDir(t, "", "../cl/_testpy") } func TestFromTestlibc(t *testing.T) { - cltest.FromDir(t, "", "../cl/_testlibc", true) + cltest.FromDir(t, "", "../cl/_testlibc") } func TestFromTestrt(t *testing.T) { - cltest.FromDir(t, "", "../cl/_testrt", true) + cltest.FromDir(t, "", "../cl/_testrt") } func TestFromTestdata(t *testing.T) { - cltest.FromDir(t, "", "../cl/_testdata", false) + cltest.FromDir(t, "", "../cl/_testdata") } func TestMakeInterface(t *testing.T) {