Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
683129b6a5 | ||
|
|
7f4022120e | ||
|
|
3f9e86c37a | ||
|
|
12f460e376 | ||
|
|
44c4488fcc | ||
|
|
44617b6554 | ||
|
|
ccc7d056ba | ||
|
|
566d5ef96f | ||
|
|
cf53f3a347 | ||
|
|
d2538d08a7 | ||
|
|
75fe9d61a3 | ||
|
|
fce0672282 | ||
|
|
69a2a01bc7 | ||
|
|
a2d4e79c20 | ||
|
|
6e0a9b2b48 | ||
|
|
276f2070ee | ||
|
|
1a158b5de3 | ||
|
|
d4a72bf661 |
48
.github/actions/setup-deps/action.yml
vendored
48
.github/actions/setup-deps/action.yml
vendored
@@ -1,48 +0,0 @@
|
||||
name: "Setup LLGO Dependencies"
|
||||
description: "Install all required dependencies for LLGO"
|
||||
inputs:
|
||||
llvm-version:
|
||||
description: "LLVM version to install"
|
||||
required: true
|
||||
default: "18"
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Install macOS dependencies
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
brew update
|
||||
brew install llvm@${{inputs.llvm-version}} bdw-gc openssl libffi libuv
|
||||
brew link --force libffi
|
||||
echo "$(brew --prefix llvm@${{inputs.llvm-version}})/bin" >> $GITHUB_PATH
|
||||
|
||||
# Install optional deps for demos.
|
||||
#
|
||||
# NOTE: Keep this list updated as new deps are introduced.
|
||||
opt_deps=(
|
||||
cjson # for github.com/goplus/llgo/c/cjson
|
||||
sqlite # for github.com/goplus/llgo/c/sqlite
|
||||
python@3.12 # for github.com/goplus/llgo/py
|
||||
)
|
||||
brew install "${opt_deps[@]}"
|
||||
- name: Install Ubuntu dependencies
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${{inputs.llvm-version}} 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-${{inputs.llvm-version}}-dev clang-${{inputs.llvm-version}} libclang-${{inputs.llvm-version}}-dev lld-${{inputs.llvm-version}} pkg-config libgc-dev libssl-dev zlib1g-dev libffi-dev libcjson-dev libunwind-dev libuv1-dev
|
||||
echo "/usr/lib/llvm-${{inputs.llvm-version}}/bin" >> $GITHUB_PATH
|
||||
|
||||
# Install optional deps for demos.
|
||||
#
|
||||
# NOTE: Keep this list updated as new deps are introduced.
|
||||
opt_deps=(
|
||||
libcjson-dev # for github.com/goplus/llgo/c/cjson
|
||||
libsqlite3-dev # for github.com/goplus/llgo/c/sqlite
|
||||
python3.12-dev # for github.com/goplus/llgo/py
|
||||
)
|
||||
sudo apt-get install -y "${opt_deps[@]}"
|
||||
51
.github/actions/setup-go/action.yml
vendored
51
.github/actions/setup-go/action.yml
vendored
@@ -1,51 +0,0 @@
|
||||
name: "Setup Go"
|
||||
description: "Setup Go environment by downloading and extracting from go.dev"
|
||||
inputs:
|
||||
go-version:
|
||||
description: "The Go version to download and use"
|
||||
required: true
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Download and setup Go
|
||||
shell: bash
|
||||
run: |
|
||||
set -e
|
||||
GO_VERSION="${{ inputs.go-version }}"
|
||||
GO_VERSION="${GO_VERSION#go}" # Remove 'go' prefix if present
|
||||
|
||||
# Determine OS and architecture
|
||||
if [[ "$RUNNER_OS" == "macOS" ]]; then
|
||||
OS="darwin"
|
||||
ARCH="arm64"
|
||||
else
|
||||
OS="linux"
|
||||
ARCH="amd64"
|
||||
fi
|
||||
|
||||
DOWNLOAD_URL="https://go.dev/dl/go${GO_VERSION}.${OS}-${ARCH}.tar.gz"
|
||||
echo "Downloading Go from: ${DOWNLOAD_URL}"
|
||||
|
||||
# Create temporary directory for download
|
||||
TMP_DIR=$(mktemp -d)
|
||||
curl -L "${DOWNLOAD_URL}" -o "${TMP_DIR}/go.tar.gz"
|
||||
|
||||
# Remove existing Go installation if any
|
||||
sudo rm -rf /usr/local/go
|
||||
|
||||
# Extract to /usr/local
|
||||
sudo tar -C /usr/local -xzf "${TMP_DIR}/go.tar.gz"
|
||||
|
||||
# Clean up
|
||||
rm -rf "${TMP_DIR}"
|
||||
|
||||
# Add to PATH
|
||||
echo "/usr/local/go/bin" >> $GITHUB_PATH
|
||||
echo "$HOME/go/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Verify Go installation
|
||||
shell: bash
|
||||
run: |
|
||||
# Verify installation
|
||||
echo "Verifying Go installation..."
|
||||
go version
|
||||
35
.github/actions/test-helloworld/action.yml
vendored
35
.github/actions/test-helloworld/action.yml
vendored
@@ -1,35 +0,0 @@
|
||||
name: 'Test Hello World'
|
||||
description: 'Test Hello World with specific Go and module versions'
|
||||
inputs:
|
||||
go-version:
|
||||
description: 'Go version being tested'
|
||||
required: true
|
||||
mod-version:
|
||||
description: 'Go module version to use'
|
||||
required: true
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Test Hello World
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Testing with Go ${{ inputs.go-version }} and go.mod ${{ inputs.mod-version }}"
|
||||
mkdir -p _test/helloworld && cd _test/helloworld
|
||||
cat > go.mod << 'EOL'
|
||||
module hello
|
||||
go ${{ inputs.mod-version }}
|
||||
EOL
|
||||
cat > main.go << 'EOL'
|
||||
package main
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/goplus/llgo/c"
|
||||
)
|
||||
func main() {
|
||||
fmt.Println("Hello, LLGo!")
|
||||
println("Hello, LLGo!")
|
||||
c.Printf(c.Str("Hello, LLGo!\n"))
|
||||
}
|
||||
EOL
|
||||
go mod tidy
|
||||
llgo run .
|
||||
9
.github/codecov.yml
vendored
9
.github/codecov.yml
vendored
@@ -1,9 +0,0 @@
|
||||
coverage:
|
||||
ignore:
|
||||
- "compiler/chore"
|
||||
- "compiler/cmd/internal"
|
||||
- "compiler/internal/build"
|
||||
- "compiler/internal/llgen"
|
||||
- "compiler/internal/mockable"
|
||||
- "compiler/internal/packages"
|
||||
- "compiler/internal/typepatch"
|
||||
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -17,13 +17,3 @@ updates:
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "gomod" # See documentation for possible values
|
||||
directory: "/compiler/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
- package-ecosystem: "gomod" # See documentation for possible values
|
||||
directory: "/runtime/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
165
.github/workflows/doc.yml
vendored
165
.github/workflows/doc.yml
vendored
@@ -1,165 +0,0 @@
|
||||
name: Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "**" ]
|
||||
pull_request:
|
||||
branches: [ "**" ]
|
||||
|
||||
jobs:
|
||||
doc_verify:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install embedme
|
||||
run: npm install -g embedme
|
||||
|
||||
- name: Verify README.md embedded code
|
||||
run: embedme --verify README.md
|
||||
|
||||
- name: Link Checker
|
||||
id: lychee
|
||||
uses: lycheeverse/lychee-action@v2
|
||||
with:
|
||||
args: --max-concurrency 3 --retry-wait-time 15 README.md
|
||||
|
||||
remote_install:
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- macos-latest
|
||||
- ubuntu-24.04
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: ./.github/actions/setup-go
|
||||
with:
|
||||
go-version: '1.23.6'
|
||||
|
||||
- name: Install dependencies on macOS
|
||||
if: startsWith(matrix.os, 'macos')
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
source doc/_readme/scripts/install_macos.sh
|
||||
|
||||
- name: Install dependencies on Ubuntu
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
source doc/_readme/scripts/install_ubuntu.sh
|
||||
|
||||
- name: Test doc code blocks
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
source doc/_readme/scripts/run.sh
|
||||
|
||||
local_install:
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- macos-latest
|
||||
- ubuntu-24.04
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
|
||||
- name: Install dependencies on macOS
|
||||
if: startsWith(matrix.os, 'macos')
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
source doc/_readme/scripts/install_macos.sh
|
||||
|
||||
- name: Install dependencies on Ubuntu
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
source doc/_readme/scripts/install_ubuntu.sh
|
||||
|
||||
- name: Install llgo with tools
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
git() {
|
||||
if [ "$1" = "clone" ]; then
|
||||
# do nothing because we already have the branch
|
||||
cd ..
|
||||
else
|
||||
command git "$@"
|
||||
fi
|
||||
}
|
||||
source doc/_readme/scripts/install_llgo.sh
|
||||
echo "LLGO_ROOT=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||
|
||||
- name: Test doc code blocks
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
source doc/_readme/scripts/run.sh
|
||||
|
||||
local_install_full:
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- macos-latest
|
||||
- ubuntu-24.04
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
|
||||
- name: Install dependencies on macOS
|
||||
if: startsWith(matrix.os, 'macos')
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
source doc/_readme/scripts/install_macos.sh
|
||||
|
||||
- name: Install dependencies on Ubuntu
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
source doc/_readme/scripts/install_ubuntu.sh
|
||||
|
||||
- name: Install llgo with tools
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
git() {
|
||||
if [ "$1" = "clone" ]; then
|
||||
# do nothing because we already have the branch
|
||||
cd ..
|
||||
else
|
||||
command git "$@"
|
||||
fi
|
||||
}
|
||||
source doc/_readme/scripts/install_full.sh
|
||||
echo "LLGO_ROOT=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||
|
||||
- name: Test doc code blocks
|
||||
run: |
|
||||
set -e
|
||||
set -x
|
||||
source doc/_readme/scripts/run.sh
|
||||
30
.github/workflows/fmt.yml
vendored
30
.github/workflows/fmt.yml
vendored
@@ -1,30 +0,0 @@
|
||||
name: Format Check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "**" ]
|
||||
pull_request:
|
||||
branches: [ "**" ]
|
||||
|
||||
jobs:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: ./.github/actions/setup-go
|
||||
with:
|
||||
go-version: '1.24.0'
|
||||
|
||||
- name: Check formatting
|
||||
run: |
|
||||
for dir in . compiler runtime; do
|
||||
pushd $dir
|
||||
if [ -n "$(go fmt ./...)" ]; then
|
||||
echo "Some files are not properly formatted. Please run 'go fmt ./...'"
|
||||
exit 1
|
||||
fi
|
||||
popd
|
||||
done
|
||||
echo "All files are properly formatted."
|
||||
90
.github/workflows/go.yml
vendored
90
.github/workflows/go.yml
vendored
@@ -5,13 +5,13 @@ name: Go
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "**" ]
|
||||
branches: [ "*" ]
|
||||
pull_request:
|
||||
branches: [ "**" ]
|
||||
branches: [ "*" ]
|
||||
|
||||
jobs:
|
||||
|
||||
test:
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
@@ -19,15 +19,53 @@ jobs:
|
||||
- ubuntu-24.04
|
||||
llvm: [18]
|
||||
runs-on: ${{matrix.os}}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: compiler
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/setup-deps
|
||||
with:
|
||||
llvm-version: ${{matrix.llvm}}
|
||||
if: startsWith(matrix.os, 'macos')
|
||||
run: |
|
||||
brew update
|
||||
brew install llvm@${{matrix.llvm}} pkg-config bdw-gc openssl
|
||||
echo "$(brew --prefix llvm@${{matrix.llvm}})/bin" >> $GITHUB_PATH
|
||||
|
||||
# Install optional deps for demos.
|
||||
#
|
||||
# NOTE: Keep this list updated as new deps are introduced.
|
||||
opt_deps=(
|
||||
cjson # for github.com/goplus/llgo/c/cjson
|
||||
sqlite # for github.com/goplus/llgo/c/sqlite
|
||||
python@3.12 # for github.com/goplus/llgo/py
|
||||
)
|
||||
brew install "${opt_deps[@]}"
|
||||
|
||||
- name: Install dependencies
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${{matrix.llvm}} 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-${{matrix.llvm}}-dev clang-${{matrix.llvm}} lld-${{matrix.llvm}} pkg-config libgc-dev libssl-dev zlib1g-dev
|
||||
echo "/usr/lib/llvm-${{matrix.llvm}}/bin" >> $GITHUB_PATH
|
||||
|
||||
# Install optional deps for demos.
|
||||
#
|
||||
# NOTE: Keep this list updated as new deps are introduced.
|
||||
opt_deps=(
|
||||
libcjson-dev # for github.com/goplus/llgo/c/cjson
|
||||
libsqlite3-dev # for github.com/goplus/llgo/c/sqlite
|
||||
python3.12-dev # for github.com/goplus/llgo/py
|
||||
)
|
||||
sudo apt-get install -y "${opt_deps[@]}"
|
||||
|
||||
- name: Install further optional dependencies for demos
|
||||
run: |
|
||||
wget -P ./_demo/llama2-c https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M.bin
|
||||
py_deps=(
|
||||
numpy # for github.com/goplus/llgo/py/numpy
|
||||
torch # for github.com/goplus/llgo/py/torch
|
||||
)
|
||||
pip3 install --break-system-packages "${py_deps[@]}"
|
||||
|
||||
- name: Clang information
|
||||
run: |
|
||||
@@ -36,22 +74,46 @@ jobs:
|
||||
clang --version
|
||||
|
||||
- name: Set up Go
|
||||
uses: ./.github/actions/setup-go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.24.0'
|
||||
go-version: '1.20'
|
||||
|
||||
- name: Build
|
||||
run: go build -v ./...
|
||||
|
||||
- name: Test
|
||||
if: ${{!startsWith(matrix.os, 'macos')}}
|
||||
run: go test ./...
|
||||
run: go test -v ./...
|
||||
|
||||
- name: Test with coverage
|
||||
if: startsWith(matrix.os, 'macos')
|
||||
run: go test -coverprofile="coverage.txt" -covermode=atomic ./...
|
||||
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
|
||||
|
||||
- name: Install
|
||||
run: go install ./...
|
||||
|
||||
- name: LLGO tests
|
||||
if: ${{!startsWith(matrix.os, 'ubuntu')}}
|
||||
run: |
|
||||
echo "Test result on ${{matrix.os}} with LLVM ${{matrix.llvm}}" > result.md
|
||||
bash .github/workflows/test_llgo.sh
|
||||
|
||||
- name: Test demos
|
||||
continue-on-error: true
|
||||
run: bash .github/workflows/test_demo.sh
|
||||
|
||||
- name: Show test result
|
||||
run: cat result.md
|
||||
|
||||
- name: PR comment with test result
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
if: false
|
||||
with:
|
||||
filePath: result.md
|
||||
comment_tag: test-result-on-${{matrix.os}}-with-llvm-${{matrix.llvm}}
|
||||
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@v5
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
token: ${{secrets.CODECOV_TOKEN}}
|
||||
slug: goplus/llgo
|
||||
|
||||
236
.github/workflows/llgo.yml
vendored
236
.github/workflows/llgo.yml
vendored
@@ -1,236 +0,0 @@
|
||||
# This workflow will build a golang project
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
|
||||
|
||||
name: LLGo
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "**" ]
|
||||
pull_request:
|
||||
branches: [ "**" ]
|
||||
|
||||
jobs:
|
||||
download-model:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download model file
|
||||
run: |
|
||||
mkdir -p ./_demo/llama2-c
|
||||
wget -P ./_demo/llama2-c https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M.bin
|
||||
|
||||
- name: Upload model as artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: llama2-model
|
||||
path: ./_demo/llama2-c/stories15M.bin
|
||||
retention-days: 1
|
||||
|
||||
llgo:
|
||||
needs: download-model
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- macos-latest
|
||||
- ubuntu-24.04
|
||||
llvm: [18]
|
||||
go: ['1.20.14', '1.21.13', '1.22.12', '1.23.6', '1.24.0']
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/setup-deps
|
||||
with:
|
||||
llvm-version: ${{matrix.llvm}}
|
||||
- name: Download model artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: llama2-model
|
||||
path: ./_demo/llama2-c/
|
||||
- name: Install further optional dependencies for demos
|
||||
run: |
|
||||
py_deps=(
|
||||
numpy # for github.com/goplus/llgo/py/numpy
|
||||
torch # for github.com/goplus/llgo/py/torch
|
||||
)
|
||||
pip3.12 install --break-system-packages "${py_deps[@]}"
|
||||
|
||||
- name: Set up Go for build
|
||||
uses: ./.github/actions/setup-go
|
||||
with:
|
||||
go-version: '1.24.0'
|
||||
|
||||
- name: Install
|
||||
working-directory: compiler
|
||||
run: |
|
||||
go install ./...
|
||||
echo "LLGO_ROOT=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up Go for testing
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{matrix.go}}
|
||||
|
||||
- name: Verify Go version
|
||||
run: |
|
||||
go_version=$(go version | cut -d' ' -f3 | sed 's/go//')
|
||||
if [[ "$go_version" != "${{matrix.go}}"* ]]; then
|
||||
echo "Expected Go version ${{matrix.go}}, but got $go_version"
|
||||
exit 1
|
||||
fi
|
||||
echo "Using Go version: $go_version"
|
||||
|
||||
- name: _xtool build tests
|
||||
run: |
|
||||
cd _xtool
|
||||
llgo build -v ./...
|
||||
|
||||
- name: LLGO tests
|
||||
if: ${{!startsWith(matrix.os, 'ubuntu')}}
|
||||
run: |
|
||||
echo "Test result on ${{matrix.os}} with LLVM ${{matrix.llvm}}" > result.md
|
||||
bash ./.github/workflows/test_llgo.sh
|
||||
|
||||
- name: Test demos
|
||||
run: |
|
||||
# TODO(lijie): force python3-embed to be linked with python-3.12-embed
|
||||
# Currently, python3-embed is python-3.13-embed, doesn't work with pytorch
|
||||
# Will remove this after pytorch is fixed.
|
||||
pcdir=$HOME/pc
|
||||
mkdir -p $pcdir
|
||||
libdir=$(pkg-config --variable=libdir python-3.12-embed)
|
||||
echo "libdir: $libdir"
|
||||
ln -s $libdir/pkgconfig/python-3.12-embed.pc $pcdir/python3-embed.pc
|
||||
export PKG_CONFIG_PATH=$pcdir
|
||||
bash .github/workflows/test_demo.sh
|
||||
|
||||
- name: Show test result
|
||||
run: cat result.md
|
||||
|
||||
- name: LLDB tests
|
||||
if: ${{startsWith(matrix.os, 'macos')}}
|
||||
working-directory: compiler
|
||||
run: |
|
||||
echo "Test lldb with llgo plugin on ${{matrix.os}} with LLVM ${{matrix.llvm}}"
|
||||
bash _lldb/runtest.sh -v
|
||||
|
||||
test:
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- macos-latest
|
||||
- ubuntu-24.04
|
||||
llvm: [18]
|
||||
go: ['1.24.0']
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/setup-deps
|
||||
with:
|
||||
llvm-version: ${{matrix.llvm}}
|
||||
- name: Install further optional dependencies for demos
|
||||
run: |
|
||||
py_deps=(
|
||||
numpy # for github.com/goplus/llgo/py/numpy
|
||||
torch # for github.com/goplus/llgo/py/torch
|
||||
)
|
||||
pip3.12 install --break-system-packages "${py_deps[@]}"
|
||||
|
||||
- name: Set up Go for build
|
||||
uses: ./.github/actions/setup-go
|
||||
with:
|
||||
go-version: '1.24.0'
|
||||
|
||||
- name: Install
|
||||
working-directory: compiler
|
||||
run: |
|
||||
go install ./...
|
||||
echo "LLGO_ROOT=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up Go for testing
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{matrix.go}}
|
||||
|
||||
- name: Verify Go version
|
||||
run: |
|
||||
go_version=$(go version | cut -d' ' -f3 | sed 's/go//')
|
||||
if [[ "$go_version" != "${{matrix.go}}"* ]]; then
|
||||
echo "Expected Go version ${{matrix.go}}, but got $go_version"
|
||||
exit 1
|
||||
fi
|
||||
echo "Using Go version: $go_version"
|
||||
|
||||
- name: run llgo test
|
||||
run: |
|
||||
llgo test ./...
|
||||
cd _demo
|
||||
llgo test -v ./runtest
|
||||
|
||||
hello:
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-24.04, macos-latest]
|
||||
llvm: [18]
|
||||
go: ['1.20.14', '1.21.13', '1.22.12', '1.23.6', '1.24.0']
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/setup-deps
|
||||
with:
|
||||
llvm-version: ${{matrix.llvm}}
|
||||
|
||||
- name: Set up Go 1.23 for building llgo
|
||||
uses: ./.github/actions/setup-go
|
||||
with:
|
||||
go-version: '1.24.0'
|
||||
|
||||
- name: Install llgo
|
||||
working-directory: compiler
|
||||
run: |
|
||||
go install ./...
|
||||
echo "LLGO_ROOT=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up Go for testing
|
||||
uses: ./.github/actions/setup-go
|
||||
with:
|
||||
go-version: ${{matrix.go}}
|
||||
|
||||
- name: Test Hello World with go.mod 1.20
|
||||
if: startsWith(matrix.go, '1.20') || startsWith(matrix.go, '1.21') || startsWith(matrix.go, '1.22') || startsWith(matrix.go, '1.23') || startsWith(matrix.go, '1.24')
|
||||
uses: ./.github/actions/test-helloworld
|
||||
with:
|
||||
go-version: ${{matrix.go}}
|
||||
mod-version: '1.20'
|
||||
|
||||
- name: Test Hello World with go.mod 1.21
|
||||
if: startsWith(matrix.go, '1.21') || startsWith(matrix.go, '1.22') || startsWith(matrix.go, '1.23') || startsWith(matrix.go, '1.24')
|
||||
uses: ./.github/actions/test-helloworld
|
||||
with:
|
||||
go-version: ${{matrix.go}}
|
||||
mod-version: '1.21'
|
||||
|
||||
- name: Test Hello World with go.mod 1.22
|
||||
if: startsWith(matrix.go, '1.22') || startsWith(matrix.go, '1.23') || startsWith(matrix.go, '1.24')
|
||||
uses: ./.github/actions/test-helloworld
|
||||
with:
|
||||
go-version: ${{matrix.go}}
|
||||
mod-version: '1.22'
|
||||
|
||||
- name: Test Hello World with go.mod 1.23
|
||||
if: startsWith(matrix.go, '1.23') || startsWith(matrix.go, '1.24')
|
||||
uses: ./.github/actions/test-helloworld
|
||||
with:
|
||||
go-version: ${{matrix.go}}
|
||||
mod-version: '1.23'
|
||||
|
||||
- name: Test Hello World with go.mod 1.24
|
||||
if: startsWith(matrix.go, '1.24')
|
||||
uses: ./.github/actions/test-helloworld
|
||||
with:
|
||||
go-version: ${{matrix.go}}
|
||||
mod-version: '1.24'
|
||||
2
.github/workflows/populate_darwin_sysroot.sh
vendored
2
.github/workflows/populate_darwin_sysroot.sh
vendored
@@ -11,7 +11,7 @@ DARWIN_ARM64_LLVM_PREFIX=.sysroot/darwin/arm64/opt/homebrew/opt/llvm@18
|
||||
mkdir -p "${DARWIN_AMD64_LLVM_PREFIX}" "${DARWIN_ARM64_LLVM_PREFIX}"
|
||||
|
||||
BREW_LLVM_FORMULA_JSON="$(mktemp)"
|
||||
curl -fsSL https://formulae.brew.sh/api/formula/llvm@18.json > "${BREW_LLVM_FORMULA_JSON}"
|
||||
curl -fsSL https://formulae.brew.sh/api/formula/llvm.json > "${BREW_LLVM_FORMULA_JSON}"
|
||||
BREW_LLVM_AMD64_BOTTLE_URL=$(jq -r '.bottle.stable.files.sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
||||
BREW_LLVM_ARM64_BOTTLE_URL=$(jq -r '.bottle.stable.files.arm64_sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
||||
curl -fsSL -H "Authorization: Bearer QQ==" "${BREW_LLVM_AMD64_BOTTLE_URL}" | tar -xzf - --strip-components=2 -C "${DARWIN_AMD64_LLVM_PREFIX}"
|
||||
|
||||
7
.github/workflows/populate_linux_sysroot.sh
vendored
7
.github/workflows/populate_linux_sysroot.sh
vendored
@@ -139,8 +139,5 @@ populate_linux_sysroot() {
|
||||
debian:bullseye \
|
||||
/populate_linux_sysroot.sh
|
||||
}
|
||||
populate_linux_sysroot amd64 "${LINUX_AMD64_PREFIX}" &
|
||||
populate_linux_sysroot arm64 "${LINUX_ARM64_PREFIX}" &
|
||||
|
||||
# Wait for both background processes to complete
|
||||
wait
|
||||
populate_linux_sysroot amd64 "${LINUX_AMD64_PREFIX}"
|
||||
populate_linux_sysroot arm64 "${LINUX_ARM64_PREFIX}"
|
||||
|
||||
4
.github/workflows/release-build.yml
vendored
4
.github/workflows/release-build.yml
vendored
@@ -32,11 +32,9 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.24.x
|
||||
go-version: 1.20.x
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
image: tonistiigi/binfmt:qemu-v7.0.0-28
|
||||
- name: Download Darwin sysroot tarball
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
|
||||
6
.github/workflows/test_demo.sh
vendored
6
.github/workflows/test_demo.sh
vendored
@@ -1,13 +1,13 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# llgo run subdirectories under _demo and _pydemo that contain *.go files
|
||||
# llgo run subdirectories under _demo and _pydemo
|
||||
total=0
|
||||
failed=0
|
||||
failed_cases=""
|
||||
for d in ./_demo/* ./_pydemo/*; do
|
||||
if [ -d "$d" ] && [ -n "$(ls "$d"/*.go 2>/dev/null)" ]; then
|
||||
total=$((total+1))
|
||||
total=$((total+1))
|
||||
if [ -d "$d" ]; then
|
||||
echo "Testing $d"
|
||||
if ! (cd "$d" && llgo run .); then
|
||||
echo "FAIL"
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -26,9 +26,6 @@ build.dir/
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Debug symbols
|
||||
*.dSYM
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
*.swp
|
||||
|
||||
@@ -16,14 +16,12 @@ before:
|
||||
|
||||
builds:
|
||||
- id: llgo-darwin-amd64
|
||||
dir: compiler
|
||||
main: ./cmd/llgo
|
||||
binary: bin/llgo
|
||||
flags:
|
||||
- -tags=darwin,amd64,byollvm
|
||||
ldflags:
|
||||
- -X github.com/goplus/llgo/compiler/internal/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/compiler/internal/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/local/opt/llvm@18/bin/llvm-config
|
||||
env:
|
||||
- CC=o64-clang
|
||||
@@ -34,14 +32,12 @@ builds:
|
||||
- darwin_amd64
|
||||
mod_timestamp: "{{.CommitTimestamp}}"
|
||||
- id: llgo-darwin-arm64
|
||||
dir: compiler
|
||||
main: ./cmd/llgo
|
||||
binary: bin/llgo
|
||||
flags:
|
||||
- -tags=darwin,arm64,byollvm
|
||||
ldflags:
|
||||
- -X github.com/goplus/llgo/compiler/internal/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/compiler/internal/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/opt/homebrew/opt/llvm@18/bin/llvm-config
|
||||
env:
|
||||
- CC=oa64-clang
|
||||
@@ -52,14 +48,12 @@ builds:
|
||||
- darwin_arm64
|
||||
mod_timestamp: "{{.CommitTimestamp}}"
|
||||
- id: llgo-linux-amd64
|
||||
dir: compiler
|
||||
main: ./cmd/llgo
|
||||
binary: bin/llgo
|
||||
flags:
|
||||
- -tags=linux,amd64,byollvm
|
||||
ldflags:
|
||||
- -X github.com/goplus/llgo/compiler/internal/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/compiler/internal/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config
|
||||
env:
|
||||
- CC=x86_64-linux-gnu-gcc
|
||||
@@ -70,14 +64,12 @@ builds:
|
||||
- linux_amd64
|
||||
mod_timestamp: "{{.CommitTimestamp}}"
|
||||
- id: llgo-linux-arm64
|
||||
dir: compiler
|
||||
main: ./cmd/llgo
|
||||
binary: bin/llgo
|
||||
flags:
|
||||
- -tags=linux,arm64,byollvm
|
||||
ldflags:
|
||||
- -X github.com/goplus/llgo/compiler/internal/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/compiler/internal/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
|
||||
- -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
|
||||
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config
|
||||
env:
|
||||
- CC=aarch64-linux-gnu-gcc
|
||||
@@ -96,7 +88,6 @@ archives:
|
||||
files:
|
||||
- LICENSE
|
||||
- README.md
|
||||
- runtime
|
||||
|
||||
checksum:
|
||||
name_template: "{{.ProjectName}}{{.Version}}.checksums.txt"
|
||||
|
||||
93
README.md
93
README.md
@@ -24,7 +24,7 @@ How can these be achieved?
|
||||
LLGo := Go + C + Python
|
||||
```
|
||||
|
||||
LLGo is compatible with C and Python through the language's **Application Binary Interface (ABI)**, while LLGo is compatible with Go through its **syntax (source code)**. And here C doesn't just include C, but all languages that are ABI compatible with C, including C/C++, Objective-C, Swift, etc.
|
||||
LLGo is compatible with C and Python through the language's **Application Binary Interface (ABI)**, while LLGo is compatible with Go through its **syntax (source code)**.
|
||||
|
||||
|
||||
## C/C++ standard libary support
|
||||
@@ -47,8 +47,6 @@ You can import a C/C++ standard library in LLGo!
|
||||
|
||||
Here is a simple example:
|
||||
|
||||
<!-- embedme doc/_readme/llgo_simple/simple.go -->
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -75,12 +73,10 @@ llgo run .
|
||||
```
|
||||
|
||||
|
||||
## How to support C/C++ and Python
|
||||
## How support C/C++ and Python
|
||||
|
||||
LLGo use `go:linkname` to link an extern symbol througth its ABI:
|
||||
|
||||
<!-- embedme doc/_readme/llgo_call_c/call_c.go#L3-L6 -->
|
||||
|
||||
```go
|
||||
import _ "unsafe" // for go:linkname
|
||||
|
||||
@@ -90,8 +86,6 @@ func Sqrt(x float64) float64
|
||||
|
||||
You can directly integrate it into [your own code](_demo/linkname/linkname.go):
|
||||
|
||||
<!-- embedme doc/_readme/llgo_call_c/call_c.go -->
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -107,8 +101,6 @@ func main() {
|
||||
|
||||
Or put it into a package (see [c/math](c/math/math.go)):
|
||||
|
||||
<!-- embedme doc/_readme/llgo_call_cmath/call_cmath.go -->
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -143,8 +135,6 @@ Note: For third-party libraries (such as pandas and pytorch), you still need to
|
||||
|
||||
Here is an example:
|
||||
|
||||
<!-- embedme doc/_readme/llgo_call_py/call_py.go -->
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -162,8 +152,6 @@ func main() {
|
||||
|
||||
It is equivalent to the following Python code:
|
||||
|
||||
<!-- embedme doc/_readme/llgo_call_py/call_math.py -->
|
||||
|
||||
```py
|
||||
import math
|
||||
|
||||
@@ -175,8 +163,6 @@ Here, We call `py.Float(2)` to create a Python number 2, and pass it to Python
|
||||
|
||||
Let's look at a slightly more complex example. For example, we use `numpy` to calculate:
|
||||
|
||||
<!-- embedme doc/_readme/llgo_py_list/py_list.go -->
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
@@ -228,7 +214,6 @@ The currently supported libraries include:
|
||||
* [c/bdwgc](https://pkg.go.dev/github.com/goplus/llgo/c/bdwgc)
|
||||
* [c/cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)
|
||||
* [c/clang](https://pkg.go.dev/github.com/goplus/llgo/c/clang)
|
||||
* [c/ffi](https://pkg.go.dev/github.com/goplus/llgo/c/ffi)
|
||||
* [c/libuv](https://pkg.go.dev/github.com/goplus/llgo/c/libuv)
|
||||
* [c/llama2](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
|
||||
* [c/lua](https://pkg.go.dev/github.com/goplus/llgo/c/lua)
|
||||
@@ -250,7 +235,7 @@ Here are some examples related to them:
|
||||
|
||||
## Go syntax support
|
||||
|
||||
All Go syntax (including `cgo`) is already supported. Here are some examples:
|
||||
All Go syntax (not including `cgo`) is already supported. Here are some examples:
|
||||
|
||||
* [concat](_demo/concat/concat.go): define a variadic function
|
||||
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
|
||||
@@ -341,8 +326,8 @@ Here are the Go packages that can be imported correctly:
|
||||
|
||||
- [Go 1.20+](https://go.dev)
|
||||
- [LLVM 18](https://llvm.org)
|
||||
- [Clang 18](https://clang.llvm.org)
|
||||
- [LLD 18](https://lld.llvm.org)
|
||||
- [Clang 18](https://clang.llvm.org)
|
||||
- [pkg-config 0.29+](https://www.freedesktop.org/wiki/Software/pkg-config/)
|
||||
- [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/)
|
||||
- [OpenSSL 3.0+](https://www.openssl.org/)
|
||||
@@ -355,78 +340,44 @@ Follow these steps to generate the `llgo` command (its usage is the same as the
|
||||
|
||||
### on macOS
|
||||
|
||||
<!-- embedme doc/_readme/scripts/install_macos.sh#L2-L1000 -->
|
||||
|
||||
```sh
|
||||
brew update
|
||||
brew install llvm@18 bdw-gc openssl cjson libffi libuv pkg-config
|
||||
brew install llvm@18 pkg-config bdw-gc openssl
|
||||
brew install python@3.12 # optional
|
||||
brew link --force libffi
|
||||
curl https://raw.githubusercontent.com/goplus/llgo/refs/heads/main/install.sh | bash
|
||||
|
||||
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
||||
```
|
||||
|
||||
### on Linux
|
||||
|
||||
#### Debian/Ubuntu
|
||||
|
||||
<!-- embedme doc/_readme/scripts/install_ubuntu.sh#L2-L1000 -->
|
||||
### on Linux (Debian/Ubuntu)
|
||||
|
||||
```sh
|
||||
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 libsqlite3-dev libunwind-dev libuv1-dev
|
||||
sudo apt-get install -y llvm-18-dev clang-18 lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev
|
||||
sudo apt-get install -y python3.12-dev # optional
|
||||
curl https://raw.githubusercontent.com/goplus/llgo/refs/heads/main/install.sh | bash
|
||||
```
|
||||
|
||||
#### Alpine Linux
|
||||
|
||||
```sh
|
||||
apk add go llvm18-dev clang18-dev lld18 pkgconf gc-dev openssl-dev zlib-dev
|
||||
apk add python3-dev # optional
|
||||
apk add g++ # build only
|
||||
export LLVM_CONFIG=/usr/lib/llvm18/bin/llvm-config
|
||||
export CGO_CPPFLAGS="$($LLVM_CONFIG --cppflags)"
|
||||
export CGO_CXXFLAGS=-std=c++17
|
||||
export CGO_LDFLAGS="$($LLVM_CONFIG --ldflags) $($LLVM_CONFIG --libs all)"
|
||||
curl https://raw.githubusercontent.com/goplus/llgo/refs/heads/main/install.sh | bash
|
||||
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
||||
```
|
||||
|
||||
### on Windows
|
||||
|
||||
TODO
|
||||
|
||||
### Install from source
|
||||
|
||||
<!-- embedme doc/_readme/scripts/install_llgo.sh#L2-L1000 -->
|
||||
## Development tools
|
||||
|
||||
* [pydump](chore/_xtool/pydump): It's the first program compiled by `llgo` (NOT `go`) in a production environment. It outputs symbol information (functions, variables, and constants) from a Python library in JSON format, preparing for the generation of corresponding packages in `llgo`.
|
||||
* [pysigfetch](https://github.com/goplus/hdq/tree/main/chore/pysigfetch): It generates symbol information by extracting information from Python's documentation site. This tool is not part of the `llgo` project, but we depend on it.
|
||||
* [llpyg](chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` and `pysigfetch` to accomplish the task.
|
||||
* [llgen](chore/llgen): It is used to compile Go packages into LLVM IR files (*.ll).
|
||||
* [ssadump](chore/ssadump): It is a Go SSA builder and interpreter.
|
||||
|
||||
How do I generate these tools?
|
||||
|
||||
```sh
|
||||
git clone https://github.com/goplus/llgo.git
|
||||
cd llgo
|
||||
./install.sh
|
||||
```
|
||||
|
||||
## Development tools
|
||||
|
||||
* [pydump](_xtool/pydump): It's the first program compiled by `llgo` (NOT `go`) in a production environment. It outputs symbol information (functions, variables, and constants) from a Python library in JSON format, preparing for the generation of corresponding packages in `llgo`.
|
||||
* [pysigfetch](https://github.com/goplus/hdq/tree/main/chore/pysigfetch): It generates symbol information by extracting information from Python's documentation site. This tool is not part of the `llgo` project, but we depend on it.
|
||||
* [llpyg](compiler/chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` and `pysigfetch` to accomplish the task.
|
||||
* [llgen](compiler/chore/llgen): It is used to compile Go packages into LLVM IR files (*.ll).
|
||||
* [ssadump](compiler/chore/ssadump): It is a Go SSA builder and interpreter.
|
||||
|
||||
How do I generate these tools?
|
||||
|
||||
<!-- embedme doc/_readme/scripts/install_full.sh#L2-L1000 -->
|
||||
|
||||
```sh
|
||||
git clone https://github.com/goplus/llgo.git
|
||||
cd llgo/compiler
|
||||
go install -v ./cmd/...
|
||||
go install -v ./chore/... # compile all tools except pydump
|
||||
export LLGO_ROOT=$PWD/..
|
||||
cd ../_xtool
|
||||
cd chore/_xtool
|
||||
llgo install ./... # compile pydump
|
||||
go install github.com/goplus/hdq/chore/pysigfetch@v0.8.1 # compile pysigfetch
|
||||
```
|
||||
@@ -435,6 +386,6 @@ go install github.com/goplus/hdq/chore/pysigfetch@v0.8.1 # compile pysigfetch
|
||||
|
||||
Below are the key modules for understanding the implementation principles of `llgo`:
|
||||
|
||||
* [ssa](https://pkg.go.dev/github.com/goplus/llgo/compiler/ssa): It generates LLVM IR files (LLVM SSA) using the semantics (interfaces) of Go SSA. Although `LLVM SSA` and `Go SSA` are both IR languages, they work at completely different levels. `LLVM SSA` is closer to machine code, which abstracts different instruction sets. While `Go SSA` is closer to a high-level language. We can think of it as the instruction set of the `Go computer`. `llgo/ssa` is not just limited to the `llgo` compiler. If we view it as the high-level expressive power of `LLVM`, you'll find it very useful. Prior to `llgo/ssa`, you had to operate `LLVM` using machine code semantics. But now, with the advanced SSA form (in the semantics of Go SSA), you can conveniently utilize `LLVM`.
|
||||
* [cl](https://pkg.go.dev/github.com/goplus/llgo/compiler/cl): It is the core of the llgo compiler. It converts a Go package into LLVM IR files. It depends on `llgo/ssa`.
|
||||
* [internal/build](https://pkg.go.dev/github.com/goplus/llgo/compiler/internal/build): It strings together the entire compilation process of `llgo`. It depends on `llgo/ssa` and `llgo/cl`.
|
||||
* [llgo/ssa](https://pkg.go.dev/github.com/goplus/llgo/ssa): It generates LLVM IR files (LLVM SSA) using the semantics (interfaces) of Go SSA. Although `LLVM SSA` and `Go SSA` are both IR languages, they work at completely different levels. `LLVM SSA` is closer to machine code, which abstracts different instruction sets. While `Go SSA` is closer to a high-level language. We can think of it as the instruction set of the `Go computer`. `llgo/ssa` is not just limited to the `llgo` compiler. If we view it as the high-level expressive power of `LLVM`, you'll find it very useful. Prior to `llgo/ssa`, you had to operate `LLVM` using machine code semantics. But now, with the advanced SSA form (in the semantics of Go SSA), you can conveniently utilize `LLVM`.
|
||||
* [llgo/cl](https://pkg.go.dev/github.com/goplus/llgo/cl): It is the core of the llgo compiler. It converts a Go package into LLVM IR files. It depends on `llgo/ssa`.
|
||||
* [llgo/internal/build](https://pkg.go.dev/github.com/goplus/llgo/internal/build): It strings together the entire compilation process of `llgo`. It depends on `llgo/ssa` and `llgo/cl`.
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package async
|
||||
|
||||
import (
|
||||
_ "unsafe"
|
||||
)
|
||||
|
||||
type Void = [0]byte
|
||||
|
||||
type Future[T any] interface {
|
||||
Then(cb func(T))
|
||||
}
|
||||
|
||||
type future[T any] struct {
|
||||
cb func(func(T))
|
||||
}
|
||||
|
||||
func (f *future[T]) Then(cb func(T)) {
|
||||
f.cb(cb)
|
||||
}
|
||||
|
||||
func Async[T any](fn func(func(T))) Future[T] {
|
||||
return &future[T]{fn}
|
||||
}
|
||||
|
||||
func Run[T any](future Future[T]) T {
|
||||
var ret T
|
||||
future.Then(func(v T) {
|
||||
ret = v
|
||||
})
|
||||
return ret
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/goplus/llgo/_demo/async/async"
|
||||
"github.com/goplus/llgo/_demo/async/timeout"
|
||||
)
|
||||
|
||||
func Sleep(i int, d time.Duration) async.Future[int] {
|
||||
return async.Async(func(resolve func(int)) {
|
||||
timeout.Timeout(d).Then(func(async.Void) {
|
||||
resolve(i)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
async.Run(async.Async(func(resolve func(async.Void)) {
|
||||
println("read file")
|
||||
defer resolve(async.Void{})
|
||||
}))
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package timeout
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/goplus/llgo/_demo/async/async"
|
||||
)
|
||||
|
||||
func Timeout(d time.Duration) async.Future[async.Void] {
|
||||
return async.Async(func(resolve func(async.Void)) {
|
||||
go func() {
|
||||
time.Sleep(d)
|
||||
resolve(async.Void{})
|
||||
}()
|
||||
})
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package main
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/runtime/internal/runtime"
|
||||
"github.com/goplus/llgo/internal/runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -3,7 +3,7 @@ package main
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/runtime/internal/runtime"
|
||||
"github.com/goplus/llgo/internal/runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -1,16 +0,0 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -DBAR
|
||||
#include <stdio.h>
|
||||
#include "foo.h"
|
||||
static void foo(Foo* f) {
|
||||
printf("foo in bar: %d\n", f->a);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func Bar(f *C.Foo) {
|
||||
C.print_foo(f)
|
||||
C.foo(f)
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
#cgo windows,!amd64 CFLAGS: -D_WIN32
|
||||
#cgo !windows CFLAGS: -D_POSIX
|
||||
#cgo windows,amd64 CFLAGS: -D_WIN64
|
||||
#cgo linux,amd64 CFLAGS: -D_LINUX64
|
||||
#cgo !windows,amd64 CFLAGS: -D_UNIX64
|
||||
#cgo pkg-config: python3-embed
|
||||
#include <stdio.h>
|
||||
#include <Python.h>
|
||||
#include "foo.h"
|
||||
typedef struct {
|
||||
int a;
|
||||
} s4;
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b;
|
||||
} s8;
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
} s12;
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
int d;
|
||||
} s16;
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
int d;
|
||||
int e;
|
||||
} s20;
|
||||
|
||||
static int test_structs(s4* s4, s8* s8, s12* s12, s16* s16, s20* s20) {
|
||||
printf("s4.a: %d\n", s4->a);
|
||||
printf("s8.a: %d, s8.b: %d\n", s8->a, s8->b);
|
||||
printf("s12.a: %d, s12.b: %d, s12.c: %d\n", s12->a, s12->b, s12->c);
|
||||
printf("s16.a: %d, s16.b: %d, s16.c: %d, s16.d: %d\n", s16->a, s16->b, s16->c, s16->d);
|
||||
printf("s20.a: %d, s20.b: %d, s20.c: %d, s20.d: %d, s20.e: %d\n", s20->a, s20->b, s20->c, s20->d, s20->e);
|
||||
|
||||
return s4->a + s8->a + s8->b + s12->a + s12->b + s12->c + s16->a + s16->b + s16->c + s16->d + s20->a + s20->b + s20->c + s20->d + s20->e;
|
||||
}
|
||||
|
||||
static void test_macros() {
|
||||
#ifdef FOO
|
||||
printf("FOO is defined\n");
|
||||
#endif
|
||||
#ifdef BAR
|
||||
printf("BAR is defined\n");
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
printf("WIN32 is defined\n");
|
||||
#endif
|
||||
#ifdef _POSIX
|
||||
printf("POSIX is defined\n");
|
||||
#endif
|
||||
#ifdef _WIN64
|
||||
printf("WIN64 is defined\n");
|
||||
#endif
|
||||
#ifdef _LINUX64
|
||||
printf("LINUX64 is defined\n");
|
||||
#endif
|
||||
#ifdef _UNIX64
|
||||
printf("UNIX64 is defined\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MY_VERSION "1.0.0"
|
||||
#define MY_CODE 0x12345678
|
||||
|
||||
static void test_void() {
|
||||
printf("test_void\n");
|
||||
}
|
||||
|
||||
typedef int (*Cb)(int);
|
||||
|
||||
extern int go_callback(int);
|
||||
|
||||
extern int c_callback(int i);
|
||||
|
||||
static void test_callback(Cb cb) {
|
||||
printf("test_callback, cb: %p, go_callback: %p, c_callback: %p\n", cb, go_callback, c_callback);
|
||||
printf("test_callback, *cb: %p, *go_callback: %p, *c_callback: %p\n", *(void**)cb, *(void**)(go_callback), *(void**)(c_callback));
|
||||
printf("cb result: %d\n", cb(123));
|
||||
printf("done\n");
|
||||
}
|
||||
|
||||
extern int go_callback_not_use_in_go(int);
|
||||
|
||||
static void run_callback() {
|
||||
test_callback(c_callback);
|
||||
test_callback(go_callback_not_use_in_go);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/_demo/cgofull/pymod1"
|
||||
"github.com/goplus/llgo/_demo/cgofull/pymod2"
|
||||
)
|
||||
|
||||
//export go_callback_not_use_in_go
|
||||
func go_callback_not_use_in_go(i C.int) C.int {
|
||||
return i + 1
|
||||
}
|
||||
|
||||
//export go_callback
|
||||
func go_callback(i C.int) C.int {
|
||||
return i + 1
|
||||
}
|
||||
|
||||
func main() {
|
||||
runPy()
|
||||
f := &C.Foo{a: 1}
|
||||
Foo(f)
|
||||
Bar(f)
|
||||
C.test_macros()
|
||||
r := C.test_structs(&C.s4{a: 1}, &C.s8{a: 1, b: 2}, &C.s12{a: 1, b: 2, c: 3}, &C.s16{a: 1, b: 2, c: 3, d: 4}, &C.s20{a: 1, b: 2, c: 3, d: 4, e: 5})
|
||||
fmt.Println(r)
|
||||
if r != 35 {
|
||||
panic("test_structs failed")
|
||||
}
|
||||
fmt.Println(C.MY_VERSION)
|
||||
fmt.Println(int(C.MY_CODE))
|
||||
C.test_void()
|
||||
|
||||
println("call run_callback")
|
||||
C.run_callback()
|
||||
|
||||
// test _Cgo_ptr and _cgoCheckResult
|
||||
println("call with go_callback")
|
||||
C.test_callback((C.Cb)(C.go_callback))
|
||||
|
||||
println("call with c_callback")
|
||||
C.test_callback((C.Cb)(C.c_callback))
|
||||
}
|
||||
|
||||
func runPy() {
|
||||
Initialize()
|
||||
defer Finalize()
|
||||
Run("print('Hello, Python!')")
|
||||
C.PyObject_Print((*C.PyObject)(unsafe.Pointer(pymod1.Float(1.23))), C.stderr, 0)
|
||||
C.PyObject_Print((*C.PyObject)(unsafe.Pointer(pymod2.Long(123))), C.stdout, 0)
|
||||
// test _Cgo_use
|
||||
C.PyObject_Print((*C.PyObject)(unsafe.Pointer(C.PyComplex_FromDoubles(C.double(1.23), C.double(4.56)))), C.stdout, 0)
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include "foo.h"
|
||||
|
||||
void print_foo(Foo *f)
|
||||
{
|
||||
printf("print_foo: %d\n", f->a);
|
||||
}
|
||||
|
||||
int c_callback(int i)
|
||||
{
|
||||
return i + 1;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -DFOO
|
||||
#include <stdio.h>
|
||||
#include "foo.h"
|
||||
static void foo(Foo* f) {
|
||||
printf("foo in bar: %d\n", f->a);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func Foo(f *C.Foo) {
|
||||
C.print_foo(f)
|
||||
C.foo(f)
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
} Foo;
|
||||
|
||||
extern void print_foo(Foo* f);
|
||||
@@ -1,24 +0,0 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
#cgo pkg-config: python3-embed
|
||||
#include <Python.h>
|
||||
*/
|
||||
import "C"
|
||||
import "fmt"
|
||||
|
||||
func Initialize() {
|
||||
C.Py_Initialize()
|
||||
}
|
||||
|
||||
func Finalize() {
|
||||
C.Py_Finalize()
|
||||
}
|
||||
|
||||
func Run(code string) error {
|
||||
if C.PyRun_SimpleString(C.CString(code)) != 0 {
|
||||
C.PyErr_Print()
|
||||
return fmt.Errorf("failed to run code")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package pymod1
|
||||
|
||||
/*
|
||||
#cgo pkg-config: python3-embed
|
||||
#include <Python.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func Float(f float64) *C.PyObject {
|
||||
return C.PyFloat_FromDouble(C.double(f))
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package pymod2
|
||||
|
||||
/*
|
||||
#cgo pkg-config: python3-embed
|
||||
#include <Python.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func Long(l int64) *C.PyObject {
|
||||
return C.PyLong_FromLongLong(C.longlong(l))
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tempDir := os.TempDir()
|
||||
noexist := filepath.Join(tempDir, "noexist.txt")
|
||||
|
||||
if _, err := os.Stat(noexist); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
fmt.Println("noexist:", err.Error())
|
||||
} else {
|
||||
fmt.Println("exist,other err:", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Open(noexist); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
fmt.Println("noexist:", err.Error())
|
||||
} else {
|
||||
fmt.Println("exist,other err:", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var data bytes.Buffer
|
||||
cmd := exec.Command("echo", "hello llgo")
|
||||
cmd.Stdout = &data
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
println("len:", len(data.Bytes()))
|
||||
println("data:", data.String())
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
var a int = 5
|
||||
defer println(a)
|
||||
defer func() {
|
||||
println(a)
|
||||
}()
|
||||
defer func() {
|
||||
println(recover().(string))
|
||||
}()
|
||||
a = 10
|
||||
panic("error")
|
||||
//Output:
|
||||
// error
|
||||
// 10
|
||||
// 5
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type MyStruct[T any] struct {
|
||||
value T
|
||||
}
|
||||
|
||||
func (m *MyStruct[T]) Method() {
|
||||
fmt.Println("In generic method")
|
||||
genericFunc[T](m.value)
|
||||
}
|
||||
|
||||
func genericFunc[T any](v T) {
|
||||
fmt.Println("In generic function")
|
||||
normalFunc()
|
||||
}
|
||||
|
||||
func normalFunc() {
|
||||
fmt.Println("In normal function")
|
||||
panic("panic occurs here")
|
||||
}
|
||||
|
||||
func main() {
|
||||
m := &MyStruct[string]{value: "hello"}
|
||||
m.Method()
|
||||
}
|
||||
|
||||
//Expected:
|
||||
// In generic method
|
||||
// In generic function
|
||||
// In normal function
|
||||
// panic: panic occurs here
|
||||
|
||||
// [0x00C6D310 github.com/goplus/llgo/internal/runtime.Rethrow+0x2f, SP = 0x60]
|
||||
// [0x00C6CF44 github.com/goplus/llgo/internal/runtime.Panic+0x2d, SP = 0x50]
|
||||
// [0x00C69420 main.normalFunc+0xf, SP = 0xa8]
|
||||
// [0x00C69564 main.genericFunc[string]+0x18, SP = 0x74]
|
||||
// [0x00C694A8 main.(*MyStruct[string]).Method+0x1f, SP = 0x84]
|
||||
// [0x00C6936C main+0x4, SP = 0x40]
|
||||
@@ -1,15 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
)
|
||||
|
||||
func main() {
|
||||
println("hello world by println")
|
||||
fmt.Println("hello world by fmt.Println")
|
||||
c.Printf(c.Str("Hello world by c.Printf\n"))
|
||||
c.Printf(c.Str("Hello world\n"))
|
||||
}
|
||||
|
||||
/* Expected output:
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func add(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
func main() {
|
||||
fn := func(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
var i int
|
||||
fn1 := func() {
|
||||
i++
|
||||
}
|
||||
fn2 := func() func() {
|
||||
return func() {
|
||||
println("closure", i)
|
||||
}
|
||||
}
|
||||
|
||||
fns := []any{add, fn, fn1, fn2}
|
||||
for _, fn := range fns {
|
||||
v := reflect.ValueOf(fn)
|
||||
fmt.Println(v.Type())
|
||||
fmt.Println(v.Kind())
|
||||
if v.Kind() != reflect.Func {
|
||||
panic(fmt.Sprintf("not func: %T", fn))
|
||||
}
|
||||
|
||||
t := v.Type()
|
||||
fmt.Println(t)
|
||||
fmt.Println(t.Kind())
|
||||
if t.Kind() != reflect.Func {
|
||||
panic(fmt.Sprintf("not func: %T", fn))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package bar
|
||||
|
||||
func Bar() int {
|
||||
return 2
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package bar
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestBar(t *testing.T) {
|
||||
if Bar() != 2 {
|
||||
t.Fatal("Bar() != 2")
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package foo
|
||||
|
||||
func Foo() int {
|
||||
return 1
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package foo
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestFoo(t *testing.T) {
|
||||
if Foo() != 1 {
|
||||
t.Fatal("Foo() != 1")
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/goplus/llgo/_demo/runtest/bar"
|
||||
"github.com/goplus/llgo/_demo/runtest/foo"
|
||||
)
|
||||
|
||||
func Zoo() int {
|
||||
return 3
|
||||
}
|
||||
|
||||
func main() {
|
||||
println("foo.Foo()", foo.Foo())
|
||||
println("bar.Bar()", bar.Bar())
|
||||
println("Zoo()", Zoo())
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestZoo(t *testing.T) {
|
||||
if Zoo() != 3 {
|
||||
t.Fatal("Zoo() != 3")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFalse(t *testing.T) {
|
||||
// t.Fatal("false")
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Counter represents a thread-safe counter
|
||||
type Counter struct {
|
||||
mu sync.Mutex
|
||||
value int64
|
||||
}
|
||||
|
||||
// Increment increases the counter value by 1
|
||||
func (c *Counter) Increment() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.value++
|
||||
}
|
||||
|
||||
// GetValue returns the current value of the counter
|
||||
func (c *Counter) GetValue() int64 {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.value
|
||||
}
|
||||
|
||||
// Constant values for the test
|
||||
const (
|
||||
numGoroutines = 64
|
||||
numIterations = 10000
|
||||
expectedTotal = numGoroutines * numIterations
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create a new counter instance
|
||||
counter := &Counter{}
|
||||
|
||||
// Create a wait group to wait for all goroutines to finish
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// Track active goroutines for monitoring
|
||||
var activeGoroutines int32
|
||||
|
||||
// Start time
|
||||
startTime := time.Now()
|
||||
|
||||
// Launch goroutines
|
||||
for i := 0; i < numGoroutines; i++ {
|
||||
wg.Add(1)
|
||||
atomic.AddInt32(&activeGoroutines, 1)
|
||||
|
||||
go func(id int) {
|
||||
defer func() {
|
||||
wg.Done()
|
||||
atomic.AddInt32(&activeGoroutines, -1)
|
||||
}()
|
||||
|
||||
// Each goroutine increments the counter numIterations times
|
||||
for j := 0; j < numIterations; j++ {
|
||||
counter.Increment()
|
||||
|
||||
// Simulate varying workload with random sleeps
|
||||
if j%100 == 0 {
|
||||
time.Sleep(time.Microsecond)
|
||||
}
|
||||
}
|
||||
fmt.Printf("Goroutine %d finished\n", id)
|
||||
}(i)
|
||||
}
|
||||
|
||||
// Monitor progress in a separate goroutine
|
||||
go func() {
|
||||
for {
|
||||
active := atomic.LoadInt32(&activeGoroutines)
|
||||
if active == 0 {
|
||||
break
|
||||
}
|
||||
fmt.Printf("Active goroutines: %d\n", active)
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for all goroutines to complete
|
||||
wg.Wait()
|
||||
|
||||
// Calculate execution time
|
||||
duration := time.Since(startTime)
|
||||
|
||||
// Get and verify the final result
|
||||
finalValue := counter.GetValue()
|
||||
fmt.Printf("\nExecution completed in: %v\n", duration)
|
||||
fmt.Printf("Final counter value: %d\n", finalValue)
|
||||
fmt.Printf("Expected value: %d\n", expectedTotal)
|
||||
|
||||
// Assert the result
|
||||
if finalValue != expectedTotal {
|
||||
panic(fmt.Sprintf("ERROR: Counter value mismatch! Expected %d, got %d\n",
|
||||
expectedTotal, finalValue))
|
||||
} else {
|
||||
fmt.Printf("SUCCESS: Counter value matches expected total\n")
|
||||
}
|
||||
|
||||
// Print some statistics
|
||||
opsPerSecond := float64(expectedTotal) / duration.Seconds()
|
||||
fmt.Printf("\nStatistics:\n")
|
||||
fmt.Printf("Operations per second: %.2f\n", opsPerSecond)
|
||||
fmt.Printf("Average time per operation: %.2f ns\n",
|
||||
float64(duration.Nanoseconds())/float64(expectedTotal))
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
llsync "github.com/goplus/llgo/c/pthread/sync"
|
||||
)
|
||||
|
||||
type L struct {
|
||||
mu sync.Mutex
|
||||
s string
|
||||
i int
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func main() {
|
||||
l := &L{s: "hello", i: 123, w: os.Stdout}
|
||||
println("sizeof(L):", unsafe.Sizeof(L{}))
|
||||
println("sizeof(sync.Mutex):", unsafe.Sizeof(sync.Mutex{}))
|
||||
println("sizeof(llsync.Mutex):", unsafe.Sizeof(llsync.Mutex{}))
|
||||
println("l:", l, "l.s:", l.s, "l.i:", l.i, "l.w:", l.w)
|
||||
l.mu.Lock()
|
||||
println("locked")
|
||||
println("l:", l, "l.s:", l.s, "l.i:", l.i, "l.w:", l.w)
|
||||
l.w.Write([]byte(l.s))
|
||||
l.w.Write([]byte("\n"))
|
||||
l.mu.Unlock()
|
||||
}
|
||||
@@ -15,15 +15,3 @@ float llgoToFloat32(long v) {
|
||||
k.v = v;
|
||||
return k.f;
|
||||
}
|
||||
|
||||
long llgoFromFloat64(double v) {
|
||||
castUnion k;
|
||||
k.d = v;
|
||||
return k.v;
|
||||
}
|
||||
|
||||
long llgoFromFloat32(float v) {
|
||||
castUnion k;
|
||||
k.f = v;
|
||||
return k.v;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,3 @@ func ToFloat64(v uintptr) float64
|
||||
|
||||
//go:linkname ToFloat32 C.llgoToFloat32
|
||||
func ToFloat32(v uintptr) float32
|
||||
|
||||
//go:linkname FromFloat64 C.llgoFromFloat64
|
||||
func FromFloat64(v float64) uintptr
|
||||
|
||||
//go:linkname FromFloat32 C.llgoFromFloat32
|
||||
func FromFloat32(v float32) uintptr
|
||||
|
||||
40
c/c.go
40
c/c.go
@@ -33,13 +33,9 @@ type (
|
||||
Float = float32
|
||||
Double = float64
|
||||
Pointer = unsafe.Pointer
|
||||
FilePtr = *FILE
|
||||
FilePtr = unsafe.Pointer
|
||||
)
|
||||
|
||||
type FILE struct {
|
||||
Unused [8]byte
|
||||
}
|
||||
|
||||
type (
|
||||
Int C.int
|
||||
Uint C.uint
|
||||
@@ -55,26 +51,6 @@ type integer interface {
|
||||
~int | ~uint | ~uintptr | ~int32 | ~uint32 | ~int64 | ~uint64
|
||||
}
|
||||
|
||||
type SizeT = uintptr
|
||||
type SsizeT = Long
|
||||
|
||||
type IntptrT = uintptr
|
||||
type UintptrT = uintptr
|
||||
type Int8T = int8
|
||||
type Int16T = int16
|
||||
type Int32T = int32
|
||||
type Int64T = int64
|
||||
|
||||
type Uint8T = uint8
|
||||
type Uint16T = uint16
|
||||
type Uint32T = uint32
|
||||
type Uint64T = uint64
|
||||
|
||||
type IntmaxT = LongLong
|
||||
type UintmaxT = UlongLong
|
||||
|
||||
type VaList = Pointer
|
||||
|
||||
//go:linkname Str llgo.cstr
|
||||
func Str(string) *Char
|
||||
|
||||
@@ -109,9 +85,6 @@ func Calloc(num uintptr, size uintptr) Pointer
|
||||
//go:linkname Free C.free
|
||||
func Free(ptr Pointer)
|
||||
|
||||
//go:linkname Realloc C.realloc
|
||||
func Realloc(ptr Pointer, size uintptr) Pointer
|
||||
|
||||
//go:linkname Memcpy C.memcpy
|
||||
func Memcpy(dst, src Pointer, n uintptr) Pointer
|
||||
|
||||
@@ -260,14 +233,6 @@ func Perror(s *Char)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
type IconvT = Pointer
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
type LocaleT = Pointer
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
//go:linkname Usleep C.usleep
|
||||
func Usleep(useconds Uint) Int
|
||||
|
||||
@@ -308,6 +273,3 @@ func GetoptLong(argc Int, argv **Char, optstring *Char, longopts *Option, longin
|
||||
func GetoptLongOnly(argc Int, argv **Char, optstring *Char, longopts *Option, longindex *Int) Int
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
//go:linkname Sysconf C.sysconf
|
||||
func Sysconf(name Int) Long
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
"github.com/goplus/llgo/c/clang"
|
||||
"github.com/goplus/llgo/compiler/chore/_xtool/llcppsymg/clangutils"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_, unit, err := clangutils.CreateTranslationUnit(&clangutils.Config{
|
||||
File: "#include <stddef.h>",
|
||||
Temp: true,
|
||||
IsCpp: false,
|
||||
})
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
clang.GetInclusions(unit, func(included_file clang.File, inclusion_stack *clang.SourceLocation, include_len c.Uint, client_data c.Pointer) {
|
||||
filename := included_file.FileName()
|
||||
c.Printf(c.Str("Included file: %s Include length: %d\n"), filename.CStr(), include_len)
|
||||
inclusions := unsafe.Slice(inclusion_stack, include_len)
|
||||
for i := range inclusions {
|
||||
loc := inclusions[i]
|
||||
var file clang.File
|
||||
var line, column c.Uint
|
||||
loc.SpellingLocation(&file, &line, &column, nil)
|
||||
filename = file.FileName()
|
||||
c.Printf(c.Str(" included from: %s:%d:%d\n"), filename.CStr(), line, column)
|
||||
}
|
||||
}, nil)
|
||||
}
|
||||
@@ -36,16 +36,13 @@ var context = newContext()
|
||||
func printCursorLocation(cursor clang.Cursor) {
|
||||
loc := cursor.Location()
|
||||
var file clang.File
|
||||
var line, column, presumedLine, presumedColumn c.Uint
|
||||
var presumedFilename clang.String
|
||||
var line, column c.Uint
|
||||
|
||||
loc.SpellingLocation(&file, &line, &column, nil)
|
||||
loc.PresumedLocation(&presumedFilename, &presumedLine, &presumedColumn)
|
||||
filename := file.FileName()
|
||||
defer filename.Dispose()
|
||||
|
||||
c.Printf(c.Str("Location: %s:%d:%d\n"), filename.CStr(), line, column)
|
||||
c.Printf(c.Str("Presumed Location: %s:%d:%d\n"), presumedFilename.CStr(), presumedLine, presumedColumn)
|
||||
c.Printf(c.Str("%s:%d:%d\n"), filename.CStr(), line, column)
|
||||
}
|
||||
|
||||
func printMarcoInfo(cursor clang.Cursor) {
|
||||
@@ -110,26 +107,20 @@ func printFuncInfo(cursor clang.Cursor) {
|
||||
}
|
||||
|
||||
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
|
||||
switch cursor.Kind {
|
||||
case clang.CursorMacroDefinition:
|
||||
if cursor.Kind == clang.CursorMacroDefinition {
|
||||
printMarcoInfo(cursor)
|
||||
case clang.CursorNamespace:
|
||||
} else if cursor.Kind == clang.CursorNamespace {
|
||||
nameStr := cursor.String()
|
||||
context.setNamespaceName(c.GoString(nameStr.CStr()))
|
||||
clang.VisitChildren(cursor, visit, nil)
|
||||
context.setNamespaceName("")
|
||||
case clang.CursorClassDecl:
|
||||
} else if cursor.Kind == clang.CursorClassDecl {
|
||||
nameStr := cursor.String()
|
||||
context.setClassName(c.GoString(nameStr.CStr()))
|
||||
clang.VisitChildren(cursor, visit, nil)
|
||||
context.setClassName("")
|
||||
case clang.CursorCXXMethod, clang.CursorFunctionDecl:
|
||||
} else if cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorFunctionDecl {
|
||||
printFuncInfo(cursor)
|
||||
case clang.CursorEnumDecl, clang.CursorStructDecl, clang.CursorUnionDecl, clang.CursorTypedefDecl:
|
||||
nameStr := cursor.String()
|
||||
printCursorLocation(cursor)
|
||||
c.Printf(c.Str("Name: %s\n"), nameStr.CStr())
|
||||
println("--------------------------------")
|
||||
}
|
||||
|
||||
return clang.ChildVisit_Continue
|
||||
|
||||
@@ -15,14 +15,6 @@ CXChildVisitResult wrap_visitor(CXCursor cursor, CXCursor parent, CXClientData d
|
||||
|
||||
extern "C" {
|
||||
|
||||
void wrap_clang_getLocation(CXTranslationUnit tu, CXFile file, unsigned line, unsigned column, CXSourceLocation *loc) {
|
||||
*loc = clang_getLocation(tu, file, line, column);
|
||||
}
|
||||
|
||||
void wrap_clang_getLocationForOffset(CXTranslationUnit tu, CXFile file, unsigned offset, CXSourceLocation *loc) {
|
||||
*loc = clang_getLocationForOffset(tu, file, offset);
|
||||
}
|
||||
|
||||
void wrap_clang_getTranslationUnitCursor(CXTranslationUnit uint, CXCursor *cur) {
|
||||
*cur = clang_getTranslationUnitCursor(uint);
|
||||
}
|
||||
@@ -35,20 +27,12 @@ int wrap_clang_Cursor_isNull(CXCursor *cursor) { return clang_Cursor_isNull(*cur
|
||||
|
||||
void wrap_clang_getCursorSemanticParent(CXCursor *C, CXCursor *parent) { *parent = clang_getCursorSemanticParent(*C); }
|
||||
|
||||
void wrap_clang_getCursorDefinition(CXCursor *C, CXCursor *def) { *def = clang_getCursorDefinition(*C); }
|
||||
|
||||
void wrap_clang_getCursorLexicalParent(CXCursor *C, CXCursor *parent) { *parent = clang_getCursorLexicalParent(*C); }
|
||||
|
||||
void wrap_clang_getOverriddenCursors(CXCursor *cursor, CXCursor **overridden, unsigned *num_overridden) {
|
||||
clang_getOverriddenCursors(*cursor, overridden, num_overridden);
|
||||
}
|
||||
|
||||
CXFile wrap_clang_getIncludedFile(CXCursor *cursor) { return clang_getIncludedFile(*cursor); }
|
||||
|
||||
void wrap_clang_getCursor(CXTranslationUnit uint, CXSourceLocation *loc, CXCursor *cur) {
|
||||
*cur = clang_getCursor(uint, *loc);
|
||||
}
|
||||
|
||||
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); }
|
||||
|
||||
void wrap_clang_getCursorExtent(CXCursor *cur, CXSourceRange *range) { *range = clang_getCursorExtent(*cur); }
|
||||
@@ -111,8 +95,6 @@ long long wrap_clang_getArraySize(CXType *arrayTyp) { return clang_getArraySize(
|
||||
|
||||
void wrap_clang_Type_getNamedType(CXType *typ, CXType *namedTyp) { *namedTyp = clang_Type_getNamedType(*typ); }
|
||||
|
||||
long long wrap_clang_Type_getSizeOf(CXType *typ) { return clang_Type_getSizeOf(*typ); }
|
||||
|
||||
unsigned wrap_clang_Cursor_isAnonymous(CXCursor *cursor) { return clang_Cursor_isAnonymous(*cursor); }
|
||||
|
||||
unsigned wrap_clang_Cursor_isAnonymousRecordDecl(CXCursor *cursor) {
|
||||
@@ -131,18 +113,8 @@ CXString wrap_clang_getCursorUSR(CXCursor *cur) { return clang_getCursorUSR(*cur
|
||||
|
||||
CXString wrap_clang_getCursorSpelling(CXCursor *cur) { return clang_getCursorSpelling(*cur); }
|
||||
|
||||
CXString wrap_clang_getCursorDisplayName(CXCursor *cur) { return clang_getCursorDisplayName(*cur); }
|
||||
|
||||
void wrap_clang_getCursorReferenced(CXCursor *cur, CXCursor *referenced) {
|
||||
*referenced = clang_getCursorReferenced(*cur);
|
||||
}
|
||||
|
||||
unsigned wrap_clang_Cursor_isVariadic(CXCursor *cur) { return clang_Cursor_isVariadic(*cur); }
|
||||
|
||||
void wrap_clang_Cursor_getCommentRange(CXCursor *cur, CXSourceRange *range) {
|
||||
*range = clang_Cursor_getCommentRange(*cur);
|
||||
}
|
||||
|
||||
CXString wrap_clang_Cursor_getRawCommentText(CXCursor *cursor) { return clang_Cursor_getRawCommentText(*cursor); }
|
||||
|
||||
CXString wrap_clang_Cursor_getMangling(CXCursor *cur) { return clang_Cursor_getMangling(*cur); }
|
||||
@@ -206,17 +178,11 @@ unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor
|
||||
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));
|
||||
}
|
||||
|
||||
int wrap_clang_Location_isInSystemHeader(CXSourceLocation *loc) { return clang_Location_isInSystemHeader(*loc); }
|
||||
|
||||
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column,
|
||||
unsigned *offset) {
|
||||
clang_getSpellingLocation(*loc, file, line, column, offset);
|
||||
}
|
||||
|
||||
void wrap_clang_getPresumedLocation(CXSourceLocation *loc, CXString *filename, unsigned *line, unsigned *column) {
|
||||
clang_getPresumedLocation(*loc, filename, line, column);
|
||||
}
|
||||
|
||||
void wrap_clang_getRangeStart(CXSourceRange *range, CXSourceLocation *loc) { *loc = clang_getRangeStart(*range); }
|
||||
|
||||
void wrap_clang_getRangeEnd(CXSourceRange *range, CXSourceLocation *loc) { *loc = clang_getRangeEnd(*range); }
|
||||
|
||||
@@ -57,12 +57,3 @@ type StringSet struct {
|
||||
*/
|
||||
// llgo:link (*StringSet).Dispose C.clang_disposeStringSet
|
||||
func (*StringSet) Dispose() {}
|
||||
|
||||
func GoString(clangStr String) (str string) {
|
||||
defer clangStr.Dispose()
|
||||
cstr := clangStr.CStr()
|
||||
if cstr != nil {
|
||||
str = c.GoString(cstr)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
270
c/clang/clang.go
270
c/clang/clang.go
@@ -1157,30 +1157,6 @@ type UnsavedFile struct {
|
||||
Length c.Ulong
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the source location associated with a given file/line/column
|
||||
* in a particular translation unit.
|
||||
*/
|
||||
// llgo:link (*TranslationUnit).wrapGetLocation C.wrap_clang_getLocation
|
||||
func (t *TranslationUnit) wrapGetLocation(file File, line, column c.Uint, loc *SourceLocation) {}
|
||||
|
||||
func (t *TranslationUnit) GetLocation(file File, line, column c.Uint) (ret SourceLocation) {
|
||||
t.wrapGetLocation(file, line, column, &ret)
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the source location associated with a given character offset
|
||||
* in a particular translation unit.
|
||||
*/
|
||||
// llgo:link (*TranslationUnit).wrapGetLocationForOffset C.wrap_clang_getLocationForOffset
|
||||
func (t *TranslationUnit) wrapGetLocationForOffset(file File, offset c.Uint, loc *SourceLocation) {}
|
||||
|
||||
func (t *TranslationUnit) GetLocationForOffset(file File, offset c.Uint) (ret SourceLocation) {
|
||||
t.wrapGetLocationForOffset(file, offset, &ret)
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* An "index" that consists of a set of translation units that would
|
||||
* typically be linked together into an executable or library.
|
||||
@@ -1635,14 +1611,6 @@ func (c Cursor) SemanticParent() (parent Cursor) {
|
||||
return
|
||||
}
|
||||
|
||||
// llgo:link (*Cursor).wrapDefinition C.wrap_clang_getCursorDefinition
|
||||
func (*Cursor) wrapDefinition(def *Cursor) {}
|
||||
|
||||
func (c Cursor) Definition() (def Cursor) {
|
||||
c.wrapDefinition(&def)
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the lexical parent of the given cursor.
|
||||
*
|
||||
@@ -1742,43 +1710,6 @@ func (c Cursor) OverriddenCursors(overridden **Cursor, numOverridden *c.Uint) {
|
||||
// llgo:link (*Cursor).DisposeOverriddenCursors C.clang_disposeOverriddenCursors
|
||||
func (c *Cursor) DisposeOverriddenCursors() {}
|
||||
|
||||
/**
|
||||
* Retrieve the file that is included by the given inclusion directive
|
||||
* cursor.
|
||||
*/
|
||||
// llgo:link (*Cursor).wrapIncludedFile C.wrap_clang_getIncludedFile
|
||||
func (c *Cursor) wrapIncludedFile() File {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c Cursor) IncludedFile() (file File) {
|
||||
return c.wrapIncludedFile()
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a source location to the cursor that describes the entity at that
|
||||
* location in the source code.
|
||||
*
|
||||
* clang_getCursor() maps an arbitrary source location within a translation
|
||||
* unit down to the most specific cursor that describes the entity at that
|
||||
* location. For example, given an expression \c x + y, invoking
|
||||
* clang_getCursor() with a source location pointing to "x" will return the
|
||||
* cursor for "x"; similarly for "y". If the cursor points anywhere between
|
||||
* "x" or "y" (e.g., on the + or the whitespace around it), clang_getCursor()
|
||||
* will return a cursor referring to the "+" expression.
|
||||
*
|
||||
* \returns a cursor representing the entity at the given source location, or
|
||||
* a NULL cursor if no such entity can be found.
|
||||
*/
|
||||
|
||||
// llgo:link (*TranslationUnit).wrapGetCursor C.wrap_clang_getCursor
|
||||
func (l *TranslationUnit) wrapGetCursor(loc *SourceLocation, cur *Cursor) {}
|
||||
|
||||
func (l *TranslationUnit) GetCursor(loc *SourceLocation) (cur Cursor) {
|
||||
l.wrapGetCursor(loc, &cur)
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the physical location of the source constructor referenced
|
||||
* by the given cursor.
|
||||
@@ -2148,61 +2079,6 @@ func (t Type) NamedType() (ret Type) {
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* List the possible error codes for \c clang_Type_getSizeOf,
|
||||
* \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
|
||||
* \c clang_Cursor_getOffsetOf.
|
||||
*
|
||||
* A value of this enumeration type can be returned if the target type is not
|
||||
* a valid argument to sizeof, alignof or offsetof.
|
||||
*/
|
||||
type LayoutError c.Int
|
||||
|
||||
const (
|
||||
/**
|
||||
* Type is of kind CXType_Invalid.
|
||||
*/
|
||||
LayoutErrorInvalid LayoutError = -1
|
||||
/**
|
||||
* The type is an incomplete Type.
|
||||
*/
|
||||
LayoutErrorIncomplete LayoutError = -2
|
||||
/**
|
||||
* The type is a dependent Type.
|
||||
*/
|
||||
LayoutErrorDependent LayoutError = -3
|
||||
/**
|
||||
* The type is not a constant size type.
|
||||
*/
|
||||
LayoutErrorNotConstantSize LayoutError = -4
|
||||
/**
|
||||
* The Field name is not valid for this record.
|
||||
*/
|
||||
LayoutErrorInvalidFieldName LayoutError = -5
|
||||
/**
|
||||
* The type is undeduced.
|
||||
*/
|
||||
LayoutErrorUndeduced LayoutError = -6
|
||||
)
|
||||
|
||||
/**
|
||||
* Return the size of a type in bytes as per C++[expr.sizeof] standard.
|
||||
*
|
||||
* If the type declaration is invalid, CXTypeLayoutError_Invalid is returned.
|
||||
* If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete
|
||||
* is returned.
|
||||
* If the type declaration is a dependent type, CXTypeLayoutError_Dependent is
|
||||
* returned.
|
||||
*/
|
||||
// llgo:link (*Type).wrapSizeOf C.wrap_clang_Type_getSizeOf
|
||||
func (t *Type) wrapSizeOf() (ret c.LongLong) {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t Type) SizeOf() (ret c.LongLong) {
|
||||
return t.wrapSizeOf()
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given cursor represents an anonymous
|
||||
* tag or namespace
|
||||
@@ -2320,39 +2196,6 @@ func (c Cursor) String() (ret String) {
|
||||
return c.wrapString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the display name for the entity referenced by this cursor.
|
||||
*
|
||||
* The display name contains extra information that helps identify the cursor,
|
||||
* such as the parameters of a function or template or the arguments of a
|
||||
* class template specialization.
|
||||
*/
|
||||
// llgo:link (*Cursor).wrapDisplayName C.wrap_clang_getCursorDisplayName
|
||||
func (*Cursor) wrapDisplayName() (ret String) {
|
||||
return
|
||||
}
|
||||
func (c Cursor) DisplayName() (ret String) {
|
||||
return c.wrapDisplayName()
|
||||
}
|
||||
|
||||
/** For a cursor that is a reference, retrieve a cursor representing the
|
||||
* entity that it references.
|
||||
*
|
||||
* Reference cursors refer to other entities in the AST. For example, an
|
||||
* Objective-C superclass reference cursor refers to an Objective-C class.
|
||||
* This function produces the cursor for the Objective-C class from the
|
||||
* cursor for the superclass reference. If the input cursor is a declaration or
|
||||
* definition, it returns that declaration or definition unchanged.
|
||||
* Otherwise, returns the NULL cursor.
|
||||
*/
|
||||
// llgo:link (*Cursor).wrapReferenced C.wrap_clang_getCursorReferenced
|
||||
func (*Cursor) wrapReferenced(referenced *Cursor) {}
|
||||
|
||||
func (c Cursor) Referenced() (referenced Cursor) {
|
||||
c.wrapReferenced(&referenced)
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns non-zero if the given cursor is a variadic function or method.
|
||||
*/
|
||||
@@ -2361,19 +2204,6 @@ func (*Cursor) wrapIsVariadic() (ret c.Uint) { return 0 }
|
||||
|
||||
func (c Cursor) IsVariadic() (ret c.Uint) { return c.wrapIsVariadic() }
|
||||
|
||||
/**
|
||||
* Given a cursor that represents a declaration, return the associated
|
||||
* comment's source range. The range may include multiple consecutive comments
|
||||
* with whitespace in between.
|
||||
*/
|
||||
// llgo:link (*Cursor).wrapCommentRange C.wrap_clang_Cursor_getCommentRange
|
||||
func (c *Cursor) wrapCommentRange(ret *SourceRange) {}
|
||||
|
||||
func (c Cursor) CommentRange() (loc SourceRange) {
|
||||
c.wrapCommentRange(&loc)
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a cursor that represents a declaration, return the associated
|
||||
* comment text, including comment markers.
|
||||
@@ -2766,29 +2596,6 @@ func VisitChildren(
|
||||
//llgo:type C
|
||||
type Visitor func(cursor, parent Cursor, clientData ClientData) ChildVisitResult
|
||||
|
||||
/**
|
||||
* Visitor invoked for each file in a translation unit
|
||||
* (used with clang_getInclusions()).
|
||||
*
|
||||
* This visitor function will be invoked by clang_getInclusions() for each
|
||||
* file included (either at the top-level or by \#include directives) within
|
||||
* a translation unit. The first argument is the file being included, and
|
||||
* the second and third arguments provide the inclusion stack. The
|
||||
* array is sorted in order of immediate inclusion. For example,
|
||||
* the first element refers to the location that included 'included_file'.
|
||||
*/
|
||||
//llgo:type C
|
||||
type InclusionVisitor func(included_file File, inclusion_stack *SourceLocation, include_len c.Uint, client_data ClientData)
|
||||
|
||||
/**
|
||||
* Visit the set of preprocessor inclusions in a translation unit.
|
||||
* The visitor function is called with the provided data for every included
|
||||
* file. This does not include headers included by the PCH file (unless one
|
||||
* is inspecting the inclusions in the PCH file itself).
|
||||
*/
|
||||
//go:linkname GetInclusions C.clang_getInclusions
|
||||
func GetInclusions(tu *TranslationUnit, visitor InclusionVisitor, client_data ClientData)
|
||||
|
||||
/**
|
||||
* Tokenize the source code described by the given range into raw
|
||||
* lexical tokens.
|
||||
@@ -2819,16 +2626,6 @@ func (t *TranslationUnit) Tokenize(ran SourceRange, tokens **Token, numTokens *c
|
||||
// llgo:link (*TranslationUnit).DisposeTokens C.clang_disposeTokens
|
||||
func (t *TranslationUnit) DisposeTokens(tokens *Token, numTokens c.Uint) {}
|
||||
|
||||
/**
|
||||
* Returns non-zero if the given source location is in a system header.
|
||||
*/
|
||||
// llgo:link (*SourceLocation).wrapIsInSystemHeader C.wrap_clang_Location_isInSystemHeader
|
||||
func (l *SourceLocation) wrapIsInSystemHeader() (ret c.Uint) { return 0 }
|
||||
|
||||
func (l SourceLocation) IsInSystemHeader() (ret c.Uint) {
|
||||
return l.wrapIsInSystemHeader()
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the file, line, column, and offset represented by
|
||||
* the given source location.
|
||||
@@ -2858,73 +2655,6 @@ func (l SourceLocation) SpellingLocation(file *File, line, column, offset *c.Uin
|
||||
l.wrapSpellingLocation(file, line, column, offset)
|
||||
}
|
||||
|
||||
func (l SourceLocation) File() (ret File) {
|
||||
l.wrapSpellingLocation(&ret, nil, nil, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (l SourceLocation) Line() (ret c.Uint) {
|
||||
l.wrapSpellingLocation(nil, &ret, nil, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (l SourceLocation) Column() (ret c.Uint) {
|
||||
l.wrapSpellingLocation(nil, nil, &ret, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (l SourceLocation) Offset() (ret c.Uint) {
|
||||
l.wrapSpellingLocation(nil, nil, nil, &ret)
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the file, line and column represented by the given source
|
||||
* location, as specified in a # line directive.
|
||||
*
|
||||
* Example: given the following source code in a file somefile.c
|
||||
*
|
||||
* \code
|
||||
* #123 "dummy.c" 1
|
||||
*
|
||||
* static int func(void)
|
||||
* {
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* the location information returned by this function would be
|
||||
*
|
||||
* File: dummy.c Line: 124 Column: 12
|
||||
*
|
||||
* whereas clang_getExpansionLocation would have returned
|
||||
*
|
||||
* File: somefile.c Line: 3 Column: 12
|
||||
*
|
||||
* \param location the location within a source file that will be decomposed
|
||||
* into its parts.
|
||||
*
|
||||
* \param filename [out] if non-NULL, will be set to the filename of the
|
||||
* source location. Note that filenames returned will be for "virtual" files,
|
||||
* which don't necessarily exist on the machine running clang - e.g. when
|
||||
* parsing preprocessed output obtained from a different environment. If
|
||||
* a non-NULL value is passed in, remember to dispose of the returned value
|
||||
* using \c clang_disposeString() once you've finished with it. For an invalid
|
||||
* source location, an empty string is returned.
|
||||
*
|
||||
* \param line [out] if non-NULL, will be set to the line number of the
|
||||
* source location. For an invalid source location, zero is returned.
|
||||
*
|
||||
* \param column [out] if non-NULL, will be set to the column number of the
|
||||
* source location. For an invalid source location, zero is returned.
|
||||
*/
|
||||
// llgo:link (*SourceLocation).wrapPresumedLocation C.wrap_clang_getPresumedLocation
|
||||
func (l *SourceLocation) wrapPresumedLocation(filename *String, line, column *c.Uint) {}
|
||||
|
||||
func (l SourceLocation) PresumedLocation(filename *String, line, column *c.Uint) {
|
||||
l.wrapPresumedLocation(filename, line, column)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a source location representing the first character within a
|
||||
* source range.
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/goplus/llgo/c"
|
||||
"github.com/goplus/llgo/c/debug"
|
||||
)
|
||||
|
||||
type T struct {
|
||||
n int
|
||||
}
|
||||
|
||||
func (t *T) Demo() {
|
||||
println(t.n)
|
||||
addr := debug.Address()
|
||||
c.Printf(c.Str("addr:0x%x\n"), addr)
|
||||
var info debug.Info
|
||||
r := debug.Addrinfo(addr, &info)
|
||||
if r == 0 {
|
||||
panic("not found info")
|
||||
}
|
||||
c.Printf(c.Str("func file:%s name:%s base:0x%x addr:0x%x\n"), info.Fname, info.Sname, info.Fbase, info.Saddr)
|
||||
}
|
||||
|
||||
func main() {
|
||||
t := &T{100}
|
||||
t.Demo()
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c/debug"
|
||||
)
|
||||
|
||||
type T struct {
|
||||
n int
|
||||
}
|
||||
|
||||
func (t *T) Demo() {
|
||||
println(t.n)
|
||||
debug.StackTrace(0, func(fr *debug.Frame) bool {
|
||||
var info debug.Info
|
||||
debug.Addrinfo(unsafe.Pointer(fr.PC), &info)
|
||||
println("[", fr.PC, "]", fr.Name, "+", fr.Offset, ", SP =", fr.SP)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
t := &T{100}
|
||||
t.Demo()
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#if defined(__linux__)
|
||||
#define UNW_LOCAL_ONLY
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <features.h>
|
||||
#endif
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <libunwind.h>
|
||||
|
||||
void *llgo_address() {
|
||||
return __builtin_return_address(0);
|
||||
}
|
||||
|
||||
int llgo_addrinfo(void *addr, Dl_info *info) {
|
||||
return dladdr(addr, info);
|
||||
}
|
||||
|
||||
void llgo_stacktrace(int skip, void *ctx, int (*fn)(void *ctx, void *pc, void *offset, void *sp, char *name)) {
|
||||
unw_cursor_t cursor;
|
||||
unw_context_t context;
|
||||
unw_word_t offset, pc, sp;
|
||||
char fname[256];
|
||||
unw_getcontext(&context);
|
||||
unw_init_local(&cursor, &context);
|
||||
int depth = 0;
|
||||
while (unw_step(&cursor) > 0) {
|
||||
if (depth < skip) {
|
||||
depth++;
|
||||
continue;
|
||||
}
|
||||
if (unw_get_reg(&cursor, UNW_REG_IP, &pc) == 0) {
|
||||
unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);
|
||||
unw_get_reg(&cursor, UNW_REG_SP, &sp);
|
||||
if (fn(ctx, (void*)pc, (void*)offset, (void*)sp, fname) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package debug
|
||||
|
||||
/*
|
||||
#cgo linux LDFLAGS: -lunwind
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
)
|
||||
|
||||
const (
|
||||
LLGoPackage = "link"
|
||||
LLGoFiles = "_wrap/debug.c"
|
||||
)
|
||||
|
||||
type Info struct {
|
||||
Fname *c.Char
|
||||
Fbase c.Pointer
|
||||
Sname *c.Char
|
||||
Saddr c.Pointer
|
||||
}
|
||||
|
||||
//go:linkname Address C.llgo_address
|
||||
func Address() unsafe.Pointer
|
||||
|
||||
//go:linkname Addrinfo C.llgo_addrinfo
|
||||
func Addrinfo(addr unsafe.Pointer, info *Info) c.Int
|
||||
|
||||
//go:linkname stacktrace C.llgo_stacktrace
|
||||
func stacktrace(skip c.Int, ctx unsafe.Pointer, fn func(ctx, pc, offset, sp unsafe.Pointer, name *c.Char) c.Int)
|
||||
|
||||
type Frame struct {
|
||||
PC uintptr
|
||||
Offset uintptr
|
||||
SP unsafe.Pointer
|
||||
Name string
|
||||
}
|
||||
|
||||
func StackTrace(skip int, fn func(fr *Frame) bool) {
|
||||
stacktrace(c.Int(1+skip), unsafe.Pointer(&fn), func(ctx, pc, offset, sp unsafe.Pointer, name *c.Char) c.Int {
|
||||
fn := *(*func(fr *Frame) bool)(ctx)
|
||||
if !fn(&Frame{uintptr(pc), uintptr(offset), sp, c.GoString(name)}) {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
})
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
struct array
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int k;
|
||||
};
|
||||
|
||||
int demo1(struct array a)
|
||||
{
|
||||
printf("c.demo1: %d %d %d %d\n",a.x,a.y,a.z,a.k);
|
||||
return a.x+a.y+a.z+a.k;
|
||||
}
|
||||
|
||||
int demo2( int (*fn)(struct array)) {
|
||||
printf("c.demo2: %p\n",fn);
|
||||
struct array a;
|
||||
a.x = 1;
|
||||
a.y = 2;
|
||||
a.z = 3;
|
||||
a.k = 4;
|
||||
return (*fn)(a);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
"github.com/goplus/llgo/c/ffi"
|
||||
)
|
||||
|
||||
const (
|
||||
LLGoPackage = "link"
|
||||
LLGoFiles = "../_wrap/wrap.c"
|
||||
)
|
||||
|
||||
//llgo:type C
|
||||
type Callback func(array) c.Int
|
||||
|
||||
//go:linkname demo1 C.demo1
|
||||
func demo1(array) c.Int
|
||||
|
||||
//go:linkname demo2 C.demo2
|
||||
func demo2(fn Callback) c.Int
|
||||
|
||||
//llgo:type C
|
||||
type array struct {
|
||||
x c.Int
|
||||
y c.Int
|
||||
z c.Int
|
||||
k c.Int
|
||||
}
|
||||
|
||||
var (
|
||||
typeInt32 = &ffi.Type{4, 4, ffi.Sint32, nil}
|
||||
typePointer = &ffi.Type{unsafe.Sizeof(0), uint16(unsafe.Alignof(0)), ffi.Pointer, nil}
|
||||
)
|
||||
|
||||
func main() {
|
||||
cdemo1()
|
||||
cdemo2()
|
||||
}
|
||||
|
||||
func cdemo1() {
|
||||
var cif ffi.Cif
|
||||
tarray := &ffi.Type{0, 0, ffi.Struct, &[]*ffi.Type{typeInt32, typeInt32, typeInt32, typeInt32, nil}[0]}
|
||||
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{tarray}[0])
|
||||
if status != ffi.OK {
|
||||
panic(status)
|
||||
}
|
||||
ar := array{1, 2, 3, 4}
|
||||
var ret int32
|
||||
ffi.Call(&cif, c.Func(demo1), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&ar)}[0])
|
||||
c.Printf(c.Str("ret: %d\n"), ret)
|
||||
}
|
||||
|
||||
func cdemo2() {
|
||||
var cif ffi.Cif
|
||||
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{typePointer}[0])
|
||||
if status != ffi.OK {
|
||||
panic(status)
|
||||
}
|
||||
var ret int32
|
||||
fn := c.Func(demo1)
|
||||
ffi.Call(&cif, c.Func(demo2), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&fn)}[0])
|
||||
c.Printf(c.Str("ret: %d\n"), ret)
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
"github.com/goplus/llgo/c/ffi"
|
||||
)
|
||||
|
||||
const (
|
||||
LLGoPackage = "link"
|
||||
LLGoFiles = "../_wrap/wrap.c"
|
||||
)
|
||||
|
||||
//llgo:type C
|
||||
type Callback func(array) c.Int
|
||||
|
||||
//go:linkname demo1 C.demo1
|
||||
func demo1(array) c.Int
|
||||
|
||||
//go:linkname demo2 C.demo2
|
||||
func demo2(fn Callback) c.Int
|
||||
|
||||
//llgo:type C
|
||||
type array struct {
|
||||
x c.Int
|
||||
y c.Int
|
||||
z c.Int
|
||||
k c.Int
|
||||
}
|
||||
|
||||
func demo(a array) c.Int {
|
||||
c.Printf(c.Str("go.demo %d %d %d %d\n"), a.x, a.y, a.z, a.k)
|
||||
return a.x + a.y + a.z + a.k
|
||||
}
|
||||
|
||||
var (
|
||||
typeInt32 = &ffi.Type{4, 4, ffi.Sint32, nil}
|
||||
typePointer = &ffi.Type{unsafe.Sizeof(0), uint16(unsafe.Alignof(0)), ffi.Pointer, nil}
|
||||
)
|
||||
|
||||
func main() {
|
||||
gofn()
|
||||
c.Printf(c.Str("\n"))
|
||||
goclosure()
|
||||
}
|
||||
|
||||
func gofn() {
|
||||
var cif ffi.Cif
|
||||
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{typePointer}[0])
|
||||
if status != ffi.OK {
|
||||
panic(status)
|
||||
}
|
||||
var fncode unsafe.Pointer
|
||||
closure := ffi.ClosureAlloc(&fncode)
|
||||
defer ffi.ClosureFree(closure)
|
||||
status = ffi.PreClosureLoc(closure, &cif, func(cif *ffi.Cif, ret unsafe.Pointer, args *unsafe.Pointer, userdata unsafe.Pointer) {
|
||||
ar := *(*array)(ffi.Index(args, 0))
|
||||
*(*c.Int)(ret) = demo(ar)
|
||||
}, nil, fncode)
|
||||
if status != ffi.OK {
|
||||
panic(status)
|
||||
}
|
||||
var ret int32
|
||||
ffi.Call(&cif, c.Func(demo2), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&fncode)}[0])
|
||||
c.Printf(c.Str("ret: %d\n"), ret)
|
||||
}
|
||||
|
||||
func goclosure() {
|
||||
var cif ffi.Cif
|
||||
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{typePointer}[0])
|
||||
if status != ffi.OK {
|
||||
panic(status)
|
||||
}
|
||||
fn := func(ar array) c.Int {
|
||||
c.Printf(c.Str("call closure %d\n"), cif.NArgs)
|
||||
return demo(ar)
|
||||
}
|
||||
var fncode unsafe.Pointer
|
||||
closure := ffi.ClosureAlloc(&fncode)
|
||||
defer ffi.ClosureFree(closure)
|
||||
status = ffi.PreClosureLoc(closure, &cif, func(cif *ffi.Cif, ret unsafe.Pointer, args *unsafe.Pointer, userdata unsafe.Pointer) {
|
||||
ar := *(*array)(ffi.Index(args, 0))
|
||||
fn := *(*func(array) c.Int)(userdata)
|
||||
*(*c.Int)(ret) = fn(ar)
|
||||
}, unsafe.Pointer(&fn), fncode)
|
||||
if status != ffi.OK {
|
||||
panic(status)
|
||||
}
|
||||
var ret int32
|
||||
ffi.Call(&cif, c.Func(demo2), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&fncode)}[0])
|
||||
c.Printf(c.Str("ret: %d\n"), ret)
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
"github.com/goplus/llgo/c/ffi"
|
||||
)
|
||||
|
||||
var (
|
||||
typeInt32 = &ffi.Type{4, 4, ffi.Sint32, nil}
|
||||
typePointer = &ffi.Type{unsafe.Sizeof(0), uint16(unsafe.Alignof(0)), ffi.Pointer, nil}
|
||||
)
|
||||
|
||||
func main() {
|
||||
var cif ffi.Cif
|
||||
status := ffi.PrepCifVar(&cif, ffi.DefaultAbi, 1, 2, typeInt32, &[]*ffi.Type{typePointer, typeInt32}[0])
|
||||
if status != ffi.OK {
|
||||
panic(status)
|
||||
}
|
||||
var ret int32
|
||||
text := c.Str("hello world: %d\n")
|
||||
var n int32 = 100
|
||||
ffi.Call(&cif, c.Func(c.Printf), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&text), unsafe.Pointer(&n)}[0])
|
||||
c.Printf(c.Str("ret: %d\n"), ret)
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
#include <ffi.h>
|
||||
|
||||
void *llog_ffi_closure_alloc(void **code) {
|
||||
return ffi_closure_alloc(sizeof(ffi_closure), code);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
//go:build ((freebsd || linux || darwin) && arm64) || (windows && (amd64 || arm64))
|
||||
|
||||
package ffi
|
||||
|
||||
const (
|
||||
DefaultAbi = 1
|
||||
)
|
||||
@@ -1,7 +0,0 @@
|
||||
//go:build freebsd || linux || darwin
|
||||
|
||||
package ffi
|
||||
|
||||
const (
|
||||
DefaultAbi = 2
|
||||
)
|
||||
132
c/ffi/ffi.go
132
c/ffi/ffi.go
@@ -1,132 +0,0 @@
|
||||
package ffi
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
)
|
||||
|
||||
const (
|
||||
LLGoPackage = "link: $(pkg-config --libs libffi); -lffi"
|
||||
LLGoFiles = "$(pkg-config --cflags libffi): _wrap/libffi.c"
|
||||
)
|
||||
|
||||
const (
|
||||
Void = iota
|
||||
Int
|
||||
Float
|
||||
Double
|
||||
LongDouble
|
||||
Uint8
|
||||
Sint8
|
||||
Uint16
|
||||
Sint16
|
||||
Uint32
|
||||
Sint32
|
||||
Uint64
|
||||
Sint64
|
||||
Struct
|
||||
Pointer
|
||||
Complex
|
||||
)
|
||||
|
||||
const (
|
||||
OK = iota
|
||||
BAD_TYPEDEF
|
||||
BAD_ABI
|
||||
BAD_ARGTYPE
|
||||
)
|
||||
|
||||
type Type struct {
|
||||
Size uintptr
|
||||
Alignment uint16
|
||||
Type uint16
|
||||
Elements **Type
|
||||
}
|
||||
|
||||
/*typedef struct {
|
||||
ffi_abi abi;
|
||||
unsigned nargs;
|
||||
ffi_type **arg_types;
|
||||
ffi_type *rtype;
|
||||
unsigned bytes;
|
||||
unsigned flags;
|
||||
#ifdef FFI_EXTRA_CIF_FIELDS
|
||||
FFI_EXTRA_CIF_FIELDS;
|
||||
#endif
|
||||
} ffi_cif;
|
||||
*/
|
||||
|
||||
type Cif struct {
|
||||
Abi c.Uint
|
||||
NArgs c.Uint
|
||||
ArgTypes **Type
|
||||
RType *Type
|
||||
Bytes c.Uint
|
||||
Flags c.Uint
|
||||
//Extra c.Uint
|
||||
}
|
||||
|
||||
/*
|
||||
ffi_status
|
||||
ffi_prep_cif(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
*/
|
||||
//go:linkname PrepCif C.ffi_prep_cif
|
||||
func PrepCif(cif *Cif, abi c.Uint, nargs c.Uint, rtype *Type, atype **Type) c.Uint
|
||||
|
||||
/*
|
||||
ffi_status ffi_prep_cif_var(ffi_cif *cif,
|
||||
ffi_abi abi,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
*/
|
||||
//go:linkname PrepCifVar C.ffi_prep_cif_var
|
||||
func PrepCifVar(cif *Cif, abi c.Uint, nfixedargs c.Uint, ntotalargs c.Uint, rtype *Type, atype **Type) c.Uint
|
||||
|
||||
/*
|
||||
void ffi_call(ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
void **avalue);
|
||||
*/
|
||||
//go:linkname Call C.ffi_call
|
||||
func Call(cif *Cif, fn unsafe.Pointer, rvalue unsafe.Pointer, avalue *unsafe.Pointer)
|
||||
|
||||
// void *ffi_closure_alloc (size_t size, void **code);
|
||||
//
|
||||
//go:linkname ClosureAlloc C.llog_ffi_closure_alloc
|
||||
func ClosureAlloc(code *unsafe.Pointer) unsafe.Pointer
|
||||
|
||||
// void ffi_closure_free (void *);
|
||||
//
|
||||
//go:linkname ClosureFree C.ffi_closure_free
|
||||
func ClosureFree(unsafe.Pointer)
|
||||
|
||||
/*
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure*,
|
||||
ffi_cif *,
|
||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
*/
|
||||
|
||||
//llgo:type C
|
||||
type ClosureFunc func(cif *Cif, ret unsafe.Pointer, args *unsafe.Pointer, userdata unsafe.Pointer)
|
||||
|
||||
//go:linkname PreClosureLoc C.ffi_prep_closure_loc
|
||||
func PreClosureLoc(closure unsafe.Pointer, cif *Cif, fn ClosureFunc, userdata unsafe.Pointer, codeloc unsafe.Pointer) c.Uint
|
||||
|
||||
func add(ptr unsafe.Pointer, offset uintptr) unsafe.Pointer {
|
||||
return unsafe.Pointer(uintptr(ptr) + offset)
|
||||
}
|
||||
|
||||
func Index(args *unsafe.Pointer, i uintptr) unsafe.Pointer {
|
||||
return (*(*unsafe.Pointer)(add(unsafe.Pointer(args), i*unsafe.Sizeof(0))))
|
||||
}
|
||||
@@ -213,16 +213,6 @@ func LoopNew() *Loop {
|
||||
return nil
|
||||
}
|
||||
|
||||
// llgo:link (*Loop).SetData C.uv_loop_set_data
|
||||
func (loop *Loop) SetData(data c.Pointer) {
|
||||
return
|
||||
}
|
||||
|
||||
// llgo:link (*Loop).GetData C.uv_loop_get_data
|
||||
func (loop *Loop) GetData() c.Pointer {
|
||||
return nil
|
||||
}
|
||||
|
||||
// llgo:link (*Loop).Now C.uv_now
|
||||
func (loop *Loop) Now() c.UlongLong {
|
||||
return 0
|
||||
|
||||
@@ -265,11 +265,6 @@ func (req *Req) GetType() ReqType {
|
||||
return 0
|
||||
}
|
||||
|
||||
// llgo:link (*Req).Cancel C.uv_cancel
|
||||
func (req *Req) Cancel() c.Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// ----------------------------------------------
|
||||
|
||||
/* Stream related function and method */
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
package libuv
|
||||
|
||||
import (
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
)
|
||||
|
||||
type Thread struct {
|
||||
Unused [8]byte
|
||||
}
|
||||
|
||||
type ThreadOptions struct {
|
||||
flags c.Uint
|
||||
stackSize uintptr
|
||||
}
|
||||
|
||||
type Work struct {
|
||||
Unused [128]byte
|
||||
}
|
||||
|
||||
// ----------------------------------------------
|
||||
|
||||
/* Function type */
|
||||
|
||||
// llgo:type C
|
||||
type ThreadCb func(arg c.Pointer)
|
||||
|
||||
//llgo:type C
|
||||
type WorkCb func(req *Work)
|
||||
|
||||
//llgo:type C
|
||||
type AfterWorkCb func(req *Work, status c.Int)
|
||||
|
||||
// ----------------------------------------------
|
||||
|
||||
/* Thread related functions and method. */
|
||||
|
||||
//go:linkname ThreadEqual C.uv_thread_equal
|
||||
func ThreadEqual(t1 *Thread, t2 *Thread) c.Int
|
||||
|
||||
//go:linkname ThreadGetCPU C.uv_thread_getcpu
|
||||
func ThreadGetCPU() c.Int
|
||||
|
||||
//go:linkname ThreadSelf C.uv_thread_self
|
||||
func ThreadSelf() Thread
|
||||
|
||||
// llgo:link (*Thread).Create C.uv_thread_create
|
||||
func (t *Thread) Create(entry ThreadCb, arg c.Pointer) c.Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// llgo:link (*Thread).CreateEx C.uv_thread_create_ex
|
||||
func (t *Thread) CreateEx(entry ThreadCb, params *ThreadOptions, arg c.Pointer) c.Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// llgo:link (*Thread).Join C.uv_thread_join
|
||||
func (t *Thread) Join() c.Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// llgo:link (*Thread).SetAffinity C.uv_thread_set_affinity
|
||||
func (t *Thread) SetAffinity(cpuMask *c.Char, oldMask *c.Char, maskSize uintptr) c.Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// llgo:link (*Thread).GetAffinity C.uv_thread_get_affinity
|
||||
func (t *Thread) GetAffinity(cpuMask *c.Char, maskSize uintptr) c.Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// ----------------------------------------------
|
||||
|
||||
/* Work related functions and method. */
|
||||
|
||||
//go:linkname QueueWork C.uv_queue_work
|
||||
func QueueWork(loop *Loop, req *Work, workCb WorkCb, afterWorkCb AfterWorkCb) c.Int
|
||||
19
c/llcppg.pub
19
c/llcppg.pub
@@ -1,19 +0,0 @@
|
||||
FILE
|
||||
size_t SizeT
|
||||
ssize_t SsizeT
|
||||
intptr_t IntptrT
|
||||
uintptr_t UintptrT
|
||||
int8_t Int8T
|
||||
int16_t Int16T
|
||||
int32_t Int32T
|
||||
int64_t Int64T
|
||||
uint8_t Uint8T
|
||||
uint16_t Uint16T
|
||||
uint32_t Uint32T
|
||||
uint64_t Uint64T
|
||||
intmax_t IntmaxT
|
||||
uintmax_t UintmaxT
|
||||
va_list VaList
|
||||
iconv_t IconvT
|
||||
locale_t LocaleT
|
||||
option Option
|
||||
@@ -13,7 +13,7 @@ func coroutineFunc(L *lua.State) c.Int {
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
@@ -18,7 +18,7 @@ func coroutineFunc(L *lua.State) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
@@ -29,7 +29,7 @@ func createCountdown(L *lua.State) c.Int {
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
L.Openlibs()
|
||||
defer L.Close()
|
||||
L.Register(c.Str("create_countdown"), createCountdown)
|
||||
|
||||
@@ -24,7 +24,7 @@ func customPanic(L *lua.State) c.Int {
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
"github.com/goplus/llgo/c/lua"
|
||||
)
|
||||
|
||||
func Hook(L *lua.State, ar *lua.Debug) {
|
||||
L.Getinfo(c.Str("nSl"), ar)
|
||||
c.Printf(c.Str("Hook called:"))
|
||||
if name := ar.Name; name != nil {
|
||||
c.Printf(c.Str("name: %s,"), name)
|
||||
}
|
||||
if what := ar.What; what != nil {
|
||||
c.Printf(c.Str("what: %s,"), what)
|
||||
}
|
||||
c.Printf(c.Str("source: %s,"), c.Pointer(unsafe.SliceData(ar.ShortSrc[:])))
|
||||
c.Printf(c.Str("line: %d\n"), ar.Currentline)
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
defer L.Close()
|
||||
L.Openlibs()
|
||||
|
||||
L.Sethook(Hook, lua.MASKLINE, 0)
|
||||
|
||||
code :=
|
||||
`function hello(name)
|
||||
print('Hello, ' .. name .. '!')
|
||||
end
|
||||
hello('llgo')`
|
||||
if res := L.Dostring(c.Str(code)); res != lua.OK {
|
||||
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Expected output:
|
||||
Hook called:what: main,source: [string "function hello(name) ..."],line: 3
|
||||
Hook called:what: main,source: [string "function hello(name) ..."],line: 1
|
||||
Hook called:what: main,source: [string "function hello(name) ..."],line: 4
|
||||
Hook called:name: hello,what: Lua,source: [string "function hello(name) ..."],line: 2
|
||||
Hello, llgo!
|
||||
Hook called:name: hello,what: Lua,source: [string "function hello(name) ..."],line: 3
|
||||
*/
|
||||
@@ -33,7 +33,7 @@ func reader(L *lua.State, data c.Pointer, size *c.Ulong) *c.Char {
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
L.Openlibs()
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ func writer(L *lua.State, p c.Pointer, sz c.Ulong, ud c.Pointer) c.Int {
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
L.Openlibs()
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
L.Openlibs()
|
||||
if res := L.Loadstring(c.Str("function doubleNumber(x) ! return x * 2 end")); res != lua.OK {
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
"github.com/goplus/llgo/c/lua"
|
||||
)
|
||||
|
||||
func GetData(L *lua.State) c.Int {
|
||||
extra := (*int)(L.Getextraspace())
|
||||
L.Pushfstring(c.Str("Stored integer is: %d"), *extra)
|
||||
return 1
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
extra := (*int)(L.Getextraspace())
|
||||
*extra = 42
|
||||
|
||||
difference := uintptr(unsafe.Pointer(L)) - uintptr(L.Getextraspace())
|
||||
if difference == unsafe.Sizeof(uintptr(0)) {
|
||||
c.Printf(c.Str("Extra space is pointer size\n"), unsafe.Sizeof(uintptr(0)))
|
||||
}
|
||||
|
||||
L.Pushcfunction(GetData)
|
||||
L.Setglobal(c.Str("GetData"))
|
||||
|
||||
if L.Dostring(c.Str("print(GetData())")) != lua.OK {
|
||||
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
||||
}
|
||||
}
|
||||
|
||||
/* Expected output:
|
||||
Extra space is pointer size
|
||||
Stored integer is: 42
|
||||
*/
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
L.Openlibs()
|
||||
if res := L.Dostring(c.Str("print('hello world')")); res != lua.OK {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
@@ -29,7 +29,7 @@ func printStack(L *lua.State, message string) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
@@ -17,7 +17,7 @@ func printStack(L *lua.State, stateName *c.Char) {
|
||||
|
||||
func main() {
|
||||
// Create a new Lua state and open libraries
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
L.Openlibs()
|
||||
|
||||
@@ -68,7 +68,7 @@ func main() {
|
||||
printStack(L, c.Str("L1"))
|
||||
|
||||
// Create a second Lua state
|
||||
L1 := lua.Newstate__1()
|
||||
L1 := lua.Newstate()
|
||||
defer L1.Close()
|
||||
|
||||
// Move two elements to the new state
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/goplus/llgo/c"
|
||||
"github.com/goplus/llgo/c/lua"
|
||||
)
|
||||
|
||||
func alloc(ud c.Pointer, ptr c.Pointer, osize c.Ulong, nsize c.Ulong) c.Pointer {
|
||||
if nsize == 0 {
|
||||
c.Free(ptr)
|
||||
return nil
|
||||
} else {
|
||||
return c.Realloc(ptr, uintptr(nsize))
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__0(alloc, nil)
|
||||
defer L.Close()
|
||||
L.Openlibs()
|
||||
if res := L.Dostring(c.Str("print('new state success')")); res != lua.OK {
|
||||
println("newstate error")
|
||||
}
|
||||
|
||||
allocf := L.Getallocf(nil)
|
||||
L.Setallocf(allocf, nil)
|
||||
|
||||
if res := L.Dostring(c.Str("print('set newstate success')")); res != lua.OK {
|
||||
println("set newstate error")
|
||||
}
|
||||
}
|
||||
|
||||
/* Expected output:
|
||||
new state success
|
||||
set newstate success
|
||||
*/
|
||||
@@ -1,8 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/c"
|
||||
"github.com/goplus/llgo/c/lua"
|
||||
)
|
||||
@@ -10,91 +8,53 @@ import (
|
||||
func printTable(L *lua.State) {
|
||||
L.Pushnil()
|
||||
for L.Next(-2) != 0 {
|
||||
key := L.Tostring(-2)
|
||||
value := L.Tostring(-1)
|
||||
switch L.Type(-2) {
|
||||
case lua.STRING:
|
||||
key := L.Tostring(-2)
|
||||
c.Printf(c.Str("%s - %s\n"), key, value)
|
||||
case lua.NUMBER:
|
||||
key := L.Tonumber(-2)
|
||||
c.Printf(c.Str("[%.0f] - %s\n"), key, value)
|
||||
case lua.LIGHTUSERDATA:
|
||||
c.Printf(c.Str("[pointer] - %s\n"), value)
|
||||
default:
|
||||
c.Printf(c.Str("unknown key type %s %d\n"), L.Typename(-2), L.Type(-2))
|
||||
}
|
||||
c.Printf(c.Str("%s - %s\n"), key, value)
|
||||
L.Pop(1)
|
||||
}
|
||||
L.Pop(1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
L.Newtable()
|
||||
|
||||
// set table name:John
|
||||
L.Pushstring(c.Str("name"))
|
||||
L.Pushstring(c.Str("John"))
|
||||
L.Settable(-3)
|
||||
|
||||
// set table age:30
|
||||
L.Pushstring(c.Str("age"))
|
||||
L.Pushnumber(30)
|
||||
L.Settable(-3)
|
||||
|
||||
// set table field fullname:John Doe
|
||||
L.Pushstring(c.Str("John Doe"))
|
||||
L.Setfield(-2, c.Str("fullname"))
|
||||
|
||||
// set index field
|
||||
L.Pushinteger(123)
|
||||
L.Seti(-2, c.Int(1))
|
||||
|
||||
// set pointer key field
|
||||
pointerKey := c.AllocaCStr("pointer key")
|
||||
L.Pushstring(c.Str("pointer value"))
|
||||
L.Rawsetp(-2, unsafe.Pointer(pointerKey))
|
||||
|
||||
// get field by Getfield
|
||||
L.Getfield(-1, c.Str("name"))
|
||||
c.Printf(c.Str("name: %s\n"), L.Tostring(-1))
|
||||
c.Printf(c.Str("%s\n"), L.Tostring(-1))
|
||||
L.Pop(1)
|
||||
|
||||
// get field by Rawget
|
||||
L.Pushstring(c.Str("fullname"))
|
||||
L.Rawget(-2)
|
||||
c.Printf(c.Str("fullname: %s\n"), L.Tostring(-1))
|
||||
L.Pop(1)
|
||||
|
||||
// get field by Gettable
|
||||
L.Pushstring(c.Str("age"))
|
||||
L.Gettable(-2)
|
||||
age := int(L.Tonumber(-1))
|
||||
c.Printf(c.Str("Age: %d\n"), age)
|
||||
L.Pop(1)
|
||||
|
||||
// get index field
|
||||
L.Geti(-1, c.Int(1))
|
||||
c.Printf(c.Str("Index[%d] value: %d\n"), 1, L.Tointeger(-1))
|
||||
L.Pop(1)
|
||||
|
||||
c.Printf(c.Str("All entries in the table:\n"))
|
||||
printTable(L)
|
||||
|
||||
}
|
||||
|
||||
/* Expected output:
|
||||
name: John
|
||||
fullname: John Doe
|
||||
John
|
||||
Age: 30
|
||||
Index[1] value: 123
|
||||
All entries in the table:
|
||||
[1] - 123
|
||||
name - John
|
||||
[pointer] - pointer value
|
||||
fullname - John Doe
|
||||
age - 30.0
|
||||
fullname - John Doe
|
||||
name - John
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,7 @@ func pushThread(state *lua.State, name string) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
|
||||
L.Openlibs()
|
||||
|
||||
@@ -12,7 +12,7 @@ type lightdata struct {
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate__1()
|
||||
L := lua.Newstate()
|
||||
defer L.Close()
|
||||
L.Openlibs()
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ func (L *State) Loadfile(filename *c.Char) c.Int { return L.Loadfilex(filename,
|
||||
// llgo:link (*State).Loadstring C.luaL_loadstring
|
||||
func (L *State) Loadstring(s *c.Char) c.Int { return 0 }
|
||||
|
||||
//go:linkname Newstate__1 C.luaL_newstate
|
||||
func Newstate__1() *State
|
||||
//go:linkname Newstate C.luaL_newstate
|
||||
func Newstate() *State
|
||||
|
||||
// /*
|
||||
// ** ===============================================================
|
||||
|
||||
399
c/lua/lua.go
399
c/lua/lua.go
@@ -10,18 +10,18 @@ const (
|
||||
LLGoPackage = "link: $(pkg-config --libs lua); -llua -lm"
|
||||
)
|
||||
|
||||
/* mark for precompiled code ('<esc>Lua') */
|
||||
// /* mark for precompiled code ('<esc>Lua') */
|
||||
|
||||
/* option for multiple returns in 'lua_pcall' and 'lua_call' */
|
||||
// /* option for multiple returns in 'lua_pcall' and 'lua_call' */
|
||||
const (
|
||||
MULTRET = -1
|
||||
)
|
||||
|
||||
/*
|
||||
* Pseudo-indices
|
||||
* (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
|
||||
* space after that to help overflow detection)
|
||||
*/
|
||||
// /*
|
||||
// ** Pseudo-indices
|
||||
// ** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
|
||||
// ** space after that to help overflow detection)
|
||||
// */
|
||||
|
||||
const (
|
||||
REGISTRYINDEX = -MAXSTACK - 1000
|
||||
@@ -31,7 +31,7 @@ func Upvalueindex(i c.Int) c.Int {
|
||||
return c.Int(REGISTRYINDEX) - i
|
||||
}
|
||||
|
||||
/* thread status */
|
||||
// /* thread status */
|
||||
const (
|
||||
OK = 0
|
||||
YIELD = 1
|
||||
@@ -45,9 +45,9 @@ type State struct {
|
||||
Unused [8]byte
|
||||
}
|
||||
|
||||
/*
|
||||
* basic types
|
||||
*/
|
||||
// /*
|
||||
// ** basic types
|
||||
// */
|
||||
const (
|
||||
NONE c.Int = -1
|
||||
NIL c.Int = 0
|
||||
@@ -59,50 +59,50 @@ const (
|
||||
FUNCTION c.Int = 6
|
||||
USERDATA c.Int = 7
|
||||
THREAD c.Int = 8
|
||||
NUMTYPES c.Int = 9
|
||||
UMTYPES c.Int = 9
|
||||
)
|
||||
|
||||
/* minimum Lua stack available to a C function */
|
||||
// /* minimum Lua stack available to a C function */
|
||||
const (
|
||||
MINSTACK = 20
|
||||
)
|
||||
|
||||
/* predefined values in the registry */
|
||||
// /* predefined values in the registry */
|
||||
const (
|
||||
RIDX_MAINTHREAD = 1
|
||||
RIDX_GLOBALS = 2
|
||||
RIDX_LAST = RIDX_GLOBALS
|
||||
)
|
||||
|
||||
/* type of numbers in Lua */
|
||||
// /* type of numbers in Lua */
|
||||
type Number = c.Double
|
||||
|
||||
/* type for integer functions */
|
||||
// /* type for integer functions */
|
||||
type Integer = c.Int
|
||||
|
||||
/* unsigned integer type */
|
||||
// /* unsigned integer type */
|
||||
type Unsigned = c.Uint
|
||||
|
||||
/* type for continuation-function contexts */
|
||||
// /* type for continuation-function contexts */
|
||||
type KContext = c.Pointer
|
||||
|
||||
/*
|
||||
* Type for C functions registered with Lua
|
||||
*/
|
||||
// /*
|
||||
// ** Type for C functions registered with Lua
|
||||
// */
|
||||
|
||||
// llgo:type C
|
||||
type CFunction func(L *State) c.Int
|
||||
|
||||
/*
|
||||
* Type for continuation functions
|
||||
*/
|
||||
// /*
|
||||
// ** Type for continuation functions
|
||||
// */
|
||||
|
||||
// llgo:type C
|
||||
type KFunction func(L *State, status c.Int, ctx KContext) c.Int
|
||||
|
||||
/*
|
||||
* Type for functions that read/write blocks when loading/dumping Lua chunks
|
||||
*/
|
||||
// /*
|
||||
// ** Type for functions that read/write blocks when loading/dumping Lua chunks
|
||||
// */
|
||||
|
||||
// llgo:type C
|
||||
type Reader func(L *State, ud c.Pointer, sz *c.Ulong) *c.Char
|
||||
@@ -110,42 +110,51 @@ type Reader func(L *State, ud c.Pointer, sz *c.Ulong) *c.Char
|
||||
// llgo:type C
|
||||
type Writer func(L *State, p c.Pointer, sz c.Ulong, ud c.Pointer) c.Int
|
||||
|
||||
/*
|
||||
* Type for memory-allocation functions
|
||||
*/
|
||||
// /*
|
||||
// ** Type for memory-allocation functions
|
||||
// */
|
||||
|
||||
// llgo:type C
|
||||
type Alloc func(ud c.Pointer, ptr c.Pointer, osize c.Ulong, nsize c.Ulong) c.Pointer
|
||||
// typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||
|
||||
/*
|
||||
* Type for warning functions
|
||||
*/
|
||||
// /*
|
||||
// ** Type for warning functions
|
||||
// */
|
||||
|
||||
// llgo:type C
|
||||
type WarnFunction func(ud c.Pointer, msg c.Char, tocont c.Int)
|
||||
// typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);
|
||||
|
||||
/*
|
||||
* Functions to be called by the debugger in specific events
|
||||
*/
|
||||
// /*
|
||||
// ** Type used by the debug API to collect debug information
|
||||
// */
|
||||
|
||||
// llgo:type C
|
||||
type Hook func(L *State, ar *Debug)
|
||||
// typedef struct lua_Debug lua_Debug;
|
||||
|
||||
/*
|
||||
* RCS ident string
|
||||
*/
|
||||
// /*
|
||||
// ** Functions to be called by the debugger in specific events
|
||||
// */
|
||||
|
||||
// typedef void (*lua_Hook) (State *L, lua_Debug *ar);
|
||||
|
||||
// /*
|
||||
// ** generic extra include file
|
||||
// */
|
||||
|
||||
// #if defined(LUA_USER_H)
|
||||
// #include LUA_USER_H
|
||||
// #endif
|
||||
|
||||
// /*
|
||||
// ** RCS ident string
|
||||
// */
|
||||
|
||||
// extern const char lua_ident[];
|
||||
|
||||
/*
|
||||
** state manipulation
|
||||
*/
|
||||
|
||||
// /*
|
||||
// ** state manipulation
|
||||
// */
|
||||
// llgo:link (*State).Close C.lua_close
|
||||
func (L *State) Close() {}
|
||||
|
||||
// llgo:link Newstate__0 C.lua_newstate
|
||||
func Newstate__0(f Alloc, ud c.Pointer) *State { return nil }
|
||||
// State *(lua_newstate) (lua_Alloc f, void *ud);
|
||||
|
||||
// llgo:link (*State).Newthread C.lua_newthread
|
||||
func (L *State) Newthread() *State { return nil }
|
||||
@@ -162,9 +171,9 @@ func (L *State) Atpanic(panicf CFunction) CFunction { return nil }
|
||||
// llgo:link (*State).Version C.lua_version
|
||||
func (L *State) Version() Number { return 0 }
|
||||
|
||||
/*
|
||||
* basic stack manipulation
|
||||
*/
|
||||
// /*
|
||||
// ** basic stack manipulation
|
||||
// */
|
||||
|
||||
// llgo:link (*State).Absindex C.lua_absindex
|
||||
func (L *State) Absindex(idx c.Int) c.Int { return 0 }
|
||||
@@ -190,9 +199,9 @@ func (L *State) Checkstack(n c.Int) c.Int { return 0 }
|
||||
// llgo:link (*State).Xmove C.lua_xmove
|
||||
func (L *State) Xmove(to *State, n c.Int) {}
|
||||
|
||||
/*
|
||||
* access functions (stack -> C)
|
||||
*/
|
||||
// /*
|
||||
// ** access functions (stack -> C)
|
||||
// */
|
||||
|
||||
// llgo:link (*State).Isnumber C.lua_isnumber
|
||||
func (L *State) Isnumber(idx c.Int) c.Int { return 0 }
|
||||
@@ -238,17 +247,15 @@ func (L *State) Touserdata(idx c.Int) c.Pointer { return nil }
|
||||
// llgo:link (*State).Tothread C.lua_tothread
|
||||
func (L *State) Tothread(idx c.Int) *State { return nil }
|
||||
|
||||
// llgo:link (*State).Topointer C.lua_topointer
|
||||
func (L *State) Topointer(idx c.Int) c.Pointer { return nil }
|
||||
// LUA_API const void *(lua_topointer) (State *L, int idx);
|
||||
|
||||
/*
|
||||
* Comparison and arithmetic functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* push functions (C -> stack)
|
||||
*/
|
||||
// /*
|
||||
// ** Comparison and arithmetic functions
|
||||
// */
|
||||
|
||||
// /*
|
||||
// ** push functions (C -> stack)
|
||||
// */
|
||||
// llgo:link (*State).Pushnil C.lua_pushnil
|
||||
func (L *State) Pushnil() {}
|
||||
|
||||
@@ -279,9 +286,9 @@ func (L *State) Pushlightuserdata(p c.Pointer) {}
|
||||
// llgo:link (*State).Pushthread C.lua_pushthread
|
||||
func (L *State) Pushthread() c.Int { return 0 }
|
||||
|
||||
/*
|
||||
* get functions (Lua -> stack)
|
||||
*/
|
||||
// /*
|
||||
// ** get functions (Lua -> stack)
|
||||
// */
|
||||
|
||||
// llgo:link (*State).Getglobal C.lua_getglobal
|
||||
func (L *State) Getglobal(name *c.Char) c.Int { return 0 }
|
||||
@@ -292,17 +299,10 @@ func (L *State) Gettable(idx c.Int) c.Int { return 0 }
|
||||
// llgo:link (*State).Getfield C.lua_getfield
|
||||
func (L *State) Getfield(idx c.Int, k *c.Char) c.Int { return 0 }
|
||||
|
||||
// llgo:link (*State).Geti C.lua_geti
|
||||
func (L *State) Geti(idx c.Int, n Integer) c.Int { return 0 }
|
||||
|
||||
// llgo:link (*State).Rawget C.lua_rawget
|
||||
func (L *State) Rawget(idx c.Int) c.Int { return 0 }
|
||||
|
||||
// llgo:link (*State).Rawgeti C.lua_rawgeti
|
||||
func (L *State) Rawgeti(idx c.Int, n Integer) c.Int { return 0 }
|
||||
|
||||
// llgo:link (*State).Rawgetp C.lua_rawgetp
|
||||
func (L *State) Rawgetp(idx c.Int, p c.Pointer) c.Int { return 0 }
|
||||
// LUA_API int (lua_geti) (State *L, int idx, lua_Integer n);
|
||||
// LUA_API int (lua_rawget) (State *L, int idx);
|
||||
// LUA_API int (lua_rawgeti) (State *L, int idx, lua_Integer n);
|
||||
// LUA_API int (lua_rawgetp) (State *L, int idx, const void *p);
|
||||
|
||||
// llgo:link (*State).Createtable C.lua_createtable
|
||||
func (L *State) Createtable(narr c.Int, nrec c.Int) {}
|
||||
@@ -313,12 +313,11 @@ func (L *State) Newuserdatauv(sz uintptr, nuvalue c.Int) c.Pointer { return nil
|
||||
// llgo:link (*State).Getmetatable C.lua_getmetatable
|
||||
func (L *State) Getmetatable(objindex c.Int) c.Int { return 0 }
|
||||
|
||||
// llgo:link (*State).Getiuservalue C.lua_getiuservalue
|
||||
func (L *State) Getiuservalue(idx c.Int, n c.Int) c.Int { return 0 }
|
||||
// LUA_API int (lua_getiuservalue) (State *L, int idx, int n);
|
||||
|
||||
/*
|
||||
* set functions (stack -> Lua)
|
||||
*/
|
||||
// /*
|
||||
// ** set functions (stack -> Lua)
|
||||
// */
|
||||
|
||||
// llgo:link (*State).Setglobal C.lua_setglobal
|
||||
func (L *State) Setglobal(name *c.Char) {}
|
||||
@@ -329,27 +328,19 @@ func (L *State) Settable(idx c.Int) {}
|
||||
// llgo:link (*State).Setfield C.lua_setfield
|
||||
func (L *State) Setfield(idx c.Int, k *c.Char) {}
|
||||
|
||||
// llgo:link (*State).Seti C.lua_seti
|
||||
func (L *State) Seti(idx c.Int, n Integer) {}
|
||||
|
||||
// llgo:link (*State).Rawset C.lua_rawset
|
||||
func (L *State) Rawset(idx c.Int) {}
|
||||
|
||||
// llgo:link (*State).Rawseti C.lua_rawseti
|
||||
func (L *State) Rawseti(idx c.Int, n Integer) {}
|
||||
|
||||
// llgo:link (*State).Rawsetp C.lua_rawsetp
|
||||
func (L *State) Rawsetp(idx c.Int, p c.Pointer) {}
|
||||
//void (lua_seti) (State *L, int idx, lua_Integer n);
|
||||
//void (lua_rawset) (State *L, int idx);
|
||||
//void (lua_rawseti) (State *L, int idx, lua_Integer n);
|
||||
//void (lua_rawsetp) (State *L, int idx, const void *p);
|
||||
|
||||
// llgo:link (*State).Setmetatable C.lua_setmetatable
|
||||
func (L *State) Setmetatable(objindex c.Int) c.Int { return 0 }
|
||||
|
||||
// llgo:link (*State).Setiuservalue C.lua_setiuservalue
|
||||
func (L *State) Setiuservalue(idx c.Int, n c.Int) c.Int { return 0 }
|
||||
//int (lua_setiuservalue) (State *L, int idx, int n);
|
||||
|
||||
/*
|
||||
* 'load' and 'call' functions (load and run Lua code)
|
||||
*/
|
||||
// /*
|
||||
// ** 'load' and 'call' functions (load and run Lua code)
|
||||
// */
|
||||
|
||||
// llgo:link (*State).Callk C.lua_callk
|
||||
func (L *State) Callk(nargs c.Int, nresults c.Int, ctx KContext, k KFunction) c.Int {
|
||||
@@ -375,9 +366,9 @@ func (L *State) Load(reader Reader, dt c.Pointer, chunkname *c.Char, mode *c.Cha
|
||||
// llgo:link (*State).Dump C.lua_dump
|
||||
func (L *State) Dump(writer Writer, data c.Pointer, strip c.Int) c.Int { return 0 }
|
||||
|
||||
/*
|
||||
* coroutine functions
|
||||
*/
|
||||
// /*
|
||||
// ** coroutine functions
|
||||
// */
|
||||
|
||||
// llgo:link (*State).Resume C.lua_resume
|
||||
func (L *State) Resume(from *State, narg c.Int, nres *c.Int) c.Int { return 0 }
|
||||
@@ -392,19 +383,16 @@ func (L *State) Isyieldable() c.Int { return 0 }
|
||||
func (L *State) Yieldk(nresults c.Int, ctx KContext, k KFunction) c.Int { return 0 }
|
||||
func (L *State) Yield(nresults c.Int) c.Int { return L.Yieldk(nresults, nil, nil) }
|
||||
|
||||
/*
|
||||
* Warning-related functions
|
||||
*/
|
||||
// /*
|
||||
// ** Warning-related functions
|
||||
// */
|
||||
|
||||
// llgo:link (*State).Setwarnf C.lua_setwarnf
|
||||
func (L *State) Setwarnf(f WarnFunction, ud c.Pointer) {}
|
||||
//void (lua_setwarnf) (State *L, lua_WarnFunction f, void *ud);
|
||||
//void (lua_warning) (State *L, const char *msg, int tocont);
|
||||
|
||||
// llgo:link (*State).Warning C.lua_warning
|
||||
func (L *State) Warning(msg *c.Char, tocont c.Int) {}
|
||||
|
||||
/*
|
||||
* garbage-collection function and options
|
||||
*/
|
||||
// /*
|
||||
// ** garbage-collection function and options
|
||||
// */
|
||||
|
||||
const (
|
||||
GCSTOP = 0
|
||||
@@ -420,49 +408,36 @@ const (
|
||||
GCINC = 11
|
||||
)
|
||||
|
||||
// llgo:link (*State).Gc C.lua_gc
|
||||
func (L *State) Gc(what c.Int, __llgo_va_list ...any) c.Int { return 0 }
|
||||
|
||||
/*
|
||||
* miscellaneous functions
|
||||
*/
|
||||
// LUA_API int (lua_gc) (State *L, int what, ...);
|
||||
|
||||
// /*
|
||||
// ** miscellaneous functions
|
||||
// */
|
||||
// llgo:link (*State).Next C.lua_next
|
||||
func (L *State) Next(idx c.Int) c.Int { return 0 }
|
||||
|
||||
// llgo:link (*State).Error C.lua_error
|
||||
func (L *State) Error() c.Int { return 0 }
|
||||
|
||||
// llgo:link (*State).Concat C.lua_concat
|
||||
func (L *State) Concat(n c.Int) {}
|
||||
// LUA_API void (lua_concat) (State *L, int n);
|
||||
// LUA_API void (lua_len) (State *L, int idx);
|
||||
|
||||
// llgo:link (*State).Len C.lua_len
|
||||
func (L *State) Len(idx c.Int) {}
|
||||
// LUA_API size_t (lua_stringtonumber) (State *L, const char *s);
|
||||
|
||||
// llgo:link (*State).Stringtonumber C.lua_stringtonumber
|
||||
func (L *State) Stringtonumber(s *c.Char) c.Ulong { return 0 }
|
||||
// LUA_API lua_Alloc (lua_getallocf) (State *L, void **ud);
|
||||
// LUA_API void (lua_setallocf) (State *L, lua_Alloc f, void *ud);
|
||||
|
||||
// llgo:link (*State).Getallocf C.lua_getallocf
|
||||
func (L *State) Getallocf(ud *c.Pointer) Alloc { return nil }
|
||||
// LUA_API void (lua_toclose) (State *L, int idx);
|
||||
// LUA_API void (lua_closeslot) (State *L, int idx);
|
||||
|
||||
// llgo:link (*State).Setallocf C.lua_setallocf
|
||||
func (L *State) Setallocf(f Alloc, ud c.Pointer) Alloc { return nil }
|
||||
// /*
|
||||
// ** {==============================================================
|
||||
// ** some useful macros
|
||||
// ** ===============================================================
|
||||
// */
|
||||
|
||||
// llgo:link (*State).Toclose C.lua_toclose
|
||||
func (L *State) Toclose(idx c.Int) {}
|
||||
// #define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
|
||||
|
||||
// llgo:link (*State).Closeslot C.lua_closeslot
|
||||
func (L *State) Closeslot(idx c.Int) {}
|
||||
|
||||
/*
|
||||
** {==============================================================
|
||||
** some useful macros
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
func (L *State) Getextraspace() c.Pointer {
|
||||
return c.Pointer(uintptr(c.Pointer(L)) - EXTRASPACE)
|
||||
}
|
||||
func (L *State) Tonumber(idx c.Int) Number { return L.Tonumberx(idx, nil) }
|
||||
func (L *State) Tostring(idx c.Int) *c.Char { return L.Tolstring(idx, nil) }
|
||||
func (L *State) Tointeger(idx c.Int) Integer { return L.Tointegerx(idx, nil) }
|
||||
@@ -483,13 +458,9 @@ func (L *State) Isboolean(n c.Int) bool { return L.Type(n) == c.Int(BOOLEA
|
||||
func (L *State) Isthread(n c.Int) bool { return L.Type(n) == c.Int(THREAD) }
|
||||
func (L *State) Isnone(n c.Int) bool { return L.Type(n) == c.Int(NONE) }
|
||||
func (L *State) Isnoneornil(n c.Int) bool { return L.Type(n) <= 0 }
|
||||
func (L *State) Pushliteral(s *c.Char) *c.Char {
|
||||
return L.Pushstring(s)
|
||||
}
|
||||
|
||||
func (L *State) Pushglobaltable() c.Int {
|
||||
return L.Rawgeti(REGISTRYINDEX, RIDX_GLOBALS)
|
||||
}
|
||||
// #define lua_pushliteral(L, s) lua_pushstring(L, "" s)
|
||||
// #define lua_pushglobaltable(L) ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
|
||||
|
||||
func (L *State) Insert(idx c.Int) {
|
||||
L.Rotate(idx, 1)
|
||||
@@ -505,41 +476,33 @@ func (L *State) Replace(idx c.Int) {
|
||||
L.Pop(1)
|
||||
}
|
||||
|
||||
/* }============================================================== */
|
||||
// /* }============================================================== */
|
||||
|
||||
/*
|
||||
** {==============================================================
|
||||
** compatibility macros
|
||||
** ===============================================================
|
||||
*/
|
||||
// /*
|
||||
// ** {==============================================================
|
||||
// ** compatibility macros
|
||||
// ** ===============================================================
|
||||
// */
|
||||
|
||||
func (L *State) Newuserdata(sz uintptr) c.Pointer {
|
||||
return L.Newuserdatauv(sz, 1)
|
||||
}
|
||||
|
||||
func (L *State) Getuservalue(idx c.Int) c.Int {
|
||||
return L.Getiuservalue(idx, 1)
|
||||
}
|
||||
// #define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1)
|
||||
// #define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1)
|
||||
|
||||
func (L *State) Setuservalue(idx c.Int) c.Int {
|
||||
return L.Setiuservalue(idx, 1)
|
||||
}
|
||||
// #define LUA_NUMTAGS LUA_NUMTYPES
|
||||
|
||||
const (
|
||||
NUMTAGS = NUMTYPES
|
||||
)
|
||||
// /* }============================================================== */
|
||||
|
||||
/* }============================================================== */
|
||||
|
||||
/*
|
||||
** {======================================================================
|
||||
** Debug API
|
||||
** =======================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* Event codes
|
||||
*/
|
||||
// /*
|
||||
// ** {======================================================================
|
||||
// ** Debug API
|
||||
// ** =======================================================================
|
||||
// */
|
||||
// /*
|
||||
// ** Event codes
|
||||
// */
|
||||
|
||||
const (
|
||||
HOOKCALL = 0
|
||||
@@ -549,9 +512,9 @@ const (
|
||||
HOOKTAILCALL = 4
|
||||
)
|
||||
|
||||
/*
|
||||
* Event masks
|
||||
*/
|
||||
// /*
|
||||
// ** Event masks
|
||||
// */
|
||||
|
||||
const (
|
||||
MASKCALL = 1 << HOOKCOUNT
|
||||
@@ -560,68 +523,22 @@ const (
|
||||
MASKCOUNT = 1 << HOOKCOUNT
|
||||
)
|
||||
|
||||
// llgo:link (*State).Getstack C.lua_getstack
|
||||
func (L *State) Getstack(level c.Int, ar *Debug) c.Int { return 0 }
|
||||
// LUA_API int (lua_getstack) (State *L, int level, lua_Debug *ar);
|
||||
// LUA_API int (lua_getinfo) (State *L, const char *what, lua_Debug *ar);
|
||||
// LUA_API const char *(lua_getlocal) (State *L, const lua_Debug *ar, int n);
|
||||
// LUA_API const char *(lua_setlocal) (State *L, const lua_Debug *ar, int n);
|
||||
// LUA_API const char *(lua_getupvalue) (State *L, int funcindex, int n);
|
||||
// LUA_API const char *(lua_setupvalue) (State *L, int funcindex, int n);
|
||||
|
||||
// llgo:link (*State).Getinfo C.lua_getinfo
|
||||
func (L *State) Getinfo(what *c.Char, ar *Debug) c.Int { return 0 }
|
||||
// LUA_API void *(lua_upvalueid) (State *L, int fidx, int n);
|
||||
// LUA_API void (lua_upvaluejoin) (State *L, int fidx1, int n1, int fidx2, int n2);
|
||||
|
||||
// llgo:link (*State).Getlocal C.lua_getlocal
|
||||
func (L *State) Getlocal(ar *Debug, n c.Int) *c.Char { return nil }
|
||||
// LUA_API void (lua_sethook) (State *L, lua_Hook func, int mask, int count);
|
||||
// LUA_API lua_Hook (lua_gethook) (State *L);
|
||||
// LUA_API int (lua_gethookmask) (State *L);
|
||||
// LUA_API int (lua_gethookcount) (State *L);
|
||||
|
||||
// llgo:link (*State).Setlocal C.lua_setlocal
|
||||
func (L *State) Setlocal(ar *Debug, n c.Int) *c.Char { return nil }
|
||||
// LUA_API int (lua_setcstacklimit) (State *L, unsigned int limit);
|
||||
|
||||
// llgo:link (*State).Getupvalue C.lua_getupvalue
|
||||
func (L *State) Getupvalue(funcindex c.Int, n c.Int) *c.Char { return nil }
|
||||
|
||||
// llgo:link (*State).Setupvalue C.lua_setupvalue
|
||||
func (L *State) Setupvalue(funcindex c.Int, n c.Int) *c.Char { return nil }
|
||||
|
||||
// llgo:link (*State).Upvalueid C.lua_upvalueid
|
||||
func (L *State) Upvalueid(fidx c.Int, n c.Int) c.Pointer { return nil }
|
||||
|
||||
// llgo:link (*State).Upvaluejoin C.lua_upvaluejoin
|
||||
func (L *State) Upvaluejoin(fidx1 c.Int, n1 c.Int, fidx2 c.Int, n2 c.Int) {}
|
||||
|
||||
// llgo:link (*State).Sethook C.lua_sethook
|
||||
func (L *State) Sethook(fn Hook, mask c.Int, count c.Int) {}
|
||||
|
||||
// llgo:link (*State).Gethook C.lua_gethook
|
||||
func (L *State) Gethook() Hook { return nil }
|
||||
|
||||
// llgo:link (*State).Gethookmask C.lua_gethookmask
|
||||
func (L *State) Gethookmask() c.Int { return 0 }
|
||||
|
||||
// llgo:link (*State).Gethookcount C.lua_gethookcount
|
||||
func (L *State) Gethookcount() c.Int { return 0 }
|
||||
|
||||
// llgo:link (*State).Setcstacklimit C.lua_setcstacklimit
|
||||
func (L *State) Setcstacklimit(limit c.Uint) c.Int { return 0 }
|
||||
|
||||
type CallInfo struct {
|
||||
Unused [8]byte
|
||||
}
|
||||
|
||||
type Debug struct {
|
||||
Event c.Int
|
||||
Name *c.Char /* (n) */
|
||||
Namewhat *c.Char /* (n) 'global', 'local', 'field', 'method' */
|
||||
What *c.Char /* (S) 'Lua', 'C', 'main', 'tail' */
|
||||
Source *c.Char /* (S) */
|
||||
Srclen uintptr /* (S) */
|
||||
Currentline c.Int /* (l) */
|
||||
Linedefined c.Int /* (S) */
|
||||
Lastlinedefined c.Int /* (S) */
|
||||
Nups byte /* (u) number of upvalues */
|
||||
Nparams byte /* (u) number of parameters */
|
||||
Isvararg c.Char /* (u) */
|
||||
Istailcall c.Char /* (t) */
|
||||
Ftransfer uint16 /* (r) index of first value transferred */
|
||||
Ntransfer uint16 /* (r) number of transferred values */
|
||||
ShortSrc [IDSIZE]c.Char /* (S) */
|
||||
/* private part */
|
||||
ICi *CallInfo
|
||||
}
|
||||
|
||||
/* }====================================================================== */
|
||||
// struct lua_Debug
|
||||
// /* }====================================================================== */
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package lua
|
||||
|
||||
import "unsafe"
|
||||
|
||||
/*
|
||||
** {==================================================================
|
||||
** Macros that affect the API and must be stable (that is, must be the
|
||||
@@ -21,21 +19,3 @@ import "unsafe"
|
||||
const (
|
||||
MAXSTACK = 1000000
|
||||
)
|
||||
|
||||
/*
|
||||
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
|
||||
** a Lua state with very fast access.
|
||||
** CHANGE it if you need a different size.
|
||||
*/
|
||||
const (
|
||||
EXTRASPACE = unsafe.Sizeof(uintptr(0))
|
||||
)
|
||||
|
||||
/*
|
||||
@@ LUA_IDSIZE gives the maximum size for the description of the source
|
||||
** of a function in debug information.
|
||||
** CHANGE it if you want a different size.
|
||||
*/
|
||||
const (
|
||||
IDSIZE = 60
|
||||
)
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
sockaddr SockAddr
|
||||
hostent Hostent
|
||||
addrinfo AddrInfo
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
int llgoClearenv() {
|
||||
extern char **environ;
|
||||
@@ -8,5 +7,3 @@ int llgoClearenv() {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int llgoErrno() { return errno; }
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
mode_t ModeT
|
||||
uid_t UidT
|
||||
gid_t GidT
|
||||
off_t OffT
|
||||
dev_t DevT
|
||||
stat StatT
|
||||
pid_t PidT
|
||||
@@ -70,8 +70,8 @@ type (
|
||||
StatT = syscall.Stat_t
|
||||
)
|
||||
|
||||
//go:linkname Errno C.llgoErrno
|
||||
func Errno() c.Int
|
||||
//go:linkname Errno errno
|
||||
var Errno c.Int
|
||||
|
||||
//go:linkname Umask C.umask
|
||||
func Umask(cmask ModeT) ModeT
|
||||
|
||||
@@ -21,8 +21,7 @@ package os
|
||||
import "C"
|
||||
|
||||
const (
|
||||
LLGoFiles = "_os/os.c"
|
||||
LLGoPackage = "link"
|
||||
LLGoPackage = "decl"
|
||||
)
|
||||
|
||||
//go:linkname Clearenv C.clearenv
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
pthread_t Thread
|
||||
attr Attr
|
||||
pthread_key_t Key
|
||||
@@ -1,7 +0,0 @@
|
||||
pthread_once_t Once
|
||||
pthread_mutexattr_t MutexAttr
|
||||
pthread_mutex_t Mutex
|
||||
pthread_rwlockattr_t RWLockAttr
|
||||
pthread_rwlock_t RWLock
|
||||
pthread_condattr_t CondAttr
|
||||
pthread_cond_t Cond
|
||||
@@ -145,4 +145,4 @@ const (
|
||||
EXDEV
|
||||
EXFULL
|
||||
EWINDOWS
|
||||
)
|
||||
)
|
||||
@@ -1,5 +0,0 @@
|
||||
time_t TimeT
|
||||
tm Tm
|
||||
clock_t ClockT
|
||||
clockid_t ClockidT
|
||||
timespec Timespec
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user