Compare commits

..

794 Commits

Author SHA1 Message Date
xushiwei
8fc97794e8 Merge pull request #536 from xushiwei/x
doc How-to-migrate-a-C&C++-Library
2024-07-18 23:36:18 +08:00
xushiwei
df2ba37687 doc How-to-migrate-a-C&C++-Library 2024-07-18 23:35:39 +08:00
xushiwei
85b16b2a54 Merge pull request #532 from morpingsss/morpingsss/LLGO-Migration-for-C-C++-Third-Party-Libraries
docs(llgo/doc) : Add a document named "LLGO Migration for C/C++ Third-Party Libraries"
2024-07-18 23:24:24 +08:00
xushiwei
eeabc6b61a Merge pull request #534 from xushiwei/q
demo: osexec - todo
2024-07-18 23:01:27 +08:00
xushiwei
2b3dafed61 demo: osexec - todo 2024-07-18 23:00:57 +08:00
xushiwei
7232fc36ab Merge pull request #533 from xushiwei/q
library os: StartProcess/Wait/Sysctl/environ; syscall.Wait4; c/syscall: zerrors; c/os: Setrlimit/Getrlimit;
2024-07-18 22:52:39 +08:00
xushiwei
a8e1fd1054 library os: StartProcess/Wait 2024-07-18 22:27:00 +08:00
xushiwei
c248a50338 forkAndExecInChild 2024-07-18 20:50:49 +08:00
xushiwei
fa0ca23798 syscall: forkAndExecInChild 2024-07-18 20:09:07 +08:00
xushiwei
ed224cf912 os.Sysctl 2024-07-18 19:31:25 +08:00
xushiwei
b51df25371 c/os: Setrlimit/Getrlimit 2024-07-18 17:56:49 +08:00
xushiwei
db8cc8eb7b syscall.Wait4 2024-07-18 17:08:24 +08:00
morpingsss
a027e9fe14 fix(llgo/doc) : fix bug 2024-07-18 17:02:30 +08:00
morpingsss
b882ca809a fix(llgo/cpp/tinyxml) : fix -> 2024-07-18 16:27:49 +08:00
xushiwei
daf0a9dc9a syscall: forkExec - todo 2024-07-18 15:58:44 +08:00
xushiwei
f2dafa7544 c/syscall: zerrors 2024-07-18 15:45:54 +08:00
morpingsss
7fe22875a6 docs(llgo/doc) : Add a document :"LLGO Migration for C/C++ Third-Party Libraries". 2024-07-18 14:52:29 +08:00
xushiwei
3da3c8ecd8 library patch: syscall, os environ 2024-07-18 14:30:49 +08:00
xushiwei
1cf57508b0 Update go.yml 2024-07-18 07:25:02 +08:00
xushiwei
f8bacfcc67 Merge pull request #524 from visualfc/sizes
build: fix unsafe.Sizeof for llgo:type C
2024-07-18 06:58:33 +08:00
xushiwei
9daa77c1a4 Merge pull request #531 from xushiwei/q
c/neco; neco demo: gen
2024-07-18 00:59:13 +08:00
xushiwei
c4775dd313 c/neco; neco demo: gen 2024-07-18 00:54:31 +08:00
xushiwei
ae87cb031e Merge pull request #522 from aofei/build
build(macOS): change full library paths to @rpath
2024-07-18 00:16:28 +08:00
xushiwei
3c049f25ee Merge pull request #530 from xushiwei/q
mv flagdemo => _cmptest
2024-07-18 00:10:31 +08:00
xushiwei
85a90b62b7 mv flagdemo => _cmptest 2024-07-18 00:09:21 +08:00
xushiwei
10b0124951 Merge pull request #525 from kindy/neco
[wip] c/neco: init and demo
2024-07-18 00:04:24 +08:00
Kindy Lin
c0d7ff9543 neco: fix 2024-07-17 22:41:35 +08:00
Aofei Sheng
74012d4869 build(macOS): change full library paths to @rpath 2024-07-17 18:50:13 +08:00
visualfc
830c40440f build: fix unsafe.Sizeof for llgo:type C 2024-07-17 18:49:18 +08:00
xushiwei
21a2f71ad9 Merge pull request #529 from visualfc/named
ssa: abiNamed set underlying size
2024-07-17 17:58:26 +08:00
visualfc
cf75e3e664 ssa: abiNamed set underlying size 2024-07-17 10:42:04 +08:00
xushiwei
ffc307323a Merge pull request #528 from xushiwei/q
cmd: dylibdeps
2024-07-17 09:18:58 +08:00
xushiwei
ff0aec28c5 cmd: dylibdeps 2024-07-17 09:16:55 +08:00
xushiwei
31394b03ae Merge pull request #527 from xushiwei/q
ssa: BinOp (map equal) fix; time.ParseDuration; fmt.Errorf; pkg: flag, strings; flagdemo: to fix bug
2024-07-17 07:45:06 +08:00
xushiwei
2ab93cb385 x 2024-07-17 07:41:14 +08:00
xushiwei
172b396dc9 pkg: flag, strings 2024-07-16 22:36:38 +08:00
xushiwei
9b82d08087 flagdemo: to fix bug 2024-07-16 22:26:23 +08:00
xushiwei
410617f73b reflect.valueInterface 2024-07-16 22:20:20 +08:00
xushiwei
ade0d38a7c patch library: todo message 2024-07-16 22:16:33 +08:00
xushiwei
3ce55a2ac4 ssa: BinOp (map equal) fix 2024-07-16 22:03:23 +08:00
xushiwei
cc6e4dbec0 time.ParseDuration; fmt.Errorf 2024-07-16 21:17:31 +08:00
xushiwei
2935ae7bf1 Merge pull request #521 from xushiwei/q
xtool/llvm/install_name_tool: Exec
2024-07-16 07:42:03 +08:00
xushiwei
96e418e63b xtool/llvm/install_name_tool: Exec 2024-07-16 07:32:18 +08:00
xushiwei
e4a84dcfe9 Merge pull request #520 from aofei/cleanup
chore: remove _demo/hello/hello
2024-07-16 07:02:57 +08:00
Aofei Sheng
9ea91cfce3 chore: remove _demo/hello/hello
Accidentally introduced in #519.
2024-07-15 23:39:20 +08:00
xushiwei
8c7f0cf988 Merge pull request #519 from aofei/rpath
build: fix rpath support on Linux
2024-07-15 23:08:46 +08:00
Aofei Sheng
afa9a00259 build: fix rpath support on Linux 2024-07-15 23:04:07 +08:00
Kindy Lin
a0ee11c300 neco: init 2024-07-15 21:52:45 +08:00
xushiwei
6e02dace18 Merge pull request #517 from xushiwei/q
xtool: llvm InstallNameTool
2024-07-15 15:12:05 +08:00
xushiwei
93bac6f26f install_name_tool: ChangeToRpath 2024-07-15 15:02:29 +08:00
xushiwei
8657fbd810 xtool: llvm InstallNameTool 2024-07-15 14:55:00 +08:00
xushiwei
68203be004 Merge pull request #502 from spongehah/c/fcntl
feat(c/os): add fcntl
2024-07-15 14:12:24 +08:00
xushiwei
b2323ef2e7 Merge pull request #516 from visualfc/clang_wrap
c/clang: wrap cursor
2024-07-15 13:33:49 +08:00
visualfc
70b017fb72 c/clang: wrap cursor 2024-07-15 13:28:34 +08:00
xushiwei
607e3bbc11 Merge pull request #515 from xushiwei/q
build: support rpath
2024-07-15 11:14:13 +08:00
spongehah
315c9285de fix: fcntl output error
Co-authored-by: 张之阳 <51194195+luoliwoshang@users.noreply.github.com>
2024-07-15 11:10:40 +08:00
赵英杰
c22427b8fd llgo/c/fcntl 2024-07-15 10:24:29 +08:00
xushiwei
2fcfac9e84 build: support rpath 2024-07-15 10:13:01 +08:00
赵英杰
7cc857233f llgo/c/fcntl:demo 2024-07-15 09:45:14 +08:00
xushiwei
f85aa09784 Merge pull request #514 from xushiwei/q
c/clang: castdump
2024-07-15 01:16:01 +08:00
xushiwei
0b0cecc2a9 c/clang: castdump 2024-07-15 01:07:26 +08:00
xushiwei
3b5b9c9587 Merge pull request #513 from xushiwei/q
cpp/llvm; os.Args; build: add llvm.BinDir to PATH
2024-07-15 00:31:11 +08:00
xushiwei
cbe190fa70 cpp/llvm; os.Args; build: add llvm.BinDir to PATH 2024-07-15 00:22:10 +08:00
xushiwei
9156466351 Update test_demo.sh 2024-07-14 11:03:45 +08:00
xushiwei
f79caf095d Update README.md 2024-07-14 11:01:08 +08:00
xushiwei
d31dcd13fc Update README.md 2024-07-14 10:57:21 +08:00
xushiwei
552224bbfe Merge pull request #510 from xushiwei/q
README: How support C and Python
2024-07-14 10:56:44 +08:00
xushiwei
5ba01674fb README: How support C and Python 2024-07-14 10:56:19 +08:00
xushiwei
7390afc5e1 Update README.md 2024-07-14 01:54:29 +08:00
xushiwei
85ec23d552 Merge pull request #509 from xushiwei/q
cpp/inih: small fix
2024-07-14 01:42:18 +08:00
xushiwei
007064c0ac cpp/inih: small fix 2024-07-14 01:41:31 +08:00
xushiwei
fd53756170 Merge pull request #508 from xushiwei/q
README: libraries
2024-07-14 01:38:59 +08:00
xushiwei
9e6dd9f23d README: libraries 2024-07-14 01:38:31 +08:00
xushiwei
ef8be6c7c2 Merge pull request #507 from luoliwoshang/c/lua
llgo/c/lua:link style
2024-07-13 23:30:07 +08:00
luoliwoshang
de4b5b70da llgo/c/lua:link style 2024-07-13 23:19:47 +08:00
xushiwei
9edeee4b3f Merge pull request #506 from xushiwei/q
_wrap: llgo_check (to be continued)
2024-07-13 19:58:07 +08:00
xushiwei
767a0cc1fd _wrap: llgo_check (to be continued) 2024-07-13 19:53:55 +08:00
xushiwei
ae09247e34 Merge pull request #505 from xushiwei/q
library: cpp/std (and more c++ mechanism, eg. build: clFiles support cflags)
2024-07-13 19:02:39 +08:00
xushiwei
a3ea4798bc build: clFiles support cflags, reuse llvm.Env; cpp/inih: _wrap/reader.cpp 2024-07-13 18:55:09 +08:00
xushiwei
af54a22d16 inih: INIReaderDispose 2024-07-13 18:11:34 +08:00
xushiwei
b026bfc71b inih.Reader: InitFromFile 2024-07-13 17:57:46 +08:00
xushiwei
80d80ad8aa library: cpp/std; cpp/inih demo: inihreader 2024-07-13 17:51:06 +08:00
xushiwei
dbecf33924 Merge pull request #504 from xushiwei/q
c.AllocaCStrs; ssa: AllocaU/ArrayAlloca/Times/AllocaCStrs; cl/_testlibc: allocacstrs; demo: sysexec
2024-07-13 12:51:33 +08:00
xushiwei
2b08e3604d TestConstBool; Test allocaCStrs 2024-07-13 12:47:29 +08:00
xushiwei
7d3a672c2b mv _demo/chandemo 2024-07-13 12:33:37 +08:00
xushiwei
022e46ae38 c.AllocaCStrs; cl/_testlibc: allocacstrs 2024-07-13 12:24:06 +08:00
xushiwei
3f930d228e Merge pull request #503 from luoliwoshang/c/socket/client
llgo/c/socket:client demo
2024-07-13 00:05:39 +08:00
luoliwoshang
5eba370f7b llgo/c/socket:client demo 2024-07-12 23:37:55 +08:00
xushiwei
e138951e9e c.AllocaCStrs; ssa: AllocaU/ArrayAlloca/Times/AllocaCStrs 2024-07-12 21:40:13 +08:00
xushiwei
5cd18d7275 Merge pull request #498 from morpingsss/morpingsss/add_inih
feat(cpp/inih): add inih parser_1
2024-07-12 20:56:50 +08:00
xushiwei
d7ff5a53a7 Merge pull request #499 from hackerchai/refactor/remove-rust-sled
refactor(rust/sled): remove sled due to move
2024-07-12 20:56:04 +08:00
xushiwei
aa14bb6fdf Merge pull request #501 from luoliwoshang/socket
llgo/c/socket:server demo
2024-07-12 20:54:27 +08:00
luoliwoshang
c275f682a9 llgo/c/socket:server demo 2024-07-12 17:39:13 +08:00
morpingsss
08894025bc fix(cpp/inih) : Use unsafe.Point to replace stirringHead 2024-07-12 14:48:17 +08:00
hackerchai
b063a48520 refactor(rust/sled): remove sled due to move
Signed-off-by: hackerchai <i@hackerchai.com>
2024-07-12 14:45:23 +08:00
xushiwei
858d38d314 Merge pull request #497 from luoliwoshang/c/perror
llgo/c:perror
2024-07-12 14:04:21 +08:00
morpingsss
f5875d09e9 feat(cpp/inih): add inih parser_4 2024-07-12 13:54:28 +08:00
morpingsss
34db181686 feat(cpp/inih): add inih parser_3 2024-07-12 13:53:01 +08:00
morpingsss
be55ea2b0b feat(cpp/inih): add inih parser_2 2024-07-12 12:03:15 +08:00
luoliwoshang
aa0dd4d10d llgo/c:perror 2024-07-12 11:18:35 +08:00
morpingsss
39533e4209 feat(cpp/inih): add inih parser_1 2024-07-12 11:13:15 +08:00
xushiwei
4bba3bf1d2 Merge pull request #496 from xushiwei/q
c/syscall/unix: remove deps of syscall
2024-07-12 01:33:54 +08:00
xushiwei
2d29d1549a c/syscall/unix: remove deps of syscall 2024-07-12 01:29:01 +08:00
xushiwei
c7a078f17f Merge pull request #495 from xushiwei/q
patch library: syscall, os, os/exec; demo: cexec; oslookpath
2024-07-12 01:20:03 +08:00
xushiwei
2cf92037e9 go1.21 2024-07-12 01:17:00 +08:00
xushiwei
452ee7a103 syscall: exec linux 2024-07-12 01:07:12 +08:00
xushiwei
68f70af2f3 c/syscall/unix 2024-07-12 00:59:32 +08:00
xushiwei
11682e487e c/os: fork/exec 2024-07-12 00:39:16 +08:00
xushiwei
4d006230f9 Merge pull request #493 from luoliwoshang/structsize
fix:correct `Sizeof` to align size properly
2024-07-11 23:39:39 +08:00
xushiwei
a32f4bb05c Merge pull request #494 from aofei/release-build.yml
ci: implement release-build.yml workflow with GoReleaser
2024-07-11 23:37:41 +08:00
luoliwoshang
6d4e260127 test:add struct size test 2024-07-11 23:04:50 +08:00
Aofei Sheng
45404b5bcf ci: implement release-build.yml workflow with GoReleaser 2024-07-11 22:59:20 +08:00
luoliwoshang
861551b2ba update:extra alignment for structs only 2024-07-11 21:16:50 +08:00
xushiwei
aac820a8d5 demo: oslookpath; syscall.Lstat/Stat 2024-07-11 19:21:04 +08:00
xushiwei
a5ff25b0fe library: c/syscall 2024-07-11 19:11:54 +08:00
xushiwei
b81638794f patch library: os/exec 2024-07-11 18:44:06 +08:00
luoliwoshang
88cfeb2791 fix:correct Sizeof to align size properly 2024-07-11 18:21:41 +08:00
xushiwei
d0b57535ed support: internal/oserror, io, io/fs 2024-07-11 18:20:12 +08:00
xushiwei
528add4702 patch library: syscall, os/exec 2024-07-11 18:00:20 +08:00
xushiwei
dd47971877 patch os: File 2024-07-11 14:47:03 +08:00
xushiwei
d51a99c8e2 Merge pull request #490 from visualfc/buildpkg
build: fix buildpkg
2024-07-11 13:40:36 +08:00
visualfc
e192f01dc3 build: fix buildpkg 2024-07-11 11:47:11 +08:00
xushiwei
aedaf57249 Update Type-Mapping-between-C-and-Go.md 2024-07-11 07:39:56 +08:00
xushiwei
222e58e76e Create Type-Mapping-between-C-and-Go.md 2024-07-10 17:31:03 +08:00
xushiwei
c8fc80f4a0 Merge pull request #489 from aofei/llgo-version
cmd: add "llgo version" command
2024-07-10 15:46:29 +08:00
Aofei Sheng
1ed180887d cmd: add "llgo version" command 2024-07-10 15:36:17 +08:00
xushiwei
d6a38a567f Merge pull request #481 from aofei/readme
readme: simplify installation instructions
2024-07-09 18:48:49 +08:00
Aofei Sheng
ae9c3276bc readme: simplify installation instructions
This also cleans up the remaining mentioned LLGOROOT.
2024-07-09 16:18:30 +08:00
xushiwei
35d34cd4e8 Update sled.go 2024-07-09 15:34:05 +08:00
xushiwei
4f45824632 Merge pull request #480 from xushiwei/q
refactor rust/sled
2024-07-09 15:27:18 +08:00
xushiwei
532da174dd refactor rust/sled 2024-07-09 15:25:21 +08:00
xushiwei
dbe13feba2 Merge pull request #450 from hackerchai/feature/rust-sled
feat(rust): implement rust sled demo
2024-07-09 14:42:19 +08:00
xushiwei
1c93061a7f Merge pull request #478 from xushiwei/q
patch time: Duration, Timer
2024-07-09 14:34:55 +08:00
xushiwei
0e371930e6 cmptest: ctxcancel 2024-07-09 14:26:02 +08:00
xushiwei
06bd748bd6 patch time: Duration, Timer 2024-07-09 14:24:48 +08:00
xushiwei
b64775772b Merge pull request #477 from visualfc/rets
ssa: fix multi result
2024-07-09 13:31:02 +08:00
visualfc
5f76314085 ssa: fix multi result 2024-07-09 13:10:02 +08:00
xushiwei
57588ea936 Merge pull request #476 from xushiwei/q
cl handleTypeDecl: typeBackground
2024-07-09 13:02:27 +08:00
xushiwei
3f344b55bb TestToBackground 2024-07-09 12:58:51 +08:00
xushiwei
e4ae0980b4 x 2024-07-09 12:42:20 +08:00
xushiwei
e41da0d697 cl handleTypeDecl: typeBackground 2024-07-09 12:38:34 +08:00
xushiwei
ce3955d393 Merge pull request #454 from visualfc/typec
cl: parser llgo:type C
2024-07-09 12:18:44 +08:00
visualfc
22a2cc564f cl: parser llgo:type C 2024-07-09 10:00:31 +08:00
Eason Chai
2b19513a05 Merge pull request #3 from luoliwoshang/feature/rust-sled
llgo:rust:sled:a working demo
2024-07-09 09:42:39 +08:00
luoliwoshang
60f8fe6f41 llgo/rust/sled:rename struct 2024-07-09 09:39:44 +08:00
luoliwoshang
a2fd010521 llgo:rust:sled:a working demo 2024-07-09 09:30:10 +08:00
hackerchai
a36d5b6302 fix(rust/sled): fix sled errors 2024-07-09 09:27:24 +08:00
hackerchai
2c14dc16dd feat(rust): implement sled support
Signed-off-by: hackerchai <i@hackerchai.com>
2024-07-09 09:27:23 +08:00
hackerchai
4c7f3f7972 feat(rust): implement rust sled demo
Signed-off-by: hackerchai <i@hackerchai.com>
2024-07-09 09:27:22 +08:00
xushiwei
794df59265 Merge pull request #475 from xushiwei/q
mv xtool/clang/parser, ar => chore/_deprecated
2024-07-09 01:36:50 +08:00
xushiwei
3dd71713c2 mv _test => c/bdwgc/_test 2024-07-09 01:33:48 +08:00
xushiwei
c0777d1a0a mv xtool/clang/parser, ar => chore/_deprecated 2024-07-09 01:29:26 +08:00
xushiwei
55392cb047 Merge pull request #474 from xushiwei/q
README: c libraries
2024-07-09 00:47:50 +08:00
xushiwei
070eedda18 README: c libraries 2024-07-09 00:43:45 +08:00
xushiwei
ae6ec78dc3 Merge pull request #430 from luoliwoshang/lua
[WIP] llgo/c/lua
2024-07-08 23:16:17 +08:00
xushiwei
9fe1b2a565 Update README.md 2024-07-08 23:11:25 +08:00
xushiwei
f374419be3 Merge pull request #472 from luoliwoshang/readme/zlib
[wip] README:zlib
2024-07-08 23:10:48 +08:00
xushiwei
0ff25cb116 Update README.md 2024-07-08 23:07:47 +08:00
xushiwei
d7e50f352a Merge pull request #473 from luoliwoshang/readme/raylib
[wip] README:raylib
2024-07-08 23:00:07 +08:00
luoliwoshang
aa9254eeb0 README:raylib 2024-07-08 22:24:41 +08:00
luoliwoshang
c1eba336a8 README:zlib 2024-07-08 21:48:40 +08:00
luoliwoshang
a5d7fc484a llgo/c/lua:table & coroutine 2024-07-08 21:31:11 +08:00
luoliwoshang
7a294e6d4e llgo/c/lua 2024-07-08 21:22:01 +08:00
xushiwei
2f79417d0d Merge pull request #470 from visualfc/fixiface
ssa: fix setDirectIface
2024-07-08 20:30:55 +08:00
visualfc
73b42f924d ssa: fix setDirectIface 2024-07-08 20:19:25 +08:00
xushiwei
ccf915e798 Update inih.go 2024-07-08 18:33:29 +08:00
morpingsss
62ffa14f10 feat(llgo/c):Add an INI parser (#466)
* feat(llgo/c):Add an INI parser
2024-07-08 18:28:18 +08:00
xushiwei
5d7840a34c Merge pull request #469 from aofei/ci
ci: update go.yml workflow to trigger on pushes and PRs to any branches
2024-07-08 17:41:29 +08:00
Aofei Sheng
fd14f6ff73 ci: update go.yml workflow to trigger on pushes and PRs to any branches
This update enables GitHub Actions in forks, streamlining development
and testing.
2024-07-08 17:32:13 +08:00
xushiwei
88962f9358 Merge pull request #462 from aofei/build-lla
build: replace precompiled *.lla with local compilation
2024-07-08 17:19:49 +08:00
Aofei Sheng
5bec1729f1 build: replace precompiled *.lla with local compilation
Switching from using precompiled *.lla files to compiling locally during
the build process for better flexibility and maintainability.

Fixes #411
2024-07-08 17:14:43 +08:00
xushiwei
f3662fc152 Merge pull request #468 from xushiwei/q
demo: ctxcancel
2024-07-08 16:05:25 +08:00
xushiwei
c5047186dd demo: ctxcancel 2024-07-08 15:50:16 +08:00
xushiwei
1e39bd8336 Program.Zero: support types.Signature/Chan 2024-07-08 15:37:20 +08:00
xushiwei
e58de234ac Merge pull request #460 from visualfc/funceq
ssa: fix func binop eq
2024-07-08 15:27:05 +08:00
visualfc
903cc181c4 cl/cltest: program init types.sizes 2024-07-08 15:21:03 +08:00
xushiwei
2183a098c3 Merge pull request #467 from xushiwei/q
library/demo: log
2024-07-08 15:20:41 +08:00
xushiwei
1d4cba9180 library/demo: log 2024-07-08 15:17:08 +08:00
xushiwei
ed724c5280 Merge pull request #464 from aofei/GOBIN
build: ensure GOBIN directory exists before use
2024-07-08 12:23:01 +08:00
xushiwei
fbd13ac42c Merge pull request #465 from morpingsss/morpingsss/add_Fopen
feat(llgo/c):Add two functions : Fopen &  Fclose
2024-07-08 12:20:03 +08:00
morpingsss
ea6eab557b feat(llgo/c):Add two functions Fopen and Fclose 2024-07-08 12:01:22 +08:00
Aofei Sheng
a1cb2a0589 build: ensure GOBIN directory exists before use 2024-07-08 08:57:18 +08:00
xushiwei
5de5a8ca94 Merge pull request #461 from goplus/dependabot/go_modules/github.com/goplus/mod-0.13.12
build(deps): bump github.com/goplus/mod from 0.13.10 to 0.13.12
2024-07-08 00:15:15 +08:00
dependabot[bot]
274026d338 build(deps): bump github.com/goplus/mod from 0.13.10 to 0.13.12
Bumps [github.com/goplus/mod](https://github.com/goplus/mod) from 0.13.10 to 0.13.12.
- [Release notes](https://github.com/goplus/mod/releases)
- [Commits](https://github.com/goplus/mod/compare/v0.13.10...v0.13.12)

---
updated-dependencies:
- dependency-name: github.com/goplus/mod
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-07 16:10:49 +00:00
visualfc
3875bc34bd ssa: fix func binop eq 2024-07-07 20:37:29 +08:00
xushiwei
8db3ccce2e Merge pull request #459 from xushiwei/ll
README: run _pydemo
2024-07-07 19:04:52 +08:00
xushiwei
34bb6fd851 README: run _pydemo 2024-07-07 19:04:10 +08:00
xushiwei
ffa74db136 Merge pull request #458 from xushiwei/ll
runtime chan fix: ChanTryRecv
2024-07-07 17:36:53 +08:00
xushiwei
66f2cbb91f runtime chan fix: ChanTryRecv 2024-07-07 17:23:21 +08:00
xushiwei
a57d49b057 Merge pull request #457 from xushiwei/q
fix #453 (select recv))
2024-07-07 16:21:45 +08:00
xushiwei
7b41a0ff16 fix #453 (select recv)) 2024-07-07 16:03:41 +08:00
xushiwei
4ca50f8973 Merge pull request #456 from aofei/llvm-18
llvm: default to LLVM 18
2024-07-07 15:44:20 +08:00
Aofei Sheng
abe2c6870b llvm: default to LLVM 18 2024-07-07 15:20:11 +08:00
xushiwei
c0ae681d69 Update README.md 2024-07-07 15:14:05 +08:00
xushiwei
b4745c0134 Merge pull request #455 from xushiwei/q
README
2024-07-07 15:12:55 +08:00
xushiwei
d369a6429e README 2024-07-07 15:12:20 +08:00
xushiwei
af3e326178 Merge pull request #453 from visualfc/select
[wip] ssa: select
2024-07-07 13:02:04 +08:00
visualfc
8e256a2d5d ssa: select 2024-07-07 11:26:22 +08:00
xushiwei
bdcbd9008d Merge pull request #452 from xushiwei/q
runtime: Select/TrySelect
2024-07-06 22:05:57 +08:00
xushiwei
453faa6a76 runtime: Select/TrySelect 2024-07-06 21:59:28 +08:00
xushiwei
b0941faf88 Merge pull request #431 from visualfc/map
ssa: support runtime.map
2024-07-04 19:17:10 +08:00
visualfc
91ba215568 internal/runtime: check abi.KindDirectIface 2024-07-04 18:59:41 +08:00
visualfc
be32f4072e internal/runtime: check abi.TFlagRegularMemory 2024-07-04 18:50:37 +08:00
visualfc
bcb217c1da ssa: set pointer directiface 2024-07-04 18:50:37 +08:00
visualfc
490a16a8df ssa: index check take address 2024-07-04 18:50:36 +08:00
visualfc
28d8c56534 ssa: index take addr 2024-07-04 18:50:36 +08:00
visualfc
46423ed166 internal/runtime: impl type.equal 2024-07-04 18:50:36 +08:00
visualfc
4286a510b4 runtime: stubs init hashkey 2024-07-04 18:50:36 +08:00
visualfc
8d193ab39f runtime: map hasher 2024-07-04 18:50:36 +08:00
visualfc
439e377111 ssa: map delete, map eql nil 2024-07-04 18:50:36 +08:00
visualfc
28ebce6b65 ssa: map range/next 2024-07-04 18:50:36 +08:00
visualfc
2ccd1625e7 ssa: support runtime.map 2024-07-04 18:50:36 +08:00
xushiwei
e05e61a59b Merge pull request #448 from xushiwei/q
patch fmt: printArg; py.Str; py.FromCStr/FromCStrAndLen/FromGoString
2024-07-04 18:44:33 +08:00
xushiwei
4660eae8c7 cl: _testpy/callpy 2024-07-04 18:39:31 +08:00
xushiwei
e55e90db1a py.Str; py.FromCStr/FromCStrAndLen/FromGoString 2024-07-04 18:34:00 +08:00
xushiwei
23da63767c patch fmt: printArg 2024-07-04 17:39:02 +08:00
xushiwei
13b19c35c6 Merge pull request #447 from xushiwei/q
patch fmt: fmt.Printf
2024-07-04 17:33:48 +08:00
xushiwei
7e25ec1ac3 patch reflect 2024-07-04 17:29:40 +08:00
xushiwei
ab1d05642e patch fmt: fmt.Printf 2024-07-04 17:05:26 +08:00
xushiwei
079b28fddf Merge pull request #445 from visualfc/namedfunc
ssa: fix named func call
2024-07-04 15:14:12 +08:00
visualfc
d52d62badb ssa: fix named func call 2024-07-04 11:28:40 +08:00
xushiwei
fa53135c8a Merge pull request #443 from xushiwei/q
README: libraries
2024-07-02 23:10:57 +08:00
xushiwei
d6a3f9fd8f README: libraries 2024-07-02 23:08:57 +08:00
xushiwei
75ca4af74e Merge pull request #442 from xushiwei/q
README: chan
2024-07-02 21:05:04 +08:00
xushiwei
dc5fc6bdc2 README: chan 2024-07-02 21:04:34 +08:00
xushiwei
67f8ee61a4 Merge pull request #440 from visualfc/chan
ssa: chan send/recv
2024-07-02 21:00:09 +08:00
visualfc
2153cf39b5 ssa: chan send/recv 2024-07-02 20:52:25 +08:00
xushiwei
0ead82ae21 Merge pull request #441 from xushiwei/q
runtime: close(chan)
2024-07-02 20:27:11 +08:00
xushiwei
98d4cf7585 runtime: close(chan) 2024-07-02 20:23:48 +08:00
xushiwei
3259536411 Merge pull request #439 from xushiwei/q
demo: cchan
2024-07-02 19:49:21 +08:00
xushiwei
f3a79cc779 demo: cchan 2024-07-02 19:49:00 +08:00
xushiwei
c45c6dbe67 Merge pull request #436 from luoliwoshang/link/warning
link:not exist method warning
2024-07-02 19:43:37 +08:00
xushiwei
a1518c33af Merge pull request #438 from visualfc/build_link
build: fix link runtime
2024-07-02 19:43:11 +08:00
visualfc
a9f7cdb630 build: fix link runtime 2024-07-02 18:40:20 +08:00
luoliwoshang
6f678294a0 link:not exist method warning 2024-07-02 17:37:32 +08:00
xushiwei
de07abee98 Merge pull request #437 from xushiwei/q
runtime: chan; cmptest: iodemo, fmtdemo
2024-07-02 16:05:14 +08:00
xushiwei
437edefa0c runtime: chan 2024-07-02 16:00:43 +08:00
xushiwei
f5b36ecbac Merge pull request #434 from visualfc/abi_patch
ssa: fix abi patch types.pointer
2024-07-02 12:14:54 +08:00
visualfc
8772c85964 ssa: fix abi patch types.pointer 2024-07-02 08:40:44 +08:00
xushiwei
a31454327a Update README.md 2024-07-02 07:39:53 +08:00
xushiwei
9e55cb114c Merge pull request #433 from xushiwei/q
abitype: support Patch (Clone + Merge); patch: os.File
2024-07-01 19:09:32 +08:00
xushiwei
04416a67d3 cl: SetPatch fix 2024-07-01 19:05:12 +08:00
xushiwei
dd2cdaf49a Merge pull request #425 from visualfc/makeslice
ssa: makeSlice fit int size and check
2024-07-01 16:59:27 +08:00
xushiwei
8c45eb7524 abitype: support Patch 2024-06-30 11:53:12 +08:00
xushiwei
c20bea50e3 Merge remote-tracking branch 'gop/main' into q 2024-06-30 11:16:53 +08:00
xushiwei
fe18c35dab patch: Clone/Merge 2024-06-28 15:14:30 +08:00
xushiwei
f6ef6abdf1 Merge pull request #424 from aofei/llvm
xtool: utilize llvm-config to find LLVM executables
2024-06-28 13:17:09 +08:00
Aofei Sheng
43a6837e81 xtool: utilize llvm-config to find LLVM executables 2024-06-27 20:27:42 +08:00
visualfc
dc4b933000 ssa: makeSlice both len/cap be non-nil 2024-06-27 20:01:27 +08:00
visualfc
c90703dc13 ssa: makeSlice fit int size and check 2024-06-27 19:57:44 +08:00
xushiwei
2165941026 patch: os.File 2024-06-27 02:28:18 +08:00
xushiwei
4a28893171 Merge pull request #429 from xushiwei/q
patch: fmt, os, runtime, syscall, time
2024-06-27 01:05:13 +08:00
xushiwei
369581976a c/time fix 2024-06-27 01:00:58 +08:00
xushiwei
7fef683980 c.Long as int64 2024-06-27 00:55:33 +08:00
xushiwei
8358f68086 Merge pull request #428 from visualfc/bytealg
ssa fix slice high, update bytealg for pkg bytes/strings
2024-06-27 00:53:42 +08:00
xushiwei
0aa6b03c2a patch time: Now 2024-06-27 00:51:21 +08:00
xushiwei
44f8c98660 demo: c ClockGettime (CLOCK_REALTIME/MONOTONIC) 2024-06-26 21:20:47 +08:00
xushiwei
188ec6ea1d patch time: time.Format 2024-06-26 20:41:34 +08:00
visualfc
8169d8509f cl/_testlibgo: bytes strings 2024-06-26 20:41:29 +08:00
visualfc
e217d39882 internal/lib/internal/bytealg: count index 2024-06-26 20:13:43 +08:00
visualfc
887ee0fd41 ssa: fix slice high 2024-06-26 20:09:38 +08:00
xushiwei
137e93319e c/time; patch: time 2024-06-26 19:36:39 +08:00
xushiwei
48a1384197 patch: fmt, os, runtime, syscall, time 2024-06-26 17:17:10 +08:00
xushiwei
8aed4d634b Merge pull request #427 from xushiwei/q
raylib demo: tetris
2024-06-26 00:52:16 +08:00
xushiwei
fd0cb4c458 raylib demo: tetris 2024-06-26 00:49:20 +08:00
xushiwei
82735f0fab Merge pull request #426 from xushiwei/q
patch os: File.Write
2024-06-26 00:31:33 +08:00
xushiwei
1d3710afd8 toSyscallErr => syscall.Errno 2024-06-26 00:28:21 +08:00
xushiwei
e8ae92f4d4 Merge pull request #423 from luoliwoshang/raylibdemo
llgo/c/raylib:tetris demo
2024-06-26 00:03:51 +08:00
luoliwoshang
b2e54a0590 llgo/c/raylib:tetris demo 2024-06-25 20:54:07 +08:00
xushiwei
d64d220b49 patch os: File.Write 2024-06-25 18:07:58 +08:00
xushiwei
2523a95a9a Merge pull request #422 from xushiwei/q
patch os, syscall, io/fs: Errno, Stdin/out/err
2024-06-25 16:14:25 +08:00
xushiwei
207c41581c patch syscall: errors for linux 2024-06-25 16:11:29 +08:00
xushiwei
6fc4a3ed04 patch os, syscall, io/fs: Errno, Stdin/out/err 2024-06-25 16:02:54 +08:00
xushiwei
2fabb6951e Merge pull request #421 from visualfc/abibasic
runtime: global abi basic
2024-06-25 15:46:00 +08:00
xushiwei
8c2f5f91d5 Merge pull request #420 from xushiwei/q
patch os: UserHomeDir/UserConfigDir/UserCacheDir
2024-06-25 15:45:29 +08:00
visualfc
7443d41444 runtime: global abi basic 2024-06-25 14:41:32 +08:00
xushiwei
4421734da1 patch os: UserHomeDir/UserConfigDir/UserCacheDir 2024-06-25 14:29:37 +08:00
xushiwei
4385ca0966 patch: internal/abi 2024-06-25 14:02:25 +08:00
xushiwei
57fa592a13 Merge pull request #419 from xushiwei/q
phi.AddIncoming fix: use checkExpr
2024-06-25 13:35:42 +08:00
xushiwei
1298118b59 phi.AddIncoming fix: use checkExpr 2024-06-25 13:31:44 +08:00
xushiwei
3f2cb40cc1 Merge pull request #418 from xushiwei/q
cmptest: sortdemo
2024-06-25 12:40:55 +08:00
xushiwei
5448abb304 cmptest: sortdemo 2024-06-25 12:40:28 +08:00
xushiwei
892fab5455 Merge pull request #417 from visualfc/abinamed
ssa: fix abiType & abiNamedOf
2024-06-25 12:34:23 +08:00
visualfc
ef3619350d ssa: fix abiType & abiNamedOf 2024-06-25 12:17:03 +08:00
xushiwei
846fb3e7f3 Merge pull request #416 from xushiwei/q
c/clang: use llvm-config
2024-06-25 12:05:05 +08:00
xushiwei
e00e9ba5aa c/clang: use llvm-config 2024-06-25 12:00:48 +08:00
xushiwei
f41511047e Merge pull request #392 from visualfc/rlite
ssa: fix abiType && abiMethoOf
2024-06-25 10:45:00 +08:00
visualfc
16352df5b1 ssa: fix abiType && abiMethoOf 2024-06-25 10:22:32 +08:00
xushiwei
5238c2457d Merge pull request #415 from xushiwei/q
c/raylib
2024-06-25 08:42:57 +08:00
xushiwei
4d57f414f5 c/raylib 2024-06-25 08:40:23 +08:00
xushiwei
6305088cb0 Merge pull request #414 from xushiwei/q
c/math (float32); c/math/rand
2024-06-25 01:32:58 +08:00
xushiwei
e2db1cd425 c/math (float32); c/math/rand 2024-06-25 01:30:13 +08:00
xushiwei
16561a8e84 Merge pull request #413 from xushiwei/q
c/zlib: Z_OK => OK
2024-06-25 01:24:42 +08:00
xushiwei
cae1b3ebd4 c/zlib: Z_OK => OK 2024-06-25 01:02:03 +08:00
xushiwei
e68737dcfb Merge pull request #404 from luoliwoshang/zlib
llgo/c/zlib
2024-06-25 00:45:19 +08:00
xushiwei
00448d23c0 Merge pull request #408 from aofei/llama2-libm
fix(c/llama2): explicitly link libm to ensure compatibility with Linux
2024-06-25 00:43:28 +08:00
xushiwei
272ae547ef Merge pull request #410 from xushiwei/q
c/clang; c/raylib demo
2024-06-25 00:43:07 +08:00
xushiwei
3fd688191c c/clang 2024-06-25 00:33:48 +08:00
luoliwoshang
5c0b6f2225 llgo/c/zlib 2024-06-24 23:03:18 +08:00
xushiwei
cc530e3446 c/raylib demo 2024-06-24 22:37:53 +08:00
xushiwei
fdc1d46b89 Merge pull request #409 from xushiwei/q
c/raylib
2024-06-24 22:03:54 +08:00
xushiwei
5dce677091 c/raylib 2024-06-24 21:56:53 +08:00
Aofei Sheng
d0fb5a4b04 fix(c/llama2): explicitly link libm to ensure compatibility with Linux 2024-06-24 17:50:05 +08:00
xushiwei
e27daed0ec c/llama2: rm precompiled *.ll files (#407) 2024-06-24 17:31:59 +08:00
xushiwei
d2183a8b32 c/llama2: rm precompiled *.ll files 2024-06-24 17:27:12 +08:00
七叶
0b2d6407dd runtime: type align (#405) 2024-06-24 17:15:45 +08:00
tsingbx
ec1b1ffe16 add math/rand (#403)
c/math/rand
2024-06-24 15:53:26 +08:00
xushiwei
32a66be555 Merge pull request #399 from visualfc/panicany
runtime: panic any custometype
2024-06-23 23:01:17 +08:00
visualfc
c090c34491 runtime: panic any custometype 2024-06-23 21:51:00 +08:00
xushiwei
4f7d3ad76c Merge pull request #398 from xushiwei/q
cppmintf: implements multiple intefaces in c++
2024-06-23 16:19:52 +08:00
xushiwei
ce81872686 cppintf: fix int type 2024-06-23 16:14:42 +08:00
xushiwei
2314c41103 cppmintf: implements multiple intefaces in c++ 2024-06-23 16:12:01 +08:00
xushiwei
df39b66e11 Merge pull request #394 from xushiwei/q
mv cases to _cmptest
2024-06-23 01:00:28 +08:00
xushiwei
adeb5de19f mv cases to _cmptest 2024-06-23 01:00:02 +08:00
xushiwei
26312e0c0e Merge pull request #393 from xushiwei/q
llgo cmptest (#391)
2024-06-23 00:53:41 +08:00
xushiwei
cd6d4021b1 llgo cmptest (#391) 2024-06-23 00:48:38 +08:00
xushiwei
24d345a970 Merge pull request #389 from xushiwei/q
cppintf: c++ name
2024-06-22 09:15:08 +08:00
xushiwei
b4fd4a0c38 cppintf: c++ name 2024-06-22 09:14:10 +08:00
xushiwei
451e695006 Merge pull request #388 from xushiwei/q
cppintf: with param
2024-06-22 08:42:35 +08:00
xushiwei
26b771f9f9 cppintf: with param 2024-06-22 02:39:29 +08:00
xushiwei
0679aedb7e Merge pull request #387 from xushiwei/q
cl: c.Func (llgo.funcAddr); demo: cppintf (how to use c++ interface)
2024-06-21 23:50:13 +08:00
xushiwei
bfa4e08a4e cl: c.Func (llgo.funcAddr); demo: cppintf (how to use c++ interface) 2024-06-21 23:44:56 +08:00
xushiwei
c1185a34aa Merge pull request #386 from xushiwei/q
build: disable verbose info for deps
2024-06-21 15:47:52 +08:00
xushiwei
be0ce57375 build: disable debug info for deps 2024-06-21 15:45:29 +08:00
xushiwei
b204b90ffc build: remove context.verbose 2024-06-21 15:31:18 +08:00
xushiwei
364b6938a5 Merge pull request #385 from xushiwei/q
patch: internal/reflectlite; demo: sort
2024-06-21 13:47:16 +08:00
xushiwei
e188925d2b patch: internal/reflectlite; demo: sort 2024-06-21 13:21:16 +08:00
xushiwei
10a47cdbbb build: use unsafe.Slice to reduce memory usage of overlayFiles 2024-06-21 12:43:17 +08:00
xushiwei
67014ae4f8 Merge pull request #384 from xushiwei/q
patch internal/reflectlite; demo: sort.Ints
2024-06-21 11:23:13 +08:00
xushiwei
b93fc3f028 patch internal/reflectlite; demo: sort.Ints 2024-06-21 11:02:28 +08:00
xushiwei
b6e5980510 Merge pull request #383 from visualfc/skipfiles
x/build: overlayFiles for fix math on amd64
2024-06-21 10:46:38 +08:00
visualfc
79e8921f76 x/build: overlayFiles for fix math on amd64 2024-06-21 07:55:17 +08:00
xushiwei
34fe3ca4fc Merge pull request #382 from xushiwei/q
patch reflect: Append/Index; Int fix
2024-06-21 03:33:44 +08:00
xushiwei
f26311c60e patch reflect: Append/Index; Int fix 2024-06-21 03:29:24 +08:00
xushiwei
43f9907af7 Merge pull request #381 from xushiwei/q
patch reflect: ValueOf/Int
2024-06-21 00:42:12 +08:00
xushiwei
0e6f5d154e patch reflect: ValueOf/Int 2024-06-21 00:31:36 +08:00
xushiwei
7042dd8447 Merge pull request #380 from xushiwei/q
patch reflect: Zero/Len
2024-06-20 23:44:51 +08:00
xushiwei
05031e0979 patch reflect: Zero/Len 2024-06-20 23:40:35 +08:00
xushiwei
28b3f6780c Merge pull request #379 from xushiwei/ll
README: reflect (partially)
2024-06-20 22:30:44 +08:00
xushiwei
f8335c6df9 README: reflect (partially) 2024-06-20 22:24:03 +08:00
xushiwei
9dcdc1f8f3 Merge pull request #378 from visualfc/abikind
ssa: abiTypeInit kind
2024-06-20 22:22:47 +08:00
visualfc
9ae7d4f2bf ssa: abiTypeInit kind 2024-06-20 22:09:26 +08:00
xushiwei
c158169bdf Merge pull request #373 from visualfc/complex
ssa: complex op and print/panic
2024-06-20 22:05:04 +08:00
visualfc
e4c1285eaf ssa: complex binop 2024-06-20 20:44:07 +08:00
visualfc
02a5375503 runtime: print/panic complex 2024-06-20 20:44:07 +08:00
xushiwei
32883b4e18 Merge pull request #377 from cpunion/fix-abi-init
Fix reentrant of ABI initialization
2024-06-20 20:36:41 +08:00
Li Jie
6d585e88a4 cl: output export file path of package in verbose 2024-06-20 20:13:53 +08:00
Li Jie
73570b5628 cl: re-generate tests 2024-06-20 20:13:53 +08:00
Li Jie
e7fcb068d9 ssa: fix reentrant of ABI initialization 2024-06-20 20:07:59 +08:00
xushiwei
a137a70278 Merge pull request #376 from xushiwei/ll
README: os (partially)
2024-06-20 19:56:40 +08:00
xushiwei
72113991a8 README: os (partially) 2024-06-20 19:55:37 +08:00
xushiwei
a04fb8e7de Merge pull request #371 from xushiwei/q
patch: reflect (reflect.Type)
2024-06-20 17:51:31 +08:00
xushiwei
ca2f30cd61 Merge pull request #375 from aofei/build-gopath
build: remove check for default GOPATH and GOROOT being identical
2024-06-20 17:47:44 +08:00
Aofei Sheng
ebfad05e3f build: remove check for default GOPATH and GOROOT being identical 2024-06-20 17:42:01 +08:00
xushiwei
f54ea9d978 Merge pull request #374 from xushiwei/check
complex testcase
2024-06-20 16:07:14 +08:00
xushiwei
d4c84cee19 complex demo 2024-06-20 16:00:11 +08:00
xushiwei
4da59cdc97 Merge pull request #363 from visualfc/panic
runtime: tracePanic
2024-06-20 15:42:51 +08:00
xushiwei
d4e7eb5888 bytealg.IndexByteString 2024-06-20 14:31:05 +08:00
xushiwei
f8b0a7105b patch: reflect (type) 2024-06-20 14:17:37 +08:00
visualfc
aecde91d33 runtime: tracePanic 2024-06-20 13:05:43 +08:00
xushiwei
870dde232a Merge pull request #369 from xushiwei/q
library: strconv
2024-06-20 11:09:43 +08:00
xushiwei
f7d7f81c49 library: strconv 2024-06-20 11:05:43 +08:00
xushiwei
1f04c61482 Merge pull request #368 from xushiwei/q
builtin: real/imag/complex; c/math/cmplx; patch: math/cmplx
2024-06-20 10:31:24 +08:00
xushiwei
5d957a6b7c libc complex64 support 2024-06-20 10:22:35 +08:00
xushiwei
94f61b0a0c TestFromTestlibgo 2024-06-20 10:07:10 +08:00
xushiwei
de6535b722 builtin: real/imag/complex; c/math/cmplx; patch: math/cmplx 2024-06-20 10:00:47 +08:00
xushiwei
6dd18e4328 Merge pull request #362 from aofei/build
build: set $GOPATH/bin as default GOBIN for Config.BinPath
2024-06-20 08:20:21 +08:00
Aofei Sheng
c46e4453c7 build: set $GOPATH/bin as default GOBIN for Config.BinPath
We should avoid making any changes to GOROOT whenever possible.

Fixes #361

Update internal/build/build.go

Co-authored-by: 张之阳 <51194195+luoliwoshang@users.noreply.github.com>
2024-06-20 08:14:05 +08:00
xushiwei
2e6312ec03 Merge pull request #366 from xushiwei/q
patch: syscall
2024-06-20 03:05:20 +08:00
xushiwei
1566a834e1 x 2024-06-20 03:00:12 +08:00
xushiwei
607deaa3c4 patch: syscall 2024-06-20 02:55:26 +08:00
xushiwei
686186d5ba Merge pull request #365 from xushiwei/q
cjson/sqlite README: remove install from source
2024-06-20 00:47:37 +08:00
xushiwei
0c1ef72285 cjson/sqlite README: remove install from source 2024-06-20 00:44:15 +08:00
xushiwei
d6bd12cfcd Merge pull request #364 from xushiwei/q
patch: io, io/fs, os; llgo.string; c string library; demo: getcwd; abi.TypeName fix: error interface is public
2024-06-20 00:35:10 +08:00
xushiwei
4a1712f4cd llgo.string (llgo/ssa.MakeString) fix 2024-06-20 00:30:36 +08:00
xushiwei
b4e298230d x 2024-06-20 00:13:41 +08:00
xushiwei
6cb42a4251 demo: getcwd; abi.TypeName fix: error interface is public 2024-06-19 23:58:20 +08:00
xushiwei
3ead4b4d4b llgo.string; c string library 2024-06-19 23:40:05 +08:00
xushiwei
3c0e321538 patch: io, io/fs, os 2024-06-19 22:21:44 +08:00
xushiwei
1f67434c8c Merge pull request #360 from xushiwei/q
llgo/ssa/abi: PathOf fix - support trim PatchPathPrefix; typepatch fix: don't change patch pkg
2024-06-19 17:13:12 +08:00
xushiwei
6058b9851c llgo/ssa/abi: PathOf fix - support trim PatchPathPrefix 2024-06-19 17:06:56 +08:00
xushiwei
c586319978 typepatch fix: don't change patch pkg 2024-06-19 12:30:38 +08:00
xushiwei
0591fe0e8b Merge pull request #357 from luoliwoshang/readme/tips
README:update python &  install instructions
2024-06-19 11:25:51 +08:00
luoliwoshang
dabe3b17e6 README:update python & git install instructions 2024-06-18 23:18:25 +08:00
xushiwei
fbf50d45cb Merge pull request #351 from visualfc/instance
build: instantiate generics
2024-06-18 21:59:27 +08:00
visualfc
d59075e897 build: instantiate generics 2024-06-18 19:26:52 +08:00
xushiwei
2b491179f7 Merge pull request #346 from visualfc/checkindex
ssa: index/indexAddr check range
2024-06-18 18:52:19 +08:00
xushiwei
a62d17b1b1 Merge pull request #356 from luoliwoshang/readme/install
README:update install instruction of LLGOROOT
2024-06-18 18:50:37 +08:00
xushiwei
2431758218 Merge pull request #355 from xushiwei/q
cl: initFnNameOfHasPatch fix (should rename before funcOf)
2024-06-18 18:47:41 +08:00
luoliwoshang
b94586fdf4 README:update install instruction of LLGOROOT 2024-06-18 18:47:00 +08:00
xushiwei
a6b83d77bd cl: initFnNameOfHasPatch fix (should rename before funcOf) 2024-06-18 18:44:07 +08:00
xushiwei
43c55b36c8 Merge pull request #352 from xushiwei/q
cl: fn.SetRecover; patch library: call init
2024-06-18 18:35:33 +08:00
xushiwei
24c7928c4b cl: pkgFNoOldInit flag if no initFnNameOld 2024-06-18 18:32:29 +08:00
xushiwei
8c876c302a patch library: call init 2024-06-18 18:23:16 +08:00
xushiwei
778a4373ae cl: fn.SetRecover; inPatch/hasPatch 2024-06-18 17:33:37 +08:00
xushiwei
7a15cf1157 patch: errors (todo) 2024-06-18 13:50:55 +08:00
xushiwei
54e3210d7e Merge pull request #350 from xushiwei/q
c/pthread/sync: RWLock/Cond; sync: RWMutex/Cond/WaitGroup
2024-06-18 10:19:53 +08:00
xushiwei
a3197c12a8 testllgo: waitgroup 2024-06-18 10:17:05 +08:00
xushiwei
e7de841939 c/pthread/sync: RWLock/Cond; sync: RWMutex/Cond/WaitGroup 2024-06-18 10:14:29 +08:00
visualfc
29ba00f370 ssa: index/indexAddr check max 2024-06-18 07:13:57 +08:00
xushiwei
e35d70f338 Merge pull request #349 from xushiwei/q
c: c.Int/Uint not alias C.int/uint
2024-06-18 01:30:25 +08:00
xushiwei
0271c65ca2 c: c.Int/Uint not alias C.int/uint 2024-06-18 01:25:57 +08:00
xushiwei
e604524301 Merge pull request #348 from xushiwei/q
c/pthread/sync.Mutex; sync.Mutex/Once; globalType: support typepatch
2024-06-18 00:15:19 +08:00
xushiwei
298831d987 README: sync (partially) 2024-06-18 00:10:21 +08:00
xushiwei
3b2e97a729 globalType: support typepatch 2024-06-18 00:06:40 +08:00
xushiwei
edaba44c87 c/pthread/sync.Mutex; sync.Mutex/Once; typepatch.IsPatched 2024-06-17 23:51:40 +08:00
xushiwei
dc2dc910e8 Merge pull request #347 from visualfc/cfunc
cl: check context.inCFunc
2024-06-17 22:27:33 +08:00
visualfc
96bf260ce9 cl: check context.inCFunc 2024-06-17 21:41:49 +08:00
xushiwei
115ea4ccbb Merge pull request #343 from xushiwei/q
cl: compileFuncDecl/funcName fix; patch library: sync; build: patch library fix (link dependencies)
2024-06-17 19:39:44 +08:00
xushiwei
3fb400beb4 merge upstream 2024-06-17 19:33:27 +08:00
xushiwei
6442279a44 testlibgo: sync (to do) 2024-06-17 19:30:59 +08:00
xushiwei
592500cb0c build: patch library fix (link dependencies) 2024-06-17 18:58:01 +08:00
xushiwei
98f3e45c0a cl: compileFuncDecl/funcName fix; patch library: sync 2024-06-17 18:32:58 +08:00
xushiwei
e365196ee3 Merge pull request #342 from aofei/dependencies
README,ci: add Dependencies section and update install instructions accordingly
2024-06-17 18:17:32 +08:00
xushiwei
f656499c23 Merge pull request #334 from aofei/build
build: explicitly link libpthread for compatibility with glibc versions before 2.34
2024-06-17 18:15:41 +08:00
Aofei Sheng
180c019d2e README,ci: add Dependencies section and update install instructions accordingly
Fixes #340
2024-06-17 18:15:08 +08:00
Aofei Sheng
7db50921bc build: explicitly link libpthread for compatibility with glibc versions before 2.34
Fixes #329
2024-06-17 14:07:51 +08:00
xushiwei
257b3f3ee6 Merge pull request #330 from visualfc/ssa.index
ssa: fix ssa.Index and indexType
2024-06-17 12:53:07 +08:00
xushiwei
f7c69b6baf Merge pull request #338 from aofei/install
ci,README: improve install instructions
2024-06-17 12:48:51 +08:00
xushiwei
89a3b84ea1 Merge pull request #339 from xushiwei/q
c/pthread/sync.Once
2024-06-17 12:47:36 +08:00
xushiwei
bec29f99e6 x 2024-06-17 12:39:54 +08:00
xushiwei
72274bda82 c/pthread/sync.Once 2024-06-17 12:14:24 +08:00
Aofei Sheng
04b62a62cb ci,README: improve install instructions 2024-06-17 12:03:09 +08:00
xushiwei
ab7329d3eb Merge pull request #335 from xushiwei/q
build: LLGoFiles (support to compile c files)
2024-06-17 11:06:43 +08:00
xushiwei
a819796ce2 build: LLGoFiles (support to compile c files) 2024-06-17 11:02:52 +08:00
xushiwei
8c6cdcc97e pkgPath 2024-06-17 05:35:05 +08:00
xushiwei
bf0148e047 canSkipToBuild 2024-06-17 05:33:07 +08:00
xushiwei
bcf44b8ab2 Merge pull request #333 from xushiwei/q
patch sync/atomic; typepatch fix (don't change types)
2024-06-17 04:16:33 +08:00
xushiwei
ebc9711309 TestErrImport 2024-06-17 04:11:31 +08:00
xushiwei
4097f90938 testlibgo: atomic 2024-06-17 03:53:31 +08:00
xushiwei
d73f77affc README: sync/atomic 2024-06-17 03:52:05 +08:00
xushiwei
b4794dc541 patch sync/atomic; typepatch fix (don't change types) 2024-06-17 03:38:01 +08:00
xushiwei
5ee156057e Merge pull request #332 from xushiwei/q
llgo:skipall; patch runtime, sync, sync/atomic
2024-06-16 23:15:04 +08:00
xushiwei
68a63bb280 TestIgnoreName 2024-06-16 23:11:28 +08:00
xushiwei
815677863f Merge pull request #331 from aofei/build
build: force use of LLVM Linker (lld) and fix usage of -dead_strip on Linux
2024-06-16 23:09:49 +08:00
xushiwei
df2f13c9b6 patch runtime, sync (use llgo:skipall) 2024-06-16 23:07:42 +08:00
Aofei Sheng
3984037c98 build: force use of LLVM Linker (lld) and fix usage of -dead_strip on Linux 2024-06-16 23:04:14 +08:00
xushiwei
9c8570b37d buildAllPkgs fix 2024-06-16 22:47:57 +08:00
visualfc
f7cddb81df ssa: fix ssa.Index and indexType 2024-06-16 22:18:02 +08:00
xushiwei
dc1fbbf796 llgo:skipall 2024-06-16 21:32:11 +08:00
xushiwei
7b7b4e5f22 patch sync/atomic 2024-06-16 20:49:31 +08:00
xushiwei
8c9b0285e4 testrt: gotypes 2024-06-16 17:12:08 +08:00
xushiwei
3ff5caef94 Merge pull request #328 from xushiwei/q
llgo/ssa: AtomicCmpXchg fix
2024-06-16 17:07:20 +08:00
xushiwei
4a3446a0a5 llgo/ssa: AtomicCmpXchg fix 2024-06-16 17:03:41 +08:00
xushiwei
6f6d9b39ba Merge pull request #327 from xushiwei/q
atomic Load/Store
2024-06-16 16:47:19 +08:00
xushiwei
7d2f68c5e4 TestErrBuiltin 2024-06-16 16:44:22 +08:00
xushiwei
5416e92dbf atomic demo 2024-06-16 16:39:55 +08:00
xushiwei
340b5bd165 atomic Load/Store 2024-06-16 16:35:46 +08:00
xushiwei
fbd15a81b4 Merge pull request #322 from luoliwoshang/cjson-linux
【WIP】README:cjson/sqlite download for linux
2024-06-16 15:26:51 +08:00
xushiwei
039d0abce2 Merge pull request #326 from xushiwei/q
atomic, atomicCmpXchg
2024-06-16 15:25:58 +08:00
xushiwei
aefb65b1b8 x 2024-06-16 15:23:38 +08:00
xushiwei
f7c322c311 demo: c atomic 2024-06-16 15:20:29 +08:00
xushiwei
b5507f79e4 atomic, atomicCmpXchg 2024-06-16 03:49:09 +08:00
luoliwoshang
a2703ce51b README:cjson sqlite download 2024-06-16 00:56:06 +08:00
xushiwei
d48b12aa09 Merge pull request #325 from xushiwei/q
build: use -dead_strip to reduce app size
2024-06-16 00:34:13 +08:00
xushiwei
452c1fbfd4 build: use -dead_strip to reduce app size 2024-06-16 00:31:25 +08:00
xushiwei
f77fd2a944 Merge pull request #324 from xushiwei/q
packages.LoadEx: support Deduper
2024-06-15 23:32:20 +08:00
xushiwei
2b1da5b231 loadPackageEx: dedup 2024-06-15 23:27:41 +08:00
xushiwei
1b48b98e22 refineEx: Deduper 2024-06-15 23:03:38 +08:00
xushiwei
4af872ddd5 loadPackageEx 2024-06-15 22:56:17 +08:00
xushiwei
6614107192 refineEx 2024-06-15 22:34:31 +08:00
xushiwei
09e1f9addf rm defaultDriverEx 2024-06-15 21:12:43 +08:00
xushiwei
baf282ecb2 packages.LoadEx: support Deduper 2024-06-15 20:46:29 +08:00
xushiwei
6022b32227 Merge pull request #323 from xushiwei/q
cl.NewPackageEx: don't skip alt(patch) package
2024-06-15 19:27:24 +08:00
xushiwei
9e9b08a5a3 cl.NewPackageEx: don't skip alt(patch) package 2024-06-15 19:18:21 +08:00
xushiwei
8147b974aa Merge pull request #321 from xushiwei/q
patches of a standard library; testlibgo: math
2024-06-15 18:49:03 +08:00
xushiwei
0a5a0ef319 cl/ssa.SetDebug 2024-06-15 18:41:45 +08:00
xushiwei
00c73b8388 ci 2024-06-15 18:28:39 +08:00
xushiwei
dcb8eb7d6d TestCollectSkipNames 2024-06-15 18:22:26 +08:00
xushiwei
7f11651311 TestGoLibMath: mac only (temp) 2024-06-15 18:08:08 +08:00
xushiwei
71518b025d TestGoLibMath: set LLGOROOT 2024-06-15 18:02:51 +08:00
xushiwei
287722b1d2 setPkgSSA 2024-06-15 17:56:45 +08:00
xushiwei
3a6f5dd4ee createAltSSAPkg 2024-06-15 17:40:05 +08:00
xushiwei
4aa3d321fa cltest.InitDebug 2024-06-15 16:26:37 +08:00
xushiwei
abb04b177c Merge remote-tracking branch 'gop/main' into q 2024-06-15 16:12:02 +08:00
xushiwei
764e0f0e7f TestGoLibMath 2024-06-15 16:08:10 +08:00
xushiwei
b668175c62 go package demo: math 2024-06-15 15:58:22 +08:00
xushiwei
5011c394d7 build: use typepatch.Pkg merge patches of a standard library 2024-06-15 15:52:44 +08:00
xushiwei
994502077a cl: collectSkipNames; processPkg bugfix 2024-06-15 14:56:03 +08:00
xushiwei
7d8bed16b0 createAltSSAPkg 2024-06-15 13:08:11 +08:00
xushiwei
a45be62b68 cl.NewPackageEx 2024-06-15 12:43:05 +08:00
xushiwei
e0a25b5098 NewPackage: altSSA 2024-06-15 12:10:08 +08:00
xushiwei
fa712aa3a0 build: aPackage.AltPkg/AltSSA 2024-06-15 11:44:52 +08:00
xushiwei
1599ba0294 private closureCtx/closureStub 2024-06-15 10:41:28 +08:00
xushiwei
94d567bf8f testlibgo: math 2024-06-15 10:24:10 +08:00
xushiwei
17f17bcc9e Merge pull request #320 from xushiwei/q
c/math; internal/lib/math
2024-06-15 10:05:23 +08:00
xushiwei
12c262621e c/sqlite: use pkg-config 2024-06-15 10:02:54 +08:00
xushiwei
dd35f2c14d c/math; internal/lib/math 2024-06-15 09:58:32 +08:00
xushiwei
66a9fd928a Merge pull request #319 from xushiwei/q
rm internal/runtime/c; mv internal/runtime/bdwgc => c/bdwgc
2024-06-15 08:50:34 +08:00
xushiwei
da82e5dd04 c/bdwgc 2024-06-15 08:47:13 +08:00
xushiwei
98498c9180 rm internal/runtime/c; mv internal/runtime/bdwgc => c/bdwgc 2024-06-15 08:43:48 +08:00
xushiwei
7b0ed42d3b Merge pull request #318 from xushiwei/q
internal/abi.Map: IndirectKey/IndirectElem
2024-06-15 08:28:20 +08:00
xushiwei
3e4fbde0b4 llgo/ssa: mv Range/Next => datastruct.go 2024-06-15 08:25:50 +08:00
xushiwei
7b0d23f91f internal/abi.Map: IndirectKey/IndirectElem 2024-06-15 08:21:27 +08:00
xushiwei
08d00fa234 Merge pull request #313 from visualfc/globals
ssa: global use elem type
2024-06-15 06:59:06 +08:00
xushiwei
2e32d9806f Merge pull request #315 from visualfc/abi
runtime: expand abi array
2024-06-15 06:55:41 +08:00
visualfc
6e73fbf65e runtime: expand abi array 2024-06-15 06:48:16 +08:00
xushiwei
b9f74d349c Merge pull request #317 from goplus/revert-316-q
Revert "runtime: map; llgo/ssa: MapUpdate"
2024-06-14 22:52:56 +08:00
xushiwei
5e45e38481 Revert "runtime: map; llgo/ssa: MapUpdate" 2024-06-14 22:50:23 +08:00
xushiwei
78b8455bba Merge pull request #316 from xushiwei/q
runtime: map; llgo/ssa: MapUpdate
2024-06-14 22:41:38 +08:00
xushiwei
6f71885aa2 TestMapUpdate 2024-06-14 22:37:46 +08:00
xushiwei
e107567997 llgo/ssa: MapUpdate fix 2024-06-14 22:33:40 +08:00
xushiwei
8d42acec16 disable llgo test temp 2024-06-14 22:14:18 +08:00
xushiwei
33d73eaecd llgo/ssa: abiMapOf 2024-06-14 22:07:48 +08:00
xushiwei
47b20b01d0 runtime: map; llgo/ssa: MapUpdate 2024-06-14 21:57:34 +08:00
xushiwei
b94cf700b4 Merge pull request #314 from luoliwoshang/link-cjson
llgo/x/cjson:link cjson by pkg-config
2024-06-14 19:11:01 +08:00
luoliwoshang
a26d30be3c llgo/x/cjson:link cjson by pkg-config 2024-06-14 11:36:48 +08:00
visualfc
ec1cca7ca4 ssa: global use elem type 2024-06-14 10:09:46 +08:00
visualfc
0c321c8c98 ssa: binop equal(func,slice,array,struct) and buildConstStr 2024-06-14 10:04:01 +08:00
xushiwei
7a54967bee runtime: map 2024-06-13 22:58:04 +08:00
xushiwei
f3b6d25aaa Merge pull request #309 from xushiwei/q
README: recover
2024-06-13 17:12:33 +08:00
xushiwei
419133d3e1 README: recover 2024-06-13 17:11:58 +08:00
xushiwei
1402ff371e Merge pull request #308 from aofei/README.md
README: fix LLGO_LIB_PYTHON instruction
2024-06-13 16:51:54 +08:00
Aofei Sheng
ee2d67c151 README: fix LLGO_LIB_PYTHON instruction 2024-06-13 15:40:35 +08:00
xushiwei
a8f1db0db1 Merge pull request #307 from xushiwei/q
recover
2024-06-13 13:55:07 +08:00
xushiwei
4abcbb9b51 recover 2024-06-13 13:51:36 +08:00
xushiwei
e33dd8acc3 Merge pull request #304 from xushiwei/q
testlibgo: math => mathbits
2024-06-13 07:33:46 +08:00
xushiwei
64e96cc101 testlibgo: math => mathbits 2024-06-13 07:30:08 +08:00
xushiwei
1aaa737dd6 Merge pull request #303 from xushiwei/q
llgo/ssa: float Const fix; cl: replace runtime => llgo/internal/runtime
2024-06-13 03:10:40 +08:00
xushiwei
31e3fc9060 x 2024-06-13 03:04:18 +08:00
xushiwei
b70b868552 TestReplaceGoName 2024-06-13 03:00:55 +08:00
xushiwei
7235357ef5 runtime: TODO - error var; cl: link goVar 2024-06-13 02:53:54 +08:00
xushiwei
18eecbe9f4 llgo/ssa: float Const fix; cl: replaceGoName runtime => llgo/internal/runtime 2024-06-13 00:56:18 +08:00
xushiwei
505525134f Merge pull request #302 from xushiwei/q
README: panic/defer
2024-06-12 23:28:30 +08:00
xushiwei
7dd740f51a README: panic/defer 2024-06-12 23:27:54 +08:00
xushiwei
3d590f8eb6 Merge pull request #301 from xushiwei/q
llgo/ssa: defer support panic; IndirectJump; runtime.Rethrow
2024-06-12 23:19:52 +08:00
xushiwei
42a5c6a19f c.GoDeferData; llgo/ssa: rm excepKey 2024-06-12 23:17:10 +08:00
xushiwei
2c4f6063a6 disable LLGO tests on ubuntu 2024-06-12 22:56:36 +08:00
xushiwei
845767b1d7 x 2024-06-12 21:13:47 +08:00
xushiwei
3e144af127 skip defer 2024-06-12 21:09:30 +08:00
xushiwei
45f470e3a7 merge upstream 2024-06-12 21:02:26 +08:00
xushiwei
42a5c60af6 runtime.Rethrow fix; llgo/ssa: IndirectJump fix 2024-06-12 20:53:30 +08:00
xushiwei
29cebd1e1f Merge pull request #300 from xushiwei/t
fix #294
2024-06-12 20:35:17 +08:00
xushiwei
4450f5a084 fix #294 2024-06-12 20:31:42 +08:00
xushiwei
b8230e144a Merge pull request #298 from visualfc/eface
ssa: interface equal
2024-06-12 20:29:15 +08:00
xushiwei
d500902eff TODO: noreturn 2024-06-12 17:38:29 +08:00
xushiwei
b787de0163 runtime: rethrow/panic; llgo/ssa: DeferData; Null => Nil 2024-06-12 17:26:07 +08:00
visualfc
2f0d525c2e ssa: binop EfaceEqual 2024-06-12 07:25:20 +08:00
visualfc
3f0c65ebb2 ssa: fix typeAssert for Nil 2024-06-11 20:50:01 +08:00
visualfc
f33796797d cl: _testgo/reader 2024-06-11 12:15:18 +08:00
xushiwei
68a09b9804 Merge pull request #299 from xushiwei/t
cl: isVargs support defer/go
2024-06-11 10:39:40 +08:00
xushiwei
5e5d149ca5 cl: isVargs support defer/go 2024-06-11 10:35:27 +08:00
visualfc
bdf1c275c4 ssa: interface equal 2024-06-11 10:24:30 +08:00
visualfc
439a69f413 ssa: fix cvtNamed 2024-06-11 10:23:36 +08:00
visualfc
a14974fbf2 cl: compile ssa.Field 2024-06-11 10:23:00 +08:00
xushiwei
1ecd9af2e1 Merge pull request #297 from cpunion/decl-test
cl: test decl only pkg kind
2024-06-11 08:28:41 +08:00
Li Jie
c8cc2dac04 cl: test decl only pkg kind 2024-06-09 19:23:22 +08:00
xushiwei
60dd33b48f llgo/ssa: defer support panic; IndirectJump/Switch 2024-06-09 09:08:22 +08:00
xushiwei
8b7d8b7786 Merge pull request #292 from xushiwei/q
disable gc: llgo -tags nogc
2024-06-08 23:12:34 +08:00
xushiwei
fb7ea7810e disable gc: llgo -tags nogc 2024-06-08 23:06:55 +08:00
xushiwei
508e16aa80 Merge pull request #291 from xushiwei/q
README: gc
2024-06-08 22:35:25 +08:00
xushiwei
a057db8756 README: gc 2024-06-08 22:30:06 +08:00
xushiwei
a1c588bde8 Merge pull request #284 from cpunion/bdwgc
Add bdwgc
2024-06-08 22:12:57 +08:00
xushiwei
9b17fdeae2 Merge pull request #290 from xushiwei/q
llgo/ssa: deferInitBuilder
2024-06-08 21:46:47 +08:00
xushiwei
29c0c737ed llgo/ssa: deferInitBuilder 2024-06-08 21:39:45 +08:00
xushiwei
be6986a7f6 Merge pull request #289 from xushiwei/q
llgo/ssa: getDefer fix
2024-06-08 20:15:07 +08:00
xushiwei
63c03bb28c llgo/ssa: getDefer fix 2024-06-08 20:09:56 +08:00
xushiwei
758f5b27c3 Merge pull request #288 from xushiwei/q
runtime.Defer: remove proc
2024-06-08 16:34:48 +08:00
xushiwei
32bfb3d57e runtime.Defer: remove proc 2024-06-08 16:31:52 +08:00
xushiwei
6bd8822a90 Merge pull request #287 from xushiwei/q
builtin: sigjmpbuf/sigsetjmp/siglongjmp
2024-06-08 15:19:56 +08:00
xushiwei
abf461a049 TestErrBuiltin 2024-06-08 15:17:49 +08:00
xushiwei
4e98055b9c TestFromTestlibc 2024-06-08 15:09:24 +08:00
xushiwei
e6ab5bd86d testFrom: expected == ';' means skipping out.ll 2024-06-08 15:04:35 +08:00
xushiwei
02e0651eab ignore setjmp/out.ll (os deps) 2024-06-08 14:59:26 +08:00
xushiwei
93be634673 builtin: sigjmpbuf/sigsetjmp/siglongjmp 2024-06-08 14:49:48 +08:00
xushiwei
a1978f661b Merge pull request #286 from xushiwei/t
llgo/ssa: eh.go (exception handling)
2024-06-08 13:34:30 +08:00
xushiwei
9bda864fed Merge remote-tracking branch 'gop/main' into q 2024-06-08 13:31:41 +08:00
xushiwei
b6903c6b99 llgo/ssa: eh.go (exception handling) 2024-06-08 13:31:11 +08:00
xushiwei
1e7394135d Merge pull request #285 from xushiwei/q
_demo: setjmp
2024-06-08 13:25:33 +08:00
Li Jie
61ccaab55b ci: show test result 2024-06-08 13:20:53 +08:00
xushiwei
f17c3c52c4 gitignore demo.ll 2024-06-08 13:12:32 +08:00
Li Jie
f16e721d01 ci: comment test result on PR 2024-06-08 13:11:24 +08:00
xushiwei
6dfdca2d19 _demo: setjmp 2024-06-08 13:10:59 +08:00
Li Jie
ee848e66ac test: run _demo/* and _pydemo/* 2024-06-08 13:10:20 +08:00
Li Jie
91e1fa6aff test: simple llgo tests 2024-06-08 10:15:28 +08:00
Li Jie
6049cf9047 runtime: add bdwgc 2024-06-08 10:15:28 +08:00
xushiwei
e91366c328 Merge pull request #282 from visualfc/runtime
build: check runtime link file
2024-06-08 07:54:00 +08:00
xushiwei
d6a5aaf4ad Merge pull request #283 from xushiwei/q
setjmp/trycatch
2024-06-08 00:13:06 +08:00
xushiwei
fcf3f2abc7 setjmp/trycatch 2024-06-08 00:08:29 +08:00
visualfc
ae77622026 build: build runtime check skip 2024-06-07 21:02:01 +08:00
visualfc
878b395e20 build: check runtime link file 2024-06-07 20:33:31 +08:00
xushiwei
92aee9b69c Merge pull request #281 from visualfc/build
build: build runtime local
2024-06-07 17:07:15 +08:00
visualfc
fe10ddc720 build: build runtime local 2024-06-07 15:25:35 +08:00
xushiwei
46899f042f Merge pull request #280 from xushiwei/q
demo: try..catch
2024-06-07 14:29:59 +08:00
xushiwei
d4249da131 demo: try..catch 2024-06-07 14:29:16 +08:00
xushiwei
6cae018066 Merge pull request #279 from xushiwei/q
c/setjmp/demo
2024-06-07 14:13:18 +08:00
xushiwei
95c1886df5 c/setjmp/demo 2024-06-07 14:12:35 +08:00
xushiwei
fbd8cb07ea Merge pull request #278 from xushiwei/q
c/setjmp
2024-06-07 13:51:10 +08:00
xushiwei
4868903844 c/setjmp 2024-06-07 13:48:36 +08:00
xushiwei
62e721b1c8 Merge pull request #276 from cpunion/libc
runtime: fix alias no effects on linux
2024-06-06 22:33:19 +08:00
Li Jie
1ceaf1df22 runtime: fix libc linking 2024-06-06 19:46:21 +08:00
xushiwei
21c9f7b7fb Merge pull request #275 from cpunion/libc
runtime: libc compatible
2024-06-06 17:24:06 +08:00
Li Jie
f5526f73c7 runtime: compatible difference of stdio symbols between linux and others 2024-06-06 17:17:26 +08:00
Li Jie
15fad2e841 cl: supports decl: <param> 2024-06-06 17:14:31 +08:00
xushiwei
3ecb43072d Merge pull request #272 from visualfc/typeassert
ssa: typeAssert support interface
2024-06-06 10:26:31 +08:00
visualfc
2fce2318ed ssa: set method.name to pkg.name if private 2024-06-06 07:30:59 +08:00
xushiwei
226fd29af8 Merge pull request #274 from xushiwei/q
ssa/python.go
2024-06-05 16:33:19 +08:00
xushiwei
c48b39baab ssa/python.go 2024-06-05 16:29:58 +08:00
xushiwei
ed19a6960e Merge pull request #273 from xushiwei/q
cl/blocks
2024-06-05 15:20:08 +08:00
xushiwei
11b4de63ee llgo_autogen.lla 2024-06-05 15:14:34 +08:00
xushiwei
b9d1d52ab3 gentests 2024-06-05 15:10:35 +08:00
xushiwei
fe548e580d use cl/blocks 2024-06-05 15:08:05 +08:00
xushiwei
fd7d2765c8 findLoop: reach 2024-06-05 15:02:11 +08:00
xushiwei
a226a70383 findLoop: mark fdel 2024-06-05 14:14:12 +08:00
xushiwei
519e69a7f8 cl/blocks 2024-06-05 13:48:11 +08:00
xushiwei
3d599f8044 Merge pull request #271 from goplus/dependabot/go_modules/golang.org/x/tools-0.22.0
build(deps): bump golang.org/x/tools from 0.21.0 to 0.22.0
2024-06-05 10:05:43 +08:00
dependabot[bot]
bbf0393008 build(deps): bump golang.org/x/tools from 0.21.0 to 0.22.0
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.21.0 to 0.22.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-05 00:52:06 +00:00
xushiwei
f1a4af013a Merge pull request #270 from xushiwei/q
llgo/ssa: NoArgsNoRet
2024-06-04 20:03:49 +08:00
xushiwei
05af9f9810 llgo/ssa: NoArgsNoRet 2024-06-04 20:02:45 +08:00
xushiwei
f68aada9f8 Merge pull request #269 from cpunion/link-args
build: support pkg-config and link args
2024-06-04 19:22:48 +08:00
Li Jie
52d60d9623 build: support pkg-config and link args 2024-06-04 16:35:17 +08:00
xushiwei
2ddf8a44bc Merge pull request #268 from visualfc/cast
cl: fix cl/_testrt/cast
2024-06-04 15:43:53 +08:00
visualfc
281fbc2bee cl: fix cl/_testrt/cast 2024-06-04 15:27:49 +08:00
xushiwei
c174568081 Merge pull request #266 from xushiwei/q
c/sqlite
2024-06-04 12:55:30 +08:00
xushiwei
f4a519c824 c/sqlite 2024-06-04 12:48:49 +08:00
xushiwei
62e4e2f716 Merge pull request #258 from visualfc/invoke
ssa: MakeInterface check abi.KindDirectIface
2024-06-04 10:35:38 +08:00
visualfc
193e6dfc93 ssa: ChangeInterface 2024-06-03 16:03:05 +08:00
visualfc
7596658e6c ssa: MakeInterface check abi.KindDirectIface 2024-06-03 11:47:16 +08:00
xushiwei
73d6bd8400 Merge pull request #264 from xushiwei/q
llgo/ssa getDefer fix: move to function start
2024-06-03 09:58:55 +08:00
xushiwei
922fabd935 llgo/ssa getDefer fix: move to function start 2024-06-03 09:56:39 +08:00
xushiwei
2f3d267439 Merge pull request #263 from xushiwei/q
llgo/ssa: DeferAlways/DeferInCond/DeferInLoop
2024-06-03 08:46:24 +08:00
xushiwei
bdaf7ff30b Merge remote-tracking branch 'gop/main' into q 2024-06-03 08:43:34 +08:00
xushiwei
cfca98512a llgo/ssa: DeferAlways/DeferInCond/DeferInLoop 2024-06-03 02:43:04 +08:00
xushiwei
23d9e86c46 Merge pull request #262 from xushiwei/q
README: defer
2024-06-03 01:43:43 +08:00
xushiwei
6ac6fb0192 README: defer 2024-06-03 01:43:17 +08:00
xushiwei
aaa36b9d3b Merge pull request #261 from xushiwei/q
defer support; llgo/ssa: IfThen/RunDefers/EndBuild
2024-06-03 01:35:33 +08:00
xushiwei
2c799a8ccf deferInit bugfix 2024-06-03 01:32:25 +08:00
xushiwei
56a5a7d72e defer refactor 2024-06-03 01:06:01 +08:00
xushiwei
410f9dd759 llgo/ssa: EndBuild 2024-06-02 21:54:51 +08:00
xushiwei
ba45217756 llgo/ssa: RunDefers 2024-06-02 15:24:42 +08:00
xushiwei
5a5929048d defer support; llgo/ssa: IfThen 2024-06-02 14:29:35 +08:00
xushiwei
bfc3c7fbf9 Merge pull request #257 from xushiwei/q
llgo/ssa: Builtin
2024-06-01 17:33:01 +08:00
xushiwei
e151bd4cd1 TestUserdefExpr 2024-06-01 17:30:37 +08:00
xushiwei
bfe68520f4 logCall: ignore vkBuiltin 2024-06-01 17:26:42 +08:00
xushiwei
45734c0b5c llgo/ssa: Builtin 2024-06-01 17:18:17 +08:00
xushiwei
d689062fc3 Merge pull request #256 from xushiwei/q
README: goroutine
2024-06-01 16:17:24 +08:00
xushiwei
881574ed39 README: goroutine 2024-06-01 16:14:26 +08:00
xushiwei
0bd5aa873b Merge pull request #255 from xushiwei/q
goroutine support; llgo/ssa: memory (malloc/free)
2024-06-01 16:09:31 +08:00
xushiwei
51f3ac2376 _testgo: goroutine 2024-06-01 16:04:35 +08:00
xushiwei
e5802853c0 goroutine support; llgo/ssa: memory (malloc/free) 2024-06-01 15:52:54 +08:00
xushiwei
edb5e36916 Merge pull request #254 from xushiwei/q
c/pthread
2024-05-31 20:07:00 +08:00
xushiwei
33ba94e784 c/pthread 2024-05-31 20:02:59 +08:00
xushiwei
9c969e0026 Merge pull request #252 from visualfc/fnnamed
ssa: fix llvm named in func
2024-05-31 16:26:25 +08:00
visualfc
858622a98d move eface demo to cl/_testrt 2024-05-31 15:53:52 +08:00
visualfc
c673489461 ssa: fix llvm named in func 2024-05-31 14:22:17 +08:00
xushiwei
53a39b6947 Merge pull request #251 from xushiwei/q
llgo/ssa: Do Call/Go/Defer
2024-05-31 12:06:09 +08:00
xushiwei
8f82d86a5d llgo/ssa: Do Call/Go/Defer 2024-05-31 12:01:11 +08:00
xushiwei
f607cd8bad Merge pull request #246 from visualfc/link_go
ssa: update linkname go style
2024-05-31 08:49:19 +08:00
visualfc
5b0965dc53 ssa: update linkname go style 2024-05-31 08:40:38 +08:00
xushiwei
0db78100cd Merge pull request #250 from xushiwei/q
README: interface demo
2024-05-31 08:33:10 +08:00
xushiwei
2196f2259f README: interface demo 2024-05-31 08:31:00 +08:00
xushiwei
55814cbda4 Merge pull request #249 from xushiwei/q
iface; abiTypes
2024-05-31 08:18:45 +08:00
xushiwei
6fb48023f2 TestMakeInterface 2024-05-31 08:16:28 +08:00
xushiwei
76c1800a53 abiTypes: abiTypeInit fix 2024-05-31 08:12:27 +08:00
xushiwei
3b2f01e974 abiTypes 2024-05-31 07:35:22 +08:00
xushiwei
db141e1f3f Merge remote-tracking branch 'gop/main' into q 2024-05-30 16:28:43 +08:00
xushiwei
8ca8824165 Merge pull request #247 from visualfc/slice_array
ssa: fix slice type from *array
2024-05-30 16:28:07 +08:00
visualfc
2e49161415 ssa: fix slice type from *array 2024-05-29 12:34:06 +08:00
xushiwei
e5f38a6fc1 abitype.go 2024-05-28 23:58:37 +08:00
xushiwei
8c105d87c1 runtime: newNamed; llgo/ssa: abiMethodOf 2024-05-28 23:45:32 +08:00
xushiwei
8c2946a41b prog.PointerSize 2024-05-28 17:55:26 +08:00
xushiwei
4f21915f35 Merge pull request #244 from xushiwei/q
TypeSizes: goProgram
2024-05-28 17:47:36 +08:00
xushiwei
585bdb549f build fix: llssa.Initialize before NewProgram 2024-05-28 17:41:50 +08:00
xushiwei
8091c9e737 goProgram: SizeOf/Offsetof fix 2024-05-28 17:32:09 +08:00
xushiwei
fc504e18d2 TypeSizes: goProgram 2024-05-28 16:59:47 +08:00
xushiwei
90c76bb992 Merge pull request #243 from xushiwei/q
github.com/goplus/llgo/internal/packages; prog.TypeSizes: todo
2024-05-28 12:25:38 +08:00
xushiwei
3da1aa3ec6 github.com/goplus/llgo/internal/packages; prog.TypeSizes: todo 2024-05-28 12:22:43 +08:00
xushiwei
0a0d72e016 Merge pull request #242 from xushiwei/q
runtime: rm NewSlice (use b.unsafeSlice); llgo/ssa: Println
2024-05-28 08:09:34 +08:00
xushiwei
550889808a TestUnsafeString 2024-05-28 08:06:58 +08:00
xushiwei
1c1da6433a runtime: rm NewSlice (use b.unsafeSlice); llgo/ssa: Println 2024-05-28 07:47:07 +08:00
xushiwei
963d7958ea Merge pull request #241 from xushiwei/q
AfterInit fix
2024-05-27 15:55:04 +08:00
xushiwei
7031247614 testgo: errors 2024-05-27 15:52:35 +08:00
xushiwei
07738e13ef AfterInit fix 2024-05-27 15:49:25 +08:00
xushiwei
3ab96aa1ee Merge pull request #237 from visualfc/eface
ssa: sliceOf arrayOf
2024-05-27 15:35:44 +08:00
visualfc
bdd3f6ed44 ssa: use DefaultTargetTriple for targetData 2024-05-27 14:54:26 +08:00
visualfc
3328847e27 ssa: sliceOf arrayOf 2024-05-27 14:54:24 +08:00
xushiwei
4a6f072361 Merge pull request #240 from xushiwei/q
llgo/ssa: abiMethodOf; AfterInit bugfix
2024-05-27 14:38:03 +08:00
xushiwei
5bbcdd121a TestFromTestgo 2024-05-27 14:32:49 +08:00
xushiwei
8e89dc8aa9 llgo/ssa: abiMethodOf; AfterInit bugfix 2024-05-27 14:32:23 +08:00
xushiwei
c458b726b4 Merge pull request #239 from xushiwei/q
abi.TypeName
2024-05-27 12:02:11 +08:00
xushiwei
c0a156f347 abi.TypeName 2024-05-27 12:00:01 +08:00
xushiwei
8e12cd6b02 Merge pull request #238 from xushiwei/q
llgo/ssa: Imethod; PrintIface; call intf.method
2024-05-27 11:54:21 +08:00
xushiwei
a6f92b8ff9 TestFromTestgo 2024-05-27 11:28:03 +08:00
xushiwei
cdb1cf1b63 runtime 2024-05-27 11:21:22 +08:00
xushiwei
877b397e04 cl: call intf.method 2024-05-27 11:18:43 +08:00
xushiwei
df13e3ab82 PrintIface 2024-05-27 09:56:42 +08:00
xushiwei
8536fe4987 llgo/ssa: Imethod 2024-05-27 09:46:07 +08:00
xushiwei
eba08334d1 abi InterfaceName/FuncName 2024-05-27 08:50:30 +08:00
xushiwei
165a99fd83 llgo/ssa: unsafeInterface; runtime.PointerTo 2024-05-27 08:07:34 +08:00
xushiwei
6754a9f3da Merge pull request #236 from xushiwei/q
rm unused code (phi, abi.Name)
2024-05-26 18:18:30 +08:00
xushiwei
12b0d81dda rm unused code (phi, abi.Name) 2024-05-26 18:10:17 +08:00
xushiwei
95da7c1c87 Merge pull request #235 from xushiwei/q
runtime: iface; llgo/ssa: phi refactor; remove abi.Name
2024-05-26 18:04:03 +08:00
xushiwei
c903785864 gentests 2024-05-26 17:55:16 +08:00
xushiwei
eae94c5f23 remove abi.Name 2024-05-26 17:53:29 +08:00
xushiwei
ddabfdca3d SetBlockEx: BeforeLast 2024-05-26 16:18:24 +08:00
xushiwei
5cf6a30027 llgo/ssa: phi refactor 2024-05-26 14:58:26 +08:00
xushiwei
91c9b4e168 llgo/ssa: pkgName 2024-05-26 09:34:43 +08:00
xushiwei
914a0c60b0 runtime: iface 2024-05-26 08:59:10 +08:00
xushiwei
773fb7c75b Merge pull request #233 from xushiwei/q
runtime: Func, Method, Imethod
2024-05-25 23:08:50 +08:00
xushiwei
afe20ffe92 runtime: Func, Method, Imethod 2024-05-25 22:52:48 +08:00
xushiwei
0b72c0b25c Merge pull request #232 from xushiwei/q
NameOff => Name; TypeOff => *Type; TextOff => Text
2024-05-25 22:00:24 +08:00
xushiwei
f06899303c gblarray 2024-05-25 21:47:02 +08:00
xushiwei
b121d1730b NameOff => Name; TypeOff => *Type; TextOff => Text 2024-05-25 21:43:59 +08:00
xushiwei
5d570b5140 Merge pull request #231 from xushiwei/q
iface
2024-05-25 12:00:43 +08:00
xushiwei
980a537930 iface: todo 2024-05-25 11:57:09 +08:00
xushiwei
d700c78f6c Merge pull request #230 from xushiwei/q
Index: mark unreachable
2024-05-25 08:43:16 +08:00
xushiwei
c7abc03fee Index: mark unreachable 2024-05-25 08:40:04 +08:00
xushiwei
9f243563b9 Merge pull request #229 from xushiwei/q
TypeAssert bugfix; abi: support named
2024-05-25 08:23:54 +08:00
xushiwei
5eac8d860a abiType fix 2024-05-25 08:20:09 +08:00
xushiwei
1c8f860b6e gentests 2024-05-25 07:47:00 +08:00
xushiwei
1226308f3d TypeAssert bugfix; testcase struczero 2024-05-25 07:43:24 +08:00
xushiwei
40dd25c122 abi: support named 2024-05-25 01:11:35 +08:00
xushiwei
fa71885cf9 Merge pull request #228 from xushiwei/q
test extractVal
2024-05-24 23:12:17 +08:00
xushiwei
2a7be0eabb Eface 2024-05-24 23:09:38 +08:00
xushiwei
ab7c828cfa InterfaceData 2024-05-24 23:06:54 +08:00
xushiwei
e6f8cfb16c test extractVal 2024-05-24 23:06:11 +08:00
xushiwei
0283a42273 Merge pull request #227 from xushiwei/q
abiType: support pointer
2024-05-24 22:58:16 +08:00
xushiwei
d1a6d29fdd x 2024-05-24 22:55:21 +08:00
xushiwei
ee15aa888f merge upstream 2024-05-24 22:50:33 +08:00
xushiwei
3cc975813d abiType: support pointer 2024-05-24 22:47:45 +08:00
xushiwei
f226177bca Merge pull request #224 from visualfc/utf8
ssa: string range; string convert bytes/rune; op eql/less
2024-05-24 11:06:12 +08:00
xushiwei
995478adac Merge pull request #225 from visualfc/typed
ssa: fix type toNamed
2024-05-24 10:55:15 +08:00
visualfc
62915d5af5 ssa: string range; string convert bytes/rune; op eql/less 2024-05-24 10:55:13 +08:00
visualfc
825e2eec51 ssa: fix type toNamed 2024-05-24 10:39:28 +08:00
xushiwei
b7f2bae2ef Merge pull request #226 from xushiwei/q
refactor: eface (any)
2024-05-24 10:34:10 +08:00
xushiwei
9b4701fed7 runtime.Struct: temp disable abi.NewName 2024-05-24 10:30:56 +08:00
xushiwei
937e55eb46 TestFromTestgo 2024-05-24 10:01:41 +08:00
xushiwei
7c003e9e7a TestMakeInterface 2024-05-24 09:52:46 +08:00
xushiwei
f0f973eb00 TestAbi 2024-05-24 09:50:51 +08:00
xushiwei
f399dd3498 TestAny 2024-05-24 09:46:29 +08:00
xushiwei
d2e5bb99ef gentests; MakeBody fix 2024-05-24 09:41:40 +08:00
xushiwei
77eeea95c7 valFromData BitCast bugfix 2024-05-24 09:30:16 +08:00
xushiwei
056ad51c24 llgo/ssa.Phi: AddIncoming fix 2024-05-24 09:20:58 +08:00
xushiwei
97e38255c6 llgo/ssa.Slice optimize speed 2024-05-24 08:23:01 +08:00
xushiwei
88004cac76 abiBasic fix 2024-05-24 07:51:41 +08:00
xushiwei
1162a5f916 AfterInit: init 2024-05-24 03:22:10 +08:00
xushiwei
418c37dd52 AfterInit bugfix: add param Builder 2024-05-24 02:42:10 +08:00
xushiwei
b66827998d llgo/ssa: AfterInit 2024-05-24 02:09:57 +08:00
xushiwei
b195656900 llgo/ssa: MakeInterface 2024-05-24 01:45:41 +08:00
xushiwei
2628ee98f3 llgo/ssa: valFromData, buildVal 2024-05-24 01:18:18 +08:00
xushiwei
176c0b2d36 abi.KindOf; llgo/ssa: valFromData 2024-05-24 00:36:51 +08:00
xushiwei
4986592dd7 TypeAssert refactor 2024-05-23 01:34:48 +08:00
xushiwei
a4c4324ba3 merge Field/Extract; prog.Tuple/Zero; TypeAssert refactor 2024-05-23 01:10:13 +08:00
xushiwei
6442ab2f20 llgo/ssa: unsafeEface 2024-05-22 13:47:21 +08:00
xushiwei
c19786bdfb llgo/ssa: AfterInit/SliceLit/InterfaceData, unsafe.Slice; ssa/abi: Basic/Struct 2024-05-22 10:07:21 +08:00
xushiwei
1b498128ef Merge pull request #222 from xushiwei/q
remove runtime.NewString
2024-05-21 01:45:01 +08:00
xushiwei
556939139b x 2024-05-21 01:42:49 +08:00
xushiwei
d5dfd37385 merge upstream 2024-05-21 01:32:06 +08:00
xushiwei
508b4d648d remove runtime.NewString 2024-05-21 01:30:15 +08:00
xushiwei
163813145d Merge pull request #221 from visualfc/printf
runtime: PrintFloat
2024-05-21 00:21:25 +08:00
visualfc
5baa1aaa2a runtime: PrintFloat 2024-05-20 22:50:37 +08:00
xushiwei
59b7d5a9f4 Merge pull request #220 from xushiwei/q
runtime: print/println
2024-05-20 21:48:42 +08:00
xushiwei
bbd1187a9c runtime: print/println 2024-05-20 21:32:10 +08:00
xushiwei
3f65ae39af Merge pull request #219 from xushiwei/q
runtime: Struct
2024-05-20 13:53:52 +08:00
xushiwei
8bac9853fa merge upstream 2024-05-20 13:51:50 +08:00
xushiwei
301a6736ac Merge pull request #218 from visualfc/println
ssa: fix builtin print
2024-05-20 13:50:12 +08:00
xushiwei
55ee21421e runtime: Struct 2024-05-20 13:47:32 +08:00
visualfc
1a4ca389cd ssa: fix builtin print 2024-05-20 12:43:37 +08:00
xushiwei
27cfeefef1 Merge pull request #217 from xushiwei/q
abi.Name; runtime: MakeAnyInt => MakeAnyIntptr; llgo/ssa: AllocU; bui…
2024-05-20 10:25:56 +08:00
xushiwei
cc357b2b7d llgo/ssa: TestMakeInterface (32bits); ssa/ssatest 2024-05-20 10:23:24 +08:00
xushiwei
6335ac6a47 runtime.MakeAnyIntptr 2024-05-20 08:51:27 +08:00
xushiwei
e61ebb4eb9 abi.Name; runtime: MakeAnyInt => MakeAnyIntptr; llgo/ssa: AllocU; builtin unsafe.String; MakeInterface; prog.PointerSize 2024-05-20 08:46:39 +08:00
xushiwei
a6b8edde62 Merge pull request #216 from goplus/dependabot/go_modules/github.com/goplus/llvm-0.7.6
build(deps): bump github.com/goplus/llvm from 0.7.6-0.20240519084034-a108b65b00c7 to 0.7.6
2024-05-19 22:49:27 +08:00
dependabot[bot]
a4450db277 build(deps): bump github.com/goplus/llvm
Bumps [github.com/goplus/llvm](https://github.com/goplus/llvm) from 0.7.6-0.20240519084034-a108b65b00c7 to 0.7.6.
- [Release notes](https://github.com/goplus/llvm/releases)
- [Commits](https://github.com/goplus/llvm/commits/v0.7.6)

---
updated-dependencies:
- dependency-name: github.com/goplus/llvm
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-19 14:46:48 +00:00
xushiwei
b7e38e95f0 Merge pull request #215 from visualfc/copy
ssa: builtin copy
2024-05-19 22:45:57 +08:00
visualfc
cda572fd59 ssa: builtin copy 2024-05-19 19:33:41 +08:00
xushiwei
af4a0ffa21 Merge pull request #214 from xushiwei/q
update llvm
2024-05-19 16:48:22 +08:00
xushiwei
f786c86f77 x 2024-05-19 16:46:05 +08:00
xushiwei
55365b1d17 update llvm 2024-05-19 16:42:22 +08:00
xushiwei
d605c850b7 Merge pull request #213 from xushiwei/q
llgo/ssa: Builder add Pkg
2024-05-19 13:03:28 +08:00
xushiwei
5bb33ce420 Merge pull request #212 from visualfc/doc
doc: update Go packages support
2024-05-19 13:01:34 +08:00
xushiwei
39268c681f llgo/ssa: Builder add Pkg 2024-05-19 13:00:58 +08:00
visualfc
a2b82c18d7 doc 2024-05-19 12:38:22 +08:00
xushiwei
83a9ab44bd Merge pull request #211 from xushiwei/q
llgo/ssa: {datstruct, interface}.go
2024-05-19 12:32:24 +08:00
xushiwei
3bf3a276de MakeInterface: todo 2024-05-19 12:31:59 +08:00
xushiwei
9a7fbaee00 llgo/ssa: {datstruct, interface}.go 2024-05-19 12:24:42 +08:00
xushiwei
6ed01f24be Merge pull request #210 from xushiwei/q
README: matplotlib; llgo/ssa: pkg.PyLoadModSyms (source code stablility)
2024-05-19 07:58:53 +08:00
xushiwei
04428c5aed llgo/ssa: pkg.PyLoadModSyms (source code stablility) 2024-05-19 07:57:12 +08:00
xushiwei
ba8e48be38 README: matplotlib 2024-05-19 07:28:56 +08:00
xushiwei
bc2613c42b Merge pull request #209 from xushiwei/q
py/matplotlib, py/matplotlib/pyplot
2024-05-19 00:52:26 +08:00
xushiwei
ac71a45b3b py/matplotlib, py/matplotlib/pyplot 2024-05-19 00:50:09 +08:00
xushiwei
30425a194e Merge pull request #208 from xushiwei/q
cl: funcOf fix: call pyfunc multiple times
2024-05-19 00:17:22 +08:00
xushiwei
63e678928b cl: funcOf fix: call pyfunc multiple times 2024-05-19 00:15:23 +08:00
xushiwei
e32896137e Merge pull request #207 from xushiwei/q
py/std done; demo: max; llgen.Gen fix: use imp
2024-05-18 23:36:30 +08:00
xushiwei
0787909045 llgen.Gen fix: use imp 2024-05-18 23:34:37 +08:00
xushiwei
1acfb53c4c py/std done; demo: max 2024-05-18 23:14:56 +08:00
xushiwei
46c7e53ca1 Merge pull request #206 from xushiwei/q
py/std: builtins; pydemo: print, tensor
2024-05-18 22:33:26 +08:00
xushiwei
7228709616 py/std: builtins; pydemo: print, tensor 2024-05-18 22:30:35 +08:00
xushiwei
2ca5d39f7d Merge pull request #205 from xushiwei/q
README: pysigfetch
2024-05-18 20:08:12 +08:00
xushiwei
08583463be README: pysigfetch 2024-05-18 20:07:41 +08:00
xushiwei
84d3f6ac9c Merge pull request #204 from goplus/dependabot/go_modules/github.com/goplus/gogen-1.16.0
build(deps): bump github.com/goplus/gogen from 1.15.2 to 1.16.0
2024-05-18 19:54:41 +08:00
xushiwei
0f8fc7bdee Merge pull request #203 from xushiwei/q
remove c2go support
2024-05-18 19:54:15 +08:00
dependabot[bot]
cc0ae5e229 build(deps): bump github.com/goplus/gogen from 1.15.2 to 1.16.0
Bumps [github.com/goplus/gogen](https://github.com/goplus/gogen) from 1.15.2 to 1.16.0.
- [Release notes](https://github.com/goplus/gogen/releases)
- [Commits](https://github.com/goplus/gogen/compare/v1.15.2...v1.16.0)

---
updated-dependencies:
- dependency-name: github.com/goplus/gogen
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-18 11:52:45 +00:00
xushiwei
5750447826 remove c2go support 2024-05-18 19:51:39 +08:00
644 changed files with 157473 additions and 4784 deletions

View File

@@ -5,25 +5,45 @@ name: Go
on:
push:
branches: [ "main" ]
branches: [ "*" ]
pull_request:
branches: [ "main" ]
branches: [ "*" ]
jobs:
test-macos:
runs-on: macos-latest
test:
strategy:
matrix:
llvm: [17]
# os: [macos-latest, ubuntu-latest]
os: [macos-latest]
llvm: [18]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Update Homebrew
if: matrix.llvm == 17 # needed as long as LLVM 17 is still fresh
# needed as long as LLVM 18 is still fresh
if: matrix.llvm == 18 && startsWith(matrix.os, 'macos')
run: brew update
- name: Install LLVM ${{ matrix.llvm }}
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@${{ matrix.llvm }}
- name: Install LLVM ${{ matrix.llvm }} and bdw-gc
if: startsWith(matrix.os, 'macos')
run: |
HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@${{ matrix.llvm }} bdw-gc
echo `brew --prefix llvm@${{ matrix.llvm }}`/bin >> $GITHUB_PATH
- name: Install LLVM ${{ matrix.llvm }} and libgc-dev
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 libcjson-dev libsqlite3-dev python3.11-dev
echo /usr/lib/llvm-${{ matrix.llvm }}/bin >> $GITHUB_PATH
- name: Clang information
run: |
echo $PATH
which clang
clang --version
- name: Set up Go
uses: actions/setup-go@v5
@@ -34,36 +54,40 @@ jobs:
run: go build -v ./...
- name: Test
if: matrix.os != 'macos-latest'
run: go test -v ./...
test-linux:
runs-on: ubuntu-20.04
strategy:
matrix:
llvm: [17]
steps:
- uses: actions/checkout@v4
- name: Test with coverage
if: matrix.os == 'macos-latest'
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
- name: Install LLVM ${{ matrix.llvm }}
run: |
echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${{ 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 --no-install-recommends llvm-${{ matrix.llvm }}-dev
- name: Install
run: go install ./...
- name: LLGO tests
if: matrix.os != 'ubuntu-latest'
run: |
echo "Test result on ${{ matrix.os }} with LLVM ${{ matrix.llvm }}" > result.md
LLGOROOT=$PWD bash .github/workflows/test_llgo.sh
- name: Test _demo and _pydemo
run: |
set +e
LLGOROOT=$PWD bash .github/workflows/test_demo.sh
exit 0
- name: Show test result
run: cat result.md
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.20'
- 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: Build
run: go build -v ./...
- name: Test
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: goplus/llgo
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: goplus/llgo

40
.github/workflows/populate_darwin_sysroot.sh vendored Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
set -e
TMPDIR="$(mktemp -d)"
export TMPDIR
trap 'rm -rf "${TMPDIR}"' EXIT
DARWIN_AMD64_LLVM_PREFIX=.sysroot/darwin/amd64/usr/local/opt/llvm@18
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.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}"
curl -fsSL -H "Authorization: Bearer QQ==" "${BREW_LLVM_ARM64_BOTTLE_URL}" | tar -xzf - --strip-components=2 -C "${DARWIN_ARM64_LLVM_PREFIX}"
patch_homebrew_lib_dir() {
local LIB_DIR="$1"
local HOMEBREW_PREFIX="$2"
for DYLIB_FILE in "${LIB_DIR}"/*.dylib; do
if [[ -f "${DYLIB_FILE}" ]]; then
ID=$(otool -D "${DYLIB_FILE}" | grep '@@HOMEBREW_PREFIX@@' | awk '{print $1}')
if [[ -n "${ID}" ]]; then
NEW_ID=${ID/'@@HOMEBREW_PREFIX@@'/${HOMEBREW_PREFIX}}
install_name_tool -id "${NEW_ID}" "${DYLIB_FILE}"
fi
DEPS=$(otool -L "${DYLIB_FILE}" | grep '@@HOMEBREW_PREFIX@@' | awk '{print $1}')
for DEP in ${DEPS}; do
NEW_DEP=${DEP/'@@HOMEBREW_PREFIX@@'/${HOMEBREW_PREFIX}}
install_name_tool -change "${DEP}" "${NEW_DEP}" "${DYLIB_FILE}"
done
fi
done
}
patch_homebrew_lib_dir "${DARWIN_AMD64_LLVM_PREFIX}/lib" /usr/lib
patch_homebrew_lib_dir "${DARWIN_ARM64_LLVM_PREFIX}/lib" /opt/homebrew

143
.github/workflows/populate_linux_sysroot.sh vendored Executable file
View File

@@ -0,0 +1,143 @@
#!/bin/bash
set -e
TMPDIR="$(mktemp -d)"
export TMPDIR
trap 'rm -rf "${TMPDIR}"' EXIT
LINUX_AMD64_PREFIX=.sysroot/linux/amd64
LINUX_ARM64_PREFIX=.sysroot/linux/arm64
mkdir -p "${LINUX_AMD64_PREFIX}" "${LINUX_ARM64_PREFIX}"
POPULATE_LINUX_SYSROOT_SCRIPT="$(mktemp)"
cat > "${POPULATE_LINUX_SYSROOT_SCRIPT}" << EOF
#!/bin/bash
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y lsb-release gnupg2 wget rsync
echo "deb http://apt.llvm.org/\$(lsb_release -cs)/ llvm-toolchain-\$(lsb_release -cs)-18 main" | tee /etc/apt/sources.list.d/llvm.list
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
apt-get update
apt-get install -y llvm-18-dev
error() {
echo -e "\$1" >&2
exit 1
}
exclude_list=()
include_list=()
exclude_list+=(--exclude "/bin")
exclude_list+=(--exclude "/boot")
exclude_list+=(--exclude "/boot*")
exclude_list+=(--exclude "/dev")
exclude_list+=(--exclude "/etc")
exclude_list+=(--exclude "/home")
exclude_list+=(--exclude "/lib/dhcpd")
exclude_list+=(--exclude "/lib/firmware")
exclude_list+=(--exclude "/lib/hdparm")
exclude_list+=(--exclude "/lib/ifupdown")
exclude_list+=(--exclude "/lib/modules")
exclude_list+=(--exclude "/lib/modprobe.d")
exclude_list+=(--exclude "/lib/modules-load.d")
exclude_list+=(--exclude "/lib/resolvconf")
exclude_list+=(--exclude "/lib/startpar")
exclude_list+=(--exclude "/lib/systemd")
exclude_list+=(--exclude "/lib/terminfo")
exclude_list+=(--exclude "/lib/udev")
exclude_list+=(--exclude "/lib/xtables")
exclude_list+=(--exclude "/lib/ssl/private")
exclude_list+=(--exclude "/lost+found")
exclude_list+=(--exclude "/media")
exclude_list+=(--exclude "/mnt")
exclude_list+=(--exclude "/proc")
exclude_list+=(--exclude "/root")
exclude_list+=(--exclude "/run")
exclude_list+=(--exclude "/sbin")
exclude_list+=(--exclude "/srv")
exclude_list+=(--exclude "/sys")
exclude_list+=(--exclude "/tmp")
exclude_list+=(--exclude "/usr/bin")
exclude_list+=(--exclude "/usr/games")
exclude_list+=(--exclude "/usr/sbin")
exclude_list+=(--exclude "/usr/share")
exclude_list+=(--exclude "/usr/src")
exclude_list+=(--exclude "/usr/local/bin")
exclude_list+=(--exclude "/usr/local/etc")
exclude_list+=(--exclude "/usr/local/games")
exclude_list+=(--exclude "/usr/local/man")
exclude_list+=(--exclude "/usr/local/sbin")
exclude_list+=(--exclude "/usr/local/share")
exclude_list+=(--exclude "/usr/local/src")
exclude_list+=(--exclude "/usr/lib/ssl/private")
exclude_list+=(--exclude "/var")
exclude_list+=(--exclude "/snap")
exclude_list+=(--exclude "*python*")
include_list+=(--include "*.a")
include_list+=(--include "*.so")
include_list+=(--include "*.so.*")
include_list+=(--include "*.h")
include_list+=(--include "*.hh")
include_list+=(--include "*.hpp")
include_list+=(--include "*.hxx")
include_list+=(--include "*.pc")
include_list+=(--include "*.def")
include_list+=(--include "*.inc")
include_list+=(--include "/lib")
include_list+=(--include "/lib32")
include_list+=(--include "/lib64")
include_list+=(--include "/libx32")
include_list+=(--include "*/")
do-sync() {
from=\$1
to=\$2
args=()
args+=(-a)
args+=(-z)
args+=(-m)
args+=(-d)
args+=(-h)
args+=(--keep-dirlinks)
args+=("--info=progress2")
args+=(--delete)
args+=(--prune-empty-dirs)
args+=(--sparse)
args+=(--links)
args+=(--copy-unsafe-links)
args+=("\${exclude_list[@]}")
args+=("\${include_list[@]}")
args+=(--exclude "*")
args+=("\${from}")
args+=("\${to}")
echo "\${args[@]}"
rsync "\${args[@]}"
exit \$?
}
do-sync / /sysroot/
EOF
chmod +x "${POPULATE_LINUX_SYSROOT_SCRIPT}"
populate_linux_sysroot() {
local ARCH="$1"
local PREFIX="$2"
docker run \
--rm \
--platform "linux/${ARCH}" \
-v "$(pwd)/${PREFIX}":/sysroot \
-v "${POPULATE_LINUX_SYSROOT_SCRIPT}":/populate_linux_sysroot.sh \
debian:bullseye \
/populate_linux_sysroot.sh
}
populate_linux_sysroot amd64 "${LINUX_AMD64_PREFIX}"
populate_linux_sysroot arm64 "${LINUX_ARM64_PREFIX}"

58
.github/workflows/release-build.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: Release Build
on:
push:
tags:
- "*"
jobs:
populate-darwin-sysroot:
runs-on: macos-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Populate Darwin sysroot
run: bash .github/workflows/populate_darwin_sysroot.sh
- name: Create Darwin sysroot tarball
run: tar -czvf .sysroot/darwin.tar.gz -C .sysroot darwin
- name: Upload Darwin sysroot tarball
uses: actions/upload-artifact@v4
with:
name: darwin-sysroot-tarball
path: .sysroot/darwin.tar.gz
compression-level: 0
build:
runs-on: ubuntu-latest
needs: populate-darwin-sysroot
steps:
- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.20.x
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Download Darwin sysroot tarball
uses: actions/download-artifact@v4
with:
name: darwin-sysroot-tarball
path: .sysroot
- name: Populate Darwin sysroot
run: tar -xzvf .sysroot/darwin.tar.gz -C .sysroot
- name: Populate Linux sysroot
run: bash .github/workflows/populate_linux_sysroot.sh
- name: Run GoReleaser
env:
GITHUB_TOKEN: ${{github.token}}
run: |
docker run \
--rm \
-e GITHUB_TOKEN=${GITHUB_TOKEN} \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(pwd):/go/src/llgo \
-w /go/src/llgo \
ghcr.io/goreleaser/goreleaser-cross:v1.22 \
release --clean --skip nfpm,snapcraft

29
.github/workflows/test_demo.sh vendored Normal file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
# llgo run subdirectories under _demo and _pydemo
total=0
failed=0
failed_cases=""
for d in ./_demo/* ./_pydemo/*; do
total=$((total+1))
if [ -d "$d" ]; then
echo "Testing $d"
if ! llgo run "$d"; then
echo "FAIL"
failed=$((failed+1))
failed_cases="$failed_cases\n* :x: $d"
else
echo "PASS"
fi
fi
done
echo "=== Done"
echo "$((total-failed))/$total tests passed"
if [ "$failed" -ne 0 ]; then
echo ":bangbang: Failed demo cases:" | tee -a result.md
echo -e "$failed_cases" | tee -a result.md
exit 1
else
echo ":white_check_mark: All demo tests passed" | tee -a result.md
fi

38
.github/workflows/test_llgo.sh vendored Normal file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
set -e
export LLGOROOT=$PWD
testcmd=/tmp/test
llgo build -o $testcmd ./c/bdwgc/_test
cases=$($testcmd)
total=$(echo "$cases" | wc -l | tr -d ' ')
failed=0
failed_cases=""
for idx in $(seq 1 $((total))); do
case=$(echo "$cases" | sed -n "${idx}p")
case_name=$(echo "$case" | cut -d',' -f2)
echo "=== Test case: $case_name"
set +e
out=$("$testcmd" "$((idx-1))" 2>&1)
exit_code=$?
set -e
if [ "${exit_code:-0}" -ne 0 ]; then
echo "failed: $out"
failed=$((failed+1))
failed_cases="$failed_cases\n* :x: $case_name"
else
echo "passed"
fi
done
echo "=== Done"
echo "$((total-failed))/$total tests passed"
if [ "$failed" -ne 0 ]; then
echo ":bangbang: Failed llgo cases:" | tee -a result.md
echo -e "$failed_cases" | tee -a result.md
exit 1
else
echo ":white_check_mark: All llgo tests passed" | tee -a result.md
fi

8
.gitignore vendored
View File

@@ -9,7 +9,8 @@
*.dylib
test.db
llgo_autogen.ll
demo.ll
llgo_autogen*.ll
stories*.bin
.DS_Store
err.log
@@ -18,6 +19,7 @@ numpy.txt
_go/
_runtime/
_tinygo/
_output/
build.dir/
.vscode/
@@ -33,3 +35,7 @@ build.dir/
# Go workspace file
go.work*
# GoReleaser
.dist/
.sysroot/

145
.goreleaser.yaml Normal file
View File

@@ -0,0 +1,145 @@
version: 2
dist: .dist
env:
- SYSROOT_DARWIN_AMD64={{.Env.PWD}}/.sysroot/darwin/amd64
- SYSROOT_DARWIN_ARM64={{.Env.PWD}}/.sysroot/darwin/arm64
- SYSROOT_LINUX_AMD64={{.Env.PWD}}/.sysroot/linux/amd64
- SYSROOT_LINUX_ARM64={{.Env.PWD}}/.sysroot/linux/arm64
- CGO_ENABLED=1
- CGO_CXXFLAGS=-std=c++17
before:
hooks:
- go mod download
builds:
- id: llgo-darwin-amd64
main: ./cmd/llgo
flags:
- -tags=darwin,amd64,byollvm
ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/local/opt/llvm@18/bin/llvm-config
env:
- CC=o64-clang
- CXX=o64-clang++
- CGO_CPPFLAGS=-I{{.Env.SYSROOT_DARWIN_AMD64}}/usr/local/opt/llvm@18/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
- CGO_LDFLAGS=-L{{.Env.SYSROOT_DARWIN_AMD64}}/usr/local/opt/llvm@18/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-18 -lz -lm
targets:
- darwin_amd64
mod_timestamp: "{{.CommitTimestamp}}"
- id: llgo-darwin-arm64
main: ./cmd/llgo
flags:
- -tags=darwin,arm64,byollvm
ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/opt/homebrew/opt/llvm@18/bin/llvm-config
env:
- CC=oa64-clang
- CXX=oa64-clang++
- CGO_CPPFLAGS=-I{{.Env.SYSROOT_DARWIN_ARM64}}/opt/homebrew/opt/llvm@18/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
- CGO_LDFLAGS=-L{{.Env.SYSROOT_DARWIN_ARM64}}/opt/homebrew/opt/llvm@18/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-18 -lz -lm
targets:
- darwin_arm64
mod_timestamp: "{{.CommitTimestamp}}"
- id: llgo-linux-amd64
main: ./cmd/llgo
flags:
- -tags=linux,amd64,byollvm
ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config
env:
- CC=x86_64-linux-gnu-gcc
- CXX=x86_64-linux-gnu-g++
- CGO_CPPFLAGS=--sysroot={{.Env.SYSROOT_LINUX_AMD64}} -I{{.Env.SYSROOT_LINUX_AMD64}}/usr/include/llvm-18 -I{{.Env.SYSROOT_LINUX_AMD64}}/usr/include/llvm-c-18 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
- CGO_LDFLAGS=--sysroot={{.Env.SYSROOT_LINUX_AMD64}} -L{{.Env.SYSROOT_LINUX_AMD64}}/usr/lib/llvm-18/lib -lLLVM-18
targets:
- linux_amd64
mod_timestamp: "{{.CommitTimestamp}}"
- id: llgo-linux-arm64
main: ./cmd/llgo
flags:
- -tags=linux,arm64,byollvm
ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config
env:
- CC=aarch64-linux-gnu-gcc
- CXX=aarch64-linux-gnu-g++
- CGO_CPPFLAGS=--sysroot={{.Env.SYSROOT_LINUX_ARM64}} -I{{.Env.SYSROOT_LINUX_ARM64}}/usr/include/llvm-18 -I{{.Env.SYSROOT_LINUX_ARM64}}/usr/include/llvm-c-18 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
- CGO_LDFLAGS=--sysroot={{.Env.SYSROOT_LINUX_ARM64}} -L{{.Env.SYSROOT_LINUX_ARM64}}/usr/lib/llvm-18/lib -lLLVM-18
targets:
- linux_arm64
mod_timestamp: "{{.CommitTimestamp}}"
archives:
- format: tar.gz
name_template: >-
{{.ProjectName}}{{.Version}}.{{.Os}}-{{.Arch}}
{{- if .Arm}}v{{.Arm}}{{end}}
files:
- LICENSE
- README.md
checksum:
name_template: "{{.ProjectName}}{{.Version}}.checksums.txt"
nfpms:
- package_name: llgo
vendor: goplus
homepage: https://github.com/goplus/llgo
maintainer: Aofei Sheng <aofei@aofeisheng.com>
description: |
LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a
subproject of the Go+ project.
LLGo aims to expand the boundaries of Go/Go+, providing limitless possibilities such as:
- Game development
- AI and data science
- WebAssembly
- Embedded development
- ...
license: Apache-2.0
formats:
- deb
- rpm
file_name_template: >-
{{.ProjectName}}{{.Version}}.{{.Os}}-{{.Arch}}
{{- if .Arm}}v{{.Arm}}{{end}}
bindir: /usr/local/bin
snapcrafts:
- name: llgo
title: A Go compiler based on LLVM
summary: A Go compiler based on LLVM
description: |
LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a
subproject of the Go+ project.
LLGo aims to expand the boundaries of Go/Go+, providing limitless possibilities such as:
- Game development
- AI and data science
- WebAssembly
- Embedded development
- ...
license: Apache-2.0
confinement: classic
name_template: >-
{{.ProjectName}}{{.Version}}.{{.Os}}-{{.Arch}}
{{- if .Arm}}v{{.Arm}}{{end}}
snapshot:
name_template: '{{trimprefix .Summary "v"}}'
release:
prerelease: auto

275
README.md
View File

@@ -10,8 +10,41 @@ llgo - A Go compiler based on LLVM
LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a subproject of [the Go+ project](https://github.com/goplus/gop).
LLGo aims to expand the boundaries of Go/Go+, providing limitless possibilities such as:
## C standard libary support
* Game development
* AI and data science
* WebAssembly
* Embedded development
* ...
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)**.
## C/C++ standard libary support
You can import a C/C++ standard library in LLGo!
* [c](https://pkg.go.dev/github.com/goplus/llgo/c)
* [c/os](https://pkg.go.dev/github.com/goplus/llgo/c/os)
* [c/syscall](https://pkg.go.dev/github.com/goplus/llgo/c/syscall)
* [c/math](https://pkg.go.dev/github.com/goplus/llgo/c/math)
* [c/math/cmplx](https://pkg.go.dev/github.com/goplus/llgo/c/math/cmplx)
* [c/math/rand](https://pkg.go.dev/github.com/goplus/llgo/c/math/rand)
* [c/pthread](https://pkg.go.dev/github.com/goplus/llgo/c/pthread)
* [c/pthread/sync](https://pkg.go.dev/github.com/goplus/llgo/c/pthread/sync)
* [c/sync/atomic](https://pkg.go.dev/github.com/goplus/llgo/c/sync/atomic)
* [c/time](https://pkg.go.dev/github.com/goplus/llgo/c/time)
* [c/socket](https://pkg.go.dev/github.com/goplus/llgo/c/socket)
* [cpp/std](https://pkg.go.dev/github.com/goplus/llgo/cpp/std)
Here is a simple example:
```go
package main
@@ -34,46 +67,98 @@ The `_demo` directory contains some C standard libary related demos (it start wi
To run these demos (If you haven't installed `llgo` yet, please refer to [How to install](#how-to-install)):
```sh
export LLGOROOT=`pwd`
cd <demo-directory> # eg. cd _demo/hello
llgo run .
```
See [github.com/goplus/llgo/c](https://pkg.go.dev/github.com/goplus/llgo/c) for more detials.
## How support C/C++ and Python
LLGo use `go:linkname` to link an extern symbol througth its ABI:
```go
import _ "unsafe" // for go:linkname
//go:linkname Sqrt C.sqrt
func Sqrt(x float64) float64
```
You can directly integrate it into [your own code](_demo/linkname/linkname.go):
```go
package main
import _ "unsafe" // for go:linkname
//go:linkname Sqrt C.sqrt
func Sqrt(x float64) float64
func main() {
println("sqrt(2) =", Sqrt(2))
}
```
Or put it into a package (see [c/math](c/math/math.go)):
```go
package main
import "github.com/goplus/llgo/c/math"
func main() {
println("sqrt(2) =", math.Sqrt(2))
}
```
## Python support
You can import a Python library in LLGo!
And you can import any Python library into `llgo` through a program called `llpyg` (see [Development tools](#development-tools)). The currently imported libraries include:
And you can import any Python library into `llgo` through a program called `llpyg` (see [Development tools](#development-tools)). The following libraries have been included in `llgo`:
* [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys)
* [os](https://pkg.go.dev/github.com/goplus/llgo/py/os)
* [math](https://pkg.go.dev/github.com/goplus/llgo/py/math)
* [json](https://pkg.go.dev/github.com/goplus/llgo/py/json)
* [inspect](https://pkg.go.dev/github.com/goplus/llgo/py/inspect)
* [statistics](https://pkg.go.dev/github.com/goplus/llgo/py/statistics)
* [numpy](https://pkg.go.dev/github.com/goplus/llgo/py/numpy)
* [py](https://pkg.go.dev/github.com/goplus/llgo/py) (abi)
* [py/std](https://pkg.go.dev/github.com/goplus/llgo/py/std) (builtins)
* [py/sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys)
* [py/os](https://pkg.go.dev/github.com/goplus/llgo/py/os)
* [py/math](https://pkg.go.dev/github.com/goplus/llgo/py/math)
* [py/json](https://pkg.go.dev/github.com/goplus/llgo/py/json)
* [py/inspect](https://pkg.go.dev/github.com/goplus/llgo/py/inspect)
* [py/statistics](https://pkg.go.dev/github.com/goplus/llgo/py/statistics)
* [py/numpy](https://pkg.go.dev/github.com/goplus/llgo/py/numpy)
* [py/pandas](https://pkg.go.dev/github.com/goplus/llgo/py/pandas)
* [py/torch](https://pkg.go.dev/github.com/goplus/llgo/py/torch)
* [py/matplotlib](https://pkg.go.dev/github.com/goplus/llgo/py/matplotlib)
Here is an example using the Python `math` library:
Note: For third-party libraries (such as pandas and pytorch), you still need to install the library files.
Here is an example:
```go
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/math"
"github.com/goplus/llgo/py/std"
)
func main() {
x := math.Sqrt(py.Float(2))
c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
x := math.Sqrt(py.Float(2)) // x = sqrt(2)
std.Print(py.Str("sqrt(2) ="), x) // print("sqrt(2) =", x)
}
```
Here, We call `py.Float(2)` to create a Python number 2, and pass it to Pythons `math.sqrt` to get `x`. Then use `x.Float64()` to convert x to Go's `float64` type, and print the value through the C `printf` function.
It is equivalent to the following Python code:
```py
import math
x = math.sqrt(2)
print("sqrt =", x)
```
Here, We call `py.Float(2)` to create a Python number 2, and pass it to Pythons `math.sqrt` to get `x`. Then we call `std.Print` to print the result.
Let's look at a slightly more complex example. For example, we use `numpy` to calculate:
@@ -81,9 +166,9 @@ Let's look at a slightly more complex example. For example, we use `numpy` to ca
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/numpy"
"github.com/goplus/llgo/py/std"
)
func main() {
@@ -98,7 +183,7 @@ func main() {
py.List(3.0, 2.0, 1.0),
)
x := numpy.Add(a, b)
c.Printf(c.Str("a+b = %s\n"), x.Str().CStr())
std.Print(py.Str("a+b ="), x)
}
```
@@ -111,83 +196,109 @@ The `_pydemo` directory contains some python related demos:
* [statistics](_pydemo/statistics/statistics.go): define a python list and call `statistics.mean` to get the mean
* [matrix](_pydemo/matrix/matrix.go): a basic `numpy` demo
To run these demos, you need to set the `LLGO_LIB_PYTHON` environment variable first.
If Python is in the search path for `clang` linking, then `LLGO_LIB_PYTHON` only needs to be set to the name of the Python library. For example:
To run these demos (If you haven't installed `llgo` yet, please refer to [How to install](#how-to-install)):
```sh
export LLGO_LIB_PYTHON=python3.12
```
You can also specify the path to tell `llgo` where the Python library is located:
```sh
export LLGO_LIB_PYTHON=/foo/bar/python3.12
```
For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python library location under macOS. So we should set it like this:
```sh
export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12
```
Note that the file name must be written in a platform-independent format, using `python3.12` instead of `libpython3.12.dylib`.
Then you can run the demos:
```sh
export LLGOROOT=`pwd`
cd <demo-directory> # eg. cd _pydemo/callpy
llgo run .
```
See [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py) for more detials.
## Other frequently used libraries
LLGo can easily import any libraries from the C ecosystem. Currently, this import process is still manual, but in the future, it will be automated similar to Python library imports.
The currently imported libraries include:
The currently supported libraries include:
* [llama2.c](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
* [cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)
* [sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite)
* [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/llama2](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
* [c/lua](https://pkg.go.dev/github.com/goplus/llgo/c/lua)
* [c/neco](https://pkg.go.dev/github.com/goplus/llgo/c/neco)
* [c/raylib](https://pkg.go.dev/github.com/goplus/llgo/c/raylib)
* [c/sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite)
* [c/zlib](https://pkg.go.dev/github.com/goplus/llgo/c/zlib)
* [cpp/inih](https://pkg.go.dev/github.com/goplus/llgo/cpp/inih)
Here are some examples related to them:
* [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example)
* [mkjson](c/cjson/_demo/mkjson/mkjson.go): create a json object and print it
* [sqlitedemo](c/sqlite/_demo/sqlitedemo/demo.go): a basic sqlite demo
* [tetris](c/raylib/_demo/tetris/tetris.go): a tetris game based on raylib
## Go syntax support
The priority of `llgo` feature iteration is:
* Popular C/Python libraries
* Full Go syntax
* Go standard libraries
* Popular Go packages
Common Go syntax is already supported. Except for the following, which needs to be improved:
* interface (Limited support)
* map (Very limited support)
* panic (Limited support)
* recover (Not supported yet)
* defer (Not supported yet)
* gc (Not supported yet)
* chan (Not supported yet)
* goroutine (Not supported yet)
* generics (Not supported yet)
Here are some examples related to Go syntax:
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)
* [errors](_cmptest/errors/errors.go): demo to implement error interface
* [defer](_cmptest/defer/defer.go): defer demo
* [goroutine](_demo/goroutine/goroutine.go): goroutine demo
## Defer
LLGo `defer` does not support usage in loops. This is not a bug but a feature, because we think that using `defer` in a loop is a very unrecommended practice.
### Garbage Collection (GC)
By default, LLGo implements `gc` based on [bdwgc](https://www.hboehm.info/gc/) (also known as [libgc](https://www.hboehm.info/gc/)).
However, you can disable gc by specifying the `nogc` tag. For example:
```sh
llgo run -tags nogc .
```
## Go packages support
Here are the Go packages that can be imported correctly:
* [unsafe](https://pkg.go.dev/unsafe)
* [unicode](https://pkg.go.dev/unicode)
* [unicode/utf8](https://pkg.go.dev/unicode/utf8)
* [unicode/utf16](https://pkg.go.dev/unicode/utf16)
* [math](https://pkg.go.dev/math)
* [math/bits](https://pkg.go.dev/math/bits)
* [math/cmplx](https://pkg.go.dev/math/cmplx)
* [errors](https://pkg.go.dev/errors)
* [context](https://pkg.go.dev/context)
* [io](https://pkg.go.dev/io)
* [io/fs](https://pkg.go.dev/io/fs)
* [log](https://pkg.go.dev/log)
* [flag](https://pkg.go.dev/flag)
* [sort](https://pkg.go.dev/sort)
* [strconv](https://pkg.go.dev/strconv)
* [strings](https://pkg.go.dev/strings)
* [sync/atomic](https://pkg.go.dev/sync/atomic)
* [sync](https://pkg.go.dev/sync) (partially)
* [syscall](https://pkg.go.dev/syscall) (partially)
* [runtime](https://pkg.go.dev/runtime) (partially)
* [os](https://pkg.go.dev/os) (partially)
* [os/exec](https://pkg.go.dev/os/exec) (partially)
* [fmt](https://pkg.go.dev/fmt) (partially)
* [reflect](https://pkg.go.dev/reflect) (partially)
* [time](https://pkg.go.dev/time) (partially)
## Dependencies
- [Go 1.20+](https://go.dev) (build only)
- [LLVM 18](https://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/)
- [cJSON 1.7+](https://github.com/DaveGamble/cJSON) (optional, for [github.com/goplus/llgo/c/cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson))
- [SQLite 3](https://www.sqlite.org) (optional, for [github.com/goplus/llgo/c/sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite))
- [Python 3.11+](https://www.python.org) (optional, for [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py))
## How to install
Follow these steps to generate the `llgo` command (its usage is the same as the `go` command):
@@ -195,19 +306,23 @@ Follow these steps to generate the `llgo` command (its usage is the same as the
### on macOS
```sh
brew update # execute if needed
brew install llvm@17
go install -v ./...
brew update # execute if needed
brew install llvm@18 pkg-config libgc
brew install cjson sqlite python@3.12 # optional
export PATH=$(brew --prefix llvm@18)/bin:$PATH # you may want to add this to your shell RC file, e.g. ~/.zshrc
go install -v github.com/goplus/llgo/cmd/llgo@latest
```
### on Linux
### on Linux (Debian/Ubuntu)
```sh
echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-17 main' | sudo tee /etc/apt/sources.list.d/llvm.list
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 # execute if needed
sudo apt-get install --no-install-recommends llvm-17-dev
go install -v ./...
sudo apt-get update # execute if needed
sudo apt-get install -y llvm-18-dev clang-18 lld-18 pkg-config libgc-dev
sudo apt-get install -y libcjson-dev libsqlite3-dev python3.12-dev # optional
export PATH=/usr/lib/llvm-18/bin:$PATH # you may want to add this to your shell RC file, e.g. ~/.bashrc
go install -v github.com/goplus/llgo/cmd/llgo@latest
```
### on Windows
@@ -218,16 +333,20 @@ TODO
## 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`.
* [llpyg](chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` to accomplish the task.
* [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
go install -v ./... # compile all tools except pydump
git clone https://github.com/goplus/llgo.git
cd llgo
go install -v ./chore/... # compile all tools except pydump
cd chore/_xtool
llgo install ./... # compile pydump
go install github.com/goplus/hdq/chore/pysigfetch@v0.8.1 # compile pysigfetch
```
## Key modules

View File

@@ -0,0 +1,21 @@
package main
func main() {
c1 := make(chan string)
c2 := make(chan string, 1)
go func() {
c1 <- "ch1"
}()
go func() {
c2 <- "ch2"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
println(msg1)
case msg2 := <-c2:
println(msg2)
}
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"fmt"
"time"
)
var c chan int
func handle(int) {}
func main() {
select {
case m := <-c:
handle(m)
case <-time.After(10 * time.Second):
fmt.Println("timed out")
}
}

11
_cmptest/chan/chan.go Normal file
View File

@@ -0,0 +1,11 @@
package main
func main() {
ch := make(chan int, 10)
println(len(ch), cap(ch))
go func() {
ch <- 100
}()
n, ok := <-ch
println(n, ok)
}

View File

@@ -0,0 +1,26 @@
package main
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
println(<-c)
}
close(quit)
}()
fibonacci(c, quit)
}

39
_cmptest/ctxcancel/ctx.go Normal file
View File

@@ -0,0 +1,39 @@
package main
import (
"context"
"fmt"
)
func main() {
// gen generates integers in a separate goroutine and
// sends them to the returned channel.
// The callers of gen need to cancel the context once
// they are done consuming generated integers not to leak
// the internal goroutine started by gen.
gen := func(ctx context.Context) <-chan int {
dst := make(chan int)
n := 1
go func() {
for {
select {
case <-ctx.Done():
return // returning not to leak the goroutine
case dst <- n:
n++
}
}
}()
return dst
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // cancel when we are finished consuming integers
for n := range gen(ctx) {
fmt.Println(n)
if n == 5 {
break
}
}
}

17
_cmptest/defer/defer.go Normal file
View File

@@ -0,0 +1,17 @@
package main
func f(s string) bool {
return len(s) > 2
}
func main() {
defer func() {
println("hi")
}()
if s := "hello"; f(s) {
defer println(s)
} else {
defer println("world")
}
defer println("bye")
}

21
_cmptest/errors/errors.go Normal file
View File

@@ -0,0 +1,21 @@
package main
// New returns an error that formats as the given text.
// Each call to New returns a distinct error value even if the text is identical.
func New(text string) error {
return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
func main() {
err := New("an error")
println(err.Error())
}

View File

@@ -0,0 +1,21 @@
package main
import (
"flag"
"fmt"
"os"
)
func main() {
fmt.Println("args:", os.Args[1:])
if len(os.Args) == 1 {
os.Args = []string{"flagdemo", "-cpu", "100"}
}
verbose := flag.Bool("v", false, "verbose")
cpu := flag.Int("cpu", 1, "cpu number")
host := flag.String("host", ":8888", "host")
flag.Parse()
fmt.Println("host:", *host, "cpu:", *cpu, "verbose:", *verbose)
}

12
_cmptest/fmtdemo/fmt.go Normal file
View File

@@ -0,0 +1,12 @@
package main
import (
"errors"
"fmt"
)
func main() {
fmt.Println("Hello, world")
fmt.Printf("%f\n", 3.14)
fmt.Printf("%v\n", errors.New("error message"))
}

View File

@@ -0,0 +1,9 @@
package foo
func Bar() any {
return struct{ V int }{1}
}
func F() any {
return struct{ v int }{1}
}

35
_cmptest/interf/interf.go Normal file
View File

@@ -0,0 +1,35 @@
package main
import (
"github.com/goplus/llgo/_cmptest/interf/foo"
)
func Foo() any {
return struct{ v int }{1}
}
func main() {
v := Foo()
if x, ok := v.(struct{ v int }); ok {
println(x.v)
} else {
println("Foo: not ok")
}
bar := foo.Bar()
if x, ok := bar.(struct{ V int }); ok {
println(x.V)
} else {
println("Bar: not ok")
}
if x, ok := foo.F().(struct{ v int }); ok {
println(x.v)
} else {
println("F: not ok")
}
}
/* Expected output:
1
1
F: not ok
*/

14
_cmptest/iodemo/io.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import (
"io"
"os"
)
func f(w io.Writer) {
w.Write([]byte("Hello, world\n"))
}
func main() {
f(os.Stdout)
}

18
_cmptest/osdemo/osd.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import (
"os"
)
func main() {
home, _ := os.UserHomeDir()
println("home:", home)
cfgdir, _ := os.UserConfigDir()
println("cfgdir:", cfgdir)
cache, _ := os.UserCacheDir()
println("cachedir:", cache)
os.Stdout.Write([]byte("Hello, World\n"))
}

30
_cmptest/osproc/exec.go Normal file
View File

@@ -0,0 +1,30 @@
package main
import (
"fmt"
"os"
"os/exec"
"runtime"
)
func main() {
ls := "ls"
args := []string{ls, "-l"}
if runtime.GOOS == "windows" {
ls = "dir"
args = []string{ls}
}
lspath, _ := exec.LookPath(ls)
if lspath != "" {
ls = lspath
}
proc, err := os.StartProcess(ls, args, &os.ProcAttr{
Files: []*os.File{nil, os.Stdout, os.Stderr},
})
if err != nil {
fmt.Println("os.StartProcess error:", err)
return
}
proc.Wait()
fmt.Println("proc.Wait done")
}

View File

@@ -0,0 +1,13 @@
package main
import "reflect"
func main() {
tyIntSlice := reflect.SliceOf(reflect.TypeOf(0))
v := reflect.Zero(tyIntSlice)
v = reflect.Append(v, reflect.ValueOf(1), reflect.ValueOf(2), reflect.ValueOf(3))
for i, n := 0, v.Len(); i < n; i++ {
item := v.Index(i)
println(item.Int())
}
}

14
_cmptest/rtype/rtype.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import "reflect"
func main() {
tyIntSlice := reflect.SliceOf(reflect.TypeOf(0))
println(tyIntSlice.String())
v := reflect.Zero(tyIntSlice)
println(v.Len())
v = reflect.ValueOf(100)
println(v.Int())
}

23
_cmptest/sortdemo/sort.go Normal file
View File

@@ -0,0 +1,23 @@
package main
import "sort"
func main() {
vals := []int{32, 58, 25, 92, 45, 78}
sort.Ints(vals)
for _, v := range vals {
println(v)
}
texts := []string{"apple", "banana", "cherry", "date", "elderberry", "fig"}
sort.Slice(texts, func(i, j int) bool {
leni, lenj := len(texts[i]), len(texts[j])
if leni != lenj {
return leni < lenj
}
return texts[i] < texts[j]
})
for _, v := range texts {
println(v)
}
}

View File

@@ -0,0 +1,12 @@
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
fmt.Println(strconv.Itoa(-123))
fmt.Println(strings.Split("abc,def,123", ","))
}

View File

@@ -0,0 +1,11 @@
package main
import "syscall"
func main() {
wd, err := syscall.Getwd()
if err != nil {
panic(err)
}
println("cwd:", wd)
}

View File

@@ -0,0 +1,8 @@
package main
import "time"
func main() {
t := time.Date(2018, time.January, 1, 2, 3, 4, 5, time.UTC)
println(t.String())
}

24
_demo/catomic/atomic.go Normal file
View File

@@ -0,0 +1,24 @@
package main
import (
"github.com/goplus/llgo/c/sync/atomic"
)
func main() {
var v int64
atomic.Store(&v, 100)
println("store:", atomic.Load(&v))
ret := atomic.Add(&v, 1)
println("ret:", ret, "v:", v)
ret, _ = atomic.CompareAndExchange(&v, 100, 102)
println("ret:", ret, "vs 100, v:", v)
ret, _ = atomic.CompareAndExchange(&v, 101, 102)
println("ret:", ret, "vs 101, v:", v)
ret = atomic.Sub(&v, 1)
println("ret:", ret, "v:", v)
}

50
_demo/cchan/cchan.go Normal file
View File

@@ -0,0 +1,50 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/internal/runtime"
)
const (
eltSize = int(unsafe.Sizeof(0))
)
func doChan(cap int) {
c := runtime.NewChan(eltSize, cap)
go func() {
v := 100
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
}()
var ret int
runtime.ChanRecv(c, unsafe.Pointer(&ret), eltSize)
println(ret)
}
func main() {
doChan(10)
doChan(0)
c := runtime.NewChan(eltSize, 3)
v := 1
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
v = 2
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
v = 3
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
runtime.ChanClose(c)
v = 10
if runtime.ChanTrySend(c, unsafe.Pointer(&v), eltSize) {
println("error: chan send to closed chan")
}
for {
if ok := runtime.ChanRecv(c, unsafe.Pointer(&v), eltSize); !ok {
break
}
println(v)
}
}

View File

@@ -0,0 +1,41 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/internal/runtime"
)
const (
eltSize = int(unsafe.Sizeof(0))
)
func fibonacci(c, quit *runtime.Chan) {
x, y := 0, 1
for {
isel, _ := runtime.Select(
runtime.ChanOp{C: c, Send: true, Val: unsafe.Pointer(&x), Size: int32(eltSize)},
runtime.ChanOp{C: quit},
)
if isel == 0 {
x, y = y, x+y
} else {
println("quit")
return
}
}
}
func main() {
c := runtime.NewChan(eltSize, 0)
quit := runtime.NewChan(eltSize, 0)
go func() {
for i := 0; i < 10; i++ {
val := 0
runtime.ChanRecv(c, unsafe.Pointer(&val), eltSize)
println(val)
}
runtime.ChanClose(quit)
}()
fibonacci(c, quit)
}

11
_demo/cexec/exec.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/os"
)
func main() {
ls := c.Str("ls")
os.Execlp(ls, ls, c.Str("-l"), nil)
}

9
_demo/complex/cmplx.go Normal file
View File

@@ -0,0 +1,9 @@
package main
import (
"math/cmplx"
)
func main() {
println("abs(3+4i):", cmplx.Abs(3+4i))
}

38
_demo/cppintf/cppintf.go Normal file
View File

@@ -0,0 +1,38 @@
package main
import (
"github.com/goplus/llgo/_demo/cppintf/foo"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/math"
)
type Bar struct {
foo.Callback
a c.Int
}
func NewBar(a c.Int) *Bar {
return &Bar{
Callback: foo.Callback{
Vptr: &foo.CallbackVtbl{
Val: c.Func((*Bar).getA),
Calc: c.Func((*Bar).sqrt),
},
},
a: a,
}
}
func (p *Bar) getA() c.Int {
return p.a
}
func (p *Bar) sqrt(v float64) float64 {
return math.Sqrt(v)
}
func main() {
bar := NewBar(1)
foo.F(&bar.Callback)
foo.G(&bar.Callback)
}

View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#define interface struct
interface ICallback {
virtual int val() = 0;
virtual double calc(double v) = 0;
};
extern "C" void f(ICallback* cb) {
printf("val: %d\ncalc(2): %lf\n", cb->val(), cb->calc(2));
}
void g(ICallback* cb) {
f(cb);
}

25
_demo/cppintf/foo/foo.go Normal file
View File

@@ -0,0 +1,25 @@
package foo
import (
"unsafe"
)
const (
LLGoFiles = "bar/bar.cpp"
LLGoPackage = "link"
)
type Callback struct {
Vptr *CallbackVtbl
}
type CallbackVtbl struct {
Val unsafe.Pointer
Calc unsafe.Pointer
}
//go:linkname F C.f
func F(cb *Callback)
//go:linkname G C._Z1gP9ICallback
func G(cb *Callback)

View File

@@ -0,0 +1,50 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/_demo/cppmintf/foo"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/math"
)
type Bar struct {
foo.Callback
a c.Int
}
func NewBar(a c.Int) *Bar {
return &Bar{
Callback: foo.Callback{
ICalc: foo.ICalc{
Vptr: &foo.ICalcVtbl{
Calc: c.Func((*Bar).sqrt),
},
},
IVal: foo.IVal{
Vptr: &foo.IValVtbl{
Val: c.Func(bar_IVal_getA),
},
},
},
a: a,
}
}
func (p *Bar) getA() c.Int {
return p.a
}
func bar_IVal_getA(this c.Pointer) c.Int {
const delta = -int(unsafe.Offsetof(foo.Callback{}.IVal))
return (*Bar)(c.Advance(this, delta)).getA()
}
func (p *Bar) sqrt(v float64) float64 {
return math.Sqrt(v)
}
func main() {
bar := NewBar(1)
foo.F(&bar.Callback)
}

View File

@@ -0,0 +1,17 @@
#include <stdio.h>
#define interface struct
interface ICalc {
virtual double calc(double v) = 0;
};
interface IVal {
virtual int val() = 0;
};
class Callback : public ICalc, public IVal {
};
extern "C" void f(Callback* cb) {
printf("val: %d\ncalc(2): %lf\n", cb->val(), cb->calc(2));
}

42
_demo/cppmintf/foo/foo.go Normal file
View File

@@ -0,0 +1,42 @@
package foo
import (
"unsafe"
)
const (
LLGoFiles = "bar/bar.cpp"
LLGoPackage = "link"
)
// -----------------------------------------------------------------------------
type ICalc struct {
Vptr *ICalcVtbl
}
type ICalcVtbl struct {
Calc unsafe.Pointer
}
// -----------------------------------------------------------------------------
type IVal struct {
Vptr *IValVtbl
}
type IValVtbl struct {
Val unsafe.Pointer
}
// -----------------------------------------------------------------------------
type Callback struct {
ICalc
IVal
}
//go:linkname F C.f
func F(cb *Callback)
// -----------------------------------------------------------------------------

12
_demo/ctime/time.go Normal file
View File

@@ -0,0 +1,12 @@
package main
import "github.com/goplus/llgo/c/time"
func main() {
var tv time.Timespec
time.ClockGettime(time.CLOCK_REALTIME, &tv)
println("REALTIME sec:", tv.Sec, "nsec:", tv.Nsec)
time.ClockGettime(time.CLOCK_MONOTONIC, &tv)
println("MONOTONIC sec:", tv.Sec, "nsec:", tv.Nsec)
}

77
_demo/fcntl/fcntl.go Normal file
View File

@@ -0,0 +1,77 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/os"
"unsafe"
)
func main() {
filename := c.Str("testfile.txt")
data := c.Str("Hello, os!")
var buffer [20]c.Char
// Open a file, O_CREAT|O_WRONLY|O_TRUNC means create, write only, or clear the file
fd := os.Open(filename, os.O_CREAT|os.O_WRONLY|os.O_TRUNC, 0644)
if fd == -1 {
c.Printf(c.Str("open error\n"))
return
}
// Writing data to a file
bytesWritten := os.Write(fd, c.Pointer(data), c.Strlen(data))
if bytesWritten == -1 {
c.Printf(c.Str("write error\n"))
os.Close(fd)
return
}
c.Printf(c.Str("Written %ld bytes to %s\n"), bytesWritten, filename)
// Get file status flags
flags := os.Fcntl(fd, os.F_GETFL)
if flags == -1 {
c.Printf(c.Str("os error\n"))
os.Close(fd)
return
}
c.Printf(c.Str("File flags: %d\n"), flags)
// Set the file status flag to non-blocking mode
if os.Fcntl(fd, os.F_SETFL, flags|os.O_NONBLOCK) == -1 {
c.Printf(c.Str("os error\n"))
os.Close(fd)
return
}
c.Printf(c.Str("set file status successfully\n"))
c.Printf(c.Str("111"))
// Close file
os.Close(fd)
// Reopen the file, O_RDONLY means read-only
fd = os.Open(filename, os.O_RDONLY)
if fd == -1 {
c.Printf(c.Str("open error\n"))
return
}
// Reading data from a file
// &buffer[:][0]
// unsafe.SliceData(buffer[:])
bytesRead := os.Read(fd, c.Pointer(unsafe.SliceData(buffer[:])), unsafe.Sizeof(buffer)-1)
if bytesRead == -1 {
c.Printf(c.Str("read error\n"))
os.Close(fd)
return
}
// Ensure that the buffer is null-terminated
buffer[bytesRead] = c.Char(0)
c.Printf(c.Str("Read %ld bytes: %s\n"), bytesRead, &buffer[0])
// Close file
os.Close(fd)
}

11
_demo/getcwd/getcwd.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/os"
)
func main() {
wd := os.Getcwd(c.Alloca(os.PATH_MAX), os.PATH_MAX)
c.Printf(c.Str("cwd: %s\n"), wd)
}

View File

@@ -0,0 +1,12 @@
package main
func main() {
done := false
go func() {
println("Hello, goroutine")
done = true
}()
for !done {
print(".")
}
}

7
_demo/gotime/time.go Normal file
View File

@@ -0,0 +1,7 @@
package main
import "time"
func main() {
println(time.Now().String())
}

View File

@@ -9,5 +9,5 @@ func main() {
}
/* Expected output:
Hello World
Hello world
*/

View File

@@ -0,0 +1,10 @@
package main
import _ "unsafe" // for go:linkname
//go:linkname Sqrt C.sqrt
func Sqrt(x float64) float64
func main() {
println("sqrt(2) =", Sqrt(2))
}

9
_demo/logdemo/log.go Normal file
View File

@@ -0,0 +1,9 @@
package main
import (
"log"
)
func main() {
log.Println("Hello")
}

11
_demo/math/math.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import (
"math"
)
func main() {
println(math.Sqrt(2))
println(math.Abs(-1.2))
println(math.Ldexp(1.2, 3))
}

18
_demo/osexec/exec.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import (
"os"
"os/exec"
"runtime"
)
func main() {
ls := "ls"
if runtime.GOOS == "windows" {
ls = "dir"
}
cmd := exec.Command(ls)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
}

View File

@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os/exec"
"runtime"
)
func main() {
ls := "ls"
if runtime.GOOS == "windows" {
ls = "dir"
}
lspath, _ := exec.LookPath(ls)
if lspath != "" {
ls = lspath
}
fmt.Println(ls)
}

15
_demo/rand/rand.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/math/rand"
)
func main() {
var s c.Uint = 6
rand.Srand(s)
rr := rand.RandR(&s)
r := rand.Rand()
println("r:", r)
println("rr:", rr)
}

16
_demo/setjmp/setjmp.go Normal file
View File

@@ -0,0 +1,16 @@
package main
import (
"github.com/goplus/llgo/c/setjmp"
)
func main() {
var jb setjmp.SigjmpBuf
switch ret := setjmp.Sigsetjmp(&jb, 0); ret {
case 0:
println("Hello, setjmp!")
setjmp.Siglongjmp(&jb, 1)
default:
println("exception:", ret)
}
}

View File

@@ -0,0 +1,32 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/os"
"github.com/goplus/llgo/c/socket"
)
func main() {
sockfd := socket.Socket(socket.AF_INET, socket.SOCK_STREAM, 0)
msg := c.Str("Hello, World!")
defer os.Close(sockfd)
server := socket.GetHostByName(c.Str("localhost"))
if server == nil {
c.Perror(c.Str("hostname get error"))
return
}
servAddr := &socket.SockaddrIn{}
servAddr.Family = socket.AF_INET
servAddr.Port = socket.Htons(uint16(1234))
c.Memcpy(unsafe.Pointer(&servAddr.Addr.Addr), unsafe.Pointer(*server.AddrList), uintptr(server.Length))
if res := socket.Connect(sockfd, (*socket.SockAddr)(unsafe.Pointer(servAddr)), c.Uint(16)); res < 0 {
c.Perror(c.Str("connect error"))
return
}
os.Write(sockfd, unsafe.Pointer(msg), c.Strlen(msg))
}

View File

@@ -0,0 +1,43 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/os"
"github.com/goplus/llgo/c/socket"
)
func main() {
var buffer [256]c.Char
sockfd := socket.Socket(socket.AF_INET, socket.SOCK_STREAM, 0)
defer os.Close(sockfd)
servAddr := &socket.SockaddrIn{
Family: socket.AF_INET,
Port: socket.Htons(uint16(1234)),
Addr: socket.InAddr{Addr: 0x00000000},
Zero: [8]c.Char{0, 0, 0, 0, 0, 0, 0, 0},
}
if res := socket.Bind(sockfd, servAddr, c.Uint(unsafe.Sizeof(*servAddr))); res < 0 {
c.Perror(c.Str("bind error"))
return
}
if socket.Listen(sockfd, 5) < 0 {
c.Printf(c.Str("listen error"))
return
}
c.Printf(c.Str("Listening on port 1234...\n"))
cliAddr, clilen := &socket.SockaddrIn{}, c.Uint(unsafe.Sizeof(servAddr))
newsockfd := socket.Accept(sockfd, cliAddr, &clilen)
defer os.Close(newsockfd)
c.Printf(c.Str("Connection accepted."))
os.Read(newsockfd, unsafe.Pointer(unsafe.SliceData(buffer[:])), 256)
c.Printf(c.Str("Received: %s"), &buffer[0])
}

26
_demo/sysexec/exec.go Normal file
View File

@@ -0,0 +1,26 @@
package main
import (
"fmt"
"os/exec"
"runtime"
"syscall"
)
func main() {
ls := "ls"
args := []string{ls, "-l"}
if runtime.GOOS == "windows" {
ls = "dir"
args = []string{ls}
}
lspath, _ := exec.LookPath(ls)
if lspath != "" {
ls = lspath
}
err := syscall.Exec(ls, args, nil)
if err != nil {
fmt.Println("syscall.Exec error:", err)
return
}
}

25
_demo/thread/thd.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/pthread"
)
var key pthread.Key
func main() {
key.Create(nil)
key.Set(c.Pointer(c.Str("main value\n")))
var thd pthread.Thread
pthread.Create(&thd, nil, func(arg c.Pointer) c.Pointer {
key.Set(c.Pointer(c.Str("thread value\n")))
c.Printf(c.Str("Hello, thread\nTLS: %s"), key.Get())
return c.Pointer(c.Str("Back to main\n"))
}, nil)
var retval c.Pointer
pthread.Join(thd, &retval)
c.Printf(c.Str("%sTLS: %s"), retval, key.Get())
}

11
_demo/timedur/timedur.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now().Add(time.Second * 5)
fmt.Println(time.Until(t))
}

View File

@@ -1,12 +1,12 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/math"
"github.com/goplus/llgo/py/std"
)
func main() {
x := math.Sqrt(py.Float(2))
c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
x := math.Sqrt(py.Float(2)) // x = sqrt(2)
std.Print(py.Str("sqrt(2) ="), x) // print("sqrt(2) =", x)
}

View File

@@ -1,9 +1,9 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/numpy"
"github.com/goplus/llgo/py/std"
)
func main() {
@@ -18,5 +18,5 @@ func main() {
py.List(3.0, 2.0, 1.0),
)
x := numpy.Add(a, b)
c.Printf(c.Str("a+b = %s\n"), x.Str().CStr())
std.Print(py.Str("a+b ="), x)
}

15
_pydemo/max/max.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import (
"github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/std"
)
func main() {
x := std.Max(py.Float(3.0), py.Float(9.0), py.Float(23.0), py.Float(100.0))
std.Print(x)
list := py.List(3.0, 9.0, 23.0, 100.0)
y := std.Max(std.Iter(list))
std.Print(y)
}

11
_pydemo/print/print.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import (
"github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/std"
)
func main() {
x := py.Float(3.14)
std.Print(x)
}

16
_pydemo/tensor/tensor.go Normal file
View File

@@ -0,0 +1,16 @@
package main
import (
"github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/std"
"github.com/goplus/llgo/py/torch"
)
func main() {
data := py.List(
py.List(1.0, 2.0),
py.List(3.0, 4.0),
)
x := torch.Tensor(data)
std.Print(x)
}

101
c/bdwgc/_test/bdwgc.go Normal file
View File

@@ -0,0 +1,101 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/bdwgc"
"github.com/goplus/llgo/c/bdwgc/_test/testing"
)
// ------ Test malloc ------
func TestMalloc(t *testing.T) {
pn := (*int)(bdwgc.Malloc(unsafe.Sizeof(int(0))))
*pn = 1 << 30
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
pl := (*int64)(bdwgc.Realloc(c.Pointer(pn), unsafe.Sizeof(int64(0))))
*pl = 1 << 60
c.Printf(c.Str("value: %lld, %llx, %p, %p\n"), *pl, *pl, pl, &pl)
bdwgc.Free(c.Pointer(pl))
}
// ------ Test finalizer ------
const (
RETURN_VALUE_FREED = 1 << 31
)
var called uint = 0
func setReturnValueFreed(pobj c.Pointer, clientData c.Pointer) {
called |= RETURN_VALUE_FREED
c.Printf(c.Str("called: %x\n"), called)
}
func setLoopValueFreed(pobj c.Pointer, clientData c.Pointer) {
pmask := (*uint)(clientData)
called |= *pmask
c.Printf(c.Str("called: %x\n"), called)
}
func isCalled(mask uint) bool {
return called&mask != 0
}
func returnValue() *int {
pn := bdwgc.Malloc(unsafe.Sizeof(int(0)))
bdwgc.RegisterFinalizer(pn, setReturnValueFreed, nil, nil, nil)
return (*int)(pn)
}
func callFunc() {
pn := returnValue()
*pn = 1 << 30
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
bdwgc.Gcollect()
check(!isCalled(RETURN_VALUE_FREED), c.Str("finalizer should not be called"))
}
func loop() {
for i := 0; i < 5; i++ {
p := bdwgc.Malloc(unsafe.Sizeof(int(0)))
pn := (*int)(p)
*pn = i
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
pflag := (*uint)(c.Malloc(unsafe.Sizeof(uint(0))))
*pflag = 1 << i
bdwgc.RegisterFinalizer(p, setLoopValueFreed, c.Pointer(pflag), nil, nil)
bdwgc.Gcollect()
check(!isCalled(1<<i), c.Str("finalizer should not be called"))
for j := 0; j < i; j++ {
check(isCalled(1<<j), c.Str("finalizers of previous objects should be called"))
}
}
}
// Clear stack to avoid reference
func clearStack() {
p := c.Alloca(128)
c.Memset(p, 0, 128)
}
func check(b bool, msg *c.Char) {
if !b {
c.Printf(c.Str("check failed: %s\n"), msg)
panic("check failed")
}
}
func TestFinalizer(t *testing.T) {
bdwgc.Init()
callFunc()
clearStack()
bdwgc.Gcollect()
check(isCalled(RETURN_VALUE_FREED), c.Str("finalizer should be called"))
loop()
}

31
c/bdwgc/_test/main.go Normal file
View File

@@ -0,0 +1,31 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/bdwgc/_test/testing"
)
type TestCase struct {
Name string
F func(*testing.T)
}
func main() {
tests := []TestCase{
{"TestMalloc", TestMalloc},
{"TestFinalizer", TestFinalizer},
}
if c.Argc == 1 {
for _, test := range tests {
c.Printf(c.Str("%s\n"), c.AllocaCStr(test.Name))
}
return
}
c.Fprintf(c.Stderr, c.Str("arg: %s\n"), c.Index(c.Argv, 1))
idx := int(c.Atoi(c.Index(c.Argv, 1)))
if idx < 0 || idx >= len(tests) {
c.Printf(c.Str("invalid test index %d"), idx)
panic("invalid test index")
}
tests[idx].F(nil)
}

View File

@@ -0,0 +1,4 @@
package testing
type T struct {
}

103
c/bdwgc/bdwgc.go Normal file
View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package bdwgc
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "link: $(pkg-config --libs bdw-gc); -lgc"
)
// -----------------------------------------------------------------------------
//go:linkname Init C.GC_init
func Init()
//go:linkname Malloc C.GC_malloc
func Malloc(size uintptr) c.Pointer
//go:linkname Realloc C.GC_realloc
func Realloc(ptr c.Pointer, size uintptr) c.Pointer
//go:linkname Free C.GC_free
func Free(ptr c.Pointer)
// -----------------------------------------------------------------------------
//go:linkname RegisterFinalizer C.GC_register_finalizer
func RegisterFinalizer(
obj c.Pointer,
fn func(c.Pointer, c.Pointer), cd c.Pointer,
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
//go:linkname RegisterFinalizerNoOrder C.GC_register_finalizer_no_order
func RegisterFinalizerNoOrder(
obj c.Pointer,
fn func(c.Pointer, c.Pointer), cd c.Pointer,
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
//go:linkname RegisterFinalizerIgnoreSelf C.GC_register_finalizer_ignore_self
func RegisterFinalizerIgnoreSelf(
obj c.Pointer,
fn func(c.Pointer, c.Pointer), cd c.Pointer,
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
//go:linkname RegisterFinalizerUnreachable C.GC_register_finalizer_unreachable
func RegisterFinalizerUnreachable(
obj c.Pointer,
fn func(c.Pointer, c.Pointer), cd c.Pointer,
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
// -----------------------------------------------------------------------------
//go:linkname Enable C.GC_enable
func Enable()
//go:linkname Disable C.GC_disable
func Disable()
//go:linkname IsDisabled C.GC_is_disabled
func IsDisabled() c.Int
//go:linkname Gcollect C.GC_gcollect
func Gcollect()
//go:linkname GetMemoryUse C.GC_get_memory_use
func GetMemoryUse() uintptr
// -----------------------------------------------------------------------------
//go:linkname EnableIncremental C.GC_enable_incremental
func EnableIncremental()
//go:linkname IsIncrementalMode C.GC_is_incremental_mode
func IsIncrementalMode() c.Int
//go:linkname IncrementalProtectionNeeds C.GC_incremental_protection_needs
func IncrementalProtectionNeeds() c.Int
//go:linkname StartIncrementalCollection C.GC_start_incremental_collection
func StartIncrementalCollection()
//go:linkname CollectALittle C.GC_collect_a_little
func CollectALittle()
// -----------------------------------------------------------------------------

17
c/bitcast/_cast/cast.c Normal file
View File

@@ -0,0 +1,17 @@
typedef union {
double d;
float f;
long v;
} castUnion;
double llgoToFloat64(long v) {
castUnion k;
k.v = v;
return k.d;
}
float llgoToFloat32(long v) {
castUnion k;
k.v = v;
return k.f;
}

30
c/bitcast/bitcast.go Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package bitcast
import _ "unsafe"
const (
LLGoFiles = "_cast/cast.c"
LLGoPackage = "link"
)
//go:linkname ToFloat64 C.llgoToFloat64
func ToFloat64(v uintptr) float64
//go:linkname ToFloat32 C.llgoToFloat32
func ToFloat32(v uintptr) float32

164
c/c.go
View File

@@ -17,6 +17,9 @@
package c
// typedef unsigned int uint;
// typedef unsigned long ulong;
// typedef unsigned long long ulonglong;
// typedef long long longlong;
import "C"
import "unsafe"
@@ -25,17 +28,22 @@ const (
)
type (
Char = int8
Int = C.int
Uint = C.uint
Long = int32
Ulong = uint32
LongLong = int64
UlongLong = uint64
Float = float32
Double = float64
Pointer = unsafe.Pointer
FilePtr = unsafe.Pointer
Char = int8
Float = float32
Double = float64
Pointer = unsafe.Pointer
FilePtr = unsafe.Pointer
)
type (
Int C.int
Uint C.uint
Long C.long
Ulong C.ulong
LongLong C.longlong
UlongLong C.ulonglong
)
type integer interface {
@@ -45,8 +53,11 @@ type integer interface {
//go:linkname Str llgo.cstr
func Str(string) *Char
//go:linkname Func llgo.funcAddr
func Func(any) Pointer
// llgo:link Advance llgo.advance
func Advance[PtrT any](ptr PtrT, offset int) PtrT { return ptr }
func Advance[PtrT any, I integer](ptr PtrT, offset I) PtrT { return ptr }
// llgo:link Index llgo.index
func Index[T any, I integer](ptr *T, offset I) T { return *ptr }
@@ -57,27 +68,114 @@ func Alloca(size uintptr) Pointer
//go:linkname AllocaCStr llgo.allocaCStr
func AllocaCStr(s string) *Char
//go:linkname Unreachable llgo.unreachable
func Unreachable()
//go:linkname AllocaCStrs llgo.allocaCStrs
func AllocaCStrs(strs []string, endWithNil bool) **Char
// TODO(xsw):
// llgo:link AllocaNew llgo.allocaNew
func AllocaNew[T any]() *T { return nil }
//go:linkname Malloc C.malloc
func Malloc(size uintptr) Pointer
//go:linkname Free C.free
func Free(ptr Pointer)
//go:linkname Memcpy C.memcpy
func Memcpy(dst, src Pointer, n uintptr) Pointer
//go:linkname Memmove C.memmove
func Memmove(dst, src Pointer, n uintptr) Pointer
//go:linkname Memset C.memset
func Memset(s Pointer, c Int, n uintptr) Pointer
//go:linkname Memchr C.memchr
func Memchr(s Pointer, c Int, n uintptr) Pointer
//go:linkname Memcmp C.memcmp
func Memcmp(s1, s2 Pointer, n uintptr) Int
// -----------------------------------------------------------------------------
//go:linkname Strlen C.strlen
func Strlen(s *Char) uintptr
//go:linkname Strcpy C.strcpy
func Strcpy(dst, src *Char) *Char
//go:linkname Strncpy C.strncpy
func Strncpy(dst, src *Char, n uintptr) *Char
//go:linkname Strcat C.strcat
func Strcat(dst, src *Char) *Char
//go:linkname Strncat C.strncat
func Strncat(dst, src *Char, n uintptr) *Char
//go:linkname Strcmp C.strcmp
func Strcmp(s1, s2 *Char) Int
//go:linkname Strncmp C.strncmp
func Strncmp(s1, s2 *Char, n uintptr) Int
//go:linkname Strchr C.strchr
func Strchr(s *Char, c Int) *Char
//go:linkname Strrchr C.strrchr
func Strrchr(s *Char, c Int) *Char
//go:linkname Strstr C.strstr
func Strstr(s1, s2 *Char) *Char
//go:linkname Strdup C.strdup
func Strdup(s *Char) *Char
//go:linkname Strndup C.strndup
func Strndup(s *Char, n uintptr) *Char
//go:linkname Strtok C.strtok
func Strtok(s, delim *Char) *Char
//go:linkname Strerror C.strerror
func Strerror(errnum Int) *Char
//go:linkname Sprintf C.sprintf
func Sprintf(s *Char, format *Char, __llgo_va_list ...any) Int
//go:linkname Snprintf C.snprintf
func Snprintf(s *Char, n uintptr, format *Char, __llgo_va_list ...any) Int
//go:linkname Vsnprintf C.vsnprintf
func Vsnprintf(s *Char, n uintptr, format *Char, ap Pointer) Int
// -----------------------------------------------------------------------------
// GoString converts a C string to a Go string.
// TODO(xsw): any => int
//
//go:linkname GoString llgo.string
func GoString(cstr *Char, __llgo_va_list /* n */ ...any) string
//go:linkname GoStringData llgo.stringData
func GoStringData(string) *Char
//go:linkname GoDeferData llgo.deferData
func GoDeferData() Pointer
// -----------------------------------------------------------------------------
//go:linkname Remove C.remove
func Remove(path *Char) Int
//go:linkname AllocaSigjmpBuf llgo.sigjmpbuf
func AllocaSigjmpBuf() Pointer
//go:linkname Sigsetjmp llgo.sigsetjmp
func Sigsetjmp(jb Pointer, savemask Int) Int
//go:linkname Siglongjmp llgo.siglongjmp
func Siglongjmp(jb Pointer, retval Int)
//go:linkname Unreachable llgo.unreachable
func Unreachable()
// -----------------------------------------------------------------------------
@@ -94,14 +192,10 @@ func Qsort(base Pointer, count, elem uintptr, compar func(a, b Pointer) Int)
// -----------------------------------------------------------------------------
//go:linkname Stdin __stdinp
var Stdin FilePtr
//go:linkname Atoi C.atoi
func Atoi(s *Char) Int
//go:linkname Stdout __stdoutp
var Stdout FilePtr
//go:linkname Stderr __stderrp
var Stderr FilePtr
// -----------------------------------------------------------------------------
//go:linkname Printf C.printf
func Printf(format *Char, __llgo_va_list ...any) Int
@@ -109,11 +203,35 @@ func Printf(format *Char, __llgo_va_list ...any) Int
//go:linkname Fprintf C.fprintf
func Fprintf(fp FilePtr, format *Char, __llgo_va_list ...any) Int
//go:linkname Fwrite C.fwrite
func Fwrite(data Pointer, size, count uintptr, fp FilePtr) uintptr
//go:linkname Fputc C.fputc
func Fputc(c Int, fp FilePtr) Int
//go:linkname Fputs C.fputs
func Fputs(s *Char, fp FilePtr) Int
//go:linkname Fflush C.fflush
func Fflush(fp FilePtr) Int
//go:linkname Fopen C.fopen
func Fopen(c *Char, mod *Char) FilePtr
//go:linkname Fclose C.fclose
func Fclose(fp FilePtr) Int
//go:linkname Perror C.perror
func Perror(s *Char)
// -----------------------------------------------------------------------------
//go:linkname Time C.time
func Time(*int32) int32
//go:linkname Usleep C.usleep
func Usleep(useconds Uint) Int
// -----------------------------------------------------------------------------
type Option struct {

31
c/c_default.go Normal file
View File

@@ -0,0 +1,31 @@
//go:build !linux
// +build !linux
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package c
import _ "unsafe"
//go:linkname Stdin __stdinp
var Stdin FilePtr
//go:linkname Stdout __stdoutp
var Stdout FilePtr
//go:linkname Stderr __stderrp
var Stderr FilePtr

31
c/c_linux.go Normal file
View File

@@ -0,0 +1,31 @@
//go:build linux
// +build linux
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package c
import _ "unsafe"
//go:linkname Stdin stdin
var Stdin FilePtr
//go:linkname Stdout stdout
var Stdout FilePtr
//go:linkname Stderr stderr
var Stderr FilePtr

View File

@@ -1,22 +1,18 @@
LLGo wrapper of DaveGamble/cJSON
=====
[![Build Status](https://github.com/goplus/cjson/actions/workflows/go.yml/badge.svg)](https://github.com/goplus/cjson/actions/workflows/go.yml)
[![GitHub release](https://img.shields.io/github/v/tag/goplus/cjson.svg?label=release)](https://github.com/goplus/cjson/releases)
[![GoDoc](https://pkg.go.dev/badge/github.com/goplus/cjson.svg)](https://pkg.go.dev/github.com/goplus/cjson)
[![Compiler](https://img.shields.io/badge/compiler-llgo-darkgreen.svg)](https://github.com/goplus/llgo)
[![Language](https://img.shields.io/badge/language-Go+-blue.svg)](https://github.com/goplus/gop)
## How to install
### on macOS (Homebrew)
```sh
git clone https://github.com/goplus/cjson.git
cd cjson
git submodule init
git submodule update
mkdir build.dir
cd build.dir
cmake ../cJSON
sudo make install
brew install cjson
```
### on Linux (Debian/Ubuntu)
```sh
apt-get install -y libcjson-dev
```
## Demos

View File

@@ -23,7 +23,7 @@ import (
)
const (
LLGoPackage = "link: cjson"
LLGoPackage = "link: $(pkg-config --libs libcjson); -lcjson"
)
// llgo:type C

Binary file not shown.

View File

@@ -0,0 +1,61 @@
package main
import (
"fmt"
"os"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/clang"
)
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
depth := *(*c.Uint)(clientData)
printAST(cursor, depth+1)
return clang.ChildVisit_Continue
}
func printAST(cursor clang.Cursor, depth c.Uint) {
cursorKind := cursor.Kind.String()
cursorSpelling := cursor.String()
for i := c.Uint(0); i < depth; i++ {
c.Fputs(c.Str(" "), c.Stdout)
}
c.Printf(c.Str("%s: %s\n"), cursorKind.CStr(), cursorSpelling.CStr())
cursorKind.Dispose()
cursorSpelling.Dispose()
clang.VisitChildren(cursor, visit, c.Pointer(&depth))
}
func main() {
if c.Argc != 2 {
fmt.Fprintln(os.Stderr, "Usage: castdump <headerFile>")
return
}
sourceFile := *c.Advance(c.Argv, 1)
index := clang.CreateIndex(0, 0)
unit := index.ParseTranslationUnit(
sourceFile,
nil, 0,
nil, 0,
clang.TranslationUnit_None,
)
if unit == nil {
println("Unable to parse translation unit. Quitting.")
c.Exit(1)
}
cursor := unit.Cursor()
printAST(cursor, 0)
unit.Dispose()
index.Dispose()
}

29
c/clang/_wrap/cursor.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include <stdio.h>
#include <clang-c/Index.h>
typedef enum CXChildVisitResult(* wrap_CXCursorVisitor) (CXCursor *cursor, CXCursor *parent, CXClientData client_data);
typedef struct {
CXClientData data;
wrap_CXCursorVisitor visitor;
} wrap_data;
CXChildVisitResult wrap_visitor(CXCursor cursor, CXCursor parent, CXClientData data) {
wrap_data *d = (wrap_data*)(data);
return d->visitor(&cursor,&parent,d->data);
}
extern "C" {
CXString wrap_clang_getCursorSpelling(CXCursor *cur) {
return clang_getCursorSpelling(*cur);
}
unsigned wrap_clang_visitChildren(CXCursor *parent,
wrap_CXCursorVisitor visitor,
CXClientData client_data) {
wrap_data data = {client_data,visitor};
return clang_visitChildren(*parent,wrap_visitor,CXClientData(&data));
}
} // extern "C"

View File

@@ -0,0 +1,7 @@
#include <stdio.h>
#include <clang-c/Index.h>
int main() {
printf("sizeof(clang.Cursor) = %lu\n", sizeof(CXCursor));
return 0;
}

View File

@@ -0,0 +1,16 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/clang"
)
const (
LLGoCFlags = "-I$(llvm-config --includedir)"
)
func main() {
c.Printf(c.Str("sizeof(clang.Cursor) = %lu\n"), unsafe.Sizeof(clang.Cursor{}))
}

59
c/clang/basic.go Normal file
View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package clang
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
/**
* A character string.
*
* The \c CXString type is used to return strings from the interface when
* the ownership of that string might differ from one call to the next.
* Use \c clang_getCString() to retrieve the string data and, once finished
* with the string data, call \c clang_disposeString() to free the string.
*/
type String struct {
Data c.Pointer
PrivateFlags c.Uint
}
/**
* Retrieve the character data associated with the given string.
*/
// llgo:link String.CStr C.clang_getCString
func (String) CStr() *c.Char { return nil }
/**
* Free the given string.
*/
// llgo:link String.Dispose C.clang_disposeString
func (String) Dispose() {}
type StringSet struct {
Strings *String
Count c.Uint
}
/**
* Free the given string set.
*/
// llgo:link (*StringSet).Dispose C.clang_disposeStringSet
func (*StringSet) Dispose() {}

292
c/clang/clang.go Normal file
View File

@@ -0,0 +1,292 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package clang
import (
"unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoFiles = "$(llvm-config --cflags): _wrap/cursor.cpp"
LLGoPackage = "link: -L$(llvm-config --libdir) -lclang; -lclang"
)
/**
* Opaque pointer representing client data that will be passed through
* to various callbacks and visitors.
*/
type ClientData = c.Pointer
/**
* Provides the contents of a file that has not yet been saved to disk.
*
* Each CXUnsavedFile instance provides the name of a file on the
* system along with the current contents of that file that have not
* yet been saved to disk.
*/
type UnsavedFile struct {
/**
* The file whose contents have not yet been saved.
*
* This file must already exist in the file system.
*/
Filename *c.Char
/**
* A buffer containing the unsaved contents of this file.
*/
Contents *c.Char
/**
* The length of the unsaved contents of this buffer.
*/
Length c.Ulong
}
/**
* An "index" that consists of a set of translation units that would
* typically be linked together into an executable or library.
*/
type Index struct {
Unused [0]byte
}
/**
* Provides a shared context for creating translation units.
*
* It provides two options:
*
* - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local"
* declarations (when loading any new translation units). A "local" declaration
* is one that belongs in the translation unit itself and not in a precompiled
* header that was used by the translation unit. If zero, all declarations
* will be enumerated.
*
* Here is an example:
*
* \code
* // excludeDeclsFromPCH = 1, displayDiagnostics=1
* Idx = clang_createIndex(1, 1);
*
* // IndexTest.pch was produced with the following command:
* // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
* TU = clang_createTranslationUnit(Idx, "IndexTest.pch");
*
* // This will load all the symbols from 'IndexTest.pch'
* clang_visitChildren(clang_getTranslationUnitCursor(TU),
* TranslationUnitVisitor, 0);
* clang_disposeTranslationUnit(TU);
*
* // This will load all the symbols from 'IndexTest.c', excluding symbols
* // from 'IndexTest.pch'.
* char *args[] = { "-Xclang", "-include-pch=IndexTest.pch" };
* TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args,
* 0, 0);
* clang_visitChildren(clang_getTranslationUnitCursor(TU),
* TranslationUnitVisitor, 0);
* clang_disposeTranslationUnit(TU);
* \endcode
*
* This process of creating the 'pch', loading it separately, and using it (via
* -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
* (which gives the indexer the same performance benefit as the compiler).
*/
//go:linkname CreateIndex C.clang_createIndex
func CreateIndex(excludeDeclarationsFromPCH, displayDiagnostics c.Int) *Index
/**
* Destroy the given index.
*
* The index must not be destroyed until all of the translation units created
* within that index have been destroyed.
*/
// llgo:link (*Index).Dispose C.clang_disposeIndex
func (*Index) Dispose() {}
/**
* Flags that control the creation of translation units.
*
* The enumerators in this enumeration type are meant to be bitwise
* ORed together to specify which options should be used when
* constructing the translation unit.
*/
const (
TranslationUnit_None = 0x0
)
/**
* Same as \c clang_parseTranslationUnit2, but returns
* the \c CXTranslationUnit instead of an error code. In case of an error this
* routine returns a \c NULL \c CXTranslationUnit, without further detailed
* error codes.
*/
// llgo:link (*Index).ParseTranslationUnit C.clang_parseTranslationUnit
func (*Index) ParseTranslationUnit(
sourceFilename *c.Char, commandLineArgs **c.Char, numCommandLineArgs c.Int,
unsavedFiles *UnsavedFile, numUnsavedFiles c.Uint, options c.Uint) *TranslationUnit {
return nil
}
/**
* A single translation unit, which resides in an index.
*/
type TranslationUnit struct {
Unused [0]byte
}
/**
* Destroy the specified CXTranslationUnit object.
*/
// llgo:link (*TranslationUnit).Dispose C.clang_disposeTranslationUnit
func (*TranslationUnit) Dispose() {}
/**
* Retrieve the cursor that represents the given translation unit.
*
* The translation unit cursor can be used to start traversing the
* various declarations within the given translation unit.
*/
// llgo:link (*TranslationUnit).Cursor C.clang_getTranslationUnitCursor
func (*TranslationUnit) Cursor() (ret Cursor) {
return
}
/**
* Describes the kind of entity that a cursor refers to.
*/
type CursorKind c.Int
/* for debug/testing */
// llgo:link CursorKind.String C.clang_getCursorKindSpelling
func (CursorKind) String() (ret String) {
return
}
/**
* A cursor representing some element in the abstract syntax tree for
* a translation unit.
*
* The cursor abstraction unifies the different kinds of entities in a
* program--declaration, statements, expressions, references to declarations,
* etc.--under a single "cursor" abstraction with a common set of operations.
* Common operation for a cursor include: getting the physical location in
* a source file where the cursor points, getting the name associated with a
* cursor, and retrieving cursors for any child nodes of a particular cursor.
*
* Cursors can be produced in two specific ways.
* clang_getTranslationUnitCursor() produces a cursor for a translation unit,
* from which one can use clang_visitChildren() to explore the rest of the
* translation unit. clang_getCursor() maps from a physical source location
* to the entity that resides at that location, allowing one to map from the
* source code into the AST.
*/
type Cursor struct {
Kind CursorKind
Xdata c.Int
Data [3]c.Pointer
}
/**
* Retrieve a name for the entity referenced by this cursor.
*/
// llgo:link (*Cursor).wrapString C.wrap_clang_getCursorSpelling
func (*Cursor) wrapString() (ret String) {
return
}
func (c Cursor) String() (ret String) {
return c.wrapString()
}
/**
* Describes how the traversal of the children of a particular
* cursor should proceed after visiting a particular child cursor.
*
* A value of this enumeration type should be returned by each
* \c CXCursorVisitor to indicate how clang_visitChildren() proceed.
*/
type ChildVisitResult c.Int
const (
/**
* Terminates the cursor traversal.
*/
ChildVisit_Break ChildVisitResult = iota
/**
* Continues the cursor traversal with the next sibling of
* the cursor just visited, without visiting its children.
*/
ChildVisit_Continue
/**
* Recursively traverse the children of this cursor, using
* the same visitor and client data.
*/
ChildVisit_Recurse
)
/**
* Visit the children of a particular cursor.
*
* This function visits all the direct children of the given cursor,
* invoking the given \p visitor function with the cursors of each
* visited child. The traversal may be recursive, if the visitor returns
* \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if
* the visitor returns \c CXChildVisit_Break.
*
* \param parent the cursor whose child may be visited. All kinds of
* cursors can be visited, including invalid cursors (which, by
* definition, have no children).
*
* \param visitor the visitor function that will be invoked for each
* child of \p parent.
*
* \param client_data pointer data supplied by the client, which will
* be passed to the visitor each time it is invoked.
*
* \returns a non-zero value if the traversal was terminated
* prematurely by the visitor returning \c CXChildVisit_Break.
*/
//go:linkname wrapVisitChildren C.wrap_clang_visitChildren
func wrapVisitChildren(
cusor *Cursor,
fn wrapVisitor,
clientData ClientData) c.Uint {
return 0
}
//llgo:type C
type wrapVisitor func(cursor, parent *Cursor, clientData ClientData) ChildVisitResult
type wrapData struct {
data ClientData
fn Visitor
}
func VisitChildren(
root Cursor,
fn Visitor,
clientData ClientData) c.Uint {
return wrapVisitChildren(&root, func(cursor, parent *Cursor, data ClientData) ChildVisitResult {
p := (*wrapData)(data)
return p.fn(*cursor, *parent, p.data)
}, unsafe.Pointer(&wrapData{clientData, fn}))
}
//llgo:type C
type Visitor func(cursor, parent Cursor, clientData ClientData) ChildVisitResult

10
c/llama2/README.md Normal file
View File

@@ -0,0 +1,10 @@
LLGo wrapper of karpathy/llama2.c
=====
## How to update source to llgo
```
git submodule init
git submodule update
cp llama2.c/run.c llama2/run.c
```

View File

@@ -23,7 +23,8 @@ import (
)
const (
LLGoPackage = "link"
LLGoFiles = "llama2/llama2.c"
LLGoPackage = "link: -lm"
)
// -----------------------------------------------------------------------------

2
c/llama2/llama2/llama2.c Normal file
View File

@@ -0,0 +1,2 @@
#define TESTING
#include "./run.c"

View File

@@ -1,2 +1,973 @@
#define TESTING
#include "../llama2.c/run.c"
/* Inference for Llama-2 Transformer model in pure C */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <fcntl.h>
#if defined _WIN32
#include "win.h"
#else
#include <unistd.h>
#include <sys/mman.h>
#endif
// ----------------------------------------------------------------------------
// Transformer model
typedef struct {
int dim; // transformer dimension
int hidden_dim; // for ffn layers
int n_layers; // number of layers
int n_heads; // number of query heads
int n_kv_heads; // number of key/value heads (can be < query heads because of multiquery)
int vocab_size; // vocabulary size, usually 256 (byte-level)
int seq_len; // max sequence length
} Config;
typedef struct {
// token embedding table
float* token_embedding_table; // (vocab_size, dim)
// weights for rmsnorms
float* rms_att_weight; // (layer, dim) rmsnorm weights
float* rms_ffn_weight; // (layer, dim)
// weights for matmuls. note dim == n_heads * head_size
float* wq; // (layer, dim, n_heads * head_size)
float* wk; // (layer, dim, n_kv_heads * head_size)
float* wv; // (layer, dim, n_kv_heads * head_size)
float* wo; // (layer, n_heads * head_size, dim)
// weights for ffn
float* w1; // (layer, hidden_dim, dim)
float* w2; // (layer, dim, hidden_dim)
float* w3; // (layer, hidden_dim, dim)
// final rmsnorm
float* rms_final_weight; // (dim,)
// (optional) classifier weights for the logits, on the last layer
float* wcls;
} TransformerWeights;
typedef struct {
// current wave of activations
float *x; // activation at current time stamp (dim,)
float *xb; // same, but inside a residual branch (dim,)
float *xb2; // an additional buffer just for convenience (dim,)
float *hb; // buffer for hidden dimension in the ffn (hidden_dim,)
float *hb2; // buffer for hidden dimension in the ffn (hidden_dim,)
float *q; // query (dim,)
float *k; // key (dim,)
float *v; // value (dim,)
float *att; // buffer for scores/attention values (n_heads, seq_len)
float *logits; // output logits
// kv cache
float* key_cache; // (layer, seq_len, dim)
float* value_cache; // (layer, seq_len, dim)
} RunState;
typedef struct {
Config config; // the hyperparameters of the architecture (the blueprint)
TransformerWeights weights; // the weights of the model
RunState state; // buffers for the "wave" of activations in the forward pass
// some more state needed to properly clean up the memory mapping (sigh)
int fd; // file descriptor for memory mapping
float* data; // memory mapped data pointer
ssize_t file_size; // size of the checkpoint file in bytes
} Transformer;
void malloc_run_state(RunState* s, Config* p) {
// we calloc instead of malloc to keep valgrind happy
int kv_dim = (p->dim * p->n_kv_heads) / p->n_heads;
s->x = calloc(p->dim, sizeof(float));
s->xb = calloc(p->dim, sizeof(float));
s->xb2 = calloc(p->dim, sizeof(float));
s->hb = calloc(p->hidden_dim, sizeof(float));
s->hb2 = calloc(p->hidden_dim, sizeof(float));
s->q = calloc(p->dim, sizeof(float));
s->key_cache = calloc(p->n_layers * p->seq_len * kv_dim, sizeof(float));
s->value_cache = calloc(p->n_layers * p->seq_len * kv_dim, sizeof(float));
s->att = calloc(p->n_heads * p->seq_len, sizeof(float));
s->logits = calloc(p->vocab_size, sizeof(float));
// ensure all mallocs went fine
if (!s->x || !s->xb || !s->xb2 || !s->hb || !s->hb2 || !s->q
|| !s->key_cache || !s->value_cache || !s->att || !s->logits) {
fprintf(stderr, "malloc failed!\n");
exit(EXIT_FAILURE);
}
}
void free_run_state(RunState* s) {
free(s->x);
free(s->xb);
free(s->xb2);
free(s->hb);
free(s->hb2);
free(s->q);
free(s->att);
free(s->logits);
free(s->key_cache);
free(s->value_cache);
}
void memory_map_weights(TransformerWeights *w, Config* p, float* ptr, int shared_weights) {
int head_size = p->dim / p->n_heads;
// make sure the multiplications below are done in 64bit to fit the parameter counts of 13B+ models
unsigned long long n_layers = p->n_layers;
w->token_embedding_table = ptr;
ptr += p->vocab_size * p->dim;
w->rms_att_weight = ptr;
ptr += n_layers * p->dim;
w->wq = ptr;
ptr += n_layers * p->dim * (p->n_heads * head_size);
w->wk = ptr;
ptr += n_layers * p->dim * (p->n_kv_heads * head_size);
w->wv = ptr;
ptr += n_layers * p->dim * (p->n_kv_heads * head_size);
w->wo = ptr;
ptr += n_layers * (p->n_heads * head_size) * p->dim;
w->rms_ffn_weight = ptr;
ptr += n_layers * p->dim;
w->w1 = ptr;
ptr += n_layers * p->dim * p->hidden_dim;
w->w2 = ptr;
ptr += n_layers * p->hidden_dim * p->dim;
w->w3 = ptr;
ptr += n_layers * p->dim * p->hidden_dim;
w->rms_final_weight = ptr;
ptr += p->dim;
ptr += p->seq_len * head_size / 2; // skip what used to be freq_cis_real (for RoPE)
ptr += p->seq_len * head_size / 2; // skip what used to be freq_cis_imag (for RoPE)
w->wcls = shared_weights ? w->token_embedding_table : ptr;
}
void read_checkpoint(char* checkpoint, Config* config, TransformerWeights* weights,
int* fd, float** data, ssize_t* file_size) {
FILE *file = fopen(checkpoint, "rb");
if (!file) { fprintf(stderr, "Couldn't open file %s\n", checkpoint); exit(EXIT_FAILURE); }
// read in the config header
if (fread(config, sizeof(Config), 1, file) != 1) { exit(EXIT_FAILURE); }
// negative vocab size is hacky way of signaling unshared weights. bit yikes.
int shared_weights = config->vocab_size > 0 ? 1 : 0;
config->vocab_size = abs(config->vocab_size);
// figure out the file size
fseek(file, 0, SEEK_END); // move file pointer to end of file
*file_size = ftell(file); // get the file size, in bytes
fclose(file);
// memory map the Transformer weights into the data pointer
*fd = open(checkpoint, O_RDONLY); // open in read only mode
if (*fd == -1) { fprintf(stderr, "open failed!\n"); exit(EXIT_FAILURE); }
*data = mmap(NULL, *file_size, PROT_READ, MAP_PRIVATE, *fd, 0);
if (*data == MAP_FAILED) { fprintf(stderr, "mmap failed!\n"); exit(EXIT_FAILURE); }
float* weights_ptr = *data + sizeof(Config)/sizeof(float);
memory_map_weights(weights, config, weights_ptr, shared_weights);
}
void build_transformer(Transformer *t, char* checkpoint_path) {
// read in the Config and the Weights from the checkpoint
read_checkpoint(checkpoint_path, &t->config, &t->weights, &t->fd, &t->data, &t->file_size);
// allocate the RunState buffers
malloc_run_state(&t->state, &t->config);
}
void free_transformer(Transformer* t) {
// close the memory mapping
if (t->data != MAP_FAILED) { munmap(t->data, t->file_size); }
if (t->fd != -1) { close(t->fd); }
// free the RunState buffers
free_run_state(&t->state);
}
// ----------------------------------------------------------------------------
// neural net blocks; the dynamics of the Transformer
void rmsnorm(float* o, float* x, float* weight, int size) {
// calculate sum of squares
float ss = 0.0f;
for (int j = 0; j < size; j++) {
ss += x[j] * x[j];
}
ss /= size;
ss += 1e-5f;
ss = 1.0f / sqrtf(ss);
// normalize and scale
for (int j = 0; j < size; j++) {
o[j] = weight[j] * (ss * x[j]);
}
}
void softmax(float* x, int size) {
// find max value (for numerical stability)
float max_val = x[0];
for (int i = 1; i < size; i++) {
if (x[i] > max_val) {
max_val = x[i];
}
}
// exp and sum
float sum = 0.0f;
for (int i = 0; i < size; i++) {
x[i] = expf(x[i] - max_val);
sum += x[i];
}
// normalize
for (int i = 0; i < size; i++) {
x[i] /= sum;
}
}
void matmul(float* xout, float* x, float* w, int n, int d) {
// W (d,n) @ x (n,) -> xout (d,)
// by far the most amount of time is spent inside this little function
int i;
#pragma omp parallel for private(i)
for (i = 0; i < d; i++) {
float val = 0.0f;
for (int j = 0; j < n; j++) {
val += w[i * n + j] * x[j];
}
xout[i] = val;
}
}
float* forward(Transformer* transformer, int token, int pos) {
// a few convenience variables
Config* p = &transformer->config;
TransformerWeights* w = &transformer->weights;
RunState* s = &transformer->state;
float *x = s->x;
int dim = p->dim;
int kv_dim = (p->dim * p->n_kv_heads) / p->n_heads;
int kv_mul = p->n_heads / p->n_kv_heads; // integer multiplier of the kv sharing in multiquery
int hidden_dim = p->hidden_dim;
int head_size = dim / p->n_heads;
// copy the token embedding into x
float* content_row = w->token_embedding_table + token * dim;
memcpy(x, content_row, dim*sizeof(*x));
// forward all the layers
for(unsigned long long l = 0; l < p->n_layers; l++) {
// attention rmsnorm
rmsnorm(s->xb, x, w->rms_att_weight + l*dim, dim);
// key and value point to the kv cache
int loff = l * p->seq_len * kv_dim; // kv cache layer offset for convenience
s->k = s->key_cache + loff + pos * kv_dim;
s->v = s->value_cache + loff + pos * kv_dim;
// qkv matmuls for this position
matmul(s->q, s->xb, w->wq + l*dim*dim, dim, dim);
matmul(s->k, s->xb, w->wk + l*dim*kv_dim, dim, kv_dim);
matmul(s->v, s->xb, w->wv + l*dim*kv_dim, dim, kv_dim);
// RoPE relative positional encoding: complex-valued rotate q and k in each head
for (int i = 0; i < dim; i+=2) {
int head_dim = i % head_size;
float freq = 1.0f / powf(10000.0f, head_dim / (float)head_size);
float val = pos * freq;
float fcr = cosf(val);
float fci = sinf(val);
int rotn = i < kv_dim ? 2 : 1; // how many vectors? 2 = q & k, 1 = q only
for (int v = 0; v < rotn; v++) {
float* vec = v == 0 ? s->q : s->k; // the vector to rotate (query or key)
float v0 = vec[i];
float v1 = vec[i+1];
vec[i] = v0 * fcr - v1 * fci;
vec[i+1] = v0 * fci + v1 * fcr;
}
}
// multihead attention. iterate over all heads
int h;
#pragma omp parallel for private(h)
for (h = 0; h < p->n_heads; h++) {
// get the query vector for this head
float* q = s->q + h * head_size;
// attention scores for this head
float* att = s->att + h * p->seq_len;
// iterate over all timesteps, including the current one
for (int t = 0; t <= pos; t++) {
// get the key vector for this head and at this timestep
float* k = s->key_cache + loff + t * kv_dim + (h / kv_mul) * head_size;
// calculate the attention score as the dot product of q and k
float score = 0.0f;
for (int i = 0; i < head_size; i++) {
score += q[i] * k[i];
}
score /= sqrtf(head_size);
// save the score to the attention buffer
att[t] = score;
}
// softmax the scores to get attention weights, from 0..pos inclusively
softmax(att, pos + 1);
// weighted sum of the values, store back into xb
float* xb = s->xb + h * head_size;
memset(xb, 0, head_size * sizeof(float));
for (int t = 0; t <= pos; t++) {
// get the value vector for this head and at this timestep
float* v = s->value_cache + loff + t * kv_dim + (h / kv_mul) * head_size;
// get the attention weight for this timestep
float a = att[t];
// accumulate the weighted value into xb
for (int i = 0; i < head_size; i++) {
xb[i] += a * v[i];
}
}
}
// final matmul to get the output of the attention
matmul(s->xb2, s->xb, w->wo + l*dim*dim, dim, dim);
// residual connection back into x
for (int i = 0; i < dim; i++) {
x[i] += s->xb2[i];
}
// ffn rmsnorm
rmsnorm(s->xb, x, w->rms_ffn_weight + l*dim, dim);
// Now for FFN in PyTorch we have: self.w2(F.silu(self.w1(x)) * self.w3(x))
// first calculate self.w1(x) and self.w3(x)
matmul(s->hb, s->xb, w->w1 + l*dim*hidden_dim, dim, hidden_dim);
matmul(s->hb2, s->xb, w->w3 + l*dim*hidden_dim, dim, hidden_dim);
// SwiGLU non-linearity
for (int i = 0; i < hidden_dim; i++) {
float val = s->hb[i];
// silu(x)=x*σ(x), where σ(x) is the logistic sigmoid
val *= (1.0f / (1.0f + expf(-val)));
// elementwise multiply with w3(x)
val *= s->hb2[i];
s->hb[i] = val;
}
// final matmul to get the output of the ffn
matmul(s->xb, s->hb, w->w2 + l*dim*hidden_dim, hidden_dim, dim);
// residual connection
for (int i = 0; i < dim; i++) {
x[i] += s->xb[i];
}
}
// final rmsnorm
rmsnorm(x, x, w->rms_final_weight, dim);
// classifier into logits
matmul(s->logits, x, w->wcls, p->dim, p->vocab_size);
return s->logits;
}
// ----------------------------------------------------------------------------
// The Byte Pair Encoding (BPE) Tokenizer that translates strings <-> tokens
typedef struct {
char *str;
int id;
} TokenIndex;
typedef struct {
char** vocab;
float* vocab_scores;
TokenIndex *sorted_vocab;
int vocab_size;
unsigned int max_token_length;
unsigned char byte_pieces[512]; // stores all single-byte strings
} Tokenizer;
int compare_tokens(const void *a, const void *b) {
return strcmp(((TokenIndex*)a)->str, ((TokenIndex*)b)->str);
}
void build_tokenizer(Tokenizer* t, char* tokenizer_path, int vocab_size) {
// i should have written the vocab_size into the tokenizer file... sigh
t->vocab_size = vocab_size;
// malloc space to hold the scores and the strings
t->vocab = (char**)malloc(vocab_size * sizeof(char*));
t->vocab_scores = (float*)malloc(vocab_size * sizeof(float));
t->sorted_vocab = NULL; // initialized lazily
for (int i = 0; i < 256; i++) {
t->byte_pieces[i * 2] = (unsigned char)i;
t->byte_pieces[i * 2 + 1] = '\0';
}
// read in the file
FILE *file = fopen(tokenizer_path, "rb");
if (!file) { fprintf(stderr, "couldn't load %s\n", tokenizer_path); exit(EXIT_FAILURE); }
if (fread(&t->max_token_length, sizeof(int), 1, file) != 1) { fprintf(stderr, "failed read\n"); exit(EXIT_FAILURE); }
int len;
for (int i = 0; i < vocab_size; i++) {
if (fread(t->vocab_scores + i, sizeof(float), 1, file) != 1) { fprintf(stderr, "failed read\n"); exit(EXIT_FAILURE);}
if (fread(&len, sizeof(int), 1, file) != 1) { fprintf(stderr, "failed read\n"); exit(EXIT_FAILURE); }
t->vocab[i] = (char *)malloc(len + 1);
if (fread(t->vocab[i], len, 1, file) != 1) { fprintf(stderr, "failed read\n"); exit(EXIT_FAILURE); }
t->vocab[i][len] = '\0'; // add the string terminating token
}
fclose(file);
}
void free_tokenizer(Tokenizer* t) {
for (int i = 0; i < t->vocab_size; i++) { free(t->vocab[i]); }
free(t->vocab);
free(t->vocab_scores);
free(t->sorted_vocab);
}
char* decode(Tokenizer* t, int prev_token, int token) {
char *piece = t->vocab[token];
// following BOS (1) token, sentencepiece decoder strips any leading whitespace (see PR #89)
if (prev_token == 1 && piece[0] == ' ') { piece++; }
// careful, some tokens designate raw bytes, and look like e.g. '<0x01>'
// parse this and convert and return the actual byte
unsigned char byte_val;
if (sscanf(piece, "<0x%02hhX>", &byte_val) == 1) {
piece = (char*)t->byte_pieces + byte_val * 2;
}
return piece;
}
void safe_printf(char *piece) {
// piece might be a raw byte token, and we only want to print printable chars or whitespace
// because some of the other bytes can be various control codes, backspace, etc.
if (piece == NULL) { return; }
if (piece[0] == '\0') { return; }
if (piece[1] == '\0') {
unsigned char byte_val = piece[0];
if (!(isprint(byte_val) || isspace(byte_val))) {
return; // bad byte, don't print it
}
}
printf("%s", piece);
}
int str_lookup(char *str, TokenIndex *sorted_vocab, int vocab_size) {
// efficiently find the perfect match for str in vocab, return its index or -1 if not found
TokenIndex tok = { .str = str }; // acts as the key to search for
TokenIndex *res = bsearch(&tok, sorted_vocab, vocab_size, sizeof(TokenIndex), compare_tokens);
return res != NULL ? res->id : -1;
}
void encode(Tokenizer* t, char *text, int8_t bos, int8_t eos, int *tokens, int *n_tokens) {
// encode the string text (input) into an upper-bound preallocated tokens[] array
// bos != 0 means prepend the BOS token (=1), eos != 0 means append the EOS token (=2)
if (text == NULL) { fprintf(stderr, "cannot encode NULL text\n"); exit(EXIT_FAILURE); }
if (t->sorted_vocab == NULL) {
// lazily malloc and sort the vocabulary
t->sorted_vocab = malloc(t->vocab_size * sizeof(TokenIndex));
for (int i = 0; i < t->vocab_size; i++) {
t->sorted_vocab[i].str = t->vocab[i];
t->sorted_vocab[i].id = i;
}
qsort(t->sorted_vocab, t->vocab_size, sizeof(TokenIndex), compare_tokens);
}
// create a temporary buffer that will store merge candidates of always two consecutive tokens
// *2 for concat, +1 for null terminator +2 for UTF8 (in case max_token_length is 1)
char* str_buffer = malloc((t->max_token_length*2 +1 +2) * sizeof(char));
size_t str_len = 0;
// start at 0 tokens
*n_tokens = 0;
// add optional BOS (=1) token, if desired
if (bos) tokens[(*n_tokens)++] = 1;
// add_dummy_prefix is true by default
// so prepend a dummy prefix token to the input string, but only if text != ""
// TODO: pretty sure this isn't correct in the general case but I don't have the
// energy to read more of the sentencepiece code to figure out what it's doing
if (text[0] != '\0') {
int dummy_prefix = str_lookup(" ", t->sorted_vocab, t->vocab_size);
tokens[(*n_tokens)++] = dummy_prefix;
}
// Okay UTF-8 time. This will get messy. Here is the reference from Wikipedia:
// Code point ↔ UTF-8 conversion
// First code point Last code point Byte 1 Byte 2 Byte 3 Byte 4
// U+0000 U+007F 0xxxxxxx
// U+0080 U+07FF 110xxxxx 10xxxxxx
// U+0800 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
// U+10000 U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
// process the raw (UTF-8) byte sequence of the input string
for (char *c = text; *c != '\0'; c++) {
// reset buffer if the current byte is ASCII or a leading byte
// 0xC0 is 11000000, so (*c & 0xC0) keeps the first 2 bits and zeros the rest
// 0x80 is 10000000
// in UTF-8, all continuation bytes start with "10" in first two bits
// so in English this is: "if this byte is not a continuation byte"
if ((*c & 0xC0) != 0x80) {
// this byte must be either a leading byte (11...) or an ASCII char (0x...)
// => reset our location, as we're starting a new UTF-8 codepoint
str_len = 0;
}
// append the current byte to the buffer
str_buffer[str_len++] = *c; // ++ is post-increment, incremented after this line
str_buffer[str_len] = '\0';
// while the next character is a continuation byte, continue appending
// but if there are too many of them, just stop to avoid overruning str_buffer size.
if ((*(c+1) & 0xC0) == 0x80 && str_len < 4) {
continue;
}
// ok c+1 is not a continuation byte, so we've read in a full codepoint
int id = str_lookup(str_buffer, t->sorted_vocab, t->vocab_size);
if (id != -1) {
// we found this codepoint in vocab, add it as a token
tokens[(*n_tokens)++] = id;
} else {
// byte_fallback encoding: just encode each byte as a token
// +3 is here because the first 3 vocab elements are <unk>, <s>, </s>
// so the individual bytes only start at index 3
for (int i=0; i < str_len; i++) {
tokens[(*n_tokens)++] = (unsigned char)str_buffer[i] + 3;
}
}
str_len = 0; // protect against a sequence of stray UTF8 continuation bytes
}
// merge the best consecutive pair each iteration, according the scores in vocab_scores
while (1) {
float best_score = -1e10;
int best_id = -1;
int best_idx = -1;
for (int i=0; i < (*n_tokens-1); i++) {
// check if we can merge the pair (tokens[i], tokens[i+1])
sprintf(str_buffer, "%s%s", t->vocab[tokens[i]], t->vocab[tokens[i+1]]);
int id = str_lookup(str_buffer, t->sorted_vocab, t->vocab_size);
if (id != -1 && t->vocab_scores[id] > best_score) {
// this merge pair exists in vocab! record its score and position
best_score = t->vocab_scores[id];
best_id = id;
best_idx = i;
}
}
if (best_idx == -1) {
break; // we couldn't find any more pairs to merge, so we're done
}
// merge the consecutive pair (best_idx, best_idx+1) into new token best_id
tokens[best_idx] = best_id;
// delete token at position best_idx+1, shift the entire sequence back 1
for (int i = best_idx+1; i < (*n_tokens-1); i++) {
tokens[i] = tokens[i+1];
}
(*n_tokens)--; // token length decreased
}
// add optional EOS (=2) token, if desired
if (eos) tokens[(*n_tokens)++] = 2;
free(str_buffer);
}
// ----------------------------------------------------------------------------
// The Sampler, which takes logits and returns a sampled token
// sampling can be done in a few ways: greedy argmax, sampling, top-p sampling
typedef struct {
float prob;
int index;
} ProbIndex; // struct used when sorting probabilities during top-p sampling
typedef struct {
int vocab_size;
ProbIndex* probindex; // buffer used in top-p sampling
float temperature;
float topp;
unsigned long long rng_state;
} Sampler;
int sample_argmax(float* probabilities, int n) {
// return the index that has the highest probability
int max_i = 0;
float max_p = probabilities[0];
for (int i = 1; i < n; i++) {
if (probabilities[i] > max_p) {
max_i = i;
max_p = probabilities[i];
}
}
return max_i;
}
int sample_mult(float* probabilities, int n, float coin) {
// sample index from probabilities (they must sum to 1!)
// coin is a random number in [0, 1), usually from random_f32()
float cdf = 0.0f;
for (int i = 0; i < n; i++) {
cdf += probabilities[i];
if (coin < cdf) {
return i;
}
}
return n - 1; // in case of rounding errors
}
int compare(const void* a, const void* b) {
ProbIndex* a_ = (ProbIndex*) a;
ProbIndex* b_ = (ProbIndex*) b;
if (a_->prob > b_->prob) return -1;
if (a_->prob < b_->prob) return 1;
return 0;
}
int sample_topp(float* probabilities, int n, float topp, ProbIndex* probindex, float coin) {
// top-p sampling (or "nucleus sampling") samples from the smallest set of
// tokens that exceed probability topp. This way we never sample tokens that
// have very low probabilities and are less likely to go "off the rails".
// coin is a random number in [0, 1), usually from random_f32()
int n0 = 0;
// quicksort indices in descending order of probabilities
// values smaller than (1 - topp) / (n - 1) cannot be part of the result
// so for efficiency we crop these out as candidates before sorting
const float cutoff = (1.0f - topp) / (n - 1);
for (int i = 0; i < n; i++) {
if (probabilities[i] >= cutoff) {
probindex[n0].index = i;
probindex[n0].prob = probabilities[i];
n0++;
}
}
qsort(probindex, n0, sizeof(ProbIndex), compare);
// truncate the list where cumulative probability exceeds topp
float cumulative_prob = 0.0f;
int last_idx = n0 - 1; // in case of rounding errors consider all elements
for (int i = 0; i < n0; i++) {
cumulative_prob += probindex[i].prob;
if (cumulative_prob > topp) {
last_idx = i;
break; // we've exceeded topp by including last_idx
}
}
// sample from the truncated list
float r = coin * cumulative_prob;
float cdf = 0.0f;
for (int i = 0; i <= last_idx; i++) {
cdf += probindex[i].prob;
if (r < cdf) {
return probindex[i].index;
}
}
return probindex[last_idx].index; // in case of rounding errors
}
void build_sampler(Sampler* sampler, int vocab_size, float temperature, float topp, unsigned long long rng_seed) {
sampler->vocab_size = vocab_size;
sampler->temperature = temperature;
sampler->topp = topp;
sampler->rng_state = rng_seed;
// buffer only used with nucleus sampling; may not need but it's ~small
sampler->probindex = malloc(sampler->vocab_size * sizeof(ProbIndex));
}
void free_sampler(Sampler* sampler) {
free(sampler->probindex);
}
unsigned int random_u32(unsigned long long *state) {
// xorshift rng: https://en.wikipedia.org/wiki/Xorshift#xorshift.2A
*state ^= *state >> 12;
*state ^= *state << 25;
*state ^= *state >> 27;
return (*state * 0x2545F4914F6CDD1Dull) >> 32;
}
float random_f32(unsigned long long *state) { // random float32 in [0,1)
return (random_u32(state) >> 8) / 16777216.0f;
}
int sample(Sampler* sampler, float* logits) {
// sample the token given the logits and some hyperparameters
int next;
if (sampler->temperature == 0.0f) {
// greedy argmax sampling: take the token with the highest probability
next = sample_argmax(logits, sampler->vocab_size);
} else {
// apply the temperature to the logits
for (int q=0; q<sampler->vocab_size; q++) { logits[q] /= sampler->temperature; }
// apply softmax to the logits to get the probabilities for next token
softmax(logits, sampler->vocab_size);
// flip a (float) coin (this is our source of entropy for sampling)
float coin = random_f32(&sampler->rng_state);
// we sample from this distribution to get the next token
if (sampler->topp <= 0 || sampler->topp >= 1) {
// simply sample from the predicted probability distribution
next = sample_mult(logits, sampler->vocab_size, coin);
} else {
// top-p (nucleus) sampling, clamping the least likely tokens to zero
next = sample_topp(logits, sampler->vocab_size, sampler->topp, sampler->probindex, coin);
}
}
return next;
}
// ----------------------------------------------------------------------------
// utilities: time
long time_in_ms() {
// return time in milliseconds, for benchmarking the model speed
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
return time.tv_sec * 1000 + time.tv_nsec / 1000000;
}
// ----------------------------------------------------------------------------
// generation loop
void generate(Transformer *transformer, Tokenizer *tokenizer, Sampler *sampler, char *prompt, int steps) {
char *empty_prompt = "";
if (prompt == NULL) { prompt = empty_prompt; }
// encode the (string) prompt into tokens sequence
int num_prompt_tokens = 0;
int* prompt_tokens = (int*)malloc((strlen(prompt)+3) * sizeof(int)); // +3 for '\0', ?BOS, ?EOS
encode(tokenizer, prompt, 1, 0, prompt_tokens, &num_prompt_tokens);
if (num_prompt_tokens < 1) {
fprintf(stderr, "something is wrong, expected at least 1 prompt token\n");
exit(EXIT_FAILURE);
}
// start the main loop
long start = 0; // used to time our code, only initialized after first iteration
int next; // will store the next token in the sequence
int token = prompt_tokens[0]; // kick off with the first token in the prompt
int pos = 0; // position in the sequence
while (pos < steps) {
// forward the transformer to get logits for the next token
float* logits = forward(transformer, token, pos);
// advance the state machine
if (pos < num_prompt_tokens - 1) {
// if we are still processing the input prompt, force the next prompt token
next = prompt_tokens[pos + 1];
} else {
// otherwise sample the next token from the logits
next = sample(sampler, logits);
}
pos++;
// data-dependent terminating condition: the BOS (=1) token delimits sequences
if (next == 1) { break; }
// print the token as string, decode it with the Tokenizer object
char* piece = decode(tokenizer, token, next);
safe_printf(piece); // same as printf("%s", piece), but skips "unsafe" bytes
fflush(stdout);
token = next;
// init the timer here because the first iteration can be slower
if (start == 0) { start = time_in_ms(); }
}
printf("\n");
// report achieved tok/s (pos-1 because the timer starts after first iteration)
if (pos > 1) {
long end = time_in_ms();
fprintf(stderr, "achieved tok/s: %f\n", (pos-1) / (double)(end-start)*1000);
}
free(prompt_tokens);
}
void read_stdin(const char* guide, char* buffer, size_t bufsize) {
// read a line from stdin, up to but not including \n
printf("%s", guide);
if (fgets(buffer, bufsize, stdin) != NULL) {
size_t len = strlen(buffer);
if (len > 0 && buffer[len - 1] == '\n') {
buffer[len - 1] = '\0'; // strip newline
}
}
}
// ----------------------------------------------------------------------------
// chat loop
// I manually inspected the tokens for a few chat conversations compared to
// python reference and that seemed ok, but this was not thoroughly tested and
// is not safely implemented, it's more a proof of concept atm.
void chat(Transformer *transformer, Tokenizer *tokenizer, Sampler *sampler,
char *cli_user_prompt, char *cli_system_prompt, int steps) {
// buffers for reading the system prompt and user prompt from stdin
// you'll notice they are soomewhat haphazardly and unsafely set atm
char system_prompt[512];
char user_prompt[512];
char rendered_prompt[1152];
int num_prompt_tokens = 0;
int* prompt_tokens = (int*)malloc(1152 * sizeof(int));
int user_idx;
// start the main loop
int8_t user_turn = 1; // user starts
int next; // will store the next token in the sequence
int token; // stores the current token to feed into the transformer
int prev_token;
int pos = 0; // position in the sequence
while (pos < steps) {
// when it is the user's turn to contribute tokens to the dialog...
if (user_turn) {
// get the (optional) system prompt at position 0
if (pos == 0) {
// at position 0, the user can also contribute a system prompt
if (cli_system_prompt == NULL) {
// system prompt was not passed in, attempt to get it from stdin
read_stdin("Enter system prompt (optional): ", system_prompt, sizeof(system_prompt));
} else {
// system prompt was passed in, use it
strcpy(system_prompt, cli_system_prompt);
}
}
// get the user prompt
if (pos == 0 && cli_user_prompt != NULL) {
// user prompt for position 0 was passed in, use it
strcpy(user_prompt, cli_user_prompt);
} else {
// otherwise get user prompt from stdin
read_stdin("User: ", user_prompt, sizeof(user_prompt));
}
// render user/system prompts into the Llama 2 Chat schema
if (pos == 0 && system_prompt[0] != '\0') {
char system_template[] = "[INST] <<SYS>>\n%s\n<</SYS>>\n\n%s [/INST]";
sprintf(rendered_prompt, system_template, system_prompt, user_prompt);
} else {
char user_template[] = "[INST] %s [/INST]";
sprintf(rendered_prompt, user_template, user_prompt);
}
// encode the rendered prompt into tokens
encode(tokenizer, rendered_prompt, 1, 0, prompt_tokens, &num_prompt_tokens);
user_idx = 0; // reset the user index
user_turn = 0;
printf("Assistant: ");
}
// determine the token to pass into the transformer next
if (user_idx < num_prompt_tokens) {
// if we are still processing the input prompt, force the next prompt token
token = prompt_tokens[user_idx++];
} else {
// otherwise use the next token sampled from previous turn
token = next;
}
// EOS (=2) token ends the Assistant turn
if (token == 2) { user_turn = 1; }
// forward the transformer to get logits for the next token
float* logits = forward(transformer, token, pos);
next = sample(sampler, logits);
pos++;
if (user_idx >= num_prompt_tokens && next != 2) {
// the Assistant is responding, so print its output
char* piece = decode(tokenizer, token, next);
safe_printf(piece); // same as printf("%s", piece), but skips "unsafe" bytes
fflush(stdout);
}
if (next == 2) { printf("\n"); }
}
printf("\n");
free(prompt_tokens);
}
// ----------------------------------------------------------------------------
// CLI, include only if not testing
#ifndef TESTING
void error_usage() {
fprintf(stderr, "Usage: run <checkpoint> [options]\n");
fprintf(stderr, "Example: run model.bin -n 256 -i \"Once upon a time\"\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, " -t <float> temperature in [0,inf], default 1.0\n");
fprintf(stderr, " -p <float> p value in top-p (nucleus) sampling in [0,1] default 0.9\n");
fprintf(stderr, " -s <int> random seed, default time(NULL)\n");
fprintf(stderr, " -n <int> number of steps to run for, default 256. 0 = max_seq_len\n");
fprintf(stderr, " -i <string> input prompt\n");
fprintf(stderr, " -z <string> optional path to custom tokenizer\n");
fprintf(stderr, " -m <string> mode: generate|chat, default: generate\n");
fprintf(stderr, " -y <string> (optional) system prompt in chat mode\n");
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
// default parameters
char *checkpoint_path = NULL; // e.g. out/model.bin
char *tokenizer_path = "tokenizer.bin";
float temperature = 1.0f; // 0.0 = greedy deterministic. 1.0 = original. don't set higher
float topp = 0.9f; // top-p in nucleus sampling. 1.0 = off. 0.9 works well, but slower
int steps = 256; // number of steps to run for
char *prompt = NULL; // prompt string
unsigned long long rng_seed = 0; // seed rng with time by default
char *mode = "generate"; // generate|chat
char *system_prompt = NULL; // the (optional) system prompt to use in chat mode
// poor man's C argparse so we can override the defaults above from the command line
if (argc >= 2) { checkpoint_path = argv[1]; } else { error_usage(); }
for (int i = 2; i < argc; i+=2) {
// do some basic validation
if (i + 1 >= argc) { error_usage(); } // must have arg after flag
if (argv[i][0] != '-') { error_usage(); } // must start with dash
if (strlen(argv[i]) != 2) { error_usage(); } // must be -x (one dash, one letter)
// read in the args
if (argv[i][1] == 't') { temperature = atof(argv[i + 1]); }
else if (argv[i][1] == 'p') { topp = atof(argv[i + 1]); }
else if (argv[i][1] == 's') { rng_seed = atoi(argv[i + 1]); }
else if (argv[i][1] == 'n') { steps = atoi(argv[i + 1]); }
else if (argv[i][1] == 'i') { prompt = argv[i + 1]; }
else if (argv[i][1] == 'z') { tokenizer_path = argv[i + 1]; }
else if (argv[i][1] == 'm') { mode = argv[i + 1]; }
else if (argv[i][1] == 'y') { system_prompt = argv[i + 1]; }
else { error_usage(); }
}
// parameter validation/overrides
if (rng_seed <= 0) rng_seed = (unsigned int)time(NULL);
if (temperature < 0.0) temperature = 0.0;
if (topp < 0.0 || 1.0 < topp) topp = 0.9;
if (steps < 0) steps = 0;
// build the Transformer via the model .bin file
Transformer transformer;
build_transformer(&transformer, checkpoint_path);
if (steps == 0 || steps > transformer.config.seq_len) steps = transformer.config.seq_len; // override to ~max length
// build the Tokenizer via the tokenizer .bin file
Tokenizer tokenizer;
build_tokenizer(&tokenizer, tokenizer_path, transformer.config.vocab_size);
// build the Sampler
Sampler sampler;
build_sampler(&sampler, transformer.config.vocab_size, temperature, topp, rng_seed);
// run!
if (strcmp(mode, "generate") == 0) {
generate(&transformer, &tokenizer, &sampler, prompt, steps);
} else if (strcmp(mode, "chat") == 0) {
chat(&transformer, &tokenizer, &sampler, prompt, system_prompt, steps);
} else {
fprintf(stderr, "unknown mode: %s\n", mode);
error_usage();
}
// memory and file handles cleanup
free_sampler(&sampler);
free_tokenizer(&tokenizer);
free_transformer(&transformer);
return 0;
}
#endif

View File

@@ -1,6 +0,0 @@
{
"cl": [
"clang -emit-llvm -S -o llgo_autogen.ll -c llama2/run.c",
"rm llgo_autogen.lla; zip llgo_autogen.lla llgo_autogen.ll"
]
}

Binary file not shown.

View File

@@ -0,0 +1,60 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func coroutineFunc(L *lua.State) {
L.Loadstring(c.Str(`
function coro_func()
for i = 1, 5 do
coroutine.yield(i)
end
end
`))
L.Pcall(0, 0, 0)
L.Getglobal(c.Str("coro_func"))
}
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
coroutineFunc(L) // Load and get the coroutine function
co := L.Newthread() // Create a new coroutine/thread
L.Pushvalue(-2) // Move the function to the top of the stack
L.Xmove(co, 1) // Move the function to the new coroutine
var nres c.Int
var status c.Int
c.Printf(c.Str("Resuming coroutine...\n"))
// Resume coroutine and handle yields
for {
status = co.Resume(nil, 0, &nres)
c.Printf(c.Str("Resuming coroutine %d...\n"), status)
if status == lua.YIELD {
yieldValue := co.Tointeger(-1)
c.Printf(c.Str("Yield value: %d\n"), yieldValue)
co.Pop(1) // Clean up the stack
// Check if the coroutine is yieldable
if co.Isyieldable() != 0 {
c.Printf(c.Str("Coroutine is yieldable.\n"))
} else {
c.Printf(c.Str("Coroutine is not yieldable.\n"))
}
} else {
break
}
}
// Check the final status of the coroutine
finalStatus := co.Status()
c.Printf(c.Str("Final status of coroutine: %d\n"), finalStatus)
}

View File

@@ -0,0 +1,21 @@
package main
import (
_ "unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
if res := L.Loadstring(c.Str("function doubleNumber(x) ! return x * 2 end")); res != lua.OK {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
}
/* Expected output:
error: [string "function doubleNumber(x) ! return x * 2 end"]:1: unexpected symbol near '!'
*/

View File

@@ -0,0 +1,32 @@
package main
import (
_ "unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
if res := L.Dostring(c.Str("function combineParams(num, str) return 'Result: ' .. str .. ' ' .. num end")); res != lua.OK {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
L.Getglobal(c.Str("combineParams"))
L.Pushnumber(3.14159)
L.Pushstring(c.Str("Hello, World!"))
if res := L.Pcall(2, 1, 0); res != lua.OK {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
if res := L.Isstring(-1); res != 0 {
result := L.Tostring(-1)
c.Printf(result)
}
}
/* Expected output:
Result: Hello, World! 3.14159
*/

View File

@@ -0,0 +1,39 @@
package main
import (
_ "unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
if res := L.Loadstring(c.Str("function doubleNumber(x) return x * 2 end")); res != lua.OK {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
if res := L.Pcall(0, 0, 0); res != lua.OK {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
L.Getglobal(c.Str("doubleNumber"))
L.Pushnumber(10)
if res := L.Pcall(1, 1, 0); res != lua.OK {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
if res := L.Isnumber(-1); res != 0 {
result := L.Tointeger(-1)
c.Printf(c.Str("result: %lld\n"), result)
} else {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
}
/* Expected output:
result: 20
*/

View File

@@ -0,0 +1,48 @@
package main
import (
_ "unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
code := c.Str(
`function processStrings(a, b, c)
print('Received string a: ' .. a)
print('Received string b: ', b)
print('Received string c (formatted): ' .. c)
return a .. b .. c
end`)
if res := L.Dostring(code); res != lua.OK {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
L.Getglobal(c.Str("processStrings"))
L.Pushstring(c.Str("Hello, World!"))
L.Pushlstring(c.Str(`Hello Lua In LLGO`), 17)
L.Pushfstring(c.Str(`Hello %s In %d`), c.Str("LLGO"), 2024)
if res := L.Pcall(3, 1, 0); res != lua.OK {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
if res := L.Isstring(-1); res != 0 {
result := L.Tostring(-1)
c.Printf(c.Str("result: %s\n"), result)
}
}
/* Expected output:
Received string a: Hello, World!
Received string b: Hello Lua In LLGO
Received string c (formatted): Hello LLGO In 2024
result: Hello, World!Hello Lua In LLGOHello LLGO In 2024
*/

View File

@@ -0,0 +1,21 @@
package main
import (
_ "unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
if res := L.Dostring(c.Str("print('hello world')")); res != lua.OK {
println("error")
}
}
/* Expected output:
hello world
*/

View File

@@ -0,0 +1,26 @@
package main
import (
_ "unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
if res := L.Loadstring(c.Str("print('hello world')")); res != lua.OK {
println("error")
}
if res := L.Pcall(0, 0, 0); res != lua.OK {
println("error")
}
}
/* Expected output:
hello world
*/

104
c/lua/_demo/stack/stack.go Normal file
View File

@@ -0,0 +1,104 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
// printStack prints the current stack of the given Lua state.
func printStack(L *lua.State, stateName *c.Char) {
top := L.Gettop()
c.Printf(c.Str("%s stack (top=%d):"), stateName, top)
for i := 1; i <= int(top); i++ {
c.Printf(c.Str("%s "), L.Tostring(c.Int(i)))
}
c.Printf(c.Str("\n"))
}
func main() {
// Create a new Lua state and open libraries
L := lua.Newstate()
defer L.Close()
L.Openlibs()
// Push initial values onto the stack
L.Pushstring(c.Str("Hello"))
L.Pushstring(c.Str("LLGO"))
L.Pushnumber(2024)
// Print initial stack
c.Printf(c.Str("Initial stack:\n"))
printStack(L, c.Str("L1"))
// Use absindex to ensure the index is positive
idx := -2
absIdx := L.Absindex(c.Int(idx))
c.Printf(c.Str("Absolute index of 'LLGO': %d\n"), absIdx)
// Copy 'LLGO' to the top of the stack
L.Pushvalue(absIdx)
c.Printf(c.Str("\nAfter pushing 'LLGO' to the top:\n"))
printStack(L, c.Str("L1"))
// Rotate stack elements
L.Rotate(c.Int(1), c.Int(-1))
c.Printf(c.Str("\nAfter rotating the stack:\n"))
printStack(L, c.Str("L1"))
// Copy the top element to index 2
L.Copy(c.Int(-1), c.Int(2))
c.Printf(c.Str("\nAfter copying the top element to index 2:\n"))
printStack(L, c.Str("L1"))
// Check if we can grow the stack
if L.Checkstack(c.Int(2)) == 0 {
c.Printf(c.Str("Cannot grow stack\n"))
return
}
// Push additional elements
L.Pushnumber(3.14)
L.Pushstring(c.Str("Lua"))
c.Printf(c.Str("\nAfter pushing more elements:\n"))
printStack(L, c.Str("L1"))
// Set the top of the stack, clearing extra elements
L.Settop(c.Int(5))
c.Printf(c.Str("\nAfter setting top to 5:\n"))
printStack(L, c.Str("L1"))
// Create a second Lua state
L1 := lua.Newstate()
defer L1.Close()
// Move two elements to the new state
L.Xmove(L1, c.Int(2))
c.Printf(c.Str("\nAfter moving two elements to L1:\n"))
printStack(L, c.Str("L1"))
printStack(L1, c.Str("L2"))
}
/* Expected output:
Initial stack:
L1 stack (top=3):Hello LLGO 2024.0
Absolute index of 'LLGO': 2
After pushing 'LLGO' to the top:
L1 stack (top=4):Hello LLGO 2024.0 LLGO
After rotating the stack:
L1 stack (top=4):LLGO 2024.0 LLGO Hello
After copying the top element to index 2:
L1 stack (top=4):LLGO Hello LLGO Hello
After pushing more elements:
L1 stack (top=6):LLGO Hello LLGO Hello 3.14 Lua
After setting top to 5:
L1 stack (top=5):LLGO Hello LLGO Hello 3.14
After moving two elements to L1:
L1 stack (top=3):LLGO Hello LLGO
L2 stack (top=2):Hello 3.14
*/

View File

@@ -0,0 +1,60 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func printTable(L *lua.State) {
L.Pushnil()
for L.Next(-2) != 0 {
key := L.Tostring(-2)
value := L.Tostring(-1)
c.Printf(c.Str("%s - %s\n"), key, value)
L.Pop(1)
}
L.Pop(1)
}
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
L.Newtable()
L.Pushstring(c.Str("name"))
L.Pushstring(c.Str("John"))
L.Settable(-3)
L.Pushstring(c.Str("age"))
L.Pushnumber(30)
L.Settable(-3)
L.Pushstring(c.Str("John Doe"))
L.Setfield(-2, c.Str("fullname"))
L.Getfield(-1, c.Str("name"))
c.Printf(c.Str("%s\n"), L.Tostring(-1))
L.Pop(1)
L.Pushstring(c.Str("age"))
L.Gettable(-2)
age := int(L.Tonumber(-1))
c.Printf(c.Str("Age: %d\n"), age)
L.Pop(1)
c.Printf(c.Str("All entries in the table:\n"))
printTable(L)
}
/* Expected output:
John
Age: 30
All entries in the table:
age - 30.0
fullname - John Doe
name - John
*/

101
c/lua/lauxlib.go Normal file
View File

@@ -0,0 +1,101 @@
package lua
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
// /* global table */
// /* extra error code for 'luaL_loadfilex' */
// /* key, in the registry, for table of loaded modules */
// /* key, in the registry, for table of preloaded loaders */
// /* predefined references */
// llgo:link (*State).Loadfilex C.luaL_loadfilex
func (L *State) Loadfilex(filename *c.Char, mode *c.Char) c.Int { return 0 }
func (L *State) Loadfile(filename *c.Char) c.Int { return L.Loadfilex(filename, nil) }
// llgo:link (*State).Loadstring C.luaL_loadstring
func (L *State) Loadstring(s *c.Char) c.Int { return 0 }
//go:linkname Newstate C.luaL_newstate
func Newstate() *State
// /*
// ** ===============================================================
// ** some useful macros
// ** ===============================================================
// */
func (L *State) Dofile(filename *c.Char) c.Int {
if loadResult := L.Loadfile(filename); loadResult != 0 {
return loadResult
}
return L.Pcall(c.Int(0), c.Int(MULTRET), c.Int(0))
}
func (L *State) Dostring(str *c.Char) c.Int {
if loadResult := L.Loadstring(str); loadResult != 0 {
return loadResult
}
return L.Pcall(c.Int(0), c.Int(MULTRET), c.Int(0))
}
// /*
// ** Perform arithmetic operations on lua_Integer values with wrap-around
// ** semantics, as the Lua core does.
// */
// /* push the value used to represent failure/error */
// /*
// ** {======================================================
// ** Generic Buffer manipulation
// ** =======================================================
// */
// /* }====================================================== */
// /*
// ** {======================================================
// ** File handles for IO library
// ** =======================================================
// */
// /*
// ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
// ** initial structure 'luaL_Stream' (it may contain other fields
// ** after that initial structure).
// */
// #define LUA_FILEHANDLE "FILE*"
// /* }====================================================== */
// /*
// ** {==================================================================
// ** "Abstraction Layer" for basic report of messages and errors
// ** ===================================================================
// */
// /* print a string */
// /* print a newline and flush the output */
// /* print an error message */
// /* }================================================================== */
// /*
// ** {============================================================
// ** Compatibility with deprecated conversions
// ** =============================================================
// */
// /* }============================================================ */

495
c/lua/lua.go Normal file
View File

@@ -0,0 +1,495 @@
package lua
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "link: $(pkg-config --libs lua); -llua -lm"
)
// /* mark for precompiled code ('<esc>Lua') */
// /* 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)
// */
// /* thread status */
const (
OK = 0
YIELD = 1
ERRRUN = 2
ERRSYNTAX = 3
ERRMEM = 4
ERRERR = 5
)
type State struct {
Unused [8]byte
}
// /*
// ** basic types
// */
const (
NONE = int(-1)
NIL = int(0)
BOOLEAN = int(1)
LIGHTUSERDATA = int(2)
NUMBER = int(3)
STRING = int(4)
TABLE = int(5)
FUNCTION = int(6)
USERDATA = int(7)
THREAD = int(8)
UMTYPES = int(9)
)
// /* minimum Lua stack available to a C function */
const (
MINSTACK = 20
)
// /* predefined values in the registry */
const (
RIDX_MAINTHREAD = 1
RIDX_GLOBALS = 2
RIDX_LAST = RIDX_GLOBALS
)
// /* type of numbers in Lua */
type Number = c.Double
// /* type for integer functions */
// TODO(zzy):consider dynamic size
type Integer = c.Int
// /* unsigned integer type */
type Unsigned = c.Uint
// /* type for continuation-function contexts */
// TODO(zzy): Context may not be c.Int
type KContext c.Int
// /*
// ** Type for C functions registered with Lua
// */
// /*
// ** Type for continuation functions
// */
// TODO(zzy): KFunction does not currently support
type KFunction func(L *State, status c.Int, ctx KContext) c.Int
// /*
// ** Type for functions that read/write blocks when loading/dumping Lua chunks
// */
// typedef const char * (*lua_Reader) (State *L, void *ud, size_t *sz);
// typedef int (*lua_Writer) (State *L, const void *p, size_t sz, void *ud);
// /*
// ** Type for memory-allocation functions
// */
// typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
// /*
// ** Type for warning functions
// */
// typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);
// /*
// ** Type used by the debug API to collect debug information
// */
// typedef struct lua_Debug lua_Debug;
// /*
// ** 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
// */
// llgo:link (*State).Close C.lua_close
func (L *State) Close() {}
// State *(lua_newstate) (lua_Alloc f, void *ud);
// State *(lua_newthread) (State *L);
// llgo:link (*State).Newthread C.lua_newthread
func (L *State) Newthread() *State { return nil }
// int (lua_closethread) (State *L, State *from);
// int (lua_resetthread) (State *L); /* Deprecated! */
// lua_CFunction (lua_atpanic) (State *L, lua_CFunction panicf);
// lua_Number (lua_version) (State *L);
// /*
// ** basic stack manipulation
// */
// llgo:link (*State).Absindex C.lua_absindex
func (L *State) Absindex(idx c.Int) c.Int { return 0 }
// llgo:link (*State).Gettop C.lua_gettop
func (L *State) Gettop() c.Int { return 0 }
// llgo:link (*State).Settop C.lua_settop
func (L *State) Settop(idx c.Int) {}
// llgo:link (*State).Pushvalue C.lua_pushvalue
func (L *State) Pushvalue(idx c.Int) {}
// llgo:link (*State).Rotate C.lua_rotate
func (L *State) Rotate(idx c.Int, n c.Int) {}
// llgo:link (*State).Copy C.lua_copy
func (L *State) Copy(fromidx c.Int, toidx c.Int) {}
// llgo:link (*State).Checkstack C.lua_checkstack
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)
// */
// LUA_API int (lua_isinteger) (State *L, int idx);
// llgo:link (*State).Isinteger C.lua_isinteger
func (L *State) Isinteger(idx c.Int) c.Int { return 0 }
// llgo:link (*State).Isnumber C.lua_isnumber
func (L *State) Isnumber(idx c.Int) c.Int { return 0 }
// llgo:link (*State).Isstring C.lua_isstring
func (L *State) Isstring(idx c.Int) c.Int { return 0 }
// TODO(zzy):add to demo
// llgo:link (*State).Type C.lua_type
func (L *State) Type(idx c.Int) c.Int { return 0 }
// TODO(zzy)
// llgo:link (*State).Typename C.lua_typename
func (L *State) Typename(tp c.Int) *c.Char { return nil }
// llgo:link (*State).Tonumberx C.lua_tonumberx
func (L *State) Tonumberx(idx c.Int, isnum *c.Int) Number { return 0 }
// llgo:link (*State).Tointegerx C.lua_tointegerx
func (L *State) Tointegerx(idx c.Int, isnum *c.Int) Integer { return 0 }
// llgo:link (*State).Toboolean C.lua_toboolean
func (L *State) Toboolean(idx c.Int) bool { return false }
// llgo:link (*State).Tolstring C.lua_tolstring
func (L *State) Tolstring(idx c.Int, len *c.Ulong) *c.Char { return nil }
// LUA_API int (lua_iscfunction) (State *L, int idx);
// LUA_API int (lua_isuserdata) (State *L, int idx);
// LUA_API lua_Unsigned (lua_rawlen) (State *L, int idx);
// LUA_API lua_CFunction (lua_tocfunction) (State *L, int idx);
// LUA_API void *(lua_touserdata) (State *L, int idx);
// LUA_API State *(lua_tothread) (State *L, int idx);
// LUA_API const void *(lua_topointer) (State *L, int idx);
// /*
// ** Comparison and arithmetic functions
// */
// /*
// ** push functions (C -> stack)
// */
// llgo:link (*State).Pushnil C.lua_pushnil
func (L *State) Pushnil() {}
// llgo:link (*State).Pushnumber C.lua_pushnumber
func (L *State) Pushnumber(n Number) {}
// llgo:link (*State).Pushinteger C.lua_pushinteger
func (L *State) Pushinteger(n Integer) {}
// llgo:link (*State).Pushstring C.lua_pushstring
func (L *State) Pushstring(s *c.Char) *c.Char {
return nil
}
// llgo:link (*State).Pushlstring C.lua_pushlstring
func (L *State) Pushlstring(s *c.Char, len c.Ulong) *c.Char {
return nil
}
// llgo:link (*State).Pushfstring C.lua_pushfstring
func (L *State) Pushfstring(format *c.Char, __llgo_va_list ...any) *c.Char { return nil }
// llgo:link (*State).Pushboolean C.lua_pushboolean
func (L *State) Pushboolean(b c.Int) {}
//const char *(lua_pushvfstring) (State *L, const char *fmt,va_list argp);
//void (lua_pushcclosure) (State *L, lua_CFunction fn, int n);
//void (lua_pushlightuserdata) (State *L, void *p);
//int (lua_pushthread) (State *L);
// /*
// ** get functions (Lua -> stack)
// */
// llgo:link (*State).Getglobal C.lua_getglobal
func (L *State) Getglobal(name *c.Char) c.Int { return 0 }
// llgo:link (*State).Gettable C.lua_gettable
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).Createtable C.lua_createtable
func (L *State) Createtable(narr c.Int, nrec c.Int) {}
// 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);
// LUA_API void *(lua_newuserdatauv) (State *L, size_t sz, int nuvalue);
// LUA_API int (lua_getmetatable) (State *L, int objindex);
// LUA_API int (lua_getiuservalue) (State *L, int idx, int n);
// /*
// ** set functions (stack -> Lua)
// */
// TODO(zzy):add to demo
// llgo:link (*State).Setglobal C.lua_setglobal
func (L *State) Setglobal(name *c.Char) {}
// llgo:link (*State).Settable C.lua_settable
func (L *State) Settable(idx c.Int) {}
// llgo:link (*State).Setfield C.lua_setfield
func (L *State) Setfield(idx c.Int, k *c.Char) {}
//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);
//int (lua_setmetatable) (State *L, int objindex);
//int (lua_setiuservalue) (State *L, int idx, int n);
// /*
// ** 'load' and 'call' functions (load and run Lua code)
// */
// llgo:link (*State).Pcallk C.lua_pcallk
func (L *State) Pcallk(nargs c.Int, nresults c.Int, errfunc c.Int, ctx KContext, k *KFunction) c.Int {
return 0
}
func (L *State) Pcall(nargs c.Int, nresults c.Int, errfunc c.Int) c.Int {
return L.Pcallk(nargs, nresults, errfunc, KContext(c.Int(0)), nil)
}
// void (lua_callk) (State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k);
// #define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
// int (lua_load) (State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode);
// int (lua_dump) (State *L, lua_Writer writer, void *data, int strip);
// /*
// ** 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 }
// llgo:link (*State).Status C.lua_status
func (L *State) Status() c.Int { return 0 }
// llgo:link (*State).Isyieldable C.lua_isyieldable
func (L *State) Isyieldable() c.Int { return 0 }
// TODO(zzy)
// int (lua_yieldk) (State *L, int nresults, lua_KContext ctx, lua_KFunction k);
// #define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
// /*
// ** Warning-related functions
// */
//void (lua_setwarnf) (State *L, lua_WarnFunction f, void *ud);
//void (lua_warning) (State *L, const char *msg, int tocont);
// /*
// ** garbage-collection function and options
// */
const (
GCSTOP = 0
GCRESTART = 1
GCCOLLECT = 2
GCCOUNT = 3
GCCOUNTB = 4
GCSTEP = 5
GCSETPAUSE = 6
GCSETSTEPMUL = 7
GCISRUNNING = 9
GCGEN = 10
GCINC = 11
)
// 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 }
// LUA_API int (lua_error) (State *L);
// LUA_API void (lua_concat) (State *L, int n);
// LUA_API void (lua_len) (State *L, int idx);
// LUA_API size_t (lua_stringtonumber) (State *L, const char *s);
// LUA_API lua_Alloc (lua_getallocf) (State *L, void **ud);
// LUA_API void (lua_setallocf) (State *L, lua_Alloc f, void *ud);
// LUA_API void (lua_toclose) (State *L, int idx);
// LUA_API void (lua_closeslot) (State *L, int idx);
// /*
// ** {==============================================================
// ** some useful macros
// ** ===============================================================
// */
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) }
func (L *State) Pop(n c.Int) { L.Settop(-(n) - 1) }
func (L *State) Newtable() { L.Createtable(0, 0) }
func (L *State) Isfunction(n c.Int) bool { return L.Type(n) == c.Int(FUNCTION) }
func (L *State) Istable(n c.Int) bool { return L.Type(n) == c.Int(TABLE) }
func (L *State) Islightuserdata(n c.Int) bool { return L.Type(n) == c.Int(LIGHTUSERDATA) }
func (L *State) Isnil(n c.Int) bool { return L.Type(n) == c.Int(NIL) }
func (L *State) Isboolean(n c.Int) bool { return L.Type(n) == c.Int(BOOLEAN) }
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 }
// #define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
// #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
// #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
// #define lua_pushliteral(L, s) lua_pushstring(L, "" s)
// #define lua_pushglobaltable(L) ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
// #define lua_insert(L,idx) lua_rotate(L, (idx), 1)
// #define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
// #define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1))
// /* }============================================================== */
// /*
// ** {==============================================================
// ** compatibility macros
// ** ===============================================================
// */
// #define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1)
// #define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1)
// #define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1)
// #define LUA_NUMTAGS LUA_NUMTYPES
// /* }============================================================== */
// /*
// ** {======================================================================
// ** Debug API
// ** =======================================================================
// */
// /*
// ** Event codes
// */
const (
HOOKCALL = 0
HOOKRET = 1
HOOKLINE = 2
HOOKCOUNT = 3
HOOKTAILCALL = 4
)
// /*
// ** Event masks
// */
// #define LUA_MASKCALL (1 << LUA_HOOKCALL)
// #define LUA_MASKRET (1 << LUA_HOOKRET)
// #define LUA_MASKLINE (1 << LUA_HOOKLINE)
// #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
const (
MASKCALL = 1 << HOOKCOUNT
MASKRET = 1 << HOOKRET
MASKLINE = 1 << HOOKLINE
MASKCOUNT = 1 << HOOKCOUNT
)
// 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);
// 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);
// 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);
// LUA_API int (lua_setcstacklimit) (State *L, unsigned int limit);
// struct lua_Debug
// /* }====================================================================== */

8
c/lua/lualib.go Normal file
View File

@@ -0,0 +1,8 @@
package lua
import (
_ "unsafe"
)
// llgo:link (*State).Openlibs C.luaL_openlibs
func (L *State) Openlibs() {}

Some files were not shown because too many files have changed in this diff Show More