Compare commits

..

299 Commits

Author SHA1 Message Date
xushiwei
683129b6a5 Merge pull request #781 from cpunion/future-io
Future IO update
2024-09-12 12:48:25 +08:00
Li Jie
7f4022120e fix deadlock 2024-09-10 14:38:46 +08:00
Li Jie
3f9e86c37a x 2024-09-10 11:49:42 +08:00
Li Jie
12f460e376 async.Run as global context, async operations run immediately 2024-09-10 11:43:44 +08:00
Li Jie
44c4488fcc async doc update 2024-09-09 10:41:22 +08:00
Li Jie
44617b6554 future supports multi-await but run once 2024-09-09 09:34:29 +08:00
Li Jie
ccc7d056ba socketio example: two tcp clients 2024-09-08 20:29:24 +08:00
Li Jie
566d5ef96f add Future.Then 2024-09-08 20:27:05 +08:00
xushiwei
cf53f3a347 Merge pull request #778 from cpunion/future-io
Future I/O
2024-09-08 17:37:33 +08:00
xushiwei
74b48ff56b Merge pull request #771 from luoliwoshang/chore/llcppsymg/config
llcppsymg:language config
2024-09-08 17:25:49 +08:00
xushiwei
9410370cc5 Merge pull request #777 from luoliwoshang/c/lua/thread
c/lua:thread
2024-09-08 17:22:01 +08:00
luoliwoshang
743ddf83c1 c/lua:thread 2024-09-07 18:55:24 +08:00
Li Jie
d2538d08a7 code clean 2024-09-07 10:20:02 +08:00
visualfc
75fe9d61a3 cl: function fix freevars cache 2024-09-07 10:04:38 +08:00
Li Jie
fce0672282 make future IO working both on go and llgo 2024-09-07 10:04:34 +08:00
Li Jie
69a2a01bc7 cbind.Bind: expose *Base argument 2024-09-07 09:45:23 +08:00
Li Jie
a2d4e79c20 new future IO and demo 2024-09-07 09:45:05 +08:00
Li Jie
6e0a9b2b48 cbind.BindF 2024-09-07 09:43:48 +08:00
Li Jie
276f2070ee hide tuple fields, only expose tuple.TN(...) and tuple.Get() 2024-09-07 09:43:48 +08:00
Li Jie
1a158b5de3 async: work both go and llgo 2024-09-07 09:43:48 +08:00
Li Jie
d4a72bf661 async.Run/Await/Race/All 2024-09-07 09:43:48 +08:00
luoliwoshang
caa707325a llcppsymg:language config 2024-09-06 09:05:35 +08:00
xushiwei
3c588e67b8 Merge pull request #767 from tsingbx/cjson
Improve the llgo cjson library
2024-09-06 06:56:49 +08:00
xushiwei
6c26dad048 Merge pull request #770 from visualfc/tpfunc
ssa: fix llgo:type c for typeparam named
2024-09-06 06:51:30 +08:00
xushiwei
393e2c125e Merge pull request #772 from luoliwoshang/castdump/typedef
castdump:use UnderlyingType instead CanonicalType in typedef
2024-09-06 06:48:12 +08:00
luoliwoshang
e56dc2ed6a castdump:use UnderlyingType instead CanonicalType 2024-09-05 15:45:36 +08:00
tsingbx
4a449ed85e change comment cBool to cJSON_Bool 2024-09-05 11:01:34 +08:00
tsingbx
88dbe90075 Revert "change comment cBool to Bool"
This reverts commit a6f6451434.
2024-09-05 11:00:20 +08:00
tsingbx
a6f6451434 change comment cBool to Bool 2024-09-05 10:58:40 +08:00
tsingbx
8a4370c1f6 change ParseBytes and ParseString, change JSON_bool to Bool, remove Bool() 2024-09-05 10:55:49 +08:00
xushiwei
7a068450b3 Merge pull request #764 from cpunion/ssa-error-exit
cl: exit 1 when SSA build error
2024-09-05 08:42:21 +08:00
xushiwei
ae3222e4c2 Merge pull request #761 from visualfc/abiname
internal/abi: fix splitName
2024-09-05 08:34:27 +08:00
xushiwei
27b4bfa3fa Merge pull request #758 from luoliwoshang/llcppg/language
llcppg/config:language
2024-09-05 08:32:49 +08:00
xushiwei
8af229947f Merge pull request #765 from cpunion/builtin-llgo-tag
cl: builtin llgo tag
2024-09-05 08:32:06 +08:00
xushiwei
f235a2f539 Merge pull request #763 from luoliwoshang/c/clang/usr
c/clang:usr & range
2024-09-05 08:31:37 +08:00
visualfc
b0ebb479f6 ssa: fix llgo:type c for typeparam named 2024-09-04 21:53:50 +08:00
tsingbx
df92e21520 fix error 2024-09-04 20:31:45 +08:00
tsingbx
a1a25cc57f complete cjson 2024-09-04 20:23:47 +08:00
Li Jie
e9aaf8e0af cl: builtin llgo tag 2024-09-04 10:07:22 +08:00
Li Jie
7a80e407af cl: exit 1 when SSA build error 2024-09-04 09:55:56 +08:00
luoliwoshang
57f8d535fb c/clang:usr & range 2024-09-03 18:33:40 +08:00
visualfc
fcc444a100 internal/abi: fix splitName 2024-09-03 15:24:08 +08:00
luoliwoshang
8ccb3c21e1 llcppg/config:language 2024-09-03 15:17:03 +08:00
xushiwei
3ce9567f62 Merge pull request #760 from visualfc/cvtnamed
ssa: cvtNamed check typeargs
2024-09-03 15:05:39 +08:00
visualfc
765e812b77 ssa: cvtNamed check typeargs 2024-09-03 11:37:31 +08:00
xushiwei
1a63c9296b Merge pull request #750 from luoliwoshang/llcppg/ast/access
llcppg/ast:field access & static
2024-09-01 05:56:23 +08:00
xushiwei
9510b5aea5 Merge pull request #755 from luoliwoshang/c/lua/dump
c/lua:dump & load
2024-09-01 05:55:47 +08:00
xushiwei
490e859fbf Merge pull request #756 from luoliwoshang/c/fread
c:fread
2024-09-01 05:55:10 +08:00
luoliwoshang
85c4a2fdc2 c/lua:dump & load demo use go file operate 2024-09-01 00:33:00 +08:00
luoliwoshang
3b9c9f6a97 c:fread 2024-08-31 20:49:23 +08:00
luoliwoshang
d1f64d3059 c/lua:dump & load 2024-08-31 20:45:19 +08:00
luoliwoshang
f62bcdc803 llcppg/ast:field access & static 2024-08-30 10:11:23 +08:00
xushiwei
2434fd778f Merge pull request #751 from hackerchai/fix/c-libuv-error-eof
fix(c/libuv): Fix EOF error value
2024-08-30 09:01:53 +08:00
xushiwei
1a38726fb7 Merge pull request #752 from spongehah/c/libuv
feature(c/libuv): Add Idle and Check
2024-08-30 09:01:34 +08:00
赵英杰
24cffb2a69 feature(c/libuv): Add idle and check 2024-08-29 17:52:18 +08:00
hackerchai
527918545e fix(c/libuv): Fix EOF error value
Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-28 17:12:38 +08:00
xushiwei
4d268f67ae Merge pull request #749 from luoliwoshang/c/clang/variadic
c/clang:variadic
2024-08-28 06:23:31 +08:00
luoliwoshang
a65c2f4312 c/clang:variadic 2024-08-27 18:54:41 +08:00
xushiwei
c490f2b849 Merge pull request #692 from spongehah/refactor/c-libuv-remove-go-wrapper
fix(c/libuv): Change the request calling method of echo_server
2024-08-27 05:23:28 +08:00
xushiwei
282f7fc2e3 Merge pull request #747 from luoliwoshang/llcppg/ast/variadic
llcppg/ast:variadic func
2024-08-27 05:21:36 +08:00
xushiwei
52348af8ec Merge pull request #748 from luoliwoshang/c/clang/cursor
c/clang:cursor
2024-08-27 05:20:20 +08:00
luoliwoshang
39d15ead6f c/clang:cursor 2024-08-26 18:47:56 +08:00
luoliwoshang
d232109fce llcppg/ast:variadic func 2024-08-26 15:11:31 +08:00
xushiwei
8e9c43610d Merge pull request #746 from luoliwoshang/c/lua/corroutine
c:lua:coroutine continuation
2024-08-25 17:52:36 +08:00
xushiwei
53a8c20cb9 Merge pull request #743 from luoliwoshang/c/clang/class
c/clang:class & method
2024-08-25 17:51:15 +08:00
xushiwei
333f60a2a6 Merge pull request #744 from aisk/py-set
feat(py): add set type
2024-08-25 17:49:55 +08:00
xushiwei
0bacc20a58 Merge pull request #745 from luoliwoshang/c/lua/userdata
c/lua:userdata
2024-08-25 17:49:14 +08:00
luoliwoshang
3e932c9bdf c/lua:coroutine continuation 2024-08-25 15:31:10 +08:00
luoliwoshang
cf8a170133 c/lua:register 2024-08-25 12:32:31 +08:00
AN Long
67a89d4b6b feat(py): add set discard 2024-08-25 00:05:00 +08:00
luoliwoshang
85c2cda7b6 c/lua:userdata 2024-08-24 15:24:47 +08:00
AN Long
61757a6518 feat(py): add set type 2024-08-24 01:10:31 +08:00
luoliwoshang
e245d08e54 c/clang:func,class,method attr 2024-08-23 23:01:39 +08:00
luoliwoshang
29f797dc24 c/clang:correct order 2024-08-23 22:50:26 +08:00
xushiwei
54ce1d8d2f Merge pull request #738 from luoliwoshang/llcppg/ast/exprnode
llcppg/ast:expr node
2024-08-22 22:33:59 +08:00
xushiwei
8e47f70066 Merge pull request #740 from luoliwoshang/c/clang/nonref
c/clang:noref type
2024-08-22 22:33:30 +08:00
xushiwei
01548089ee Merge pull request #739 from luoliwoshang/llcppg/ast/enumtype
llcppg/ast:enum type
2024-08-22 22:33:07 +08:00
xushiwei
de8d598f46 Merge pull request #741 from luoliwoshang/llcppg/ast/scoping
llcppg/ast:scoping for Tagexpr
2024-08-22 22:32:07 +08:00
luoliwoshang
63aad4b9bf llcppg/ast:scoping for Tagexpr 2024-08-22 17:17:51 +08:00
luoliwoshang
33cdb7a541 c/clang:noref type 2024-08-22 12:18:38 +08:00
luoliwoshang
7c2f769a9a llcppg/ast:enum type 2024-08-22 10:25:02 +08:00
luoliwoshang
e084550390 llcppg/ast:expr 2024-08-22 10:00:19 +08:00
xushiwei
3c282e8cf9 Merge pull request #735 from visualfc/linkname
[wip] ssa: prog.linkname; abi llvm.LinkOnceAnyLinkage always
2024-08-22 05:44:16 +08:00
xushiwei
3c4fbdb50e Merge pull request #733 from luoliwoshang/llcppg/ast/refertype
llcppg/ast:rvalue reference
2024-08-22 05:40:39 +08:00
xushiwei
18cdc28963 Merge pull request #734 from luoliwoshang/llcppg/ast/func
llcppg/ast:func decl
2024-08-22 05:40:05 +08:00
xushiwei
5f004e7167 Merge pull request #736 from luoliwoshang/c/clang/anonymous
c/clang:anonymous record & underlying type
2024-08-22 05:37:00 +08:00
xushiwei
96489607ab Merge pull request #737 from luoliwoshang/llcppg/ast/typeexpr
llcppg/ast:record type
2024-08-22 05:35:55 +08:00
luoliwoshang
7436e44416 llcppg/ast:record type 2024-08-21 20:49:59 +08:00
luoliwoshang
8d30e51603 c/clang:typedef 2024-08-21 18:34:12 +08:00
luoliwoshang
64b582e397 c/clang:anonymous record 2024-08-21 14:55:43 +08:00
luoliwoshang
8b86d07bfc llcppg/ast:func decl 2024-08-21 14:12:24 +08:00
luoliwoshang
e3fefdebe1 llcppg/ast:value reference 2024-08-21 10:39:02 +08:00
xushiwei
46aec4a593 Merge pull request #731 from luoliwoshang/llcppg/ast/tagexpr
llcppg/ast:TagExpr
2024-08-21 06:30:19 +08:00
visualfc
2feb3e1d7a ssa: prog.linkname; abi llvm.LinkOnceAnyLinkage always 2024-08-20 21:11:27 +08:00
luoliwoshang
2609f45799 llcppg/ast:TagExpr 2024-08-20 12:03:21 +08:00
xushiwei
9053cbb90f Merge pull request #732 from luoliwoshang/c/clang/freetoken
c/clang:free tokens
2024-08-20 11:44:32 +08:00
luoliwoshang
3794d7ab65 c/clang:free tokens 2024-08-20 11:10:29 +08:00
xushiwei
7eeca21a05 Merge pull request #730 from xushiwei/q
llgocppg ast/token
2024-08-20 09:05:48 +08:00
xushiwei
70464154c7 Merge pull request #691 from luoliwoshang/llcppg/builtin
llcppg/ast:builtin type
2024-08-20 09:05:34 +08:00
xushiwei
1b29078fad Merge pull request #729 from luoliwoshang/c/clang/elementtype
c/clang:element type
2024-08-20 08:59:29 +08:00
xushiwei
864b078610 llgocppg ast/token 2024-08-20 08:58:43 +08:00
xushiwei
1a8b319ce2 Merge pull request #727 from luoliwoshang/llcppg/ast/marco
llcppg/ast:marco & token
2024-08-20 08:50:28 +08:00
luoliwoshang
a353514fc8 c/clang:element type 2024-08-19 18:07:36 +08:00
luoliwoshang
06e294fb3e llcppg/ast:builtin type 2024-08-19 11:25:47 +08:00
luoliwoshang
961d4c4a3a llcppg/ast:marco & token 2024-08-19 11:25:18 +08:00
xushiwei
876aea39e5 Merge pull request #728 from luoliwoshang/c/clang/tokenkind
c/clang:token kind
2024-08-17 22:37:19 +08:00
luoliwoshang
67be2ba95b c/clang:token kind 2024-08-16 18:46:36 +08:00
xushiwei
53d2d080f4 Merge pull request #726 from visualfc/fixmap
ssa: fix map zero
2024-08-16 16:52:29 +08:00
xushiwei
998fbeb381 Merge pull request #724 from visualfc/gc
build: check -tags nogc
2024-08-16 16:45:59 +08:00
xushiwei
1c6e4b7750 Merge pull request #725 from luoliwoshang/os/tomode
lib/os:fix error fileMode to ModeT
2024-08-16 16:42:28 +08:00
visualfc
8fbe21c79c ssa: fix map zero 2024-08-16 14:51:52 +08:00
visualfc
d6d0faac6e build: check -tags nogc 2024-08-16 11:34:58 +08:00
luoliwoshang
2d4f01e6cb lib/os:fix error fileMode to ModeT 2024-08-16 09:38:00 +08:00
xushiwei
b42ad3170e Merge pull request #722 from xushiwei/q
README: net/textproto
2024-08-15 22:08:48 +08:00
xushiwei
a8dddc81f1 README: net/textproto 2024-08-15 22:08:21 +08:00
xushiwei
2e1e6f784b Merge pull request #714 from luoliwoshang/llcppg/ast/basiclit
llcppg/ast:basiclit
2024-08-15 22:02:47 +08:00
xushiwei
2af9b95c7a Merge pull request #707 from spongehah/golib/net/textproto
lib/net/textproto: patch Dial
2024-08-15 20:58:14 +08:00
xushiwei
90be010c2b Merge pull request #721 from aofei/os
c/os: fix `Execl`, `Execle`, and `Execlp` func signatures
2024-08-15 20:53:31 +08:00
xushiwei
3b6b16cf77 Merge pull request #720 from xushiwei/q
c/pthread: nogc
2024-08-15 20:53:16 +08:00
xushiwei
c0c5c87c29 mv _pthread => _wrap 2024-08-15 20:47:42 +08:00
xushiwei
f5bbf4b515 c/pthread: nogc 2024-08-15 20:43:52 +08:00
Aofei Sheng
c7465608a7 c/os: fix Execl, Execle, and Execlp func signatures 2024-08-15 20:32:54 +08:00
xushiwei
03f0a4289b Merge pull request #719 from aofei/bdwgc
gc: fix missing pthread registration causing unknown thread error
2024-08-15 20:06:21 +08:00
xushiwei
bb2a6b73fe Merge pull request #518 from visualfc/ptrsize
runtime: init abi.Type.PtrBytes
2024-08-15 19:56:56 +08:00
Aofei Sheng
8e66091dd2 gc: fix missing pthread registration causing unknown thread error
- Use `GC_pthread_create` instead of `pthread_create` when GC is
  enabled.
2024-08-15 19:55:05 +08:00
xushiwei
a5c114a848 Merge pull request #693 from luoliwoshang/llcppsymg/unuse-comment
llcppsymg:remove unused bug-fix loop
2024-08-15 19:52:08 +08:00
xushiwei
254b2c27ac Merge pull request #700 from hackerchai/fix/c-net-byte-order-conv-func
refactor(c/net): Use c link instead of manual implement func
2024-08-15 19:45:57 +08:00
xushiwei
29fcb4504c Merge pull request #712 from luoliwoshang/os/mkdirdemo
lib/os:mkdir demo
2024-08-15 19:30:53 +08:00
xushiwei
ec7402b80a Merge pull request #715 from luoliwoshang/c/clang/arraysize
c/clang:array size & raw comment
2024-08-15 19:30:10 +08:00
xushiwei
4501519c4f Merge pull request #716 from aisk/py-tuple-helper
feat(py): Add Python tuple constructor helper
2024-08-15 18:21:51 +08:00
xushiwei
58ad7dab1b Merge pull request #718 from spongehah/c/libuv
refactor(c/libuv): Add multiple struct size
2024-08-15 18:18:58 +08:00
xushiwei
4da26a2f8d Merge pull request #717 from visualfc/funcdecl
ssa: makeInterface check funcdecl => closure
2024-08-15 18:18:28 +08:00
visualfc
9e6aed0760 runtime: init abi.Type.PtrBytes 2024-08-15 15:40:43 +08:00
luoliwoshang
7033f11d56 c/clang:array size & raw comment 2024-08-15 15:29:26 +08:00
赵英杰
8fcac42f34 c/libuv: Add multiple struct size 2024-08-15 10:57:29 +08:00
赵英杰
4a6a97ee75 lib/net/textproto: patch Dial 2024-08-15 10:43:57 +08:00
visualfc
2174d8fe8c ssa: makeInterface check funcdecl => closure 2024-08-15 10:12:18 +08:00
AN Long
eb6f487e2a fix: typo in document 2024-08-14 22:40:55 +08:00
AN Long
6bbe68dfcb test: Add py.Tuple test 2024-08-14 22:07:00 +08:00
AN Long
bbeceae42e feat(py): Add Python tuple constructor helper 2024-08-14 21:45:46 +08:00
luoliwoshang
cfe785762d llcppg/ast:basiclit 2024-08-14 18:27:15 +08:00
luoliwoshang
fdbb329fb6 lib/os:mkdir demo 2024-08-14 15:22:11 +08:00
xushiwei
9f1100b967 Merge pull request #710 from visualfc/sigsegv
[wip] runtime: signal SIGSEGV
2024-08-14 15:09:10 +08:00
xushiwei
94706d6139 Merge pull request #711 from luoliwoshang/os/filemode
lib/os:fileMode to ModeT , `Mkdir` run normally
2024-08-14 15:07:56 +08:00
xushiwei
b63609e2fa Merge pull request #695 from visualfc/instance_abi
cl: makeInterface check instance named
2024-08-14 15:06:07 +08:00
luoliwoshang
84c420139d lib/os:fileMode to ModeT 2024-08-14 14:24:15 +08:00
visualfc
027d21035e runtime: signal SIGSEGV 2024-08-14 11:30:24 +08:00
xushiwei
cc9de01c99 Merge pull request #705 from luoliwoshang/os/mkdir
[wip] lib/os: patch MkdirAll
2024-08-14 10:29:48 +08:00
xushiwei
61c6f240e9 Merge pull request #708 from xushiwei/q
llgo cmptest -gen
2024-08-14 10:27:33 +08:00
luoliwoshang
997d673b83 lib/os:MkdirAll use 1.21.13 2024-08-14 10:22:54 +08:00
xushiwei
6c72846d63 llgo cmptest -gen 2024-08-14 09:47:40 +08:00
luoliwoshang
8bd6e1d119 lib/os: patch MkdirAll 2024-08-14 09:41:16 +08:00
xushiwei
6484a8e6a4 Merge pull request #706 from hackerchai/fix/c-libuv-struct-size
fix(c/libuv): Add multiple struct size
2024-08-14 08:57:54 +08:00
xushiwei
0e8e108680 Merge pull request #701 from aofei/cmptest
cmptest: add support for comparison with `llgo.expect` files
2024-08-14 08:57:20 +08:00
visualfc
3435b6c4a4 cl: makeInterface check instance named 2024-08-13 21:59:19 +08:00
xushiwei
d4af6af594 Merge pull request #703 from visualfc/constuptr
ssa: const support unsafe.pointer
2024-08-13 17:22:12 +08:00
xushiwei
b834abd293 Merge pull request #702 from aofei/os.CreateTemp
lib/os: patch `TempDir`, `MkdirTemp`, `CreateTemp`
2024-08-13 17:13:07 +08:00
xushiwei
01a6dd79c4 Merge pull request #704 from aisk/py-uintptr-to-int
fix(py): Change uintptr to int in container types
2024-08-13 17:10:37 +08:00
hackerchai
948b6cf7e7 fix(c/libuv): Add multiple struct size
Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-13 16:51:42 +08:00
visualfc
b1718f329e ssa: const support unsafe.pointer 2024-08-12 22:01:15 +08:00
AN Long
7237f549a6 fix(py): Change uintptr to int in container types 2024-08-12 21:56:57 +08:00
Aofei Sheng
30b1660005 lib/os: patch TempDir, MkdirTemp, CreateTemp 2024-08-12 18:20:22 +08:00
Aofei Sheng
200fe07473 cmptest: add support for comparison with llgo.expect files
Fixes #671
2024-08-12 13:52:20 +08:00
hackerchai
86cb22d8c9 refactor(c/net): Use c link instead of manual implement func
Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-12 10:53:18 +08:00
xushiwei
321766fd46 Merge pull request #699 from aisk/py-tuple
feat(py): Add more method to tuple object
2024-08-12 09:38:47 +08:00
xushiwei
3eedad96ed Merge pull request #696 from luoliwoshang/c/lua/custom-panic
c/lua:custom panic
2024-08-12 09:36:42 +08:00
AN Long
4b26dac08a feat(py): Add more method to tuple object 2024-08-11 20:40:06 +08:00
luoliwoshang
04ef069a20 c/lua:custom panic 2024-08-10 20:18:31 +08:00
luoliwoshang
b925ed60e3 llcppsymg:remove unused bug-fix loop 2024-08-09 14:20:33 +08:00
xushiwei
dfd85a7c53 Merge pull request #643 from visualfc/defernext
ssa: fix defer move block[0] index
2024-08-09 12:54:46 +08:00
visualfc
6ca63d4c68 ssa: fix defer move block[0] index 2024-08-09 12:07:07 +08:00
赵英杰
2325b547fd fix(c/libuv): Change the request calling method of echo_server 2024-08-09 10:35:14 +08:00
xushiwei
34e454c054 Merge pull request #689 from visualfc/slicetoarray
ssa: SliceToArrayPointer
2024-08-09 09:44:46 +08:00
visualfc
302386d22c ssa: SliceToArrayPointer 2024-08-09 09:02:57 +08:00
xushiwei
210c483635 Merge pull request #687 from xushiwei/q
library syscall: linux fix
2024-08-09 00:33:09 +08:00
xushiwei
8ca4212650 library syscall: linux fix 2024-08-09 00:22:29 +08:00
xushiwei
c91dba5ed6 Merge pull request #686 from xushiwei/q
rollback golang.org/x/tools v0.22.0 => v0.19.0
2024-08-08 23:58:31 +08:00
xushiwei
c8de05f101 rollback golang.org/x/tools v0.22.0 => v0.19.0 2024-08-08 23:52:29 +08:00
xushiwei
0ac7cde498 Merge pull request #684 from visualfc/initafter
cl: build initAfter
2024-08-08 23:05:02 +08:00
visualfc
108829ad9c cl: build initAfter 2024-08-08 21:36:18 +08:00
xushiwei
c5b96f4e9c Merge pull request #681 from luoliwoshang/llcppsymg/refine
llcppsymg:improve parse symbol
2024-08-08 16:26:24 +08:00
luoliwoshang
4c2099d33e llcppg:remove unuse types 2024-08-08 15:18:16 +08:00
luoliwoshang
fe5de95008 llcppsymg:improve parsing process 2024-08-08 15:17:10 +08:00
xushiwei
4b0cfc0751 Merge pull request #677 from tsingbx/bigInt
llgo support big.Int
2024-08-08 14:23:32 +08:00
tsingbx
c2bf05942e add openssl BIGNUM support 2024-08-08 13:34:04 +08:00
tsingbx
df37f80c8e add big.Int Lsh and Rsh and test it 2024-08-08 13:33:14 +08:00
xushiwei
2c19d7218d Merge pull request #680 from xushiwei/q
llcppg design
2024-08-08 11:57:20 +08:00
xushiwei
34899e8d36 llcppg design 2024-08-08 11:49:55 +08:00
xushiwei
bf8c10ed25 Merge pull request #678 from spongehah/refactor/c-libuv-remove-go-wrapper
fix(c/libuv): Adjust comment errors and demo code
2024-08-08 11:33:10 +08:00
xushiwei
93c33e08c2 Merge pull request #679 from xushiwei/hmac
llcppg/ast: ppdNode
2024-08-08 11:31:01 +08:00
xushiwei
3992dd1dd0 Merge pull request #675 from hackerchai/feature/c-net-add-missing-funcs
feat(c/net): Add SockaddrStorage func, Ntohs func & SetSockOpt func
2024-08-08 11:30:48 +08:00
xushiwei
cab29c2be7 llcppg/ast: ppdNode 2024-08-08 11:21:56 +08:00
hackerchai
f582657ffd fix(c/net): Remove unused implicit import
Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-08 10:12:47 +08:00
赵英杰
2823ac1aee fix(c/libuv): Adjust comment errors and demo code 2024-08-08 10:04:20 +08:00
tsingbx
289caa7cc2 add BN_CTX Start, Get, End and Add big.Int Mul and test it 2024-08-08 09:10:31 +08:00
tsingbx
0a8bad46b5 add big.Int Set, Abs, Neg and add test it 2024-08-08 08:31:03 +08:00
xushiwei
aa4f518262 Merge pull request #673 from cpunion/libuv-async
Add libuv async
2024-08-07 21:43:50 +08:00
xushiwei
f76fa879fc Merge pull request #676 from luoliwoshang/xtool/ast/funcproto
castdump:funcproto type & computed enum value
2024-08-07 21:42:47 +08:00
luoliwoshang
8d70aba1f5 castdump:funcproto type & enum value 2024-08-07 20:33:35 +08:00
Li Jie
a44bb35aec libuv: add async 2024-08-07 20:24:43 +08:00
xushiwei
4fda2b656f Merge pull request #672 from luoliwoshang/c/clang/type-tree
castdump:array,typedef,pointer,funcproto,enum & builtin type
2024-08-07 19:15:37 +08:00
xushiwei
e626d00fdf Merge pull request #674 from hackerchai/feature/c-calloc
feat(c): Add Calloc func
2024-08-07 18:39:35 +08:00
hackerchai
bf09e3c3ae feat(c/net): Add SockaddrStorage func, Ntohs func & SetSockOpt func 2024-08-07 18:04:04 +08:00
hackerchai
753dcd3301 feat(c): Add Calloc func 2024-08-07 16:45:17 +08:00
Li Jie
8b5dee510e libuv: add uv_stop 2024-08-07 16:21:12 +08:00
luoliwoshang
9cb73fbf78 castdump:array,typedef,pointer & builtin type 2024-08-07 15:52:26 +08:00
xushiwei
e6b4deb5c4 Merge pull request #657 from hackerchai/fix/c-libuv-missing-func
feat(c/libuv): Add libuv missing funcs & refactor go func style
2024-08-07 15:04:52 +08:00
hackerchai
8848222728 feat(c/libuv): Add GetIoWatcherFd func using LLGoFiles 2024-08-07 14:49:21 +08:00
hackerchai
3cd62994c7 Revert "refactor(c/libuv): Use cgo alias replace struct assertion in fs"
This reverts commit 45ba5b8dc50a13223e05ad673f4e57d7277d3f24.

# Conflicts:
#	c/libuv/net.go
2024-08-07 14:49:20 +08:00
hackerchai
dd93a97790 Revert "feat(c/libuv): Add GetIoWatcherFd func"
This reverts commit 1ce16727b1195a65c8f2c9de07a864ed5e3902ef.

Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-07 14:49:19 +08:00
hackerchai
e40e2d2d14 style(c/libuv): Use go type funcs & update demo(syanc_fs, echo_server) 2024-08-07 14:49:18 +08:00
hackerchai
26f8ce7b5a refactor(c/libuv): Use cgo alias replace struct assertion in fs
refactro(c/libuv): Use cgo alias avoid implicit struct member declaration
2024-08-07 14:49:17 +08:00
hackerchai
9a61e374b5 refactor(c/libuv): Move some func due to libuv doc
doc: https://docs.libuv.org/en/v1.x/
2024-08-07 14:49:16 +08:00
hackerchai
9b12e9819c fix(c/libuv/demo): Fix echo_server stream convert 2024-08-07 14:49:15 +08:00
hackerchai
5d0a91239c feat(c/libuv): Add GetIoWatcherFd func 2024-08-07 14:49:14 +08:00
hackerchai
c848278690 feat(c/libuv): Add uv_close & uv_signal func
Signed-off-by: hackerchai <i@hackerchai.com>

feat(c/libuv): Add uv_signal_stop func

Signed-off-by: hackerchai <i@hackerchai.com>

feat(c/libuv): Add GetIoWatcher, GetFd func & add Io srtuct

Signed-off-by: hackerchai <i@hackerchai.com>

refactor(c/libuv):  Rename some func

refactor(c/libuv): Remove net go wrapper

refactor(c/libuv):  Add GetIoWatcherFd func
2024-08-07 14:49:13 +08:00
luoliwoshang
2ebb929e2c castdump:accessMap 2024-08-07 10:59:27 +08:00
xushiwei
b34334ba93 Merge pull request #669 from visualfc/abimap
ssa: fix abi map init
2024-08-07 07:54:27 +08:00
visualfc
05a01cd803 ssa: fix abi map init 2024-08-06 22:24:21 +08:00
xushiwei
9ac0c06f26 Merge pull request #667 from luoliwoshang/c/clang/type
c/clang:cursor enum & type kind
2024-08-06 22:00:27 +08:00
xushiwei
52af22b0e8 Merge pull request #660 from luoliwoshang/c/clang/fullast
c/clang:full ast dump
2024-08-06 21:56:06 +08:00
luoliwoshang
81cfc73b48 castdump:full ast dump 2024-08-06 21:37:00 +08:00
xushiwei
f892bfccdf Merge pull request #665 from xushiwei/hmac
library: crypto/hmac, internal/fmtsort
2024-08-06 18:56:37 +08:00
xushiwei
dbed8fefac library: crypto/hmac 2024-08-06 18:49:24 +08:00
luoliwoshang
ca14637909 c/clang:type kind 2024-08-06 18:23:31 +08:00
luoliwoshang
7db618fba5 c/clang:cursor enum & access pecifier 2024-08-06 18:23:19 +08:00
xushiwei
29c74c09ce library/README: crypto/hmac, crypto/subtle 2024-08-06 17:19:31 +08:00
xushiwei
a2b5b9f97e library (todo): crypto/hmac, internal/fmtsort 2024-08-06 17:03:22 +08:00
tsingbx
6a05aa4e53 llgo support crypto hmac (#663)
* llgo support crypto/hmac
2024-08-06 16:47:51 +08:00
xushiwei
43fd5d233a Merge pull request #662 from xushiwei/cast
TypedefDecl
2024-08-06 15:10:15 +08:00
xushiwei
0bd39ed035 TypedefDecl 2024-08-06 15:09:39 +08:00
xushiwei
1db8aad039 Merge pull request #661 from xushiwei/cast
llcppg: c/c++ ast
2024-08-06 11:00:51 +08:00
xushiwei
fb2d4267f5 llcppg: c/c++ ast 2024-08-06 11:00:13 +08:00
xushiwei
d7b203ae08 Merge pull request #655 from tsingbx/hmac2
add openssl hmac
2024-08-05 23:21:19 +08:00
xushiwei
3e07f2e3bc Merge pull request #656 from spongehah/golib/net-url
library: net/url
2024-08-05 20:11:31 +08:00
xushiwei
94cf6f6640 Merge pull request #658 from luoliwoshang/c/clang/marco
c/clang:marco content
2024-08-05 20:10:10 +08:00
luoliwoshang
6da5fe4317 c/clang:marco content 2024-08-05 19:38:29 +08:00
赵英杰
3a68dee850 library: net/url 2024-08-05 18:00:27 +08:00
tsingbx
2ccfa6a2e8 add EVP_sha1, EVP_sha224.... 2024-08-05 17:38:01 +08:00
tsingbx
f7bf671050 add openssl hmac
delete GetMD and HMAC function

delete macro

tidy code

add hmac
2024-08-05 16:57:47 +08:00
xushiwei
4bff9cc3df Merge pull request #653 from luoliwoshang/c/clang/marco
[wip] c/clang:marco info
2024-08-05 12:53:23 +08:00
xushiwei
13c68a0184 Merge pull request #654 from visualfc/fixstd
cpp/std: fix std::string def
2024-08-05 12:48:33 +08:00
visualfc
6d92949715 cpp/std: fix std::string def 2024-08-05 11:17:42 +08:00
luoliwoshang
5cf31bd3f3 c/clang:marco info 2024-08-04 17:35:15 +08:00
xushiwei
929d4c8d61 Merge pull request #647 from aofei/ssa-llgolink
ssa: add `llgo:link` support to `Builder.abiMthd`
2024-08-04 12:08:52 +08:00
Aofei Sheng
482f796bad ssa: add llgo:link support to Builder.abiMthd 2024-08-04 11:00:31 +08:00
xushiwei
d85f532ab1 Merge pull request #652 from xushiwei/q
c/os: llgoClearenv
2024-08-04 10:55:03 +08:00
xushiwei
b1654f7807 c/os: llgoClearenv 2024-08-04 10:54:41 +08:00
xushiwei
4f8526e527 Merge pull request #649 from aofei/clearenv
fix(c/os): add missing `clearenv` for macOS
2024-08-04 10:50:18 +08:00
Aofei Sheng
4b568fc469 fix(c/os): add missing clearenv for macOS 2024-08-04 09:58:01 +08:00
xushiwei
d06146ed97 Merge pull request #645 from spongehah/refactor/c-libuv-remove-go-wrapper
refactor(c-libuv): Added TODO(uid) comment & adjusted the position of Handle, Stream, Req, Write, Connect
2024-08-04 07:35:21 +08:00
xushiwei
8e0e809733 Merge pull request #648 from aofei/sync
perf(lib/sync): avoid using `defer`
2024-08-04 07:31:49 +08:00
Aofei Sheng
d1f33a6c4c perf(lib/sync): avoid using defer 2024-08-03 09:05:43 +08:00
赵英杰
b3e1b6fdbf refactor(c-libuv): Added TODO(uid) comment & adjusted the position of Handle, Stream, Req, Write, Connect 2024-08-03 00:25:14 +08:00
xushiwei
0bd259403c Merge pull request #644 from xushiwei/q
library: io/ioutil
2024-08-02 14:35:23 +08:00
xushiwei
c186846463 README: io/ioutil 2024-08-02 14:27:10 +08:00
xushiwei
5f92c3b3fc library: io/ioutil 2024-08-02 14:26:13 +08:00
xushiwei
0665091cef Merge pull request #641 from xushiwei/q
c/openssl: bio, pem, rsa
2024-08-01 23:03:48 +08:00
xushiwei
688d153427 c/openssl: bio, pem, rsa 2024-08-01 22:55:17 +08:00
xushiwei
bec5ba7a73 Merge pull request #638 from luoliwoshang/doc/c/visibile
doc/c:refine symbol visibility desc
2024-08-01 17:17:39 +08:00
xushiwei
acedf4d6a3 Merge pull request #613 from hackerchai/fix/c-libuv-struct
fix(c/libuv): Add libuv fs struct new func & fix async_fs demo
2024-08-01 17:13:51 +08:00
hackerchai
5dd5494f93 refactor(c/libuv): Adapt libuv.Fs struct 2024-08-01 10:57:59 +08:00
hackerchai
f253e4fabe Revert "fix(c/libuv): Add libuv fs struct new func"
This reverts commit 5fdb0a9634b5ecc29ddd50b6e5cce9938bcb7934.

# Conflicts:
#	c/libuv/_wrap/fs.c
#	c/libuv/fs.go
2024-08-01 10:57:58 +08:00
hackerchai
acd09d24d5 fix(c/libuv): Fix async_fs demo return 255 error & pointer not allocated error
Signed-off-by: hackerchai <i@hackerchai.com>

fix(c/libuv): Mv LLGoFiles declaration

Signed-off-by: hackerchai <i@hackerchai.com>

fix(c/libuv/demo): Fix return 255 error & pointer not allocated error

Signed-off-by: hackerchai <i@hackerchai.com>

refactor(c/libuv): Rewrite FsNew() logic

Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-01 10:57:57 +08:00
hackerchai
ceac95c81a fix(c/libuv): Add libuv fs struct new func
Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-01 10:54:01 +08:00
luoliwoshang
47a05d0ea2 doc/c:refine symbol visibility description 2024-08-01 09:54:48 +08:00
xushiwei
d2975479f2 Merge pull request #637 from xushiwei/q
README: math/big
2024-08-01 08:52:27 +08:00
xushiwei
3c238ffae7 Merge pull request #629 from luoliwoshang/doc/c
doc/c: fix incorrect Constructor and Destructor usage in bindings
2024-08-01 08:51:38 +08:00
xushiwei
69f8d1b717 README: math/big 2024-08-01 08:46:37 +08:00
xushiwei
45cd9e65d3 Merge pull request #634 from xushiwei/q
library: math/big.Int (mini-impl for _cmptest/bigintdemo)
2024-08-01 00:38:24 +08:00
xushiwei
2e4b1d8c2b library: math/big.Int (mini-impl for _cmptest/bigintdemo) 2024-08-01 00:32:21 +08:00
luoliwoshang
4e3b65188d doc/c:update implicit destructors description 2024-08-01 00:10:03 +08:00
xushiwei
0ab32e066b Merge pull request #633 from xushiwei/q
c/openssl: bignum, rsa
2024-07-31 23:21:25 +08:00
xushiwei
79d8b00b27 c/openssl: bignum, rsa 2024-07-31 22:34:13 +08:00
xushiwei
eb02c5a451 Merge pull request #631 from xushiwei/q
library: crypto, crypto/{sha1, sha256, sha512}
2024-07-31 19:04:24 +08:00
xushiwei
85509c777d library: crypto 2024-07-31 18:59:25 +08:00
xushiwei
27677f86e4 library: crypto/{sha1, sha256, sha512} 2024-07-31 18:55:46 +08:00
xushiwei
16174ca874 Merge pull request #627 from tsingbx/main
add crypto sha1,sha256,sha512
2024-07-31 18:39:54 +08:00
luoliwoshang
a4e9233231 doc/c:fix incorrect usage in construtors 2024-07-31 15:24:31 +08:00
luoliwoshang
4fdfafa17f doc/c:update destructor usage 2024-07-31 15:10:50 +08:00
tsingbx
c9a7dab419 delete sum 2024-07-31 14:56:03 +08:00
tsingbx
8882d75132 fix test error 2024-07-31 14:36:42 +08:00
tsingbx
f67b15b926 fix test fail 2024-07-31 14:28:15 +08:00
tsingbx
2d7958f726 add crypto sha1, sha256, sha512 2024-07-31 13:56:42 +08:00
xushiwei
36072584d0 Merge pull request #626 from aofei/goreleaser
fix(.goreleaser.yaml): correct ldflags for build version and time
2024-07-31 13:38:40 +08:00
Aofei Sheng
2119e52f55 fix(.goreleaser.yaml): correct ldflags for build version and time 2024-07-31 13:27:54 +08:00
xushiwei
ca1aa6b663 Merge pull request #625 from aofei/opt-deps
ci: install further optional dependencies for demos
2024-07-31 13:00:34 +08:00
xushiwei
10af671b76 Merge pull request #624 from xushiwei/q
library: go/parser (todo)
2024-07-31 13:00:09 +08:00
Aofei Sheng
a4ec6cce96 ci: install further optional dependencies for demos
Achieved 100% pass rate for demo tests, at least on macOS.
2024-07-31 12:34:51 +08:00
xushiwei
5082ba7102 library: go/parser (todo) 2024-07-31 12:29:09 +08:00
xushiwei
7405e7001b Merge pull request #623 from xushiwei/q
library: encoding, go/{token, scanner}
2024-07-31 11:56:09 +08:00
xushiwei
4c70651b81 library: go/{token, scanner} 2024-07-31 11:33:15 +08:00
xushiwei
21b5b60278 Merge pull request #622 from xushiwei/q
library: crypto/rand
2024-07-31 10:30:20 +08:00
xushiwei
0abc5ec452 README: crypto/rand 2024-07-31 10:30:04 +08:00
xushiwei
b1d2d620fa Merge pull request #621 from aofei/deps
deps: require zlib 1.2+
2024-07-31 10:27:47 +08:00
xushiwei
af6e4abe84 library: crypto/rand 2024-07-31 10:26:18 +08:00
Aofei Sheng
45b4315842 deps: require zlib 1.2+ 2024-07-31 09:52:48 +08:00
xushiwei
d2cb96a9e5 Merge pull request #620 from xushiwei/q
c/openssl: rand
2024-07-31 01:33:10 +08:00
xushiwei
a3ff845a14 c/openssl: rand 2024-07-31 01:27:08 +08:00
194 changed files with 14449 additions and 3873 deletions

View File

@@ -18,7 +18,7 @@ jobs:
- macos-latest - macos-latest
- ubuntu-24.04 - ubuntu-24.04
llvm: [18] llvm: [18]
runs-on: ${{ matrix.os }} runs-on: ${{matrix.os}}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -26,17 +26,46 @@ jobs:
if: startsWith(matrix.os, 'macos') if: startsWith(matrix.os, 'macos')
run: | run: |
brew update brew update
brew install llvm@${{ matrix.llvm }} pkg-config bdw-gc openssl cjson sqlite python@3.12 brew install llvm@${{matrix.llvm}} pkg-config bdw-gc openssl
echo "$(brew --prefix llvm@${{ matrix.llvm }})/bin" >> $GITHUB_PATH echo "$(brew --prefix llvm@${{matrix.llvm}})/bin" >> $GITHUB_PATH
# Install optional deps for demos.
#
# NOTE: Keep this list updated as new deps are introduced.
opt_deps=(
cjson # for github.com/goplus/llgo/c/cjson
sqlite # for github.com/goplus/llgo/c/sqlite
python@3.12 # for github.com/goplus/llgo/py
)
brew install "${opt_deps[@]}"
- name: Install dependencies - name: Install dependencies
if: startsWith(matrix.os, 'ubuntu') if: startsWith(matrix.os, 'ubuntu')
run: | 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 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 - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update sudo apt-get update
sudo apt-get install -y llvm-${{ matrix.llvm }}-dev clang-${{ matrix.llvm }} lld-${{ matrix.llvm }} pkg-config libgc-dev libssl-dev libcjson-dev libsqlite3-dev python3.12-dev sudo apt-get install -y llvm-${{matrix.llvm}}-dev clang-${{matrix.llvm}} lld-${{matrix.llvm}} pkg-config libgc-dev libssl-dev zlib1g-dev
echo "/usr/lib/llvm-${{ matrix.llvm }}/bin" >> $GITHUB_PATH echo "/usr/lib/llvm-${{matrix.llvm}}/bin" >> $GITHUB_PATH
# Install optional deps for demos.
#
# NOTE: Keep this list updated as new deps are introduced.
opt_deps=(
libcjson-dev # for github.com/goplus/llgo/c/cjson
libsqlite3-dev # for github.com/goplus/llgo/c/sqlite
python3.12-dev # for github.com/goplus/llgo/py
)
sudo apt-get install -y "${opt_deps[@]}"
- name: Install further optional dependencies for demos
run: |
wget -P ./_demo/llama2-c https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M.bin
py_deps=(
numpy # for github.com/goplus/llgo/py/numpy
torch # for github.com/goplus/llgo/py/torch
)
pip3 install --break-system-packages "${py_deps[@]}"
- name: Clang information - name: Clang information
run: | run: |
@@ -53,27 +82,25 @@ jobs:
run: go build -v ./... run: go build -v ./...
- name: Test - name: Test
if: matrix.os != 'macos-latest' if: ${{!startsWith(matrix.os, 'macos')}}
run: go test -v ./... run: go test -v ./...
- name: Test with coverage - name: Test with coverage
if: matrix.os == 'macos-latest' if: startsWith(matrix.os, 'macos')
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./... run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
- name: Install - name: Install
run: go install ./... run: go install ./...
- name: LLGO tests - name: LLGO tests
if: matrix.os != 'ubuntu-latest' if: ${{!startsWith(matrix.os, 'ubuntu')}}
run: | run: |
echo "Test result on ${{ matrix.os }} with LLVM ${{ matrix.llvm }}" > result.md echo "Test result on ${{matrix.os}} with LLVM ${{matrix.llvm}}" > result.md
LLGOROOT=$PWD bash .github/workflows/test_llgo.sh bash .github/workflows/test_llgo.sh
- name: Test _demo and _pydemo - name: Test demos
run: | continue-on-error: true
set +e run: bash .github/workflows/test_demo.sh
LLGOROOT=$PWD bash .github/workflows/test_demo.sh
exit 0
- name: Show test result - name: Show test result
run: cat result.md run: cat result.md
@@ -83,10 +110,10 @@ jobs:
if: false if: false
with: with:
filePath: result.md filePath: result.md
comment_tag: test-result-on-${{ matrix.os }}-with-llvm-${{ matrix.llvm }} comment_tag: test-result-on-${{matrix.os}}-with-llvm-${{matrix.llvm}}
- name: Upload coverage reports to Codecov - name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4 uses: codecov/codecov-action@v4
with: with:
token: ${{ secrets.CODECOV_TOKEN }} token: ${{secrets.CODECOV_TOKEN}}
slug: goplus/llgo slug: goplus/llgo

View File

@@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
set -e
# llgo run subdirectories under _demo and _pydemo # llgo run subdirectories under _demo and _pydemo
total=0 total=0
@@ -8,7 +9,7 @@ for d in ./_demo/* ./_pydemo/*; do
total=$((total+1)) total=$((total+1))
if [ -d "$d" ]; then if [ -d "$d" ]; then
echo "Testing $d" echo "Testing $d"
if ! llgo run "$d"; then if ! (cd "$d" && llgo run .); then
echo "FAIL" echo "FAIL"
failed=$((failed+1)) failed=$((failed+1))
failed_cases="$failed_cases\n* :x: $d" failed_cases="$failed_cases\n* :x: $d"

View File

@@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
set -e set -e
export LLGOROOT=$PWD
testcmd=/tmp/test testcmd=/tmp/test
llgo build -o $testcmd ./c/bdwgc/_test llgo build -o $testcmd ./c/bdwgc/_test
cases=$($testcmd) cases=$($testcmd)

View File

@@ -20,8 +20,8 @@ builds:
flags: flags:
- -tags=darwin,amd64,byollvm - -tags=darwin,amd64,byollvm
ldflags: ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}} - -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}} - -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/local/opt/llvm@18/bin/llvm-config - -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/local/opt/llvm@18/bin/llvm-config
env: env:
- CC=o64-clang - CC=o64-clang
@@ -36,8 +36,8 @@ builds:
flags: flags:
- -tags=darwin,arm64,byollvm - -tags=darwin,arm64,byollvm
ldflags: ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}} - -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}} - -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/opt/homebrew/opt/llvm@18/bin/llvm-config - -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/opt/homebrew/opt/llvm@18/bin/llvm-config
env: env:
- CC=oa64-clang - CC=oa64-clang
@@ -52,8 +52,8 @@ builds:
flags: flags:
- -tags=linux,amd64,byollvm - -tags=linux,amd64,byollvm
ldflags: ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}} - -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}} - -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config - -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config
env: env:
- CC=x86_64-linux-gnu-gcc - CC=x86_64-linux-gnu-gcc
@@ -68,8 +68,8 @@ builds:
flags: flags:
- -tags=linux,arm64,byollvm - -tags=linux,arm64,byollvm
ldflags: ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}} - -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}} - -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config - -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config
env: env:
- CC=aarch64-linux-gnu-gcc - CC=aarch64-linux-gnu-gcc

View File

@@ -269,13 +269,16 @@ Here are the Go packages that can be imported correctly:
* [unicode/utf8](https://pkg.go.dev/unicode/utf8) * [unicode/utf8](https://pkg.go.dev/unicode/utf8)
* [unicode/utf16](https://pkg.go.dev/unicode/utf16) * [unicode/utf16](https://pkg.go.dev/unicode/utf16)
* [math](https://pkg.go.dev/math) * [math](https://pkg.go.dev/math)
* [math/big](https://pkg.go.dev/math/big) (partially)
* [math/bits](https://pkg.go.dev/math/bits) * [math/bits](https://pkg.go.dev/math/bits)
* [math/cmplx](https://pkg.go.dev/math/cmplx) * [math/cmplx](https://pkg.go.dev/math/cmplx)
* [math/rand](https://pkg.go.dev/math/rand) * [math/rand](https://pkg.go.dev/math/rand)
* [net/url](https://pkg.go.dev/net/url)
* [errors](https://pkg.go.dev/errors) * [errors](https://pkg.go.dev/errors)
* [context](https://pkg.go.dev/context) * [context](https://pkg.go.dev/context)
* [io](https://pkg.go.dev/io) * [io](https://pkg.go.dev/io)
* [io/fs](https://pkg.go.dev/io/fs) * [io/fs](https://pkg.go.dev/io/fs)
* [io/ioutil](https://pkg.go.dev/io/ioutil)
* [log](https://pkg.go.dev/log) * [log](https://pkg.go.dev/log)
* [flag](https://pkg.go.dev/flag) * [flag](https://pkg.go.dev/flag)
* [sort](https://pkg.go.dev/sort) * [sort](https://pkg.go.dev/sort)
@@ -294,18 +297,29 @@ Here are the Go packages that can be imported correctly:
* [fmt](https://pkg.go.dev/fmt) (partially) * [fmt](https://pkg.go.dev/fmt) (partially)
* [reflect](https://pkg.go.dev/reflect) (partially) * [reflect](https://pkg.go.dev/reflect) (partially)
* [time](https://pkg.go.dev/time) (partially) * [time](https://pkg.go.dev/time) (partially)
* [encoding](https://pkg.go.dev/encoding)
* [encoding/binary](https://pkg.go.dev/encoding/binary) * [encoding/binary](https://pkg.go.dev/encoding/binary)
* [encoding/hex](https://pkg.go.dev/encoding/hex) * [encoding/hex](https://pkg.go.dev/encoding/hex)
* [encoding/base32](https://pkg.go.dev/encoding/base32) * [encoding/base32](https://pkg.go.dev/encoding/base32)
* [encoding/base64](https://pkg.go.dev/encoding/base64) * [encoding/base64](https://pkg.go.dev/encoding/base64)
* [encoding/csv](https://pkg.go.dev/encoding/csv) * [encoding/csv](https://pkg.go.dev/encoding/csv)
* [net/textproto](https://pkg.go.dev/net/textproto)
* [hash](https://pkg.go.dev/hash) * [hash](https://pkg.go.dev/hash)
* [hash/adler32](https://pkg.go.dev/hash/adler32) * [hash/adler32](https://pkg.go.dev/hash/adler32)
* [hash/crc32](https://pkg.go.dev/hash/crc32) (partially) * [hash/crc32](https://pkg.go.dev/hash/crc32) (partially)
* [hash/crc64](https://pkg.go.dev/hash/crc64) * [hash/crc64](https://pkg.go.dev/hash/crc64)
* [crypto](https://pkg.go.dev/crypto)
* [crypto/md5](https://pkg.go.dev/crypto/md5) * [crypto/md5](https://pkg.go.dev/crypto/md5)
* [crypto/sha1](https://pkg.go.dev/crypto/sha1)
* [crypto/sha256](https://pkg.go.dev/crypto/sha256)
* [crypto/sha512](https://pkg.go.dev/crypto/sha512) (partially)
* [crypto/hmac](https://pkg.go.dev/crypto/hmac) (partially)
* [crypto/rand](https://pkg.go.dev/crypto/rand) (partially)
* [crypto/subtle](https://pkg.go.dev/crypto/subtle) (partially)
* [regexp](https://pkg.go.dev/regexp) * [regexp](https://pkg.go.dev/regexp)
* [regexp/syntax](https://pkg.go.dev/regexp/syntax) * [regexp/syntax](https://pkg.go.dev/regexp/syntax)
* [go/token](https://pkg.go.dev/go/token)
* [go/scanner](https://pkg.go.dev/go/scanner)
## Dependencies ## Dependencies
@@ -317,8 +331,7 @@ Here are the Go packages that can be imported correctly:
- [pkg-config 0.29+](https://www.freedesktop.org/wiki/Software/pkg-config/) - [pkg-config 0.29+](https://www.freedesktop.org/wiki/Software/pkg-config/)
- [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/) - [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/)
- [OpenSSL 3.0+](https://www.openssl.org/) - [OpenSSL 3.0+](https://www.openssl.org/)
- [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)) - [zlib 1.2+](https://www.zlib.net)
- [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.12+](https://www.python.org) (optional, for [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py)) - [Python 3.12+](https://www.python.org) (optional, for [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py))
## How to install ## How to install
@@ -328,10 +341,9 @@ Follow these steps to generate the `llgo` command (its usage is the same as the
### on macOS ### on macOS
```sh ```sh
brew update # execute if needed brew update
brew install llvm@18 pkg-config bdw-gc openssl brew install llvm@18 pkg-config bdw-gc openssl
brew install cjson sqlite python@3.12 # optional brew install 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 go install -v github.com/goplus/llgo/cmd/llgo@latest
``` ```
@@ -340,10 +352,9 @@ go install -v github.com/goplus/llgo/cmd/llgo@latest
```sh ```sh
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-18 main" | sudo tee /etc/apt/sources.list.d/llvm.list 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 - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update # execute if needed sudo apt-get update
sudo apt-get install -y llvm-18-dev clang-18 lld-18 pkg-config libgc-dev libssl-dev sudo apt-get install -y llvm-18-dev clang-18 lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev
sudo apt-get install -y libcjson-dev libsqlite3-dev python3.12-dev # optional sudo apt-get install -y 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 go install -v github.com/goplus/llgo/cmd/llgo@latest
``` ```

View File

@@ -0,0 +1,34 @@
package main
import (
"fmt"
"go/parser"
"go/token"
)
func main() {
fset := token.NewFileSet() // positions are relative to fset
src := `package foo
import (
"fmt"
"time"
)
func bar() {
fmt.Println(time.Now())
}`
// Parse src but stop after processing the imports.
f, err := parser.ParseFile(fset, "", src, parser.ImportsOnly)
if err != nil {
fmt.Println(err)
return
}
// Print the imports from the file's AST.
for _, s := range f.Imports {
fmt.Println(s.Path.Value)
}
}

View File

@@ -0,0 +1,63 @@
package main
import (
"fmt"
"math/big"
)
func fib() {
// Initialize two big ints with the first two numbers in the sequence.
a := big.NewInt(0)
b := big.NewInt(1)
// Initialize limit as 10^99, the smallest integer with 100 digits.
var limit big.Int
limit.Exp(big.NewInt(10), big.NewInt(99), nil)
// Loop while a is smaller than 1e100.
for a.Cmp(&limit) < 0 {
// Compute the next Fibonacci number, storing it in a.
a.Add(a, b)
// Swap a and b so that b is the next number in the sequence.
a, b = b, a
}
fmt.Println(a) // 100-digit Fibonacci number
}
func abs() {
a := big.NewInt(64)
b := big.NewInt(-52)
a.Set(b)
a.Abs(a)
a.Set(big.NewInt(-164))
a.Abs(a)
fmt.Println("value: ", a.String())
}
func neg() {
fmt.Println("value: ", big.NewInt(-64).Neg(big.NewInt(-64)))
fmt.Println("value: ", big.NewInt(64).Neg(big.NewInt(64)))
fmt.Println("value: ", big.NewInt(0).Neg(big.NewInt(0)))
}
func calc() {
a := big.NewInt(64)
b := big.NewInt(-52)
c := big.NewInt(54)
fmt.Println("value:", a.Add(a, b))
fmt.Println("value:", a.Sub(b, c))
d := big.NewInt(10)
e := big.NewInt(4)
fmt.Println("value:", d.Mul(d, e))
}
func bitop() {
a := big.NewInt(4)
fmt.Println("value:", a.Lsh(a, 1))
b := big.NewInt(16)
fmt.Println("value:", b.Rsh(b, 2))
}
func main() {
bitop()
}

View File

@@ -0,0 +1,27 @@
package main
import (
"fmt"
"go/scanner"
"go/token"
)
func main() {
// src is the input that we want to tokenize.
src := []byte("cos(x) + 1i*sin(x) // Euler")
// Initialize the scanner.
var s scanner.Scanner
fset := token.NewFileSet() // positions are relative to fset
file := fset.AddFile("", fset.Base(), len(src)) // register input "file"
s.Init(file, src, nil /* no error handler */, scanner.ScanComments)
// Repeated calls to Scan yield the token sequence found in the input.
for {
pos, tok, lit := s.Scan()
if tok == token.EOF {
break
}
fmt.Printf("%s\t%s\t%q\n", fset.Position(pos), tok, lit)
}
}

15
_cmptest/hmacdemo/hmac.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import (
"crypto/hmac"
"crypto/sha1"
"fmt"
"io"
)
func main() {
h := hmac.New(sha1.New, []byte("<key>"))
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x", h.Sum(nil))
}

View File

@@ -0,0 +1,19 @@
package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
)
func main() {
r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.")
b, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", b)
}

View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"crypto"
"crypto/md5" "crypto/md5"
"fmt" "fmt"
"io" "io"
@@ -10,5 +11,10 @@ func main() {
h := md5.New() h := md5.New()
io.WriteString(h, "The fog is getting thicker!") io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!") io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x", h.Sum(nil)) fmt.Printf("%x\n", h.Sum(nil))
h = crypto.MD5.New()
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x\n", h.Sum(nil))
} }

14
_cmptest/sha1demo/sha1.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import (
"crypto/sha1"
"fmt"
"io"
)
func main() {
h := sha1.New()
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x", h.Sum(nil))
}

View File

@@ -0,0 +1,14 @@
package main
import (
"crypto/sha256"
"fmt"
"io"
)
func main() {
h := sha256.New()
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x", h.Sum(nil))
}

View File

@@ -0,0 +1,14 @@
package main
import (
"crypto/sha512"
"fmt"
"io"
)
func main() {
h := sha512.New()
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x", h.Sum(nil))
}

20
_cmptest/urldemo/url.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
u, err := url.Parse("http://foo.example.com/foo?bar=1")
if err != nil {
log.Fatal(err)
}
u.Scheme = "https"
u.Host = "bar.example.com"
q := u.Query()
q.Set("bar", "2")
u.RawQuery = q.Encode()
fmt.Println(u)
}

View File

@@ -0,0 +1,13 @@
package main
import "net/textproto"
func main() {
h := make(textproto.MIMEHeader)
h.Set("host", "www.example.com")
println(h.Get("Host"))
}
/* Expected output:
www.example.com
*/

34
_demo/mkdirdemo/mkdir.go Normal file
View File

@@ -0,0 +1,34 @@
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
tempDir, err := os.MkdirTemp("", "example*")
if err != nil {
fmt.Println("Failed to create temp directory:", err)
return
}
defer os.Remove(tempDir)
fmt.Println("Temp directory:", tempDir)
tempFile, err := os.CreateTemp("", "example*.txt")
if err != nil {
fmt.Println("Failed to create temp file:", err)
return
}
defer tempFile.Close()
defer os.Remove(tempFile.Name())
fmt.Println("Temp file:", tempFile.Name())
nestedDir := filepath.Join("nested", "directory")
err = os.MkdirAll(nestedDir, 0755)
if err != nil {
fmt.Println("Failed to create nested directory:", err)
return
}
fmt.Println("Nest directory:", nestedDir)
}

18
_demo/randcrypt/rand.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import (
"crypto/rand"
"fmt"
)
func main() {
c := 10
b := make([]byte, c)
_, err := rand.Read(b)
if err != nil {
fmt.Println("error:", err)
return
}
// The slice should now contain random bytes instead of only zeroes.
fmt.Printf("%x\n", b)
}

6
c/c.go
View File

@@ -79,6 +79,9 @@ func AllocaNew[T any]() *T { return nil }
//go:linkname Malloc C.malloc //go:linkname Malloc C.malloc
func Malloc(size uintptr) Pointer func Malloc(size uintptr) Pointer
//go:linkname Calloc C.calloc
func Calloc(num uintptr, size uintptr) Pointer
//go:linkname Free C.free //go:linkname Free C.free
func Free(ptr Pointer) func Free(ptr Pointer)
@@ -213,6 +216,9 @@ func Fputc(c Int, fp FilePtr) Int
//go:linkname Fputs C.fputs //go:linkname Fputs C.fputs
func Fputs(s *Char, fp FilePtr) Int func Fputs(s *Char, fp FilePtr) Int
//go:linkname Fread C.fread
func Fread(data Pointer, size, count uintptr, fp FilePtr) uintptr
//go:linkname Fflush C.fflush //go:linkname Fflush C.fflush
func Fflush(fp FilePtr) Int func Fflush(fp FilePtr) Int

View File

@@ -26,87 +26,25 @@ const (
LLGoPackage = "link: $(pkg-config --libs libcjson); -lcjson" LLGoPackage = "link: $(pkg-config --libs libcjson); -lcjson"
) )
type Bool c.Int
// llgo:type C // llgo:type C
type JSON struct { type JSON struct {
Unused [0]byte Unused [0]byte
} }
//go:linkname Parse C.cJSON_Parse
func Parse(value *c.Char) *JSON
//go:linkname ParseWithLength C.cJSON_ParseWithLength
func ParseWithLength(value *byte, valueLength uintptr) *JSON
func ParseBytes(value []byte) *JSON { func ParseBytes(value []byte) *JSON {
return ParseWithLength(unsafe.SliceData(value), uintptr(len(value))) return ParseWithLength((*c.Char)(unsafe.Pointer(unsafe.SliceData(value))), uintptr(len(value)))
} }
func ParseString(value string) *JSON { func ParseString(value string) *JSON {
return ParseWithLength(unsafe.StringData(value), uintptr(len(value))) return ParseWithLength((*c.Char)(unsafe.Pointer(unsafe.StringData(value))), uintptr(len(value)))
} }
//go:linkname Null C.cJSON_CreateNull // CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
func Null() *JSON
//go:linkname True C.cJSON_CreateTrue
func True() *JSON
//go:linkname False C.cJSON_CreateFalse
func False() *JSON
//go:linkname Bool C.cJSON_CreateBool
func Bool(boolean c.Int) *JSON
//go:linkname Number C.cJSON_CreateNumber
func Number(num float64) *JSON
//go:linkname String C.cJSON_CreateString
func String(str *c.Char) *JSON
//go:linkname Array C.cJSON_CreateArray
func Array() *JSON
//go:linkname Object C.cJSON_CreateObject
func Object() *JSON
// raw json
// //
//go:linkname Raw C.cJSON_CreateRaw // Render a cJSON entity to text for transfer/storage without any formatting.
func Raw(raw *c.Char) *JSON
// Create a string where valuestring references a string so
// it will not be freed by Delete
// //
//go:linkname StringRef C.cJSON_CreateStringReference
func StringRef(str *c.Char) *JSON
// Create an object that only references it's elements so
// they will not be freed by Delete
//
//go:linkname ObjectRef C.cJSON_CreateObjectReference
func ObjectRef(child *JSON) *JSON
// Create an array that only references it's elements so
// they will not be freed by Delete
//
//go:linkname ArrayRef C.cJSON_CreateArrayReference
func ArrayRef(child *JSON) *JSON
// Delete a JSON entity and all subentities.
//
// llgo:link (*JSON).Delete C.cJSON_Delete
func (o *JSON) Delete() {}
// Append item to the specified array.
//
// llgo:link (*JSON).AddItem C.cJSON_AddItemToArray
func (o *JSON) AddItem(item *JSON) c.Int { return 0 }
// Append item to the specified object.
//
// llgo:link (*JSON).SetItem C.cJSON_AddItemToObject
func (o *JSON) SetItem(key *c.Char, item *JSON) c.Int { return 0 }
// llgo:link (*JSON).CStr C.cJSON_PrintUnformatted // llgo:link (*JSON).CStr C.cJSON_PrintUnformatted
func (o *JSON) CStr() *c.Char { return nil } func (o *JSON) CStr() *c.Char { return nil }
@@ -115,39 +53,618 @@ func (o *JSON) CStr() *c.Char { return nil }
// llgo:link (*JSON).Cstr C.cJSON_PrintUnformatted // llgo:link (*JSON).Cstr C.cJSON_PrintUnformatted
func (o *JSON) Cstr() *c.Char { return nil } func (o *JSON) Cstr() *c.Char { return nil }
// malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks
//
//go:linkname FreeCStr C.cJSON_free
func FreeCStr(*c.Char)
// CJSON_PUBLIC(const char*) cJSON_Version(void);
//
// returns the version of cJSON as a string
//
//go:linkname Version C.cJSON_Version
func Version() *c.Char
// CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
//
// Memory Management: the caller is always responsible to free
// the results from all variants of cJSON_Parse (with cJSON_Delete)
// and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or
// cJSON_free as appropriate). The exception is cJSON_PrintPreallocated,
// where the caller has full responsibility of the buffer.
//
//go:linkname Parse C.cJSON_Parse
func Parse(value *c.Char) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
//
// Memory Management: the caller is always responsible to free
// the results from all variants of cJSON_Parse (with cJSON_Delete)
// and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or
// cJSON_free as appropriate). The exception is cJSON_PrintPreallocated,
// where the caller has full responsibility of the buffer.
//
//go:linkname ParseWithLength C.cJSON_ParseWithLength
func ParseWithLength(value *c.Char, valueLength uintptr) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_Bool require_null_terminated);
//
// ParseWithOpts allows you to require (and check) that the JSON is null terminated,
// and to retrieve the pointer to the final byte parsed.
// If you supply a ptr in return_parse_end and parsing fails, then
// return_parse_end will contain a pointer to the error so will match
// cJSON_GetErrorPtr().
//
//go:linkname ParseWithOpts C.cJSON_ParseWithOpts
func ParseWithOpts(value *c.Char, return_parse_end **c.Char, require_null_terminated Bool) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_Bool require_null_terminated);
//
// ParseWithOpts allows you to require (and check) that the JSON is null terminated,
// and to retrieve the pointer to the final byte parsed.
// If you supply a ptr in return_parse_end and parsing fails, then
// return_parse_end will contain a pointer to the error so will match
// cJSON_GetErrorPtr().
//
//go:linkname ParseWithLengthOpts C.cJSON_ParseWithLengthOpts
func ParseWithLengthOpts(value *c.Char, buffer_length uintptr, return_parse_end **c.Char, require_null_terminated Bool) *JSON
// CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
// Render a JSON entity to text for transfer/storage. // Render a JSON entity to text for transfer/storage.
// //
// llgo:link (*JSON).Print C.cJSON_Print // llgo:link (*JSON).Print C.cJSON_Print
func (o *JSON) Print() *c.Char { return nil } func (o *JSON) Print() *c.Char { return nil }
// CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
// Render a JSON entity to text for transfer/storage without any formatting. // Render a JSON entity to text for transfer/storage without any formatting.
// //
// llgo:link (*JSON).PrintUnformatted C.cJSON_PrintUnformatted // llgo:link (*JSON).PrintUnformatted C.cJSON_PrintUnformatted
func (o *JSON) PrintUnformatted() *c.Char { return nil } func (o *JSON) PrintUnformatted() *c.Char { return nil }
// CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_Bool fmt);
//
// Render a JSON entity to text using a buffered strategy. // Render a JSON entity to text using a buffered strategy.
//
// prebuffer is a guess at the final size. guessing well reduces reallocation. // prebuffer is a guess at the final size. guessing well reduces reallocation.
//
// fmt=0 gives unformatted, =1 gives formatted. // fmt=0 gives unformatted, =1 gives formatted.
// //
// llgo:link (*JSON).PrintBuffered C.cJSON_PrintBuffered // llgo:link (*JSON).PrintBuffered C.cJSON_PrintBuffered
func (o *JSON) PrintBuffered(prebuffer c.Int, fmt c.Int) *c.Char { return nil } func (o *JSON) PrintBuffered(prebuffer c.Int, fmt Bool) *c.Char { return nil }
// llgo:link (*JSON).GetObjectItemCaseSensitive C.cJSON_GetObjectItemCaseSensitive // CJSON_PUBLIC(cJSON_Bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_Bool format);
func (o *JSON) GetObjectItemCaseSensitive(key *c.Char) *JSON { return nil } //
// Render a cJSON entity to text using a buffer already allocated in memory with given
// length. Returns 1 on success and 0 on failure.
// note that cJSON is not always 100% accurate in estimating how much memory it will use,
// so to be safe allocate 5 bytes more than you actually need
//
// llgo:link (*JSON).PrintPreallocated C.cJSON_PrintPreallocated
func (o *JSON) PrintPreallocated(buffer *c.Char, length c.Int, format Bool) Bool {
return Bool(0)
}
// CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
// Delete a JSON entity and all subentities.
//
// llgo:link (*JSON).Delete C.cJSON_Delete
func (o *JSON) Delete() {}
// CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
//
// Returns the number of items in an array (or object).
//
// llgo:link (*JSON).GetArraySize C.cJSON_GetArraySize // llgo:link (*JSON).GetArraySize C.cJSON_GetArraySize
func (o *JSON) GetArraySize() c.Int { return 0 } func (o *JSON) GetArraySize() c.Int { return 0 }
// CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
//
// Retrieve item number "index" from array "array". Returns NULL if unsuccessful.
//
// llgo:link (*JSON).GetArrayItem C.cJSON_GetArrayItem // llgo:link (*JSON).GetArrayItem C.cJSON_GetArrayItem
func (o *JSON) GetArrayItem(index c.Int) *JSON { return nil } func (o *JSON) GetArrayItem(index c.Int) *JSON { return nil }
// CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
//
// Get item "string" from object. Case insensitive.
//
// llgo:link (*JSON).GetObjectItem C.cJSON_GetObjectItem
func (o *JSON) GetObjectItem(s *c.Char) *JSON { return nil }
// CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
//
// Get item "string" from object. Case sensitive.
//
// llgo:link (*JSON).GetObjectItemCaseSensitive C.cJSON_GetObjectItemCaseSensitive
func (o *JSON) GetObjectItemCaseSensitive(key *c.Char) *JSON { return nil }
// CJSON_PUBLIC(cJSON_Bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
//
// llgo:link (*JSON).HasObjectItem C.cJSON_HasObjectItem
func (o *JSON) HasObjectItem(s *c.Char) Bool { return Bool(0) }
// CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
//
// For analysing failed parses. This returns a pointer to the parse error.
// You'll probably need to look a few chars back to make sense of it.
// Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds.
//
//go:linkname GetErrorPtr C.cJSON_GetErrorPtr
func GetErrorPtr() *c.Char
// CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
//
// Check item type and return its value
//
// llgo:link (*JSON).GetStringValue C.cJSON_GetStringValue // llgo:link (*JSON).GetStringValue C.cJSON_GetStringValue
func (o *JSON) GetStringValue() *c.Char { return nil } func (o *JSON) GetStringValue() *c.Char { return nil }
// CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
//
// Check item type and return its value
//
// llgo:link (*JSON).GetNumberValue C.cJSON_GetNumberValue
func (o *JSON) GetNumberValue() c.Double { return 0 }
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsInvalid(const cJSON * const item);
//
// These functions check the type of an item
//
// llgo:link (*JSON).IsInvalid C.cJSON_IsInvalid
func (o *JSON) IsInvalid() Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsFalse(const cJSON * const item);
//
// These functions check the type of an item
//
// llgo:link (*JSON).IsFalse C.cJSON_IsFalse
func (o *JSON) IsFalse() Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsTrue(const cJSON * const item);
//
// These functions check the type of an item
//
// llgo:link (*JSON).IsTrue C.cJSON_IsTrue
func (o *JSON) IsTrue() Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsBool(const cJSON * const item);
//
// These functions check the type of an item
//
// llgo:link (*JSON).IsBool C.cJSON_IsBool
func (o *JSON) IsBool() Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsNull(const cJSON * const item);
//
// These functions check the type of an item
//
// llgo:link (*JSON).IsNull C.cJSON_IsNull
func (o *JSON) IsNull() Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsNumber(const cJSON * const item);
//
// These functions check the type of an item
//
// llgo:link (*JSON).IsNumber C.cJSON_IsNumber
func (o *JSON) IsNumber() Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsString(const cJSON * const item);
//
// These functions check the type of an item
//
// llgo:link (*JSON).IsString C.cJSON_IsString
func (o *JSON) IsString() Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsArray(const cJSON * const item);
//
// These functions check the type of an item
//
// llgo:link (*JSON).IsArray C.cJSON_IsArray
func (o *JSON) IsArray() Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsObject(const cJSON * const item);
//
// These functions check the type of an item
//
// llgo:link (*JSON).IsObject C.cJSON_IsObject
func (o *JSON) IsObject() Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsRaw(const cJSON * const item);
//
// These functions check the type of an item
//
// llgo:link (*JSON).IsRaw C.cJSON_IsRaw
func (o *JSON) IsRaw() Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
//
// These calls create a cJSON item of the appropriate type.
//
//go:linkname Null C.cJSON_CreateNull
func Null() *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
//
// same as Null func
//
//go:linkname CreateNull C.cJSON_CreateNull
func CreateNull() *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
//
//go:linkname True C.cJSON_CreateTrue
func True() *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
//
// same as True func
//
//go:linkname CreateTrue C.cJSON_CreateTrue
func CreateTrue() *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
//
//go:linkname False C.cJSON_CreateFalse
func False() *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
//
// same as False func
//
//go:linkname CreateFalse C.cJSON_CreateFalse
func CreateFalse() *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_Bool boolean);
//
// same as Bool func
//
//go:linkname CreateBool C.cJSON_CreateBool
func CreateBool(boolean c.Int) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
//
//go:linkname Number C.cJSON_CreateNumber
func Number(num float64) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
//
// same as Number func
//
//go:linkname CreateNumber C.cJSON_CreateNumber
func CreateNumber(num float64) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
//
//go:linkname String C.cJSON_CreateString
func String(str *c.Char) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
//
// same as String func
//
//go:linkname CreateString C.cJSON_CreateString
func CreateString(str *c.Char) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
// raw json
//
//go:linkname Raw C.cJSON_CreateRaw
func Raw(raw *c.Char) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
//
// same as Raw func
//
//go:linkname CreateRaw C.cJSON_CreateRaw
func CreateRaw(raw *c.Char) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
//
//go:linkname Array C.cJSON_CreateArray
func Array() *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
//
// same as Array func
//
//go:linkname CreateArray C.cJSON_CreateArray
func CreateArray() *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
//
//go:linkname Object C.cJSON_CreateObject
func Object() *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
//
// same as Object func
//
//go:linkname CreateObject C.cJSON_CreateObject
func CreateObject() *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
//
// Create a string where valuestring references a string so
// it will not be freed by Delete
//
//go:linkname StringRef C.cJSON_CreateStringReference
func StringRef(str *c.Char) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
//
// same as StringRef func
//
//go:linkname CreateStringReference C.cJSON_CreateStringReference
func CreateStringReference(str *c.Char) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
//
// Create an object that only references it's elements so
// they will not be freed by Delete
//
//go:linkname ObjectRef C.cJSON_CreateObjectReference
func ObjectRef(child *JSON) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
//
// same as ObjectRef func
//
//go:linkname CreateObjectReference C.cJSON_CreateObjectReference
func CreateObjectReference(child *JSON) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
//
// Create an array that only references it's elements so
// they will not be freed by Delete
//
//go:linkname ArrayRef C.cJSON_CreateArrayReference
func ArrayRef(child *JSON) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
//
// same as ArrayRef func
//
//go:linkname CreateArrayReference C.cJSON_CreateArrayReference
func CreateArrayReference(child *JSON) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
//
//go:linkname CreateIntArray C.cJSON_CreateIntArray
func CreateIntArray(numbers *c.Int, count c.Int) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
//
//go:linkname CreateFloatArray C.cJSON_CreateFloatArray
func CreateFloatArray(numbers *c.Float, count c.Int) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
//
//go:linkname CreateDoubleArray C.cJSON_CreateDoubleArray
func CreateDoubleArray(numbers *c.Double, count c.Int) *JSON
// CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
//
//go:linkname CreateStringArray C.cJSON_CreateStringArray
func CreateStringArray(strings *c.Char, count c.Int) *JSON
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
//
// Append item to the specified array.
//
// llgo:link (*JSON).AddItem C.cJSON_AddItemToArray
func (o *JSON) AddItem(item *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
//
// same as AddItem func
//
// llgo:link (*JSON).AddItemToArray C.cJSON_AddItemToArray
func (o *JSON) AddItemToArray(item *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
//
// Append item to the specified object.
//
// llgo:link (*JSON).SetItem C.cJSON_AddItemToObject
func (o *JSON) SetItem(key *c.Char, item *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
//
// same as SetItem func
//
// llgo:link (*JSON).AddItemToObject C.cJSON_AddItemToObject
func (o *JSON) AddItemToObject(key *c.Char, item *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
//
// Use this when string is definitely const (i.e. a literal, or as good as),
// and will definitely survive the cJSON object.
// warning that When this function was used, make sure to always check that
// (item->type & cJSON_StringIsConst) is zero before writing to `item->string`
//
// llgo:link (*JSON).AddItemToObjectCS C.cJSON_AddItemToObjectCS
func (o *JSON) AddItemToObjectCS(s *c.Char, item *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
//
// Append reference to item to the specified array/object.
// Use this when you want to add an existing cJSON to a new cJSON,
// but don't want to corrupt your existing cJSON.
//
// llgo:link (*JSON).AddItemReferenceToArray C.cJSON_AddItemReferenceToArray
func (o *JSON) AddItemReferenceToArray(item *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
//
// llgo:link (*JSON).AddItemReferenceToObject C.cJSON_AddItemReferenceToObject
func (o *JSON) AddItemReferenceToObject(s *c.Char, item *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
//
// Remove/Detach items from Arrays/Objects.
//
// llgo:link (*JSON).DetachItemViaPointer C.cJSON_DetachItemViaPointer
func (o *JSON) DetachItemViaPointer(item *JSON) *JSON { return nil }
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
//
// llgo:link (*JSON).DetachItemFromArray C.cJSON_DetachItemFromArray
func (o *JSON) DetachItemFromArray(which c.Int) *JSON { return nil }
// CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
//
// llgo:link (*JSON).DeleteItemFromArray C.cJSON_DeleteItemFromArray
func (o *JSON) DeleteItemFromArray(which c.Int) {}
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
//
// llgo:link (*JSON).DetachItemFromObject C.cJSON_DetachItemFromObject
func (o *JSON) DetachItemFromObject(s *c.Char) *JSON { return nil }
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
//
// llgo:link (*JSON).DetachItemFromObjectCaseSensitive C.cJSON_DetachItemFromObjectCaseSensitive
func (o *JSON) DetachItemFromObjectCaseSensitive(s *c.Char) *JSON { return nil }
// CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
//
// llgo:link (*JSON).DeleteItemFromObject C.cJSON_DeleteItemFromObject
func (o *JSON) DeleteItemFromObject(s *c.Char) {}
// CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
//
// llgo:link (*JSON).DeleteItemFromObjectCaseSensitive C.cJSON_DeleteItemFromObjectCaseSensitive
func (o *JSON) DeleteItemFromObjectCaseSensitive(s *c.Char) {}
// CJSON_PUBLIC(cJSON_Bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem);
//
// Update array items.
// Shifts pre-existing items to the right.
//
// llgo:link (*JSON).InsertItemInArray C.cJSON_InsertItemInArray
func (o *JSON) InsertItemInArray(which c.Int, newitem *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
//
// llgo:link (*JSON).ReplaceItemViaPointer C.cJSON_ReplaceItemViaPointer
func (o *JSON) ReplaceItemViaPointer(item *JSON, replacement *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
//
// llgo:link (*JSON).ReplaceItemInArray C.cJSON_ReplaceItemInArray
func (o *JSON) ReplaceItemInArray(which c.Int, newitem *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
//
// llgo:link (*JSON).ReplaceItemInObject C.cJSON_ReplaceItemInObject
func (o *JSON) ReplaceItemInObject(s *c.Char, newitem *JSON) Bool { return Bool(0) }
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
//
// llgo:link (*JSON).ReplaceItemInObjectCaseSensitive C.cJSON_ReplaceItemInObjectCaseSensitive
func (o *JSON) ReplaceItemInObjectCaseSensitive(s *c.Char, newitem *JSON) Bool {
return Bool(0)
}
// CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_Bool recurse);
//
// Duplicate a cJSON item
//
// Duplicate will create a new, identical cJSON item to the one you pass,
// in new memory that will need to be released. With recurse!=0,
// it will duplicate any children connected to the item.
// The item->next and ->prev pointers are always zero on return from Duplicate.
//
// llgo:link (*JSON).Duplicate C.cJSON_Duplicate
func (o *JSON) Duplicate(recurse Bool) *JSON { return nil }
// CJSON_PUBLIC(cJSON_Bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_Bool case_sensitive);
//
// Recursively compare two cJSON items for equality. If either a or b is NULL or invalid,
// they will be considered unequal. case_sensitive determines if object keys are treated
// case sensitive (1) or case insensitive (0)
//
// llgo:link (*JSON).Compare C.cJSON_Compare
func (o *JSON) Compare(b *JSON, case_sensitive Bool) Bool { return Bool(0) }
// CJSON_PUBLIC(void) cJSON_Minify(char *json);
//
// Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
// The input pointer json cannot point to a read-only address area, such as a string constant,
// but should point to a readable and writable address area.
//
//go:linkname Minify C.cJSON_Minify
func Minify()
// CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
//
// Helper functions for creating and adding items to an object at the same time.
// They return the added item or NULL on failure.
//
// llgo:link (*JSON).AddNullToObject C.cJSON_AddNullToObject
func (o *JSON) AddNullToObject(name *c.Char) *JSON { return nil }
// CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
//
// llgo:link (*JSON).AddTrueToObject C.cJSON_AddTrueToObject
func (o *JSON) AddTrueToObject(name *c.Char) *JSON { return nil }
// CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
//
// llgo:link (*JSON).AddFalseToObject C.cJSON_AddFalseToObject
func (o *JSON) AddFalseToObject(name *c.Char) *JSON { return nil }
// CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_Bool boolean);
//
// llgo:link (*JSON).AddBoolToObject C.cJSON_AddBoolToObject
func (o *JSON) AddBoolToObject(name *c.Char, b Bool) *JSON { return nil }
// CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
//
// llgo:link (*JSON).AddNumberToObject C.cJSON_AddNumberToObject
func (o *JSON) AddNumberToObject(name *c.Char, num c.Double) *JSON { return nil }
// CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
//
// llgo:link (*JSON).AddStringToObject C.cJSON_AddStringToObject
func (o *JSON) AddStringToObject(name *c.Char, s *c.Char) *JSON { return nil }
// CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
//
// llgo:link (*JSON).AddRawToObject C.cJSON_AddRawToObject
func (o *JSON) AddRawToObject(name *c.Char, raw *c.Char) *JSON { return nil }
// CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
//
// llgo:link (*JSON).AddObjectToObject C.cJSON_AddObjectToObject
func (o *JSON) AddObjectToObject(name *c.Char) *JSON { return nil }
// CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
//
// llgo:link (*JSON).AddArrayToObject C.cJSON_AddArrayToObject
func (o *JSON) AddArrayToObject(name *c.Char) *JSON { return nil }
// CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
//
// helper for the cJSON_SetNumberValue macro
//
// llgo:link (*JSON).SetNumberHelper C.cJSON_SetNumberHelper
func (o *JSON) SetNumberHelper(number c.Double) c.Double { return 0 }
// CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
//
// Change the valuestring of a cJSON_String object, only takes effect when type of
// object is cJSON_String
//
// llgo:link (*JSON).SetValuestring C.cJSON_SetValuestring
func (o *JSON) SetValuestring(v *c.Char) *c.Char { return nil }
// CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
//
// malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks
//
//go:linkname Malloc C.cJSON_malloc
func Malloc(size uintptr)
// CJSON_PUBLIC(void) cJSON_free(void *object);
//
//go:linkname Free C.cJSON_free //go:linkname Free C.cJSON_free
func Free(ptr unsafe.Pointer) func Free(ptr unsafe.Pointer)
//go:linkname FreeCStr C.cJSON_free
func FreeCStr(*c.Char)

View File

@@ -1,61 +0,0 @@
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()
}

View File

@@ -12,6 +12,7 @@ import (
type Context struct { type Context struct {
namespaceName string namespaceName string
className string className string
unit *clang.TranslationUnit
} }
func newContext() *Context { func newContext() *Context {
@@ -26,23 +27,51 @@ func (c *Context) setClassName(name string) {
c.className = name c.className = name
} }
func (c *Context) setUnit(unit *clang.TranslationUnit) {
c.unit = unit
}
var context = newContext() var context = newContext()
func print_cursor_info(cursor clang.Cursor) { func printCursorLocation(cursor clang.Cursor) {
loc := cursor.Location() loc := cursor.Location()
var file clang.File var file clang.File
var line, column c.Uint var line, column c.Uint
loc.SpellingLocation(&file, &line, &column, nil) loc.SpellingLocation(&file, &line, &column, nil)
filename := file.FileName() filename := file.FileName()
defer filename.Dispose()
c.Printf(c.Str("%s:%d:%d\n"), filename.CStr(), line, column) c.Printf(c.Str("%s:%d:%d\n"), filename.CStr(), line, column)
}
func printMarcoInfo(cursor clang.Cursor) {
printCursorLocation(cursor)
name := cursor.String()
c.Printf(c.Str("Marco Name: %s\n"), name.CStr())
ran := cursor.Extent()
var numTokens c.Uint
var tokens *clang.Token
context.unit.Tokenize(ran, &tokens, &numTokens)
c.Printf(c.Str("Content: "))
tokensSlice := unsafe.Slice(tokens, int(numTokens))
for _, tok := range tokensSlice {
tokStr := context.unit.Token(tok)
c.Printf(c.Str("%s "), tokStr.CStr())
tokStr.Dispose()
}
c.Printf(c.Str("\n"))
println("--------------------------------")
}
func printFuncInfo(cursor clang.Cursor) {
printCursorLocation(cursor)
cursorStr := cursor.String() cursorStr := cursor.String()
symbol := cursor.Mangling() symbol := cursor.Mangling()
defer symbol.Dispose() defer symbol.Dispose()
defer cursorStr.Dispose() defer cursorStr.Dispose()
defer filename.Dispose()
if context.namespaceName != "" && context.className != "" { if context.namespaceName != "" && context.className != "" {
fmt.Printf("%s:%s:", context.namespaceName, context.className) fmt.Printf("%s:%s:", context.namespaceName, context.className)
@@ -51,7 +80,7 @@ func print_cursor_info(cursor clang.Cursor) {
} }
c.Printf(c.Str("%s\n"), cursorStr.CStr()) c.Printf(c.Str("%s\n"), cursorStr.CStr())
if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl { if cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorFunctionDecl {
c.Printf(c.Str("symbol:%s\n"), symbol.CStr()) c.Printf(c.Str("symbol:%s\n"), symbol.CStr())
typeStr := cursor.ResultType().String() typeStr := cursor.ResultType().String()
@@ -78,18 +107,20 @@ func print_cursor_info(cursor clang.Cursor) {
} }
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult { func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
if cursor.Kind == clang.Namespace { if cursor.Kind == clang.CursorMacroDefinition {
printMarcoInfo(cursor)
} else if cursor.Kind == clang.CursorNamespace {
nameStr := cursor.String() nameStr := cursor.String()
context.setNamespaceName(c.GoString(nameStr.CStr())) context.setNamespaceName(c.GoString(nameStr.CStr()))
clang.VisitChildren(cursor, visit, nil) clang.VisitChildren(cursor, visit, nil)
context.setNamespaceName("") context.setNamespaceName("")
} else if cursor.Kind == clang.ClassDecl { } else if cursor.Kind == clang.CursorClassDecl {
nameStr := cursor.String() nameStr := cursor.String()
context.setClassName(c.GoString(nameStr.CStr())) context.setClassName(c.GoString(nameStr.CStr()))
clang.VisitChildren(cursor, visit, nil) clang.VisitChildren(cursor, visit, nil)
context.setClassName("") context.setClassName("")
} else if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl { } else if cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorFunctionDecl {
print_cursor_info(cursor) printFuncInfo(cursor)
} }
return clang.ChildVisit_Continue return clang.ChildVisit_Continue
@@ -105,7 +136,7 @@ func parse(filename *c.Char) {
filename, filename,
unsafe.SliceData(args), 3, unsafe.SliceData(args), 3,
nil, 0, nil, 0,
clang.TranslationUnit_None, clang.DetailedPreprocessingRecord,
) )
if unit == nil { if unit == nil {
@@ -113,6 +144,7 @@ func parse(filename *c.Char) {
c.Exit(1) c.Exit(1)
} }
context.setUnit(unit)
cursor := unit.Cursor() cursor := unit.Cursor()
clang.VisitChildren(cursor, visit, nil) clang.VisitChildren(cursor, visit, nil)

View File

@@ -15,9 +15,37 @@ CXChildVisitResult wrap_visitor(CXCursor cursor, CXCursor parent, CXClientData d
extern "C" { extern "C" {
CXString wrap_clang_getCursorSpelling(CXCursor *cur) { return clang_getCursorSpelling(*cur); } void wrap_clang_getTranslationUnitCursor(CXTranslationUnit uint, CXCursor *cur) {
*cur = clang_getTranslationUnitCursor(uint);
}
CXString wrap_clang_Cursor_getMangling(CXCursor *cur) { return clang_Cursor_getMangling(*cur); } unsigned wrap_clang_equalCursors(CXCursor *cursor1, CXCursor *cursor2) {
return clang_equalCursors(*cursor1, *cursor2);
}
int wrap_clang_Cursor_isNull(CXCursor *cursor) { return clang_Cursor_isNull(*cursor); }
void wrap_clang_getCursorSemanticParent(CXCursor *C, CXCursor *parent) { *parent = clang_getCursorSemanticParent(*C); }
void wrap_clang_getCursorLexicalParent(CXCursor *C, CXCursor *parent) { *parent = clang_getCursorLexicalParent(*C); }
void wrap_clang_getOverriddenCursors(CXCursor *cursor, CXCursor **overridden, unsigned *num_overridden) {
clang_getOverriddenCursors(*cursor, overridden, num_overridden);
}
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); }
void wrap_clang_getCursorExtent(CXCursor *cur, CXSourceRange *range) { *range = clang_getCursorExtent(*cur); }
void wrap_clang_getCursorType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorType(*cur); }
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
void wrap_clang_getTypedefDeclUnderlyingType(CXCursor *cur, CXType *typ) {
*typ = clang_getTypedefDeclUnderlyingType(*cur);
}
long long wrap_clang_getEnumConstantDeclValue(CXCursor *cur) { return clang_getEnumConstantDeclValue(*cur); }
int wrap_clang_Cursor_getNumArguments(CXCursor *cur) { return clang_Cursor_getNumArguments(*cur); } int wrap_clang_Cursor_getNumArguments(CXCursor *cur) { return clang_Cursor_getNumArguments(*cur); }
@@ -25,21 +53,124 @@ void wrap_clang_Cursor_getArgument(CXCursor *C, unsigned i, CXCursor *argCur) {
*argCur = clang_Cursor_getArgument(*C, i); *argCur = clang_Cursor_getArgument(*C, i);
} }
void wrap_clang_getTranslationUnitCursor(CXTranslationUnit uint, CXCursor *cur) { void wrap_clang_getCanonicalType(CXType *typ, CXType *canonicalType) { *canonicalType = clang_getCanonicalType(*typ); }
*cur = clang_getTranslationUnitCursor(uint);
unsigned wrap_clang_isConstQualifiedType(CXType *typ) { return clang_isConstQualifiedType(*typ); }
unsigned wrap_clang_Cursor_isMacroFunctionLike(CXCursor *cur) { return clang_Cursor_isMacroFunctionLike(*cur); }
unsigned wrap_clang_Cursor_isMacroBuiltin(CXCursor *cur) { return clang_Cursor_isMacroBuiltin(*cur); }
unsigned wrap_clang_Cursor_isFunctionInlined(CXCursor *cur) { return clang_Cursor_isFunctionInlined(*cur); }
unsigned wrap_clang_isVolatileQualifiedType(CXType *T) { return clang_isVolatileQualifiedType(*T); }
unsigned wrap_clang_isRestrictQualifiedType(CXType *T) { return clang_isRestrictQualifiedType(*T); }
void wrap_clang_getPointeeType(CXType *pointerTyp, CXType *pointeeTyp) {
*pointeeTyp = clang_getPointeeType(*pointerTyp);
} }
void wrap_clang_getCursorType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorType(*cur); } void wrap_clang_getNonReferenceType(CXType *typ, CXType *nonRefTyp) { *nonRefTyp = clang_getNonReferenceType(*typ); }
void wrap_clang_getTypeDeclaration(CXType *typ, CXCursor *cur) { *cur = clang_getTypeDeclaration(*typ); }
void wrap_clang_getResultType(CXType *typ, CXType *resultTyp) { *resultTyp = clang_getResultType(*typ); }
int wrap_clang_getNumArgTypes(CXType *typ) { return clang_getNumArgTypes(*typ); }
void wrap_clang_getArgType(CXType *typ, unsigned i, CXType *argTyp) { *argTyp = clang_getArgType(*typ, i); }
unsigned wrap_clang_isFunctionTypeVariadic(CXType *typ) { return clang_isFunctionTypeVariadic(*typ); }
void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorResultType(*cur); } void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorResultType(*cur); }
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); } void wrap_clang_getElementType(CXType *Typ, CXType *elemTyp) { *elemTyp = clang_getElementType(*Typ); }
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); } void wrap_clang_getArrayElementType(CXType *arrayTyp, CXType *elemTyp) {
*elemTyp = clang_getArrayElementType(*arrayTyp);
}
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column, long long wrap_clang_getArraySize(CXType *arrayTyp) { return clang_getArraySize(*arrayTyp); }
unsigned *offset) {
clang_getSpellingLocation(*loc, file, line, column, offset); void wrap_clang_Type_getNamedType(CXType *typ, CXType *namedTyp) { *namedTyp = clang_Type_getNamedType(*typ); }
unsigned wrap_clang_Cursor_isAnonymous(CXCursor *cursor) { return clang_Cursor_isAnonymous(*cursor); }
unsigned wrap_clang_Cursor_isAnonymousRecordDecl(CXCursor *cursor) {
return clang_Cursor_isAnonymousRecordDecl(*cursor);
}
enum CX_CXXAccessSpecifier wrap_clang_getCXXAccessSpecifier(CXCursor *cursor) {
return clang_getCXXAccessSpecifier(*cursor);
}
enum CX_StorageClass wrap_clang_Cursor_getStorageClass(CXCursor *cursor) {
return clang_Cursor_getStorageClass(*cursor);
}
CXString wrap_clang_getCursorUSR(CXCursor *cur) { return clang_getCursorUSR(*cur); }
CXString wrap_clang_getCursorSpelling(CXCursor *cur) { return clang_getCursorSpelling(*cur); }
unsigned wrap_clang_Cursor_isVariadic(CXCursor *cur) { return clang_Cursor_isVariadic(*cur); }
CXString wrap_clang_Cursor_getRawCommentText(CXCursor *cursor) { return clang_Cursor_getRawCommentText(*cursor); }
CXString wrap_clang_Cursor_getMangling(CXCursor *cur) { return clang_Cursor_getMangling(*cur); }
unsigned wrap_clang_CXXConstructor_isConvertingConstructor(CXCursor *cursor) {
return clang_CXXConstructor_isConvertingConstructor(*cursor);
}
unsigned wrap_clang_CXXConstructor_isCopyConstructor(CXCursor *cursor) {
return clang_CXXConstructor_isCopyConstructor(*cursor);
}
unsigned wrap_clang_CXXConstructor_isDefaultConstructor(CXCursor *cursor) {
return clang_CXXConstructor_isDefaultConstructor(*cursor);
}
unsigned wrap_clang_CXXConstructor_isMoveConstructor(CXCursor *cursor) {
return clang_CXXConstructor_isMoveConstructor(*cursor);
}
unsigned wrap_clang_CXXField_isMutable(CXCursor *cursor) { return clang_CXXField_isMutable(*cursor); }
unsigned wrap_clang_CXXMethod_isDefaulted(CXCursor *cursor) { return clang_CXXMethod_isDefaulted(*cursor); }
unsigned wrap_clang_CXXMethod_isDeleted(CXCursor *cursor) { return clang_CXXMethod_isDeleted(*cursor); }
unsigned wrap_clang_CXXMethod_isPureVirtual(CXCursor *cursor) { return clang_CXXMethod_isPureVirtual(*cursor); }
unsigned wrap_clang_CXXMethod_isStatic(CXCursor *cursor) { return clang_CXXMethod_isStatic(*cursor); }
unsigned wrap_clang_CXXMethod_isVirtual(CXCursor *cursor) { return clang_CXXMethod_isVirtual(*cursor); }
unsigned wrap_clang_CXXMethod_isCopyAssignmentOperator(CXCursor *cursor) {
return clang_CXXMethod_isCopyAssignmentOperator(*cursor);
}
unsigned wrap_clang_CXXMethod_isMoveAssignmentOperator(CXCursor *cursor) {
return clang_CXXMethod_isMoveAssignmentOperator(*cursor);
}
unsigned wrap_clang_CXXMethod_isExplicit(CXCursor *cursor) { return clang_CXXMethod_isExplicit(*cursor); }
unsigned wrap_clang_CXXRecord_isAbstract(CXCursor *cursor) { return clang_CXXRecord_isAbstract(*cursor); }
unsigned wrap_clang_EnumDecl_isScoped(CXCursor *cursor) { return clang_EnumDecl_isScoped(*cursor); }
unsigned wrap_clang_CXXMethod_isConst(CXCursor *cursor) { return clang_CXXMethod_isConst(*cursor); }
CXTokenKind wrap_clang_getTokenKind(CXToken *token) { return clang_getTokenKind(*token); }
CXString wrap_clang_getTokenSpelling(CXTranslationUnit unit, CXToken *token) {
return clang_getTokenSpelling(unit, *token);
}
void wrap_clang_tokenize(CXTranslationUnit unit, CXSourceRange *Range, CXToken **Tokens, unsigned *NumTokens) {
clang_tokenize(unit, *Range, Tokens, NumTokens);
} }
unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor, CXClientData client_data) { unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor, CXClientData client_data) {
@@ -47,4 +178,13 @@ unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data)); return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));
} }
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column,
unsigned *offset) {
clang_getSpellingLocation(*loc, file, line, column, offset);
}
void wrap_clang_getRangeStart(CXSourceRange *range, CXSourceLocation *loc) { *loc = clang_getRangeStart(*range); }
void wrap_clang_getRangeEnd(CXSourceRange *range, CXSourceLocation *loc) { *loc = clang_getRangeEnd(*range); }
} // extern "C" } // extern "C"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/libuv"
)
func ensure(b bool, msg string) {
if !b {
panic(msg)
}
}
func main() {
loop := libuv.LoopNew()
defer loop.Close()
a := &libuv.Async{}
r := loop.Async(a, func(a *libuv.Async) {
println("async callback")
a.Close(nil) // or loop.Stop()
})
ensure(r == 0, "Async failed")
go func() {
println("begin async task")
c.Usleep(100 * 1000)
println("send async event")
ensure(a.Send() == 0, "Send failed")
}()
loop.Run(libuv.RUN_DEFAULT)
println("done")
}
/*Expected Output:
begin async task
send async event
async callback
done
*/

View File

@@ -13,11 +13,11 @@ const BUFFER_SIZE = 1024
var ( var (
loop *libuv.Loop loop *libuv.Loop
openReq libuv.Fs openReq libuv.Fs
readReq libuv.Fs
closeReq libuv.Fs closeReq libuv.Fs
buffer [BUFFER_SIZE]c.Char buffer [BUFFER_SIZE]c.Char
iov libuv.Buf iov libuv.Buf
file libuv.File
) )
func main() { func main() {
@@ -31,7 +31,11 @@ func main() {
libuv.FsOpen(loop, &openReq, c.Str("example.txt"), os.O_RDONLY, 0, onOpen) libuv.FsOpen(loop, &openReq, c.Str("example.txt"), os.O_RDONLY, 0, onOpen)
// Run the loop // Run the loop
libuv.Run(loop, libuv.RUN_DEFAULT) result := loop.Run(libuv.RUN_DEFAULT)
if result != 0 {
c.Fprintf(c.Stderr, c.Str("Error in Run: %s\n"), libuv.Strerror(libuv.Errno(result)))
}
// Cleanup // Cleanup
defer cleanup() defer cleanup()
@@ -39,59 +43,74 @@ func main() {
func onOpen(req *libuv.Fs) { func onOpen(req *libuv.Fs) {
// Check for errors // Check for errors
if libuv.FsGetResult(req) < 0 { if req.GetResult() < 0 {
c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(libuv.Errno(libuv.LoopClose(loop)))) c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
libuv.LoopClose(loop) loop.Close()
return return
} }
// Store the file descriptor
file = libuv.File(req.GetResult())
// Init buffer // Init buffer
iov = libuv.InitBuf((*c.Char)(unsafe.Pointer(&buffer[0])), c.Uint(unsafe.Sizeof(buffer))) iov = libuv.InitBuf((*c.Char)(unsafe.Pointer(&buffer[0])), c.Uint(unsafe.Sizeof(buffer)))
// Read the file // Read the file
readRes := libuv.FsRead(loop, &readReq, libuv.File(libuv.FsGetResult(req)), &iov, 1, -1, onRead) readFile()
}
func readFile() {
// Initialize the request every time
var readReq libuv.Fs
// Read the file
readRes := libuv.FsRead(loop, &readReq, file, &iov, 1, -1, onRead)
if readRes != 0 { if readRes != 0 {
c.Printf(c.Str("Error in FsRead: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(readRes)), readRes) c.Printf(c.Str("Error in FsRead: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(readRes)), readRes)
libuv.LoopClose(loop) readReq.ReqCleanup()
return loop.Close()
} }
} }
func onRead(req *libuv.Fs) { func onRead(req *libuv.Fs) {
// Cleanup the request
defer req.ReqCleanup()
// Check for errors // Check for errors
if libuv.FsGetResult(req) < 0 { if req.GetResult() < 0 {
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req)))) c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
libuv.LoopClose(loop) } else if req.GetResult() == 0 {
} else if libuv.FsGetResult(req) == 0 {
c.Printf(c.Str("EOF\n"))
// Close the file // Close the file
closeRes := libuv.FsClose(loop, &closeReq, libuv.File(libuv.FsGetResult(&openReq)), onClose) closeRes := libuv.FsClose(loop, &closeReq, libuv.File(openReq.GetResult()), onClose)
if closeRes != 0 { if closeRes != 0 {
// Print the content
c.Printf(c.Str("Error in FsClose: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(closeRes)), closeRes) c.Printf(c.Str("Error in FsClose: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(closeRes)), closeRes)
libuv.LoopClose(loop) loop.Close()
return return
} }
} else { } else {
c.Printf(c.Str("Read %d bytes\n"), libuv.FsGetResult(req)) c.Printf(c.Str("Read %d bytes\n"), req.GetResult())
c.Printf(c.Str("Read content: %.*s\n"), libuv.FsGetResult(req), (*c.Char)(unsafe.Pointer(&buffer[0]))) c.Printf(c.Str("Read content: %.*s\n"), req.GetResult(), (*c.Char)(unsafe.Pointer(&buffer[0])))
libuv.LoopClose(loop) // Read the file again
readFile()
} }
} }
func onClose(req *libuv.Fs) { func onClose(req *libuv.Fs) {
// Check for errors // Check for errors
if libuv.FsGetResult(req) < 0 { if req.GetResult() < 0 {
c.Fprintf(c.Stderr, c.Str("Error closing file: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req)))) c.Fprintf(c.Stderr, c.Str("Error closing file: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
} else { } else {
c.Printf(c.Str("\nFile closed successfully.\n")) c.Printf(c.Str("\nFile closed successfully.\n"))
} }
libuv.LoopClose(loop)
} }
func cleanup() { func cleanup() {
// Cleanup the requests // Cleanup the requests
libuv.FsReqCleanup(&openReq) openReq.ReqCleanup()
libuv.FsReqCleanup(&readReq) closeReq.ReqCleanup()
libuv.FsReqCleanup(&closeReq)
// Close the loop // Close the loop
libuv.LoopClose(loop) result := loop.Close()
if result != 0 {
c.Fprintf(c.Stderr, c.Str("Error in LoopClose: %s\n"), libuv.Strerror(libuv.Errno(result)))
}
} }

View File

@@ -1,8 +1,6 @@
package main package main
import ( import (
"unsafe"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/libuv" "github.com/goplus/llgo/c/libuv"
"github.com/goplus/llgo/c/net" "github.com/goplus/llgo/c/net"
@@ -11,8 +9,6 @@ import (
var DEFAULT_PORT c.Int = 8080 var DEFAULT_PORT c.Int = 8080
var DEFAULT_BACKLOG c.Int = 128 var DEFAULT_BACKLOG c.Int = 128
var loop *libuv.Loop
type WriteReq struct { type WriteReq struct {
Req libuv.Write Req libuv.Write
Buf libuv.Buf Buf libuv.Buf
@@ -20,11 +16,11 @@ type WriteReq struct {
func main() { func main() {
// Initialize the default event loop // Initialize the default event loop
loop = libuv.DefaultLoop() var loop = libuv.DefaultLoop()
// Initialize a TCP server // Initialize a TCP server
var server libuv.Tcp server := &libuv.Tcp{}
libuv.InitTcp(loop, &server) libuv.InitTcp(loop, server)
// Set up the address to bind the server to // Set up the address to bind the server to
var addr net.SockaddrIn var addr net.SockaddrIn
@@ -32,22 +28,24 @@ func main() {
c.Printf(c.Str("Listening on %s:%d\n"), c.Str("0.0.0.0"), DEFAULT_PORT) c.Printf(c.Str("Listening on %s:%d\n"), c.Str("0.0.0.0"), DEFAULT_PORT)
// Bind the server to the specified address and port // Bind the server to the specified address and port
(&server).Bind((*net.SockAddr)(c.Pointer(&addr)), 0) server.Bind((*net.SockAddr)(c.Pointer(&addr)), 0)
res := (*libuv.Stream)(&server).Listen(DEFAULT_BACKLOG, OnNewConnection) res := (*libuv.Stream)(server).Listen(DEFAULT_BACKLOG, OnNewConnection)
if res != 0 { if res != 0 {
c.Fprintf(c.Stderr, c.Str("Listen error: %s\n"), libuv.Strerror((libuv.Errno(res)))) c.Fprintf(c.Stderr, c.Str("Listen error: %s\n"), libuv.Strerror(libuv.Errno(res)))
return return
} }
// Start listening for incoming connections // Start listening for incoming connections
libuv.Run(loop, libuv.RUN_DEFAULT) loop.Run(libuv.RUN_DEFAULT)
} }
func FreeWriteReq(req *libuv.Write) { func FreeWriteReq(req *libuv.Write) {
wr := (*WriteReq)(c.Pointer(req)) wr := (*WriteReq)(c.Pointer(req))
// Free the buffer base and the WriteReq itself. // Free the buffer base.
if wr.Buf.Base != nil {
c.Free(c.Pointer(wr.Buf.Base)) c.Free(c.Pointer(wr.Buf.Base))
c.Free(c.Pointer(wr)) wr.Buf.Base = nil
}
} }
func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) { func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) {
@@ -58,29 +56,24 @@ func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) {
func EchoWrite(req *libuv.Write, status c.Int) { func EchoWrite(req *libuv.Write, status c.Int) {
if status != 0 { if status != 0 {
c.Fprintf(c.Stderr, c.Str("Write error: %s\n"), libuv.Strerror((libuv.Errno(status)))) c.Fprintf(c.Stderr, c.Str("Write error: %s\n"), libuv.Strerror(libuv.Errno(status)))
} }
FreeWriteReq(req) FreeWriteReq(req)
} }
func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) { func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) {
if nread > 0 { if nread > 0 {
req := (*WriteReq)(c.Malloc(unsafe.Sizeof(WriteReq{}))) req := new(WriteReq)
if req == nil {
c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for write request\n"))
c.Free(c.Pointer(buf.Base))
return
}
// Initialize the buffer with the data read. // Initialize the buffer with the data read.
req.Buf = libuv.InitBuf(buf.Base, c.Uint(nread)) req.Buf = libuv.InitBuf(buf.Base, c.Uint(nread))
// Write the data back to the client. // Write the data back to the client.
(&req.Req).Write(client, &req.Buf, 1, EchoWrite) req.Req.Write(client, &req.Buf, 1, EchoWrite)
return return
} }
if nread < 0 { if nread < 0 {
// Handle read errors and EOF. // Handle read errors and EOF.
if (libuv.Errno)(nread) != libuv.EOF { if (libuv.Errno)(nread) != libuv.EOF {
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror((libuv.Errno)(nread))) c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(nread)))
} }
(*libuv.Handle)(c.Pointer(client)).Close(nil) (*libuv.Handle)(c.Pointer(client)).Close(nil)
} }
@@ -97,7 +90,7 @@ func OnNewConnection(server *libuv.Stream, status c.Int) {
} }
// Allocate memory for a new client. // Allocate memory for a new client.
client := (*libuv.Tcp)(c.Malloc(unsafe.Sizeof(libuv.Tcp{}))) client := &libuv.Tcp{}
if client == nil { if client == nil {
c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for client\n")) c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for client\n"))
@@ -105,9 +98,8 @@ func OnNewConnection(server *libuv.Stream, status c.Int) {
} }
// Initialize the client TCP handle. // Initialize the client TCP handle.
if libuv.InitTcp(loop, client) < 0 { if libuv.InitTcp(libuv.DefaultLoop(), client) < 0 {
c.Fprintf(c.Stderr, c.Str("Failed to initialize client\n")) c.Fprintf(c.Stderr, c.Str("Failed to initialize client\n"))
c.Free(c.Pointer(client))
return return
} }

5
c/libuv/_wrap/libuv.c Normal file
View File

@@ -0,0 +1,5 @@
#include <uv.h>
int uv_tcp_get_io_watcher_fd (uv_tcp_t* handle) {
return handle->io_watcher.fd;
}

50
c/libuv/async.go Normal file
View File

@@ -0,0 +1,50 @@
/*
* 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 libuv
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
// struct uv_async_t
type Async struct {
Handle
// On macOS arm64, sizeof uv_async_t is 128 bytes.
// Handle is 92 bytes, so we need 36 bytes to fill the gap.
// Maybe reserve more for future use.
Unused [36]byte
}
// typedef void (*uv_async_cb)(uv_async_t* handle);
// llgo:type C
type AsyncCb func(*Async)
// int uv_async_init(uv_loop_t*, uv_async_t* async, uv_async_cb async_cb);
//
// llgo:link (*Loop).Async C.uv_async_init
func (loop *Loop) Async(a *Async, cb AsyncCb) c.Int {
return 0
}
// int uv_async_send(uv_async_t* async);
//
// llgo:link (*Async).Send C.uv_async_send
func (a *Async) Send() c.Int {
return 0
}

27
c/libuv/check.go Normal file
View File

@@ -0,0 +1,27 @@
package libuv
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
/* Handle types. */
type Check struct {
Unused [120]byte
}
/* Function type */
// llgo:type C
type CheckCb func(Check *Check)
//go:linkname InitCheck C.uv_check_init
func InitCheck(loop *Loop, Check *Check) c.Int
// llgo:link (*Check).Start C.uv_check_start
func (Check *Check) Start(CheckCb CheckCb) c.Int { return 0 }
// llgo:link (*Check).Stop C.uv_check_stop
func (Check *Check) Stop() c.Int { return 0 }

View File

@@ -95,7 +95,7 @@ const (
ECHARSET Errno = -4080 ECHARSET Errno = -4080
ENONET Errno = -4056 ENONET Errno = -4056
UNKNOWN Errno = -4094 UNKNOWN Errno = -4094
EOF Errno = -1 EOF Errno = -4095
EREMOTEIO Errno = -4030 EREMOTEIO Errno = -4030
ERRNO_MAX Errno = EOF - 1 ERRNO_MAX Errno = EOF - 1
) )

View File

@@ -69,7 +69,7 @@ type File c.Int
/* Handle types. */ /* Handle types. */
type Fs struct { type Fs struct {
Unused [0]byte Unused [440]byte
} }
type FsEvent struct { type FsEvent struct {
@@ -106,29 +106,40 @@ type FsPollCb func(handle *FsPoll, status c.Int, events c.Int)
/* Fs related function and method */ /* Fs related function and method */
//go:linkname FsGetType C.uv_fs_get_type // llgo:link (*Fs).GetType C.uv_fs_get_type
func FsGetType(req *Fs) FsType func (req *Fs) GetType() FsType {
return 0
}
//go:linkname FsGetPath C.uv_fs_get_path // llgo:link (*Fs).GetPath C.uv_fs_get_path
func FsGetPath(req *Fs) *c.Char func (req *Fs) GetPath() *c.Char {
return nil
}
//go:linkname FsGetResult C.uv_fs_get_result // llgo:link (*Fs).GetResult C.uv_fs_get_result
func FsGetResult(req *Fs) c.Int func (req *Fs) GetResult() c.Int {
return 0
}
//go:linkname FsGetPtr C.uv_fs_get_ptr // llgo:link (*Fs).GetPtr C.uv_fs_get_ptr
func FsGetPtr(req *Fs) c.Pointer func (req *Fs) GetPtr() c.Pointer {
return nil
}
//go:linkname FsGetSystemError C.uv_fs_get_system_error // llgo:link (*Fs).GetSystemError C.uv_fs_get_system_error
func FsGetSystemError(req *Fs) c.Int func (req *Fs) GetSystemError() c.Int {
return 0
}
//go:linkname FsGetStatBuf C.uv_fs_get_statbuf // llgo:link (*Fs).GetStatBuf C.uv_fs_get_statbuf
func FsGetStatBuf(req *Fs) *Stat func (req *Fs) GetStatBuf() *Stat {
return nil
}
//go:linkname FsReqCleanup C.uv_fs_req_cleanup // llgo:link (*Fs).ReqCleanup C.uv_fs_req_cleanup
func FsReqCleanup(req *Fs) func (req *Fs) ReqCleanup() {
// No return value needed for this method
//go:linkname DefaultLoop C.uv_default_loop }
func DefaultLoop() *Loop
//go:linkname FsOpen C.uv_fs_open //go:linkname FsOpen C.uv_fs_open
func FsOpen(loop *Loop, req *Fs, path *c.Char, flags c.Int, mode c.Int, cb FsCb) c.Int func FsOpen(loop *Loop, req *Fs, path *c.Char, flags c.Int, mode c.Int, cb FsCb) c.Int
@@ -241,32 +252,56 @@ func FsLchown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb)
//go:linkname FsLstat C.uv_fs_lstat //go:linkname FsLstat C.uv_fs_lstat
func FsLstat(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int func FsLstat(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
// ----------------------------------------------
/* FsEvent related function and method */
//go:linkname FsEventInit C.uv_fs_event_init //go:linkname FsEventInit C.uv_fs_event_init
func FsEventInit(loop *Loop, handle *FsEvent) c.Int func FsEventInit(loop *Loop, handle *FsEvent) c.Int
//go:linkname FsEventStart C.uv_fs_event_start // llgo:link (*FsEvent).Start C.uv_fs_event_start
func FsEventStart(handle *FsEvent, cb FsEventCb, path *c.Char, flags c.Int) c.Int func (handle *FsEvent) Start(cb FsEventCb, path *c.Char, flags c.Int) c.Int {
return 0
}
//go:linkname FsEventStop C.uv_fs_event_stop // llgo:link (*FsEvent).Stop C.uv_fs_event_stop
func FsEventStop(handle *FsEvent) c.Int func (handle *FsEvent) Stop() c.Int {
return 0
}
//go:linkname FsEventClose C.uv_fs_event_close // llgo:link (*FsEvent).Close C.uv_fs_event_close
func FsEventClose(handle *FsEvent) c.Int func (handle *FsEvent) Close() c.Int {
return 0
}
//go:linkname FsEventGetpath C.uv_fs_event_getpath // llgo:link (*FsEvent).Getpath C.uv_fs_event_getpath
func FsEventGetpath(handle *FsEvent) *c.Char func (handle *FsEvent) Getpath() *c.Char {
return nil
}
// ----------------------------------------------
/* FsPoll related function and method */
//go:linkname FsPollInit C.uv_fs_poll_init //go:linkname FsPollInit C.uv_fs_poll_init
func FsPollInit(loop *Loop, handle *FsPoll) c.Int func FsPollInit(loop *Loop, handle *FsPoll) c.Int
//go:linkname FsPollStart C.uv_fs_poll_start // llgo:link (*FsPoll).Start C.uv_fs_poll_start
func FsPollStart(handle *FsPoll, cb FsPollCb, path *c.Char, interval uint) c.Int func (handle *FsPoll) Start(cb FsPollCb, path *c.Char, interval uint) c.Int {
return 0
}
//go:linkname FsPollStop C.uv_fs_poll_stop // llgo:link (*FsPoll).Stop C.uv_fs_poll_stop
func FsPollStop(handle *FsPoll) c.Int func (handle *FsPoll) Stop() c.Int {
return 0
}
//go:linkname FsPollClose C.uv_fs_poll_close // llgo:link (*FsPoll).Close C.uv_fs_poll_close
func FsPollClose(handle *FsPoll) c.Int func (handle *FsPoll) Close() c.Int {
return 0
}
//go:linkname FsPollGetPath C.uv_fs_poll_getpath // llgo:link (*FsPoll).GetPath C.uv_fs_poll_getpath
func FsPollGetPath(handle *FsPoll) *c.Char func (handle *FsPoll) GetPath() *c.Char {
return nil
}

27
c/libuv/idle.go Normal file
View File

@@ -0,0 +1,27 @@
package libuv
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
/* Handle types. */
type Idle struct {
Unused [120]byte
}
/* Function type */
// llgo:type C
type IdleCb func(idle *Idle)
//go:linkname InitIdle C.uv_idle_init
func InitIdle(loop *Loop, idle *Idle) c.Int
// llgo:link (*Idle).Start C.uv_idle_start
func (idle *Idle) Start(idleCb IdleCb) c.Int { return 0 }
// llgo:link (*Idle).Stop C.uv_idle_stop
func (idle *Idle) Stop() c.Int { return 0 }

View File

@@ -9,6 +9,7 @@ import (
const ( const (
LLGoPackage = "link: $(pkg-config --libs libuv); -luv" LLGoPackage = "link: $(pkg-config --libs libuv); -luv"
LLGoFiles = "$(pkg-config --cflags libuv): _wrap/libuv.c"
) )
// ---------------------------------------------- // ----------------------------------------------
@@ -97,44 +98,13 @@ type Loop struct {
Unused [0]byte Unused [0]byte
} }
type Handle struct {
Unused [96]byte
}
type Stream struct {
Unused [264]byte
}
type Poll struct { type Poll struct {
Unused [0]byte Data c.Pointer
Unused [160]byte
} }
/* Request types. */ /* Request types. */
type Req struct {
Unused [0]byte
}
type GetAddrInfo struct {
Unused [0]byte
}
type GetNameInfo struct {
Unused [0]byte
}
type Shutdown struct {
Unused [0]byte
}
type Write struct {
Unused [192]byte
}
type Connect struct {
Unused [0]byte
}
type Buf struct { type Buf struct {
Base *c.Char Base *c.Char
Len uintptr Len uintptr
@@ -157,24 +127,12 @@ type FreeFunc func(ptr c.Pointer)
// llgo:type C // llgo:type C
type AllocCb func(handle *Handle, suggestedSize uintptr, buf *Buf) type AllocCb func(handle *Handle, suggestedSize uintptr, buf *Buf)
// llgo:type C
type ReadCb func(stream *Stream, nread c.Long, buf *Buf)
// llgo:type C
type WriteCb func(req *Write, status c.Int)
// llgo:type C // llgo:type C
type GetaddrinfoCb func(req *GetAddrInfo, status c.Int, res *net.AddrInfo) type GetaddrinfoCb func(req *GetAddrInfo, status c.Int, res *net.AddrInfo)
// llgo:type C // llgo:type C
type GetnameinfoCb func(req *GetNameInfo, status c.Int, hostname *c.Char, service *c.Char) type GetnameinfoCb func(req *GetNameInfo, status c.Int, hostname *c.Char, service *c.Char)
// llgo:type C
type ConnectionCb func(server *Stream, status c.Int)
// llgo:type C
type ShutdownCb func(req *Shutdown, status c.Int)
// llgo:type C // llgo:type C
type WalkCb func(handle *Handle, arg c.Pointer) type WalkCb func(handle *Handle, arg c.Pointer)
@@ -197,223 +155,88 @@ func ReplaceAllocator(mallocFunc MallocFunc, reallocFunc ReallocFunc, callocFunc
// ---------------------------------------------- // ----------------------------------------------
// llgo:link (*Shutdown).Shutdown C.uv_shutdown
func (shutdown *Shutdown) Shutdown(stream *Stream, shutdownCb ShutdownCb) c.Int {
return 0
}
// ----------------------------------------------
/* Handle related function and method */
// llgo:link (*Handle).Ref C.uv_ref
func (handle *Handle) Ref() {}
// llgo:link (*Handle).Unref C.uv_unref
func (handle *Handle) Unref() {}
// llgo:link (*Handle).HasRef C.uv_has_ref
func (handle *Handle) HasRef() c.Int {
return 0
}
//go:linkname HandleSize C.uv_handle_size
func HandleSize(handleType HandleType) uintptr
// llgo:link (*Handle).GetType C.uv_handle_get_type
func (handle *Handle) GetType() HandleType {
return 0
}
//go:linkname HandleTypeName C.uv_handle_type_name
func HandleTypeName(handleType HandleType) *c.Char
// llgo:link (*Handle).GetData C.uv_handle_get_data
func (handle *Handle) GetData() c.Pointer {
return nil
}
// llgo:link (*Handle).GetLoop C.uv_handle_get_loop
func (handle *Handle) GetLoop() *Loop {
return nil
}
// llgo:link (*Handle).SetData C.uv_handle_set_data
func (handle *Handle) SetData(data c.Pointer) {}
// llgo:link (*Handle).IsActive C.uv_is_active
func (handle *Handle) IsActive() c.Int {
return 0
}
// llgo:link (*Handle).Close C.uv_close
func (handle *Handle) Close(closeCb CloseCb) {}
// llgo:link (*Handle).SendBufferSize C.uv_send_buffer_size
func (handle *Handle) SendBufferSize(value *c.Int) c.Int {
return 0
}
// llgo:link (*Handle).RecvBufferSize C.uv_recv_buffer_size
func (handle *Handle) RecvBufferSize(value *c.Int) c.Int {
return 0
}
// llgo:link (*Handle).Fileno C.uv_fileno
func (handle *Handle) Fileno(fd *OsFd) c.Int {
return 0
}
//go:linkname Pipe C.uv_pipe
func Pipe(fds [2]File, readFlags c.Int, writeFlags c.Int) c.Int {
return 0
}
//go:linkname Socketpair C.uv_socketpair
func Socketpair(_type c.Int, protocol c.Int, socketVector [2]OsSock, flag0 c.Int, flag1 c.Int) c.Int {
return 0
}
// llgo:link (*Handle).IsClosing C.uv_is_closing
func (handle *Handle) IsClosing() c.Int {
return 0
}
// ----------------------------------------------
/* Req related function and method */
//go:linkname ReqSize C.uv_req_size
func ReqSize(reqType ReqType) uintptr
// llgo:link (*Req).GetData C.uv_req_get_data
func (req *Req) GetData() c.Pointer {
return nil
}
// llgo:link (*Req).SetData C.uv_handle_set_data
func (req *Req) SetData(data c.Pointer) {}
// llgo:link (*Req).GetType C.uv_req_get_type
func (req *Req) GetType() ReqType {
return 0
}
//go:linkname TypeName C.uv_req_type_name
func TypeName(reqType ReqType) *c.Char
// ----------------------------------------------
/* Stream related function and method */
// llgo:link (*Stream).GetWriteQueueSize C.uv_stream_get_write_queue_size
func (stream *Stream) GetWriteQueueSize() uintptr {
return 0
}
// llgo:link (*Stream).Listen C.uv_listen
func (stream *Stream) Listen(backlog c.Int, connectionCb ConnectionCb) c.Int {
return 0
}
// llgo:link (*Stream).Accept C.uv_accept
func (server *Stream) Accept(client *Stream) c.Int {
return 0
}
// llgo:link (*Stream).StartRead C.uv_read_start
func (stream *Stream) StartRead(allocCb AllocCb, readCb ReadCb) c.Int {
return 0
}
// llgo:link (*Stream).StopRead C.uv_read_stop
func (stream *Stream) StopRead() c.Int {
return 0
}
// llgo:link (*Write).Write C.uv_write
func (req *Write) Write(stream *Stream, bufs *Buf, nbufs c.Uint, writeCb WriteCb) c.Int {
return 0
}
// llgo:link (*Write).Write2 C.uv_write2
func (req *Write) Write2(stream *Stream, bufs *Buf, nbufs c.Uint, sendStream *Stream, writeCb WriteCb) c.Int {
return 0
}
// llgo:link (*Stream).TryWrite C.uv_try_write
func (stream *Stream) TryWrite(bufs *Buf, nbufs c.Uint) c.Int {
return 0
}
// llgo:link (*Stream).TryWrite2 C.uv_try_write2
func (stream *Stream) TryWrite2(bufs *Buf, nbufs c.Uint, sendStream *Stream) c.Int {
return 0
}
// llgo:link (*Stream).IsReadable C.uv_is_readable
func (stream *Stream) IsReadable() c.Int {
return 0
}
// llgo:link (*Stream).IsWritable C.uv_is_writable
func (stream *Stream) IsWritable() c.Int {
return 0
}
// llgo:link (*Stream).SetBlocking C.uv_stream_set_blocking
func (stream *Stream) SetBlocking(blocking c.Int) c.Int {
return 0
}
// ----------------------------------------------
/* Loop related functions and method. */ /* Loop related functions and method. */
//go:linkname DefaultLoop C.uv_default_loop
func DefaultLoop() *Loop
//go:linkname LoopSize C.uv_loop_size //go:linkname LoopSize C.uv_loop_size
func LoopSize() uintptr func LoopSize() uintptr
//go:linkname Run C.uv_run // llgo:link (*Loop).Run C.uv_run
func Run(loop *Loop, mode RunMode) c.Int func (loop *Loop) Run(mode RunMode) c.Int {
return 0
}
//go:linkname LoopAlive C.uv_loop_alive // llgo:link (*Loop).Alive C.uv_loop_alive
func LoopAlive(loop *Loop) c.Int func (loop *Loop) Alive() c.Int {
return 0
}
//go:linkname LoopClose C.uv_loop_close // void uv_stop(uv_loop_t *loop)
func LoopClose(loop *Loop) c.Int //
// llgo:link (*Loop).Stop C.uv_stop
func (loop *Loop) Stop() {}
//go:linkname LoopConfigure C.uv_loop_configure // llgo:link (*Loop).Close C.uv_loop_close
func LoopConfigure(loop *Loop, option LoopOption, arg c.Int) c.Int func (loop *Loop) Close() c.Int {
return 0
}
//go:linkname LoopDefault C.uv_default_loop // llgo:link (*Loop).Configure C.uv_loop_configure
func LoopDefault() *Loop func (loop *Loop) Configure(option LoopOption, arg c.Int) c.Int {
return 0
}
//go:linkname LoopDelete C.uv_loop_delete // llgo:link LoopDefault C.uv_default_loop
func LoopDelete(loop *Loop) c.Int func LoopDefault() *Loop {
return nil
}
//go:linkname LoopFork C.uv_loop_fork // llgo:link (*Loop).Delete C.uv_loop_delete
func LoopFork(loop *Loop) c.Int func (loop *Loop) Delete() c.Int {
return 0
}
//go:linkname LoopInit C.uv_loop_init // llgo:link (*Loop).Fork C.uv_loop_fork
func LoopInit(loop *Loop) c.Int func (loop *Loop) Fork() c.Int {
return 0
}
//go:linkname LoopNew C.uv_loop_new // llgo:link (*Loop).Init C.uv_loop_init
func LoopNew() *Loop func (loop *Loop) Init() c.Int {
return 0
}
//go:linkname LoopNow C.uv_now // llgo:link LoopNew C.uv_loop_new
func LoopNow(loop *Loop) c.UlongLong func LoopNew() *Loop {
return nil
}
//go:linkname LoopUpdateTime C.uv_update_time // llgo:link (*Loop).Now C.uv_now
func LoopUpdateTime(loop *Loop) func (loop *Loop) Now() c.UlongLong {
return 0
}
//go:linkname LoopBackendFd C.uv_backend_fd // llgo:link (*Loop).UpdateTime C.uv_update_time
func LoopBackendFd(loop *Loop) c.Int func (loop *Loop) UpdateTime() {
// No return value needed for this method
}
//go:linkname LoopBackendTimeout C.uv_backend_timeout // llgo:link (*Loop).BackendFd C.uv_backend_fd
func LoopBackendTimeout(loop *Loop) c.Int func (loop *Loop) BackendFd() c.Int {
return 0
}
//go:linkname LoopWalk C.uv_walk // llgo:link (*Loop).BackendTimeout C.uv_backend_timeout
func LoopWalk(loop *Loop, walkCb WalkCb, arg c.Pointer) func (loop *Loop) BackendTimeout() c.Int {
return 0
}
// llgo:link (*Loop).Walk C.uv_walk
func (loop *Loop) Walk(walkCb WalkCb, arg c.Pointer) {
// No return value needed for this method
}
// ---------------------------------------------- // ----------------------------------------------
@@ -429,28 +252,15 @@ func InitBuf(base *c.Char, len c.Uint) Buf
//go:linkname PollInit C.uv_poll_init //go:linkname PollInit C.uv_poll_init
func PollInit(loop *Loop, handle *Poll, fd OsFd) c.Int func PollInit(loop *Loop, handle *Poll, fd OsFd) c.Int
//go:linkname PollStart C.uv_poll_start
func PollStart(handle *Poll, events c.Int, cb PollCb) c.Int
//go:linkname PollStop C.uv_poll_stop
func PollStop(handle *Poll) c.Int
//go:linkname PollInitSocket C.uv_poll_init_socket //go:linkname PollInitSocket C.uv_poll_init_socket
func PollInitSocket(loop *Loop, handle *Poll, socket c.Int) c.Int func PollInitSocket(loop *Loop, handle *Poll, socket c.Int) c.Int
// ---------------------------------------------- // llgo:link (*Poll).Start C.uv_poll_start
func (handle *Poll) Start(events c.Int, cb PollCb) c.Int {
return 0
}
/* Getaddrinfo related function and method */ // llgo:link (*Poll).Stop C.uv_poll_stop
func (handle *Poll) Stop() c.Int {
//go:linkname Getaddrinfo C.uv_getaddrinfo return 0
func Getaddrinfo(loop *Loop, req *GetAddrInfo, getaddrinfoCb GetaddrinfoCb, node *c.Char, service *c.Char, hints *net.AddrInfo) c.Int }
//go:linkname Freeaddrinfo C.uv_freeaddrinfo
func Freeaddrinfo(addrInfo *net.AddrInfo)
// ----------------------------------------------
/* Getnameinfo related function and method */
//go:linkname Getnameinfo C.uv_getnameinfo
func Getnameinfo(loop *Loop, req *GetNameInfo, getnameinfoCb GetnameinfoCb, addr *net.SockAddr, flags c.Int) c.Int

View File

@@ -65,18 +65,66 @@ type UdpFlags c.Int
/* Handle types. */ /* Handle types. */
type Tcp struct { // TODO(spongehah): Handle
Unused [264]byte type Handle struct {
Data c.Pointer
Unused [88]byte
} }
// TODO(spongehah): Stream
type Stream struct {
Data c.Pointer
Unused [256]byte
}
// TODO(spongehah): Tcp
type Tcp struct {
Data c.Pointer
Unused [256]byte
}
// TODO(spongehah): Udp
type Udp struct { type Udp struct {
Unused [0]byte Unused [224]byte
} }
/* Request types. */ /* Request types. */
// TODO(spongehah): Req
type Req struct {
Unused [64]byte
}
// TODO(spongehah): UdpSend
type UdpSend struct { type UdpSend struct {
Unused [0]byte Unused [320]byte
}
// TODO(spongehah): Write
type Write struct {
Data c.Pointer
Unused [184]byte
}
// TODO(spongehah): Connect
type Connect struct {
Data c.Pointer
Unused [88]byte
}
// TODO(spongehah): GetAddrInfo
type GetAddrInfo struct {
Unused [160]byte
}
// TODO(spongehah): GetNameInfo
type GetNameInfo struct {
Unused [1320]byte
}
// TODO(spongehah): Shutdown
type Shutdown struct {
Unused [80]byte
} }
// ---------------------------------------------- // ----------------------------------------------
@@ -95,6 +143,197 @@ type UdpSendCb func(req *UdpSend, status c.Int)
// llgo:type C // llgo:type C
type UdpRecvCb func(handle *Udp, nread c.Long, buf *Buf, addr *net.SockAddr, flags c.Uint) type UdpRecvCb func(handle *Udp, nread c.Long, buf *Buf, addr *net.SockAddr, flags c.Uint)
// llgo:type C
type ReadCb func(stream *Stream, nread c.Long, buf *Buf)
// llgo:type C
type WriteCb func(req *Write, status c.Int)
// llgo:type C
type ConnectionCb func(server *Stream, status c.Int)
// llgo:type C
type ShutdownCb func(req *Shutdown, status c.Int)
// ----------------------------------------------
/* Handle related function and method */
//go:linkname HandleSize C.uv_handle_size
func HandleSize(handleType HandleType) uintptr
//go:linkname HandleTypeName C.uv_handle_type_name
func HandleTypeName(handleType HandleType) *c.Char
// llgo:link (*Handle).Ref C.uv_ref
func (handle *Handle) Ref() {}
// llgo:link (*Handle).Unref C.uv_unref
func (handle *Handle) Unref() {}
// llgo:link (*Handle).HasRef C.uv_has_ref
func (handle *Handle) HasRef() c.Int {
return 0
}
// llgo:link (*Handle).GetType C.uv_handle_get_type
func (handle *Handle) GetType() HandleType {
return 0
}
// llgo:link (*Handle).GetData C.uv_handle_get_data
func (handle *Handle) GetData() c.Pointer {
return nil
}
// llgo:link (*Handle).GetLoop C.uv_handle_get_loop
func (handle *Handle) GetLoop() *Loop {
return nil
}
// llgo:link (*Handle).SetData C.uv_handle_set_data
func (handle *Handle) SetData(data c.Pointer) {}
// llgo:link (*Handle).IsActive C.uv_is_active
func (handle *Handle) IsActive() c.Int {
return 0
}
// llgo:link (*Handle).Close C.uv_close
func (handle *Handle) Close(closeCb CloseCb) {}
// llgo:link (*Handle).SendBufferSize C.uv_send_buffer_size
func (handle *Handle) SendBufferSize(value *c.Int) c.Int {
return 0
}
// llgo:link (*Handle).RecvBufferSize C.uv_recv_buffer_size
func (handle *Handle) RecvBufferSize(value *c.Int) c.Int {
return 0
}
// llgo:link (*Handle).Fileno C.uv_fileno
func (handle *Handle) Fileno(fd *OsFd) c.Int {
return 0
}
// llgo:link (*Handle).IsClosing C.uv_is_closing
func (handle *Handle) IsClosing() c.Int {
return 0
}
// llgo:link (*Handle).IsReadable C.uv_is_readable
func (handle *Handle) IsReadable() c.Int {
return 0
}
// llgo:link (*Handle).IsWritable C.uv_is_writable
func (handle *Handle) IsWritable() c.Int {
return 0
}
//go:linkname Pipe C.uv_pipe
func Pipe(fds [2]File, readFlags c.Int, writeFlags c.Int) c.Int {
return 0
}
//go:linkname Socketpair C.uv_socketpair
func Socketpair(_type c.Int, protocol c.Int, socketVector [2]OsSock, flag0 c.Int, flag1 c.Int) c.Int {
return 0
}
// ----------------------------------------------
/* Req related function and method */
//go:linkname ReqSize C.uv_req_size
func ReqSize(reqType ReqType) uintptr
//go:linkname TypeName C.uv_req_type_name
func TypeName(reqType ReqType) *c.Char
// llgo:link (*Req).GetData C.uv_req_get_data
func (req *Req) GetData() c.Pointer {
return nil
}
// llgo:link (*Req).SetData C.uv_req_set_data
func (req *Req) SetData(data c.Pointer) {}
// llgo:link (*Req).GetType C.uv_req_get_type
func (req *Req) GetType() ReqType {
return 0
}
// ----------------------------------------------
/* Stream related function and method */
// llgo:link (*Stream).GetWriteQueueSize C.uv_stream_get_write_queue_size
func (stream *Stream) GetWriteQueueSize() uintptr {
return 0
}
// llgo:link (*Stream).Listen C.uv_listen
func (stream *Stream) Listen(backlog c.Int, connectionCb ConnectionCb) c.Int {
return 0
}
// llgo:link (*Stream).Accept C.uv_accept
func (server *Stream) Accept(client *Stream) c.Int {
return 0
}
// llgo:link (*Stream).StartRead C.uv_read_start
func (stream *Stream) StartRead(allocCb AllocCb, readCb ReadCb) c.Int {
return 0
}
// llgo:link (*Stream).StopRead C.uv_read_stop
func (stream *Stream) StopRead() c.Int {
return 0
}
// llgo:link (*Write).Write C.uv_write
func (req *Write) Write(stream *Stream, bufs *Buf, nbufs c.Uint, writeCb WriteCb) c.Int {
return 0
}
// llgo:link (*Write).Write2 C.uv_write2
func (req *Write) Write2(stream *Stream, bufs *Buf, nbufs c.Uint, sendStream *Stream, writeCb WriteCb) c.Int {
return 0
}
// llgo:link (*Stream).TryWrite C.uv_try_write
func (stream *Stream) TryWrite(bufs *Buf, nbufs c.Uint) c.Int {
return 0
}
// llgo:link (*Stream).TryWrite2 C.uv_try_write2
func (stream *Stream) TryWrite2(bufs *Buf, nbufs c.Uint, sendStream *Stream) c.Int {
return 0
}
// llgo:link (*Stream).IsReadable C.uv_is_readable
func (stream *Stream) IsReadable() c.Int {
return 0
}
// llgo:link (*Stream).IsWritable C.uv_is_writable
func (stream *Stream) IsWritable() c.Int {
return 0
}
// llgo:link (*Stream).SetBlocking C.uv_stream_set_blocking
func (stream *Stream) SetBlocking(blocking c.Int) c.Int {
return 0
}
//go:linkname StreamShutdown C.uv_shutdown
func StreamShutdown(shutdown *Shutdown, stream *Stream, shutdownCb ShutdownCb) c.Int {
return 0
}
// ---------------------------------------------- // ----------------------------------------------
/* Tcp related function and method */ /* Tcp related function and method */
@@ -145,6 +384,11 @@ func (tcp *Tcp) CloseReset(closeCb CloseCb) c.Int {
return 0 return 0
} }
// llgo:link (*Tcp).GetIoWatcherFd C.uv_tcp_get_io_watcher_fd
func (tcp *Tcp) GetIoWatcherFd() c.Int {
return 0
}
//go:linkname TcpConnect C.uv_tcp_connect //go:linkname TcpConnect C.uv_tcp_connect
func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int
@@ -218,9 +462,6 @@ func (udp *Udp) SetTTL(ttl c.Int) c.Int {
return 0 return 0
} }
//go:linkname Send C.uv_udp_send
func Send(req *UdpSend, udp *Udp, bufs *Buf, nbufs c.Uint, addr *net.SockAddr, sendCb UdpSendCb) c.Int
// llgo:link (*Udp).TrySend C.uv_udp_try_send // llgo:link (*Udp).TrySend C.uv_udp_try_send
func (udp *Udp) TrySend(bufs *Buf, nbufs c.Uint, addr *net.SockAddr) c.Int { func (udp *Udp) TrySend(bufs *Buf, nbufs c.Uint, addr *net.SockAddr) c.Int {
return 0 return 0
@@ -251,8 +492,13 @@ func (udp *Udp) GetSendQueueCount() uintptr {
return 0 return 0
} }
//go:linkname Send C.uv_udp_send
func Send(req *UdpSend, udp *Udp, bufs *Buf, nbufs c.Uint, addr *net.SockAddr, sendCb UdpSendCb) c.Int
// ---------------------------------------------- // ----------------------------------------------
/* DNS related function and method */
//go:linkname Ip4Addr C.uv_ip4_addr //go:linkname Ip4Addr C.uv_ip4_addr
func Ip4Addr(ip *c.Char, port c.Int, addr *net.SockaddrIn) c.Int func Ip4Addr(ip *c.Char, port c.Int, addr *net.SockaddrIn) c.Int
@@ -273,3 +519,20 @@ func InetNtop(af c.Int, src c.Pointer, dst *c.Char, size uintptr) c.Int
//go:linkname InetPton C.uv_inet_pton //go:linkname InetPton C.uv_inet_pton
func InetPton(af c.Int, src *c.Char, dst c.Pointer) c.Int func InetPton(af c.Int, src *c.Char, dst c.Pointer) c.Int
// ----------------------------------------------
/* Getaddrinfo related function and method */
//go:linkname Getaddrinfo C.uv_getaddrinfo
func Getaddrinfo(loop *Loop, req *GetAddrInfo, getaddrinfoCb GetaddrinfoCb, node *c.Char, service *c.Char, hints *net.AddrInfo) c.Int
//go:linkname Freeaddrinfo C.uv_freeaddrinfo
func Freeaddrinfo(addrInfo *net.AddrInfo)
// ----------------------------------------------
/* Getnameinfo related function and method */
//go:linkname Getnameinfo C.uv_getnameinfo
func Getnameinfo(loop *Loop, req *GetNameInfo, getnameinfoCb GetnameinfoCb, addr *net.SockAddr, flags c.Int) c.Int

View File

@@ -9,7 +9,7 @@ import (
/* Handle types. */ /* Handle types. */
type Signal struct { type Signal struct {
Unused [0]byte Unused [152]byte
} }
// ---------------------------------------------- // ----------------------------------------------
@@ -26,8 +26,17 @@ type SignalCb func(handle *Signal, sigNum c.Int)
//go:linkname SignalInit C.uv_signal_init //go:linkname SignalInit C.uv_signal_init
func SignalInit(loop *Loop, handle *Signal) c.Int func SignalInit(loop *Loop, handle *Signal) c.Int
//go:linkname SignalStart C.uv_signal_start // llgo:link (*Signal).Start C.uv_signal_start
func SignalStart(handle *Signal, cb SignalCb, signum c.Int) c.Int func (handle *Signal) Start(cb SignalCb, signum c.Int) c.Int {
return 0
}
//go:linkname SignalStartOneshot C.uv_signal_start_oneshot // llgo:link (*Signal).StartOneshot C.uv_signal_start_oneshot
func SignalStartOneshot(handle *Signal, cb SignalCb, signum c.Int) c.Int func (handle *Signal) StartOneshot(cb SignalCb, signum c.Int) c.Int {
return 0
}
// llgo:link (*Signal).Stop C.uv_signal_stop
func (handle *Signal) Stop() c.Int {
return 0
}

View File

@@ -10,13 +10,14 @@ import (
/* Handle types. */ /* Handle types. */
// TODO(spongehah): Timer
type Timer struct { type Timer struct {
Unused [0]byte Unused [152]byte
} }
// ---------------------------------------------- // ----------------------------------------------
// llgo:type Cgit // llgo:type C
type TimerCb func(timer *Timer) type TimerCb func(timer *Timer)
// ---------------------------------------------- // ----------------------------------------------
@@ -27,7 +28,7 @@ type TimerCb func(timer *Timer)
func InitTimer(loop *Loop, timer *Timer) c.Int func InitTimer(loop *Loop, timer *Timer) c.Int
// llgo:link (*Timer).Start C.uv_timer_start // llgo:link (*Timer).Start C.uv_timer_start
func (timer *Timer) Start(cb TimerCb, timeout uint64, repeat uint64) c.Int { func (timer *Timer) Start(cb TimerCb, timeoutMs uint64, repeat uint64) c.Int {
return 0 return 0
} }

View File

@@ -0,0 +1,72 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func countdownContinue(L *lua.State, status c.Int, ctx lua.KContext) c.Int {
return countdown(L)
}
func countdown(L *lua.State) c.Int {
arg := L.Tointeger(lua.Upvalueindex(1))
c.Printf(c.Str("resume called with %d\n"), arg)
if arg > 0 {
L.Pushinteger(arg - 1)
L.Replace(lua.Upvalueindex(1))
L.Pushinteger(arg)
return L.Yieldk(1, c.Pointer(uintptr(0)), countdownContinue)
}
return 0
}
func createCountdown(L *lua.State) c.Int {
max := L.Checkinteger(1)
L.Pushinteger(max)
L.Pushcclosure(countdown, 1)
return 1
}
func main() {
L := lua.Newstate()
L.Openlibs()
defer L.Close()
L.Register(c.Str("create_countdown"), createCountdown)
testcode := c.Str(`
local countdown = create_countdown(5)
local co = coroutine.create(countdown)
while true do
local success, value = coroutine.resume(co)
if not success then
print('Error:', value)
break
end
if value == nil then break end
print('Lua received:', value)
end
print('Countdown finished');
`)
if L.Dostring(testcode) != lua.OK {
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
}
L.Openlibs()
}
/* Expected output:
resume called with 5
Lua received: 5
resume called with 4
Lua received: 4
resume called with 3
Lua received: 3
resume called with 2
Lua received: 2
resume called with 1
Lua received: 1
resume called with 0
Countdown finished
*/

View File

@@ -0,0 +1,64 @@
package main
import (
"os"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func triggerError(L *lua.State) c.Int {
L.Pushstring(c.Str("This is an error triggered"))
return L.Error()
}
func triggerFormatError(L *lua.State) c.Int {
return L.LError(c.Str("This is an error code:(%d)"), 42)
}
func customPanic(L *lua.State) c.Int {
msg := L.Tostring(-1)
c.Printf(c.Str("Pani'c: %s\n"), msg)
os.Exit(1)
return 0
}
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
L.Atpanic(customPanic)
L.Register(c.Str("trigger_error"), triggerError)
L.Register(c.Str("trigger_format_error"), triggerFormatError)
c.Printf(c.Str("1. error (protected):\n"))
L.Getglobal(c.Str("trigger_error"))
if L.Pcall(0, 0, 0) != lua.OK {
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
L.Pop(1)
}
c.Printf(c.Str("2. format_error (protected):\n"))
L.Getglobal(c.Str("trigger_format_error"))
if L.Pcall(0, 0, 0) != lua.OK {
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
L.Pop(1)
}
c.Printf(c.Str("3. Unprotected call (panic):\n"))
L.Getglobal(c.Str("trigger_error"))
// This will trigger unprotected panic and catch by customPanic
L.Call(0, 0)
}
/* Expected output:
1. error (protected):
Error: This is an error triggered
2. format_error (protected):
Error: This is an error code:(42)
3. Unprotected call (panic):
Panic: This is an error triggered
*/

View File

@@ -0,0 +1,68 @@
package main
import (
"os"
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func reader(L *lua.State, data c.Pointer, size *c.Ulong) *c.Char {
file := (*os.File)(data)
fileInfo, err := file.Stat()
if err != nil {
return nil
}
fileSize := fileInfo.Size()
buffer := make([]byte, fileSize)
bytesRead, err := file.Read(buffer)
if err != nil {
return nil
}
*size = c.Ulong(bytesRead)
if bytesRead > 0 {
return (*c.Char)(unsafe.Pointer(unsafe.SliceData(buffer)))
}
return nil
}
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
file, err := os.Open("../llgofunc.luac")
if err != nil {
c.Printf(c.Str("Failed to open file for reading\n"))
return
}
defer file.Close()
if L.Load(reader, c.Pointer(file), c.Str("greet"), nil) != lua.OK {
c.Printf(c.Str("Failed to dump Lua function\n"))
}
c.Printf(c.Str("Stack size before call: %d\n"), L.Gettop())
c.Printf(c.Str("Top element type after call: %s\n"), L.Typename(L.Type(-1)))
L.Pushstring(c.Str("World"))
if L.Pcall(1, 1, 0) != lua.OK {
c.Printf(c.Str("Failed to call function: %s\n"))
}
if L.Isstring(-1) != 0 {
c.Printf(c.Str("Result: %s\n"), L.Tostring(-1))
}
}
/* Expected output:
Stack size before call: 1
Top element type after call: function
Result: Hello, World!
*/

View File

@@ -0,0 +1,56 @@
package main
import (
"os"
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func writer(L *lua.State, p c.Pointer, sz c.Ulong, ud c.Pointer) c.Int {
file := (*os.File)(ud)
data := unsafe.Slice((*byte)(p), sz)
n, err := file.Write(data)
if err != nil || n != int(sz) {
return 1
}
return lua.OK
}
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
if res := L.Loadstring(c.Str(`
function greet(name)
return 'Hello, ' .. name .. '!'
end
return greet
`)); res != lua.OK {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
if res := L.Pcall(0, 1, 0); res != lua.OK {
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
}
if !L.Isfunction(-1) {
c.Printf(c.Str("Expected a function, but got %s"), L.Typename(L.Type(-1)))
}
file, err := os.Create("../llgofunc.luac")
if err != nil {
c.Printf(c.Str("Failed to open file for writing\n"))
return
}
defer file.Close()
if L.Dump(writer, c.Pointer(file), 0) != lua.OK {
c.Printf(c.Str("Failed to dump Lua function\n"))
}
}

View File

@@ -0,0 +1,44 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func pushThread(state *lua.State, name string) {
isMain := state.Pushthread()
if isMain != 0 {
c.Printf(c.Str("%s Thread is main\n"), c.AllocaCStr(name))
} else {
c.Printf(c.Str("%s Thread is not main\n"), c.AllocaCStr(name))
}
}
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
pushThread(L, "main")
L.Pop(1)
newThread := L.Newthread()
pushThread(newThread, "newthread")
state := newThread.Tothread(-1)
if newThread == state {
c.Printf(c.Str("Successfully retrieved thread from stack\n"))
}
status := state.Status()
c.Printf(c.Str("New thread status: %d"), status)
if L.Closethread(newThread) != lua.OK {
println("Failed to close thread status %d", state.Status())
}
}
/* Expected output:
main Thread is main
newthread Thread is not main
Successfully retrieved thread from stack
New thread status: 0
*/

View File

@@ -0,0 +1,43 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
type lightdata struct {
value int
}
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
data := L.Newuserdata(unsafe.Sizeof(0))
*((*int)(data)) = 42
L.Setglobal(c.Str("data"))
light := &lightdata{value: 24}
L.Pushlightuserdata(unsafe.Pointer(light))
L.Setglobal(c.Str("lightdata"))
L.Getglobal(c.Str("data"))
if L.Isuserdata(-1) != 0 {
data := L.Touserdata(-1)
c.Printf(c.Str("userdata %d\n"), *(*int)(data))
}
L.Getglobal(c.Str("lightdata"))
if L.Islightuserdata(-1) {
light := (*lightdata)(L.Touserdata(-1))
c.Printf(c.Str("lightdata %d\n"), light.value)
}
}
/* Expected output:
userdata 42
lightdata 24
*/

View File

@@ -14,6 +14,15 @@ import (
// /* key, in the registry, for table of preloaded loaders */ // /* key, in the registry, for table of preloaded loaders */
// llgo:link (*State).Checkinteger C.luaL_checkinteger
func (L *State) Checkinteger(arg c.Int) Integer { return 0 }
// llgo:link (*State).Checknumber C.luaL_checknumber
func (L *State) Checknumber(arg c.Int) Number { return 0 }
// llgo:link (*State).LError C.luaL_error
func (L *State) LError(format *c.Char, __llgo_va_list ...any) c.Int { return 0 }
// /* predefined references */ // /* predefined references */
// llgo:link (*State).Loadfilex C.luaL_loadfilex // llgo:link (*State).Loadfilex C.luaL_loadfilex

View File

@@ -23,6 +23,14 @@ const (
// ** space after that to help overflow detection) // ** space after that to help overflow detection)
// */ // */
const (
REGISTRYINDEX = -MAXSTACK - 1000
)
func Upvalueindex(i c.Int) c.Int {
return c.Int(REGISTRYINDEX) - i
}
// /* thread status */ // /* thread status */
const ( const (
OK = 0 OK = 0
@@ -70,8 +78,6 @@ const (
type Number = c.Double type Number = c.Double
// /* type for integer functions */ // /* type for integer functions */
// TODO(zzy):consider dynamic size
type Integer = c.Int type Integer = c.Int
// /* unsigned integer type */ // /* unsigned integer type */
@@ -91,15 +97,18 @@ type CFunction func(L *State) c.Int
// ** Type for continuation functions // ** Type for continuation functions
// */ // */
// TODO(zzy): KFunction does not currently support // llgo:type C
type KFunction func(L *State, status c.Int, ctx KContext) c.Int type KFunction func(L *State, status c.Int, ctx KContext) c.Int
// /* // /*
// ** Type for functions that read/write blocks when loading/dumping Lua chunks // ** Type for functions that read/write blocks when loading/dumping Lua chunks
// */ // */
// typedef const char * (*lua_Reader) (State *L, void *ud, size_t *sz); // llgo:type C
// typedef int (*lua_Writer) (State *L, const void *p, size_t sz, void *ud); type Reader func(L *State, ud c.Pointer, sz *c.Ulong) *c.Char
// llgo:type C
type Writer func(L *State, p c.Pointer, sz c.Ulong, ud c.Pointer) c.Int
// /* // /*
// ** Type for memory-allocation functions // ** Type for memory-allocation functions
@@ -150,10 +159,17 @@ func (L *State) Close() {}
// llgo:link (*State).Newthread C.lua_newthread // llgo:link (*State).Newthread C.lua_newthread
func (L *State) Newthread() *State { return nil } func (L *State) Newthread() *State { return nil }
// int (lua_closethread) (State *L, State *from); // llgo:link (*State).Closethread C.lua_closethread
// int (lua_resetthread) (State *L); /* Deprecated! */ func (L *State) Closethread(from *State) c.Int { return 0 }
// lua_CFunction (lua_atpanic) (State *L, lua_CFunction panicf);
// lua_Number (lua_version) (State *L); // llgo:link (*State).Resetthread C.lua_resetthread
func (L *State) Resetthread(from *State) c.Int { return 0 }
// llgo:link (*State).Atpanic C.lua_atpanic
func (L *State) Atpanic(panicf CFunction) CFunction { return nil }
// llgo:link (*State).Version C.lua_version
func (L *State) Version() Number { return 0 }
// /* // /*
// ** basic stack manipulation // ** basic stack manipulation
@@ -199,7 +215,8 @@ func (L *State) Iscfunction(idx c.Int) c.Int { return 0 }
// llgo:link (*State).Isinteger C.lua_isinteger // llgo:link (*State).Isinteger C.lua_isinteger
func (L *State) Isinteger(idx c.Int) c.Int { return 0 } func (L *State) Isinteger(idx c.Int) c.Int { return 0 }
// LUA_API int (lua_isuserdata) (State *L, int idx); // llgo:link (*State).Isuserdata C.lua_isuserdata
func (L *State) Isuserdata(idx c.Int) c.Int { return 0 }
// llgo:link (*State).Type C.lua_type // llgo:link (*State).Type C.lua_type
func (L *State) Type(idx c.Int) c.Int { return 0 } func (L *State) Type(idx c.Int) c.Int { return 0 }
@@ -224,8 +241,12 @@ func (L *State) Tolstring(idx c.Int, len *c.Ulong) *c.Char { return nil }
// llgo:link (*State).Tocfunction C.lua_tocfunction // llgo:link (*State).Tocfunction C.lua_tocfunction
func (L *State) Tocfunction(idx c.Int) CFunction { return nil } func (L *State) Tocfunction(idx c.Int) CFunction { return nil }
// LUA_API void *(lua_touserdata) (State *L, int idx); // llgo:link (*State).Touserdata C.lua_touserdata
// LUA_API State *(lua_tothread) (State *L, int idx); func (L *State) Touserdata(idx c.Int) c.Pointer { return nil }
// llgo:link (*State).Tothread C.lua_tothread
func (L *State) Tothread(idx c.Int) *State { return nil }
// LUA_API const void *(lua_topointer) (State *L, int idx); // LUA_API const void *(lua_topointer) (State *L, int idx);
// /* // /*
@@ -259,8 +280,11 @@ func (L *State) Pushcclosure(fn CFunction, n c.Int) {}
// llgo:link (*State).Pushboolean C.lua_pushboolean // llgo:link (*State).Pushboolean C.lua_pushboolean
func (L *State) Pushboolean(b c.Int) {} func (L *State) Pushboolean(b c.Int) {}
//void (lua_pushlightuserdata) (State *L, void *p); // llgo:link (*State).Pushlightuserdata C.lua_pushlightuserdata
//int (lua_pushthread) (State *L); func (L *State) Pushlightuserdata(p c.Pointer) {}
// llgo:link (*State).Pushthread C.lua_pushthread
func (L *State) Pushthread() c.Int { return 0 }
// /* // /*
// ** get functions (Lua -> stack) // ** get functions (Lua -> stack)
@@ -283,7 +307,8 @@ func (L *State) Getfield(idx c.Int, k *c.Char) c.Int { return 0 }
// llgo:link (*State).Createtable C.lua_createtable // llgo:link (*State).Createtable C.lua_createtable
func (L *State) Createtable(narr c.Int, nrec c.Int) {} func (L *State) Createtable(narr c.Int, nrec c.Int) {}
// LUA_API void *(lua_newuserdatauv) (State *L, size_t sz, int nuvalue); // llgo:link (*State).Newuserdatauv C.lua_newuserdatauv
func (L *State) Newuserdatauv(sz uintptr, nuvalue c.Int) c.Pointer { return nil }
// llgo:link (*State).Getmetatable C.lua_getmetatable // llgo:link (*State).Getmetatable C.lua_getmetatable
func (L *State) Getmetatable(objindex c.Int) c.Int { return 0 } func (L *State) Getmetatable(objindex c.Int) c.Int { return 0 }
@@ -335,9 +360,11 @@ func (L *State) Pcall(nargs c.Int, nresults c.Int, errfunc c.Int) c.Int {
return L.Pcallk(nargs, nresults, errfunc, nil, nil) return L.Pcallk(nargs, nresults, errfunc, nil, nil)
} }
// int (lua_load) (State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); // llgo:link (*State).Load C.lua_load
func (L *State) Load(reader Reader, dt c.Pointer, chunkname *c.Char, mode *c.Char) c.Int { return 0 }
// int (lua_dump) (State *L, lua_Writer writer, void *data, int strip); // llgo:link (*State).Dump C.lua_dump
func (L *State) Dump(writer Writer, data c.Pointer, strip c.Int) c.Int { return 0 }
// /* // /*
// ** coroutine functions // ** coroutine functions
@@ -389,7 +416,8 @@ const (
// llgo:link (*State).Next C.lua_next // llgo:link (*State).Next C.lua_next
func (L *State) Next(idx c.Int) c.Int { return 0 } func (L *State) Next(idx c.Int) c.Int { return 0 }
// LUA_API int (lua_error) (State *L); // llgo:link (*State).Error C.lua_error
func (L *State) Error() c.Int { return 0 }
// LUA_API void (lua_concat) (State *L, int n); // LUA_API void (lua_concat) (State *L, int n);
// LUA_API void (lua_len) (State *L, int idx); // LUA_API void (lua_len) (State *L, int idx);
@@ -416,7 +444,10 @@ 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) Pop(n c.Int) { L.Settop(-(n) - 1) }
func (L *State) Newtable() { L.Createtable(0, 0) } func (L *State) Newtable() { L.Createtable(0, 0) }
// #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) func (L *State) Register(name *c.Char, f CFunction) {
L.Pushcfunction(f)
L.Setglobal(name)
}
func (L *State) Pushcfunction(f CFunction) { L.Pushcclosure(f, 0) } func (L *State) Pushcfunction(f CFunction) { L.Pushcclosure(f, 0) }
func (L *State) Isfunction(n c.Int) bool { return L.Type(n) == c.Int(FUNCTION) } func (L *State) Isfunction(n c.Int) bool { return L.Type(n) == c.Int(FUNCTION) }
@@ -431,9 +462,19 @@ func (L *State) Isnoneornil(n c.Int) bool { return L.Type(n) <= 0 }
// #define lua_pushliteral(L, s) lua_pushstring(L, "" s) // #define lua_pushliteral(L, s) lua_pushstring(L, "" s)
// #define lua_pushglobaltable(L) ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)) // #define lua_pushglobaltable(L) ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
// #define lua_insert(L,idx) lua_rotate(L, (idx), 1) func (L *State) Insert(idx c.Int) {
// #define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) L.Rotate(idx, 1)
// #define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1)) }
func (L *State) Remove(idx c.Int) {
L.Rotate(idx, -1)
L.Pop(1)
}
func (L *State) Replace(idx c.Int) {
L.Copy(-1, idx)
L.Pop(1)
}
// /* }============================================================== */ // /* }============================================================== */
@@ -443,7 +484,10 @@ func (L *State) Isnoneornil(n c.Int) bool { return L.Type(n) <= 0 }
// ** =============================================================== // ** ===============================================================
// */ // */
// #define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1) func (L *State) Newuserdata(sz uintptr) c.Pointer {
return L.Newuserdatauv(sz, 1)
}
// #define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1) // #define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1)
// #define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1) // #define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1)
@@ -471,10 +515,6 @@ const (
// /* // /*
// ** Event masks // ** 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 ( const (
MASKCALL = 1 << HOOKCOUNT MASKCALL = 1 << HOOKCOUNT

21
c/lua/luaconf.go Normal file
View File

@@ -0,0 +1,21 @@
package lua
/*
** {==================================================================
** Macros that affect the API and must be stable (that is, must be the
** same when you compile Lua and when you compile code that links to
** Lua).
** =====================================================================
*/
/*
@@ LUAI_MAXSTACK limits the size of the Lua stack.
** CHANGE it if you need a different limit. This limit is arbitrary;
** its only purpose is to stop Lua from consuming unlimited stack
** space (and to reserve some numbers for pseudo-indices).
** (It must fit into max(size_t)/32 and max(int)/2.)
*/
const (
MAXSTACK = 1000000
)

View File

@@ -17,7 +17,7 @@
package net package net
import ( import (
_ "unsafe" "unsafe"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
) )
@@ -97,6 +97,13 @@ const (
EAI_OVERFLOW /* argument buffer overflow */ EAI_OVERFLOW /* argument buffer overflow */
) )
const (
ALIGNSIZE = unsafe.Sizeof(c.LongLong(0))
MAXSIZE = 128
PAD1_SIZE = ALIGNSIZE - unsafe.Sizeof(byte(0)) - unsafe.Sizeof(byte(0))
PAD2_SIZE = MAXSIZE - unsafe.Sizeof(byte(0)) - unsafe.Sizeof(byte(0)) - PAD1_SIZE - ALIGNSIZE
)
// (TODO) merge to inet // (TODO) merge to inet
const INET_ADDRSTRLEN = 16 const INET_ADDRSTRLEN = 16
@@ -117,6 +124,14 @@ type SockaddrIn6 struct {
ScopeId c.Uint ScopeId c.Uint
} }
type SockaddrStorage struct {
Len uint8
Family uint8
pad1 [PAD1_SIZE]c.Char
align c.LongLong
pad2 [PAD2_SIZE]c.Char
}
type InAddr struct { type InAddr struct {
Addr c.Uint Addr c.Uint
} }
@@ -171,6 +186,21 @@ func Send(c.Int, c.Pointer, uintptr, c.Int) c.Long
//go:linkname Recv C.recv //go:linkname Recv C.recv
func Recv(c.Int, c.Pointer, uintptr, c.Int) c.Long func Recv(c.Int, c.Pointer, uintptr, c.Int) c.Long
//go:linkname SetSockOpt C.setsockopt
func SetSockOpt(socket c.Int, level c.Int, optionName c.Int, optionValue c.Pointer, sockLen c.Uint) c.Int
//go:linkname Ntohs C.ntohs
func Ntohs(x uint16) uint16
//go:linkname Htons C.htons
func Htons(x uint16) uint16
//go:linkname Ntohl C.ntohl
func Ntohl(x c.Uint) c.Uint
//go:linkname Htonl C.htonl
func Htonl(x c.Uint) c.Uint
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
type AddrInfo struct { type AddrInfo struct {
@@ -191,13 +221,3 @@ func Getaddrinfo(host *c.Char, port *c.Char, addrInfo *AddrInfo, result **AddrIn
func Freeaddrinfo(addrInfo *AddrInfo) c.Int func Freeaddrinfo(addrInfo *AddrInfo) c.Int
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
func swapInt16(data uint16) uint16 {
return (data << 8) | (data >> 8)
}
func Htons(x uint16) uint16 {
return swapInt16(x)
}
// -----------------------------------------------------------------------------

View File

@@ -0,0 +1,44 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/openssl"
)
func newInt(n openssl.BN_ULONG) *openssl.BIGNUM {
ret := openssl.BNNew()
ret.SetWord(n)
return ret
}
func main() {
ctx := openssl.BN_CTXNew()
defer ctx.Free()
// Initialize two big ints with the first two numbers in the sequence.
a := newInt(0)
b := newInt(1)
defer a.Free()
defer b.Free()
// Initialize limit as 10^99, the smallest integer with 100 digits.
v10, v99 := newInt(10), newInt(99)
defer v10.Free()
defer v99.Free()
limit := openssl.BNNew()
defer limit.Free()
limit.Exp(v10, v99, ctx)
// Loop while a is smaller than 1e100.
for a.Cmp(limit) < 0 {
// Compute the next Fibonacci number, storing it in a.
a.Add(a, b)
// Swap a and b so that b is the next number in the sequence.
a, b = b, a
}
cstr := a.CStr()
c.Printf(c.Str("%s\n"), cstr) // 100-digit Fibonacci number
openssl.FreeCStr(cstr)
}

View File

@@ -0,0 +1,40 @@
package main
import (
"fmt"
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/openssl"
)
func main() {
str := "Hello, World!"
key := "123456"
var lenKey = len(key)
var digest = make([]byte, openssl.EVP_MAX_MD_SIZE)
var digestLen c.Uint
ctx := openssl.NewHMAC_CTX()
if ctx == nil {
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error creating HMAC_CTX"))
return
}
defer ctx.Free()
var ret c.Int = ctx.InitEx(unsafe.Pointer(unsafe.StringData(key)), c.Int(lenKey), openssl.EVP_sha256(), nil)
if ret == 0 {
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error initializing HMAC_CTX"))
return
}
ret = ctx.UpdateString(str)
if ret == 0 {
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error updating HMAC_CTX"))
return
}
ret = ctx.Final(unsafe.SliceData(digest), &digestLen)
if ret == 0 {
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error finalizing HMAC_CTX"))
return
}
fmt.Printf("HMAC:%x\n", digest[:digestLen])
}

View File

@@ -0,0 +1,17 @@
package main
import (
"fmt"
"github.com/goplus/llgo/c/openssl"
)
func main() {
b := make([]byte, 10)
openssl.RANDBytes(b)
fmt.Printf("%x\n", b)
openssl.RANDPrivBytes(b)
fmt.Printf("%x\n", b)
}

View File

@@ -0,0 +1,5 @@
#include <openssl/crypto.h>
void opensslFree(void *ptr) {
OPENSSL_free(ptr);
}

61
c/openssl/bio.go Normal file
View File

@@ -0,0 +1,61 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
type BIO struct {
Unused [0]byte
}
// BIO *BIO_new_mem_buf(const void *buf, int len);
//
//go:linkname BIONewMemBuf C.BIO_new_mem_buf
func BIONewMemBuf(buf unsafe.Pointer, len c.Int) *BIO
// int BIO_free(BIO *a);
//
// llgo:link (*BIO).Free C.BIO_free
func (*BIO) Free() c.Int { return 0 }
// int BIO_up_ref(BIO *a);
//
// llgo:link (*BIO).UpRef C.BIO_up_ref
func (*BIO) UpRef() c.Int { return 0 }
// int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes);
//
// llgo:link (*BIO).ReadEx C.BIO_read_ex
func (*BIO) ReadEx(data unsafe.Pointer, dlen uintptr, readbytes *uintptr) c.Int { return 0 }
// int BIO_write(BIO *b, const void *data, int dlen);
//
// llgo:link (*BIO).Write C.BIO_write
func (*BIO) Write(data unsafe.Pointer, dlen c.Int) c.Int { return 0 }
// int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written);
//
// llgo:link (*BIO).WriteEx C.BIO_write_ex
func (*BIO) WriteEx(data unsafe.Pointer, dlen uintptr, written *uintptr) c.Int { return 0 }
// -----------------------------------------------------------------------------

409
c/openssl/bn.go Normal file
View File

@@ -0,0 +1,409 @@
/*
* 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 openssl
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
type BN_ULONG = uint64
// -----------------------------------------------------------------------------
type BN_CTX struct {
Unused [0]byte
}
// BN_CTX *BN_CTX_new(void);
//
//go:linkname BN_CTXNew C.BN_CTX_new
func BN_CTXNew() *BN_CTX
// BN_CTX *BN_CTX_secure_new(void);
//
//go:linkname BN_CTXSecureNew C.BN_CTX_secure_new
func BN_CTXSecureNew() *BN_CTX
// BN_CTX *BN_CTX_new_ex(OSSL_LIB_CTX *ctx);
// BN_CTX *BN_CTX_secure_new_ex(OSSL_LIB_CTX *ctx);
// void BN_CTX_free(BN_CTX *c);
//
// llgo:link (*BN_CTX).Free C.BN_CTX_free
func (*BN_CTX) Free() {}
// void BN_CTX_start(BN_CTX *ctx);
//
// llgo:link (*BN_CTX).Start C.BN_CTX_start
func (*BN_CTX) Start() {}
// BIGNUM *BN_CTX_get(BN_CTX *ctx);
//
// llgo:link (*BN_CTX).Get C.BN_CTX_get
func (*BN_CTX) Get() *BIGNUM { return nil }
// void BN_CTX_end(BN_CTX *ctx);
//
// llgo:link (*BN_CTX).End C.BN_CTX_end
func (*BN_CTX) End() {}
// -----------------------------------------------------------------------------
type BIGNUM struct {
Unused [0]byte
}
// BIGNUM *BN_new(void);
//
//go:linkname BNNew C.BN_new
func BNNew() *BIGNUM
// BIGNUM *BN_secure_new(void);
//
//go:linkname BNSecureNew C.BN_secure_new
func BNSecureNew() *BIGNUM
// void BN_free(BIGNUM *a);
//
// llgo:link (*BIGNUM).Free C.BN_free
func (*BIGNUM) Free() {}
// void BN_clear_free(BIGNUM *a);
//
// llgo:link (*BIGNUM).ClearFree C.BN_clear_free
func (*BIGNUM) ClearFree() {}
// void BN_clear(BIGNUM *a);
//
// llgo:link (*BIGNUM).Clear C.BN_clear
func (*BIGNUM) Clear() {}
// BIGNUM *BN_dup(const BIGNUM *a);
//
// llgo:link (*BIGNUM).Dup C.BN_dup
func (*BIGNUM) Dup() *BIGNUM { return nil }
// BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Copy C.BN_copy
func (*BIGNUM) Copy(b *BIGNUM) *BIGNUM { return nil }
// void BN_swap(BIGNUM *a, BIGNUM *b);
//
// llgo:link (*BIGNUM).Swap C.BN_swap
func (*BIGNUM) Swap(b *BIGNUM) {}
// int BN_is_zero(const BIGNUM *a);
//
// llgo:link (*BIGNUM).IsZero C.BN_is_zero
func (*BIGNUM) IsZero() c.Int { return 0 }
// void BN_zero_ex(BIGNUM *a);
//
// llgo:link (*BIGNUM).SetZero C.BN_zero_ex
func (*BIGNUM) SetZero() {}
// int BN_is_one(const BIGNUM *a);
//
// llgo:link (*BIGNUM).IsOne C.BN_is_one
func (*BIGNUM) IsOne() c.Int { return 0 }
// int BN_is_odd(const BIGNUM *a);
//
// llgo:link (*BIGNUM).IsOdd C.BN_is_odd
func (*BIGNUM) IsOdd() c.Int { return 0 }
// int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w);
//
// llgo:link (*BIGNUM).AbsIsWord C.BN_abs_is_word
func (*BIGNUM) AbsIsWord(w BN_ULONG) c.Int { return 0 }
// int BN_is_word(const BIGNUM *a, const BN_ULONG w);
//
// llgo:link (*BIGNUM).IsWord C.BN_is_word
func (*BIGNUM) IsWord(w BN_ULONG) c.Int { return 0 }
// int BN_set_word(BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).SetWord C.BN_set_word
func (*BIGNUM) SetWord(w BN_ULONG) c.Int { return 0 }
// BN_ULONG BN_get_word(const BIGNUM *a);
//
// llgo:link (*BIGNUM).GetWord C.BN_get_word
func (*BIGNUM) GetWord() BN_ULONG { return 0 }
// BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).ModWord C.BN_mod_word
func (*BIGNUM) ModWord(w BN_ULONG) BN_ULONG { return 0 }
// BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).DivWord C.BN_div_word
func (*BIGNUM) DivWord(w BN_ULONG) BN_ULONG { return 0 }
// int BN_mul_word(BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).MulWord C.BN_mul_word
func (*BIGNUM) MulWord(w BN_ULONG) c.Int { return 0 }
// int BN_add_word(BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).AddWord C.BN_add_word
func (*BIGNUM) AddWord(w BN_ULONG) c.Int { return 0 }
// int BN_sub_word(BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).SubWord C.BN_sub_word
func (*BIGNUM) SubWord(w BN_ULONG) c.Int { return 0 }
// char *BN_bn2hex(const BIGNUM *a);
//
// llgo:link (*BIGNUM).Bn2hex C.BN_bn2hex
func (*BIGNUM) Bn2hex() *c.Char { return nil }
// char *BN_bn2dec(const BIGNUM *a);
//
// llgo:link (*BIGNUM).Bn2dec C.BN_bn2dec
func (*BIGNUM) Bn2dec() *c.Char { return nil }
// llgo:link (*BIGNUM).CStr C.BN_bn2dec
func (*BIGNUM) CStr() *c.Char { return nil }
// int BN_hex2bn(BIGNUM **a, const char *str);
//
//go:linkname BNHex2bn C.BN_hex2bn
func BNHex2bn(a **BIGNUM, str *c.Char) c.Int
// int BN_dec2bn(BIGNUM **a, const char *str);
//
//go:linkname BNDec2bn C.BN_dec2bn
func BNDec2bn(a **BIGNUM, str *c.Char) c.Int
// int BN_asc2bn(BIGNUM **a, const char *str);
//
//go:linkname BNAsc2bn C.BN_asc2bn
func BNAsc2bn(a **BIGNUM, str *c.Char) c.Int
// BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNBin2bn C.BN_bin2bn
func BNBin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNSignedBin2bn C.BN_signed_bin2bn
func BNSignedBin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// int BN_bn2bin(const BIGNUM *a, unsigned char *to);
//
// llgo:link (*BIGNUM).Bn2bin C.BN_bn2bin
func (bn *BIGNUM) Bn2bin(to *byte) c.Int { return 0 }
// int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).Bn2binpad C.BN_bn2binpad
func (bn *BIGNUM) Bn2binpad(to *byte, tolen c.Int) c.Int { return 0 }
// int BN_signed_bn2bin(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).SignedBn2bin C.BN_signed_bn2bin
func (bn *BIGNUM) SignedBn2bin(to *byte, tolen c.Int) c.Int { return 0 }
// BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNLebin2bn C.BN_lebin2bn
func BNLebin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// BIGNUM *BN_signed_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNSignedLebin2bn C.BN_signed_lebin2bn
func BNSignedLebin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).Bn2lebinpad C.BN_bn2lebinpad
func (bn *BIGNUM) Bn2lebinpad(to *byte, tolen c.Int) c.Int { return 0 }
// int BN_signed_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).SignedBn2lebin C.BN_signed_bn2lebin
func (bn *BIGNUM) SignedBn2lebin(to *byte, tolen c.Int) c.Int { return 0 }
// BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNNative2bn C.BN_native2bn
func BNNative2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// BIGNUM *BN_signed_native2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNSignedNative2bn C.BN_signed_native2bn
func BNSignedNative2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).Bn2nativepad C.BN_bn2nativepad
func (bn *BIGNUM) Bn2nativepad(to *byte, tolen c.Int) c.Int { return 0 }
// int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).SignedBn2native C.BN_signed_bn2native
func (bn *BIGNUM) SignedBn2native(to *byte, tolen c.Int) c.Int { return 0 }
// BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNMpi2bn C.BN_mpi2bn
func BNMpi2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
//
// llgo:link (*BIGNUM).Bn2mpi C.BN_bn2mpi
func (bn *BIGNUM) Bn2mpi(to *byte) c.Int { return 0 }
// int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Sub C.BN_sub
func (*BIGNUM) Sub(a, b *BIGNUM) c.Int { return 0 }
// int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Add C.BN_add
func (*BIGNUM) Add(a, b *BIGNUM) c.Int { return 0 }
// int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Usub C.BN_usub
func (*BIGNUM) Usub(a, b *BIGNUM) c.Int { return 0 }
// int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Uadd C.BN_uadd
func (*BIGNUM) Uadd(a, b *BIGNUM) c.Int { return 0 }
// int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Mul C.BN_mul
func (*BIGNUM) Mul(r, a, b *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Sqr C.BN_sqr
func (*BIGNUM) Sqr(r, a *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
/** BN_set_negative sets sign of a BIGNUM
* \param b pointer to the BIGNUM object
* \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise
*/
// void BN_set_negative(BIGNUM *b, int n);
//
// llgo:link (*BIGNUM).SetNegative C.BN_set_negative
func (*BIGNUM) SetNegative(n c.Int) {}
/** BN_is_negative returns 1 if the BIGNUM is negative
* \param b pointer to the BIGNUM object
* \return 1 if a < 0 and 0 otherwise
*/
// int BN_is_negative(const BIGNUM *b);
//
// llgo:link (*BIGNUM).IsNegative C.BN_is_negative
func (*BIGNUM) IsNegative() c.Int { return 0 }
// int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Div C.BN_div
func (*BIGNUM) Div(rem, m, d *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Nnmod C.BN_nnmod
func (*BIGNUM) Nnmod(r, m, d *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_cmp(const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Cmp C.BN_cmp
func (*BIGNUM) Cmp(b *BIGNUM) c.Int { return 0 }
// int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Ucmp C.BN_ucmp
func (*BIGNUM) Ucmp(b *BIGNUM) c.Int { return 0 }
// int BN_is_bit_set(const BIGNUM *a, int n);
//
// llgo:link (*BIGNUM).IsBitSet C.BN_is_bit_set
func (*BIGNUM) IsBitSet(n c.Int) c.Int { return 0 }
// int BN_set_bit(BIGNUM *a, int n);
//
// llgo:link (*BIGNUM).SetBit C.BN_set_bit
func (*BIGNUM) SetBit(n c.Int) c.Int { return 0 }
// int BN_clear_bit(BIGNUM *a, int n);
//
// llgo:link (*BIGNUM).ClearBit C.BN_clear_bit
func (*BIGNUM) ClearBit(n c.Int) c.Int { return 0 }
// int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
//
// llgo:link (*BIGNUM).Lshift C.BN_lshift
func (*BIGNUM) Lshift(a *BIGNUM, n c.Int) c.Int { return 0 }
// int BN_lshift1(BIGNUM *r, const BIGNUM *a);
//
// llgo:link (*BIGNUM).Lshift1 C.BN_lshift1
func (*BIGNUM) Lshift1(a *BIGNUM) c.Int { return 0 }
// int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
//
// llgo:link (*BIGNUM).Rshift C.BN_rshift
func (*BIGNUM) Rshift(a *BIGNUM, n c.Int) c.Int { return 0 }
// int BN_rshift1(BIGNUM *r, const BIGNUM *a);
//
// llgo:link (*BIGNUM).Rshift1 C.BN_rshift1
func (*BIGNUM) Rshift1(a *BIGNUM) c.Int { return 0 }
// int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Exp C.BN_exp
func (*BIGNUM) Exp(a, p *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).ModExp C.BN_mod_exp
func (*BIGNUM) ModExp(a, p, m *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Gcd C.BN_gcd
func (*BIGNUM) Gcd(a, b *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_are_coprime(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).AreCoprime C.BN_are_coprime
func (*BIGNUM) AreCoprime(b *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// -----------------------------------------------------------------------------
type BN_GENCB struct {
Unused [0]byte
}
// -----------------------------------------------------------------------------

156
c/openssl/err.go Normal file
View File

@@ -0,0 +1,156 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
/*-
* The error code packs differently depending on if it records a system
* error or an OpenSSL error.
*
* A system error packs like this (we follow POSIX and only allow positive
* numbers that fit in an |int|):
*
* +-+-------------------------------------------------------------+
* |1| system error number |
* +-+-------------------------------------------------------------+
*
* An OpenSSL error packs like this:
*
* <---------------------------- 32 bits -------------------------->
* <--- 8 bits ---><------------------ 23 bits ----------------->
* +-+---------------+---------------------------------------------+
* |0| library | reason |
* +-+---------------+---------------------------------------------+
*
* A few of the reason bits are reserved as flags with special meaning:
*
* <5 bits-<>--------- 19 bits ----------------->
* +-------+-+-----------------------------------+
* | rflags| | reason |
* +-------+-+-----------------------------------+
* ^
* |
* ERR_RFLAG_FATAL = ERR_R_FATAL
*
* The reason flags are part of the overall reason code for practical
* reasons, as they provide an easy way to place different types of
* reason codes in different numeric ranges.
*
* The currently known reason flags are:
*
* ERR_RFLAG_FATAL Flags that the reason code is considered fatal.
* For backward compatibility reasons, this flag
* is also the code for ERR_R_FATAL (that reason
* code served the dual purpose of flag and reason
* code in one in pre-3.0 OpenSSL).
* ERR_RFLAG_COMMON Flags that the reason code is common to all
* libraries. All ERR_R_ macros must use this flag,
* and no other _R_ macro is allowed to use it.
*/
type Errno c.Ulong
// ERR_get_error returns the earliest error code from the thread's error queue and
// removes the entry. This function can be called repeatedly until there are no more
// error codes to return.
//
// unsigned long ERR_get_error(void);
//
//go:linkname ERRGetError C.ERR_get_error
func ERRGetError() Errno
// ERR_get_error_all() is the same as ERR_get_error(), but on success it additionally
// stores the filename, line number and function where the error occurred in *file,
// *line and *func, and also extra text and flags in *data, *flags. If any of those
// parameters are NULL, it will not be changed.
//
// unsigned long ERR_get_error_all(
// const char **file, int *line, const char **func, const char **data, int *flags);
//
//go:linkname ERRGetErrorAll C.ERR_get_error_all
func ERRGetErrorAll(
file **c.Char, line *c.Int, function **c.Char, data **c.Char, flags *c.Int) Errno
// unsigned long ERR_peek_error(void);
//
//go:linkname ERRPeekError C.ERR_peek_error
func ERRPeekError() Errno
// unsigned long ERR_peek_error_all(
// const char **file, int *line, const char **func, const char **data, int *flags);
//
//go:linkname ERRPeekErrorAll C.ERR_peek_error_all
func ERRPeekErrorAll(
file **c.Char, line *c.Int, function **c.Char, data **c.Char, flags *c.Int) Errno
// unsigned long ERR_peek_last_error(void);
//
//go:linkname ERRPeekLastError C.ERR_peek_last_error
func ERRPeekLastError() Errno
// unsigned long ERR_peek_last_error_all(
// const char **file, int *line, const char **func, const char **data, int *flags);
//
//go:linkname ERRPeekLastErrorAll C.ERR_peek_last_error_all
func ERRPeekLastErrorAll(
file **c.Char, line *c.Int, function **c.Char, data **c.Char, flags *c.Int) Errno
// void ERR_clear_error(void);
//
//go:linkname ERRClearError C.ERR_clear_error
func ERRClearError()
// ERR_error_string() generates a human-readable string representing the error code e,
// and places it at buf. buf must be at least 256 bytes long.
//
// char *ERR_error_string(unsigned long e, char *buf);
//
//go:linkname ERRErrorString C.ERR_error_string
func ERRErrorString(e Errno, buf *c.Char) *c.Char
// ERR_lib_error_string() and ERR_reason_error_string() return the library name and
// reason string respectively.
//
// const char *ERR_lib_error_string(unsigned long e);
//
//go:linkname ERRLibErrorString C.ERR_lib_error_string
func ERRLibErrorString(e Errno) *c.Char
// const char *ERR_reason_error_string(unsigned long e);
//
//go:linkname ERRReasonErrorString C.ERR_reason_error_string
func ERRReasonErrorString(e Errno) *c.Char
// void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), void *u);
//
// [pid]:error:[error code]:[library name]:[function name]:[reason string]:[filename]:[line]:[optional text message]
//
//go:linkname ERRPrintErrorsCb C.ERR_print_errors_cb
func ERRPrintErrorsCb(cb func(str *c.Char, len uintptr, u unsafe.Pointer) c.Int, u unsafe.Pointer)
// void ERR_print_errors_fp(FILE *fp);
//
//go:linkname ERRPrintErrorsFp C.ERR_print_errors_fp
func ERRPrintErrorsFp(fp c.FilePtr)
// -----------------------------------------------------------------------------

133
c/openssl/hmac.go Normal file
View File

@@ -0,0 +1,133 @@
package openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
const (
EVP_MAX_MD_SIZE = 64 /* longest known is SHA512 */
)
// -----------------------------------------------------------------------------
type EVP_MD struct {
Unused [0]byte
}
// const EVP_MD *EVP_sha1(void)
//
//go:linkname EVP_sha1 C.EVP_sha1
func EVP_sha1() *EVP_MD
// const EVP_MD *EVP_sha224(void)
//
//go:linkname EVP_sha224 C.EVP_sha224
func EVP_sha224() *EVP_MD
// func EVP_sha256() *EVP_MD
//
//go:linkname EVP_sha256 C.EVP_sha256
func EVP_sha256() *EVP_MD
// const EVP_MD *EVP_sha512_224(void)
//
//go:linkname EVP_sha512_224 C.EVP_sha512_224
func EVP_sha512_224() *EVP_MD
// const EVP_MD *EVP_sha512_256(void)
//
//go:linkname EVP_sha512_256 C.EVP_sha512_256
func EVP_sha512_256() *EVP_MD
// const EVP_MD *EVP_sha384(void)
//
//go:linkname EVP_sha384 C.EVP_sha384
func EVP_sha384() *EVP_MD
// const EVP_MD *EVP_sha512(void)
//
//go:linkname EVP_sha512 C.EVP_sha512
func EVP_sha512() *EVP_MD
// -----------------------------------------------------------------------------
type HMAC_CTX struct {
Unused [0]byte
}
// OSSL_DEPRECATEDIN_3_0 HMAC_CTX *HMAC_CTX_new(void);
//
//go:linkname NewHMAC_CTX C.HMAC_CTX_new
func NewHMAC_CTX() *HMAC_CTX
// OSSL_DEPRECATEDIN_3_0 void HMAC_CTX_free(HMAC_CTX *ctx);
//
// llgo:link (*HMAC_CTX).Free C.HMAC_CTX_free
func (ctx *HMAC_CTX) Free() {}
// OSSL_DEPRECATEDIN_3_0 size_t HMAC_size(const HMAC_CTX *e);
//
// llgo:link (*HMAC_CTX).Size C.HMAC_size
func (ctx *HMAC_CTX) Size() uintptr { return 0 }
// OSSL_DEPRECATEDIN_3_0 int HMAC_CTX_reset(HMAC_CTX *ctx);
//
// llgo:link (*HMAC_CTX).Reset C.HMAC_CTX_reset
func (ctx *HMAC_CTX) Reset() c.Int { return 0 }
// OSSL_DEPRECATEDIN_1_1_0 __owur int HMAC_Init(HMAC_CTX *ctx,
// const void *key, int len,
// const EVP_MD *md);
//
// llgo:link (*HMAC_CTX).Init C.HMAC_Init
func (ctx *HMAC_CTX) Init(key unsafe.Pointer, len c.Int, md *EVP_MD) c.Int { return 0 }
func (ctx *HMAC_CTX) InitBytes(key []byte, md *EVP_MD) c.Int {
return ctx.Init(unsafe.Pointer(unsafe.SliceData(key)), c.Int(len(key)), md)
}
func (ctx *HMAC_CTX) InitString(key string, md *EVP_MD) c.Int {
return ctx.Init(unsafe.Pointer(unsafe.StringData(key)), c.Int(len(key)), md)
}
// OSSL_DEPRECATEDIN_3_0 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
// const EVP_MD *md, ENGINE *impl);
//
// llgo:link (*HMAC_CTX).InitEx C.HMAC_Init_ex
func (ctx *HMAC_CTX) InitEx(key unsafe.Pointer, len c.Int, md *EVP_MD, impl unsafe.Pointer) c.Int {
return 0
}
// OSSL_DEPRECATEDIN_3_0 int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data,
// size_t len);
//
// llgo:link (*HMAC_CTX).Update C.HMAC_Update
func (ctx *HMAC_CTX) Update(data unsafe.Pointer, len uintptr) c.Int { return 0 }
func (ctx *HMAC_CTX) UpdateBytes(data []byte) c.Int {
return ctx.Update(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)))
}
func (ctx *HMAC_CTX) UpdateString(data string) c.Int {
return ctx.Update(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)))
}
// OSSL_DEPRECATEDIN_3_0 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md,
// unsigned int *len);
//
// llgo:link (*HMAC_CTX).Final C.HMAC_Final
func (ctx *HMAC_CTX) Final(md *byte, len *c.Uint) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 __owur int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
//
// llgo:link (*HMAC_CTX).Copy C.HMAC_CTX_copy
func (ctx *HMAC_CTX) Copy(sctx *HMAC_CTX) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
//
// llgo:link (*HMAC_CTX).SetFlags C.HMAC_CTX_set_flags
func (ctx *HMAC_CTX) SetFlags(flags c.Ulong) {}
// -----------------------------------------------------------------------------

View File

@@ -16,8 +16,23 @@
package openssl package openssl
const ( import (
LLGoPackage = "link: $(pkg-config --libs openssl); -lssl -lcrypto" "unsafe"
"github.com/goplus/llgo/c"
) )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
const (
LLGoFiles = "$(pkg-config --cflags openssl): _wrap/openssl.c"
LLGoPackage = "link: $(pkg-config --libs openssl); -lssl -lcrypto"
)
//go:linkname Free C.opensslFree
func Free(ptr unsafe.Pointer)
//go:linkname FreeCStr C.opensslFree
func FreeCStr(ptr *c.Char)
// -----------------------------------------------------------------------------

37
c/openssl/pem.go Normal file
View File

@@ -0,0 +1,37 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
// typedef int (*pem_password_cb)(char *buf, int size, int rwflag, void *userdata);
//
// llgo:type C
type PemPasswordCb func(buf *c.Char, size, rwflag c.Int, userdata unsafe.Pointer) c.Int
// RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **x, pem_password_cb *cb, void *u);
//
//go:linkname PEMReadBioRSAPrivateKey C.PEM_read_bio_RSAPrivateKey
func PEMReadBioRSAPrivateKey(bp *BIO, x **RSA, cb PemPasswordCb, u unsafe.Pointer) *RSA
// -----------------------------------------------------------------------------

80
c/openssl/rand.go Normal file
View File

@@ -0,0 +1,80 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
// int RAND_bytes(unsigned char *buf, int num);
//
//go:linkname RANDBufferWithLen C.RAND_bytes
func RANDBufferWithLen(buf *byte, num c.Int) c.Int
func RANDBytes(buf []byte) c.Int {
return RANDBufferWithLen(unsafe.SliceData(buf), c.Int(len(buf)))
}
// int RAND_priv_bytes(unsigned char *buf, int num);
//
//go:linkname RANDPrivBufferWithLen C.RAND_priv_bytes
func RANDPrivBufferWithLen(buf *byte, num c.Int) c.Int
func RANDPrivBytes(buf []byte) c.Int {
return RANDPrivBufferWithLen(unsafe.SliceData(buf), c.Int(len(buf)))
}
// void RAND_seed(const void *buf, int num);
//
//go:linkname RANDSeed C.RAND_seed
func RANDSeed(buf unsafe.Pointer, num c.Int)
// void RAND_keep_random_devices_open(int keep);
//
//go:linkname RANDKeepRandomDevicesOpen C.RAND_keep_random_devices_open
func RANDKeepRandomDevicesOpen(keep c.Int)
// int RAND_load_file(const char *file, long max_bytes);
//
//go:linkname RANDLoadFile C.RAND_load_file
func RANDLoadFile(file *c.Char, maxBytes c.Long) c.Int
// int RAND_write_file(const char *file);
//
//go:linkname RANDWriteFile C.RAND_write_file
func RANDWriteFile(file *c.Char) c.Int
// const char *RAND_file_name(char *file, size_t num);
//
//go:linkname RANDFileName C.RAND_file_name
func RANDFileName(file *c.Char, num uintptr) *c.Char
// int RAND_status(void);
//
//go:linkname RANDStatus C.RAND_status
func RANDStatus() c.Int
// int RAND_poll(void);
//
//go:linkname RANDPoll C.RAND_poll
func RANDPoll() c.Int
// -----------------------------------------------------------------------------

305
c/openssl/rsa.go Normal file
View File

@@ -0,0 +1,305 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
type RSA_METHOD struct {
Unused [0]byte
}
// OSSL_DEPRECATEDIN_3_0 RSA_METHOD *RSA_meth_new(const char *name, int flags);
//
//go:linkname RSAMethNew C.RSA_meth_new
func RSAMethNew(name *byte, flags c.Int) *RSA_METHOD
// OSSL_DEPRECATEDIN_3_0 void RSA_meth_free(RSA_METHOD *meth);
//
// llgo:link (*RSA_METHOD).Free C.RSA_meth_free
func (*RSA_METHOD) Free() {}
// OSSL_DEPRECATEDIN_3_0
// int RSA_meth_set_init(RSA_METHOD *rsa, int (*init) (RSA *rsa));
//
// llgo:link (*RSA_METHOD).SetInit C.RSA_meth_set_init
func (*RSA_METHOD) SetInit(init func(rsa *RSA) c.Int) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0
// int RSA_meth_set_finish(RSA_METHOD *rsa, int (*finish) (RSA *rsa));
//
// llgo:link (*RSA_METHOD).SetFinish C.RSA_meth_set_finish
func (*RSA_METHOD) SetFinish(finish func(rsa *RSA) c.Int) c.Int { return 0 }
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_mod_exp(RSA_METHOD *rsa,
int (*mod_exp) (BIGNUM *r0, const BIGNUM *i, RSA *rsa,
BN_CTX *ctx));
*/
// llgo:link (*RSA_METHOD).SetModExp C.RSA_meth_set_mod_exp
func (*RSA_METHOD) SetModExp(modExp func(
r0 *BIGNUM, i *BIGNUM, rsa *RSA, ctx *BN_CTX) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_bn_mod_exp(RSA_METHOD *rsa,
int (*bn_mod_exp) (BIGNUM *r,
const BIGNUM *a,
const BIGNUM *p,
const BIGNUM *m,
BN_CTX *ctx,
BN_MONT_CTX *m_ctx));
//-llgo:link (*RSA_METHOD).SetBnModExp C.RSA_meth_set_bn_mod_exp
func (*RSA_METHOD) SetBnModExp(bnModExp func(
r *BIGNUM, a *BIGNUM, p *BIGNUM, m *BIGNUM, ctx *BN_CTX, mCtx *BN_MONT_CTX) c.Int) c.Int {
return 0
}
*/
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_pub_enc(RSA_METHOD *rsa,
int (*pub_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding));
*/
// llgo:link (*RSA_METHOD).SetPubEnc C.RSA_meth_set_pub_enc
func (*RSA_METHOD) SetPubEnc(pubEnc func(
flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_pub_dec(RSA_METHOD *rsa,
int (*pub_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding));
*/
// llgo:link (*RSA_METHOD).SetPubDec C.RSA_meth_set_pub_dec
func (*RSA_METHOD) SetPubDec(pubDec func(
flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_priv_enc(RSA_METHOD *rsa,
int (*priv_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding));
*/
// llgo:link (*RSA_METHOD).SetPrivEnc C.RSA_meth_set_priv_enc
func (*RSA_METHOD) SetPrivEnc(privEnc func(
flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_priv_dec(RSA_METHOD *rsa,
int (*priv_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding));
*/
// llgo:link (*RSA_METHOD).SetPrivDec C.RSA_meth_set_priv_dec
func (*RSA_METHOD) SetPrivDec(privDec func(
flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_sign(RSA_METHOD *rsa,
int (*sign) (int type, const unsigned char *m,
unsigned int m_length,
unsigned char *sigret, unsigned int *siglen,
const RSA *rsa));
*/
// llgo:link (*RSA_METHOD).SetSign C.RSA_meth_set_sign
func (*RSA_METHOD) SetSign(sign func(
typ c.Int, msg *byte, mlen c.Uint,
sigret *byte, siglen *c.Uint, rsa *RSA) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_verify(RSA_METHOD *rsa,
int (*verify) (int dtype, const unsigned char *m,
unsigned int m_length,
const unsigned char *sigbuf,
unsigned int siglen, const RSA *rsa));
*/
// llgo:link (*RSA_METHOD).SetVerify C.RSA_meth_set_verify
func (*RSA_METHOD) SetVerify(verify func(
dtype c.Int, msg *byte, mlen c.Uint,
sigbuf *byte, siglen c.Uint, rsa *RSA) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_keygen(RSA_METHOD *rsa,
int (*keygen) (RSA *rsa, int bits, BIGNUM *e,
BN_GENCB *cb));
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_multi_prime_keygen(RSA_METHOD *meth,
int (*keygen) (RSA *rsa, int bits,
int primes, BIGNUM *e,
BN_GENCB *cb));
*/
// -----------------------------------------------------------------------------
type RSA struct {
Unused [0]byte
}
// OSSL_DEPRECATEDIN_3_0 RSA *RSA_new(void);
//
//go:linkname RSANew C.RSA_new
func RSANew() *RSA
// OSSL_DEPRECATEDIN_3_0 RSA *RSA_new_method(ENGINE *engine);
// OSSL_DEPRECATEDIN_3_0 void RSA_free(RSA *r);
//
// llgo:link (*RSA).Free C.RSA_free
func (*RSA) Free() {}
// "up" the RSA object's reference count
// OSSL_DEPRECATEDIN_3_0 int RSA_up_ref(RSA *r);
//
// llgo:link (*RSA).UpRef C.RSA_up_ref
func (*RSA) UpRef() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_bits(const RSA *rsa);
//
// llgo:link (*RSA).Bits C.RSA_bits
func (*RSA) Bits() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_size(const RSA *rsa);
//
// llgo:link (*RSA).Size C.RSA_size
func (*RSA) Size() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_security_bits(const RSA *rsa);
//
// llgo:link (*RSA).SecurityBits C.RSA_security_bits
func (*RSA) SecurityBits() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_flags(const RSA *r);
//
// llgo:link (*RSA).Flags C.RSA_flags
func (*RSA) Flags() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 void RSA_set_flags(RSA *r, int flags);
//
// llgo:link (*RSA).SetFlags C.RSA_set_flags
func (*RSA) SetFlags(flags c.Int) {}
// OSSL_DEPRECATEDIN_3_0 void RSA_clear_flags(RSA *r, int flags);
//
// llgo:link (*RSA).ClearFlags C.RSA_clear_flags
func (*RSA) ClearFlags(flags c.Int) {}
// OSSL_DEPRECATEDIN_3_0 int RSA_test_flags(const RSA *r, int flags);
//
// llgo:link (*RSA).TestFlags C.RSA_test_flags
func (*RSA) TestFlags(flags c.Int) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_get_version(RSA *r);
//
// llgo:link (*RSA).GetVersion C.RSA_get_version
func (*RSA) GetVersion() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_set_ex_data(RSA *r, int idx, void *arg);
//
// llgo:link (*RSA).SetExData C.RSA_set_ex_data
func (*RSA) SetExData(idx c.Int, arg unsafe.Pointer) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 void *RSA_get_ex_data(const RSA *r, int idx);
//
// llgo:link (*RSA).GetExData C.RSA_get_ex_data
func (*RSA) GetExData(idx c.Int) unsafe.Pointer { return nil }
// OSSL_DEPRECATEDIN_3_0 int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
//
// llgo:link (*RSA).SetMethod C.RSA_set_method
func (*RSA) SetMethod(meth *RSA_METHOD) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
//
// llgo:link (*RSA).GenerateKeyEx C.RSA_generate_key_ex
func (*RSA) GenerateKeyEx(bits c.Int, e *BIGNUM, cb *BN_GENCB) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, BIGNUM *e, BN_GENCB *cb);
//
// llgo:link (*RSA).GenerateMultiPrimeKey C.RSA_generate_multi_prime_key
func (*RSA) GenerateMultiPrimeKey(bits, primes c.Int, e *BIGNUM, cb *BN_GENCB) c.Int { return 0 }
/*
// next 4 return -1 on error
OSSL_DEPRECATEDIN_3_0
int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding);
OSSL_DEPRECATEDIN_3_0
int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding);
OSSL_DEPRECATEDIN_3_0
int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding);
OSSL_DEPRECATEDIN_3_0
int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding);
*/
//go:linkname RSAPublicEncrypt C.RSA_public_encrypt
func RSAPublicEncrypt(flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int
//go:linkname RSAPrivateEncrypt C.RSA_private_encrypt
func RSAPrivateEncrypt(flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int
//go:linkname RSAPublicDecrypt C.RSA_public_decrypt
func RSAPublicDecrypt(flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int
//go:linkname RSAPrivateDecrypt C.RSA_private_decrypt
func RSAPrivateDecrypt(flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int
// OSSL_DEPRECATEDIN_3_0 int RSA_sign(
// int type, const unsigned char *m, unsigned int m_length,
// unsigned char *sigret, unsigned int *siglen, RSA *rsa);
//
//go:linkname RSASign C.RSA_sign
func RSASign(typ c.Int, msg *byte, mlen c.Uint, sigret *byte, siglen *c.Uint, rsa *RSA) c.Int
// OSSL_DEPRECATEDIN_3_0 int RSA_verify(int type, const unsigned char *m,
// unsigned int m_length,
// const unsigned char *sigbuf,
// unsigned int siglen, RSA *rsa);
// -----------------------------------------------------------------------------

9
c/os/_os/os.c Normal file
View File

@@ -0,0 +1,9 @@
#include <stdlib.h>
int llgoClearenv() {
extern char **environ;
if (environ != NULL) {
*environ = NULL;
}
return 0;
}

View File

@@ -27,10 +27,6 @@ import (
"github.com/goplus/llgo/c/syscall" "github.com/goplus/llgo/c/syscall"
) )
const (
LLGoPackage = "decl"
)
const ( const (
PATH_MAX = C.PATH_MAX PATH_MAX = C.PATH_MAX
) )
@@ -150,9 +146,6 @@ func Putenv(env *c.Char) c.Int
//go:linkname Unsetenv C.unsetenv //go:linkname Unsetenv C.unsetenv
func Unsetenv(name *c.Char) c.Int func Unsetenv(name *c.Char) c.Int
//go:linkname Clearenv C.clearenv
func Clearenv()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//go:linkname Fchdir C.fchdir //go:linkname Fchdir C.fchdir
@@ -243,12 +236,12 @@ func Isatty(fd c.Int) c.Int
// Execl requires the full path of the program to be provided. // Execl requires the full path of the program to be provided.
// //
//go:linkname Execl C.execl //go:linkname Execl C.execl
func Execl(path *c.Char, __llgo_va_list ...any) c.Int func Execl(path *c.Char, arg0 *c.Char, __llgo_va_list ...any) c.Int
// Execle(const char *path, const char *arg0, ..., /* (char *)0, char *const envp[] */) // Execle(const char *path, const char *arg0, ..., /* (char *)0, char *const envp[] */)
// //
//go:linkname Execle C.execle //go:linkname Execle C.execle
func Execle(path *c.Char, __llgo_va_list ...any) c.Int func Execle(path *c.Char, arg0 *c.Char, __llgo_va_list ...any) c.Int
// Execlp(const char *file, const char *arg0, ..., /*, (char *)0, */) // Execlp(const char *file, const char *arg0, ..., /*, (char *)0, */)
// //
@@ -256,7 +249,7 @@ func Execle(path *c.Char, __llgo_va_list ...any) c.Int
// paths specified in the PATH environment variable. // paths specified in the PATH environment variable.
// //
//go:linkname Execlp C.execlp //go:linkname Execlp C.execlp
func Execlp(file *c.Char, __llgo_va_list ...any) c.Int func Execlp(file *c.Char, arg0 *c.Char, __llgo_va_list ...any) c.Int
//go:linkname Execv C.execv //go:linkname Execv C.execv
func Execv(path *c.Char, argv **c.Char) c.Int func Execv(path *c.Char, argv **c.Char) c.Int

28
c/os/os_linux.go Normal file
View File

@@ -0,0 +1,28 @@
//go: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 os
import "C"
const (
LLGoPackage = "decl"
)
//go:linkname Clearenv C.clearenv
func Clearenv()

29
c/os/os_other.go Normal file
View File

@@ -0,0 +1,29 @@
//go: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 os
import "C"
const (
LLGoFiles = "_os/os.c"
LLGoPackage = "link"
)
//go:linkname Clearenv C.llgoClearenv
func Clearenv()

View File

@@ -22,10 +22,6 @@ import (
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
) )
const (
LLGoPackage = "decl"
)
func __noop__() c.Int { func __noop__() c.Int {
return 0 return 0
} }
@@ -36,59 +32,12 @@ type aThread struct {
Unused [8]byte Unused [8]byte
} }
//llgo:type C
type RoutineFunc func(c.Pointer) c.Pointer
// Thread represents a POSIX thread. // Thread represents a POSIX thread.
type Thread = *aThread type Thread = *aThread
// The pthread_create() function starts a new thread in the calling
// process. The new thread starts execution by invoking
// start_routine(); arg is passed as the sole argument of
// start_routine().
//
// The new thread terminates in one of the following ways:
//
// - It calls pthread_exit(3), specifying an exit status value that
// is available to another thread in the same process that calls
// pthread_join(3).
//
// - It returns from start_routine(). This is equivalent to
// calling pthread_exit(3) with the value supplied in the return
// statement.
//
// - It is canceled (see pthread_cancel(3)).
//
// - Any of the threads in the process calls exit(3), or the main
// thread performs a return from main(). This causes the
// termination of all threads in the process.
//
// On success, pthread_create() returns 0; on error, it returns an
// error number, and the contents of *thread are undefined.
//
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
//
//go:linkname Create C.pthread_create
func Create(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg c.Pointer) c.Int
// The pthread_join() function waits for the thread specified by
// thread to terminate. If that thread has already terminated, then
// pthread_join() returns immediately. The thread specified by
// thread must be joinable.
//
// If retval is not NULL, then pthread_join() copies the exit status
// of the target thread (i.e., the value that the target thread
// supplied to pthread_exit(3)) into the location pointed to by
// retval. If the target thread was canceled, then PTHREAD_CANCELED
// is placed in the location pointed to by retval.
//
// If multiple threads simultaneously try to join with the same
// thread, the results are undefined. If the thread calling
// pthread_join() is canceled, then the target thread will remain
// joinable (i.e., it will not be detached).
//
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
//
//go:linkname Join C.pthread_join
func Join(thread Thread, retval *c.Pointer) c.Int
// The pthread_exit() function terminates the calling thread and // The pthread_exit() function terminates the calling thread and
// returns a value via retval that (if the thread is joinable) is // returns a value via retval that (if the thread is joinable) is
// available to another thread in the same process that calls // available to another thread in the same process that calls

80
c/pthread/pthread_gc.go Normal file
View File

@@ -0,0 +1,80 @@
//go:build !nogc
// +build !nogc
/*
* 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 pthread
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "link: $(pkg-config --libs bdw-gc); -lgc"
)
// The pthread_create() function starts a new thread in the calling
// process. The new thread starts execution by invoking
// start_routine(); arg is passed as the sole argument of
// start_routine().
//
// The new thread terminates in one of the following ways:
//
// - It calls pthread_exit(3), specifying an exit status value that
// is available to another thread in the same process that calls
// pthread_join(3).
//
// - It returns from start_routine(). This is equivalent to
// calling pthread_exit(3) with the value supplied in the return
// statement.
//
// - It is canceled (see pthread_cancel(3)).
//
// - Any of the threads in the process calls exit(3), or the main
// thread performs a return from main(). This causes the
// termination of all threads in the process.
//
// On success, pthread_create() returns 0; on error, it returns an
// error number, and the contents of *thread are undefined.
//
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
//
//go:linkname Create C.GC_pthread_create
func Create(pthread *Thread, attr *Attr, routine RoutineFunc, arg c.Pointer) c.Int
// The pthread_join() function waits for the thread specified by
// thread to terminate. If that thread has already terminated, then
// pthread_join() returns immediately. The thread specified by
// thread must be joinable.
//
// If retval is not NULL, then pthread_join() copies the exit status
// of the target thread (i.e., the value that the target thread
// supplied to pthread_exit(3)) into the location pointed to by
// retval. If the target thread was canceled, then PTHREAD_CANCELED
// is placed in the location pointed to by retval.
//
// If multiple threads simultaneously try to join with the same
// thread, the results are undefined. If the thread calling
// pthread_join() is canceled, then the target thread will remain
// joinable (i.e., it will not be detached).
//
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
//
//go:linkname Join C.GC_pthread_join
func Join(thread Thread, retval *c.Pointer) c.Int

80
c/pthread/pthread_nogc.go Normal file
View File

@@ -0,0 +1,80 @@
//go:build nogc
// +build nogc
/*
* 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 pthread
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "decl"
)
// The pthread_create() function starts a new thread in the calling
// process. The new thread starts execution by invoking
// start_routine(); arg is passed as the sole argument of
// start_routine().
//
// The new thread terminates in one of the following ways:
//
// - It calls pthread_exit(3), specifying an exit status value that
// is available to another thread in the same process that calls
// pthread_join(3).
//
// - It returns from start_routine(). This is equivalent to
// calling pthread_exit(3) with the value supplied in the return
// statement.
//
// - It is canceled (see pthread_cancel(3)).
//
// - Any of the threads in the process calls exit(3), or the main
// thread performs a return from main(). This causes the
// termination of all threads in the process.
//
// On success, pthread_create() returns 0; on error, it returns an
// error number, and the contents of *thread are undefined.
//
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
//
//go:linkname Create C.pthread_create
func Create(pthread *Thread, attr *Attr, routine RoutineFunc, arg c.Pointer) c.Int
// The pthread_join() function waits for the thread specified by
// thread to terminate. If that thread has already terminated, then
// pthread_join() returns immediately. The thread specified by
// thread must be joinable.
//
// If retval is not NULL, then pthread_join() copies the exit status
// of the target thread (i.e., the value that the target thread
// supplied to pthread_exit(3)) into the location pointed to by
// retval. If the target thread was canceled, then PTHREAD_CANCELED
// is placed in the location pointed to by retval.
//
// If multiple threads simultaneously try to join with the same
// thread, the results are undefined. If the thread calling
// pthread_join() is canceled, then the target thread will remain
// joinable (i.e., it will not be detached).
//
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
//
//go:linkname Join C.pthread_join
func Join(thread Thread, retval *c.Pointer) c.Int

View File

@@ -27,7 +27,7 @@ import (
) )
const ( const (
LLGoFiles = "_pthd/pthd.c" LLGoFiles = "_wrap/pthd.c"
LLGoPackage = "link" LLGoPackage = "link"
) )

32
c/signal/signal.go Normal file
View File

@@ -0,0 +1,32 @@
package signal
import (
"unsafe"
"github.com/goplus/llgo/c"
)
import "C"
const (
LLGoPackage = "link"
)
//llgo:type C
type SignalHandler func(c.Int)
//llgo:type C
type sigactiont struct {
handler SignalHandler
tramp unsafe.Pointer
mask c.Int
flags c.Int
}
//go:linkname sigaction C.sigaction
func sigaction(sig c.Int, act, old *sigactiont) c.Int
func Signal(sig c.Int, hanlder SignalHandler) c.Int {
var act sigactiont
act.handler = hanlder
return sigaction(sig, &act, nil)
}

View File

@@ -0,0 +1,221 @@
package main
import (
"fmt"
"os"
"strings"
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/clang"
)
type Data struct {
Depth c.Uint
Unit *clang.TranslationUnit
}
var accessMap = map[clang.CXXAccessSpecifier]string{
clang.CXXInvalidAccessSpecifier: "invalid",
clang.CXXPublic: "public",
clang.CXXProtected: "protected",
clang.CXXPrivate: "private",
}
func printIndent(depth c.Uint) {
fmt.Print(strings.Repeat(" ", int(depth)))
}
func accessToString(spec clang.CXXAccessSpecifier) string {
if str, ok := accessMap[spec]; ok {
return str
}
return "unknown"
}
func visit(cursor, parent clang.Cursor, ClientData c.Pointer) clang.ChildVisitResult {
data := (*Data)(ClientData)
printAST(cursor, data)
return clang.ChildVisit_Continue
}
func printType(t clang.Type, data *Data) {
printIndent(data.Depth)
typeSpell := t.String()
typeKind := t.Kind.String()
if t.Kind == clang.TypeInvalid {
} else if t.Kind == clang.TypeUnexposed {
c.Printf(c.Str("<UnexposedType|%s>: %s\n"), typeKind.CStr(), typeSpell.CStr())
} else if t.Kind >= clang.TypeFirstBuiltin && t.Kind <= clang.TypeLastBuiltin {
c.Printf(c.Str("<BuiltinType|%s>: %s\n"), typeKind.CStr(), typeSpell.CStr())
} else if t.Kind > clang.TypeComplex {
c.Printf(c.Str("<ComplexType|%s>: %s\n"), typeKind.CStr(), typeSpell.CStr())
}
data.Depth++
switch t.Kind {
case clang.TypePointer:
printType(t.PointeeType(), data)
case clang.TypeIncompleteArray, clang.TypeVariableArray, clang.TypeDependentSizedArray, clang.TypeConstantArray:
printType(t.ArrayElementType(), data)
case clang.TypeTypedef:
printType(t.TypeDeclaration().TypedefDeclUnderlyingType(), data)
case clang.TypeElaborated:
printType(t.NamedType(), data)
case clang.TypeFunctionProto:
printType(t.ResultType(), data)
for i := 0; i < int(t.NumArgTypes()); i++ {
printType(t.ArgType(c.Uint(i)), data)
}
}
data.Depth--
typeKind.Dispose()
typeSpell.Dispose()
}
func printLocation(cursor clang.Cursor) {
loc := cursor.Location()
var file clang.File
var line, column c.Uint
loc.SpellingLocation(&file, &line, &column, nil)
filename := file.FileName()
defer filename.Dispose()
c.Printf(c.Str("(Loc:%s:%d:%d)\n"), filename.CStr(), line, column)
}
func printAccess(cursor clang.Cursor) {
kind := cursor.Kind.String()
spell := cursor.String()
defer kind.Dispose()
defer spell.Dispose()
c.Printf(c.Str("%s: %s %s"), kind.CStr(), spell.CStr(), c.AllocaCStr(accessToString(cursor.CXXAccessSpecifier())))
printLocation(cursor)
}
func printMacro(cursor clang.Cursor, unit *clang.TranslationUnit) {
kind := cursor.Kind.String()
defer kind.Dispose()
c.Printf(c.Str("%s: "), kind.CStr())
ran := cursor.Extent()
var numTokens c.Uint
var tokens *clang.Token
unit.Tokenize(ran, &tokens, &numTokens)
defer unit.DisposeTokens(tokens, numTokens)
tokensSlice := unsafe.Slice(tokens, int(numTokens))
for _, tok := range tokensSlice {
tokStr := unit.Token(tok)
c.Printf(c.Str("%s "), tokStr.CStr())
tokStr.Dispose()
}
printLocation(cursor)
}
func printFunc(cursor clang.Cursor, data *Data) {
kind := cursor.Kind.String()
spell := cursor.String()
symbol := cursor.Mangling()
defer symbol.Dispose()
defer kind.Dispose()
defer spell.Dispose()
c.Printf(c.Str("%s: %s (Symbol: %s)"), kind.CStr(), spell.CStr(), symbol.CStr())
printLocation(cursor)
printType(cursor.Type(), data)
}
func printEnumConstant(cursor clang.Cursor) {
kind := cursor.Kind.String()
spell := cursor.String()
defer kind.Dispose()
defer spell.Dispose()
c.Printf(c.Str("%s: %s:%lld"), kind.CStr(), spell.CStr(), cursor.EnumConstantDeclValue())
printLocation(cursor)
}
func printDefault(cursor clang.Cursor, data *Data) {
kind := cursor.Kind.String()
spell := cursor.String()
defer kind.Dispose()
defer spell.Dispose()
// node which has type
if cursor.Type().Kind != clang.TypeInvalid {
c.Printf(c.Str("%s: %s"), kind.CStr(), spell.CStr())
printLocation(cursor)
printType(cursor.Type(), data)
} else {
c.Printf(c.Str("%s: %s\n"), kind.CStr(), spell.CStr())
}
}
func printAST(cursor clang.Cursor, data *Data) {
kind := cursor.Kind.String()
spell := cursor.String()
printIndent(data.Depth)
switch cursor.Kind {
case clang.CursorCXXAccessSpecifier:
printAccess(cursor)
case clang.CursorMacroDefinition:
printMacro(cursor, data.Unit)
case clang.CursorFunctionDecl, clang.CursorCXXMethod, clang.CursorConstructor, clang.CursorDestructor:
printFunc(cursor, data)
case clang.CursorEnumConstantDecl:
printEnumConstant(cursor)
default:
printDefault(cursor, data)
}
data.Depth++
clang.VisitChildren(cursor, visit, c.Pointer(data))
data.Depth--
kind.Dispose()
spell.Dispose()
}
func main() {
if c.Argc != 2 {
fmt.Fprintln(os.Stderr, "Usage: castdump <headerFile>")
return
}
args := make([]*c.Char, 3)
args[0] = c.Str("-x")
args[1] = c.Str("c++")
args[2] = c.Str("-std=c++11")
sourceFile := *c.Advance(c.Argv, 1)
index := clang.CreateIndex(0, 0)
unit := index.ParseTranslationUnit(
sourceFile,
unsafe.SliceData(args), 3,
nil, 0,
clang.DetailedPreprocessingRecord,
)
defer index.Dispose()
defer unit.Dispose()
if unit == nil {
println("Unable to parse translation unit. Quitting.")
c.Exit(1)
}
cursor := unit.Cursor()
Data := &Data{
Depth: 0,
Unit: unit,
}
printAST(cursor, Data)
}

View File

@@ -26,6 +26,7 @@ func GetConf(data []byte) (Conf, error) {
Libs: GetStringItem(parsedConf, "libs", ""), Libs: GetStringItem(parsedConf, "libs", ""),
Include: GetStringArrayItem(parsedConf, "include"), Include: GetStringArrayItem(parsedConf, "include"),
TrimPrefixes: GetStringArrayItem(parsedConf, "trimPrefixes"), TrimPrefixes: GetStringArrayItem(parsedConf, "trimPrefixes"),
Cplusplus: GetBoolItem(parsedConf, "cplusplus"),
} }
return Conf{ return Conf{
@@ -58,3 +59,14 @@ func GetStringArrayItem(obj *cjson.JSON, key string) (value []string) {
} }
return return
} }
func GetBoolItem(obj *cjson.JSON, key string) bool {
item := obj.GetObjectItemCaseSensitive(c.AllocaCStr(key))
if item == nil {
return false
}
if item.IsBool() != 0 {
return item.IsTrue() != 0
}
return false
}

View File

@@ -22,7 +22,6 @@ import (
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"unsafe" "unsafe"
@@ -61,11 +60,11 @@ func main() {
check(err) check(err)
filepaths := generateHeaderFilePath(conf.CFlags, conf.Include) filepaths := genHeaderFilePath(conf.CFlags, conf.Include)
astInfos, err := parse.ParseHeaderFile(filepaths) headerInfos, err := parse.ParseHeaderFile(filepaths, conf.TrimPrefixes)
check(err) check(err)
symbolInfo := getCommonSymbols(symbols, astInfos, conf.TrimPrefixes) symbolInfo := getCommonSymbols(symbols, headerInfos, conf.TrimPrefixes)
err = genSymbolTableFile(symbolInfo) err = genSymbolTableFile(symbolInfo)
check(err) check(err)
@@ -77,8 +76,8 @@ func check(err error) {
} }
} }
func parseDylibSymbols(lib string) ([]types.CPPSymbol, error) { func parseDylibSymbols(lib string) ([]*nm.Symbol, error) {
dylibPath, err := generateDylibPath(lib) dylibPath, err := genDylibPath(lib)
if err != nil { if err != nil {
return nil, errors.New("failed to generate dylib path") return nil, errors.New("failed to generate dylib path")
} }
@@ -88,22 +87,15 @@ func parseDylibSymbols(lib string) ([]types.CPPSymbol, error) {
return nil, errors.New("failed to list symbols in dylib") return nil, errors.New("failed to list symbols in dylib")
} }
var symbols []types.CPPSymbol var symbols []*nm.Symbol
for _, file := range files { for _, file := range files {
for _, sym := range file.Symbols { symbols = append(symbols, file.Symbols...)
demangleName := decodeSymbolName(sym.Name)
symbols = append(symbols, types.CPPSymbol{
Symbol: sym,
DemangleName: demangleName,
})
}
} }
return symbols, nil return symbols, nil
} }
func generateDylibPath(lib string) (string, error) { func genDylibPath(lib string) (string, error) {
output := lib output := lib
libPath := "" libPath := ""
libName := "" libName := ""
@@ -123,31 +115,20 @@ func generateDylibPath(lib string) (string, error) {
return dylibPath, nil return dylibPath, nil
} }
func decodeSymbolName(symbolName string) string { func decodeSymbol(symbolName string) string {
if symbolName == "" { if symbolName == "" {
return "" return ""
} }
demangled := llvm.ItaniumDemangle(symbolName, true) demangled := llvm.ItaniumDemangle(symbolName, true)
if demangled == nil { if demangled == nil {
return symbolName return symbolName
} }
defer c.Free(unsafe.Pointer(demangled)) defer c.Free(unsafe.Pointer(demangled))
demangleName := c.GoString(demangled) demangleName := c.GoString(demangled)
if demangleName == "" { return strings.TrimSpace(demangleName)
return symbolName
}
decodedName := strings.TrimSpace(demangleName)
decodedName = strings.ReplaceAll(decodedName,
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const",
"std::string")
return decodedName
} }
func generateHeaderFilePath(cflags string, files []string) []string { func genHeaderFilePath(cflags string, files []string) []string {
prefixPath := cflags prefixPath := cflags
prefixPath = strings.TrimPrefix(prefixPath, "-I") prefixPath = strings.TrimPrefix(prefixPath, "-I")
var includePaths []string var includePaths []string
@@ -157,82 +138,23 @@ func generateHeaderFilePath(cflags string, files []string) []string {
return includePaths return includePaths
} }
func getCommonSymbols(dylibSymbols []types.CPPSymbol, astInfoList []types.ASTInformation, prefix []string) []types.SymbolInfo { func getCommonSymbols(dylibSymbols []*nm.Symbol, symbolMap map[string]string, prefix []string) []*types.SymbolInfo {
var commonSymbols []types.SymbolInfo var commonSymbols []*types.SymbolInfo
functionNameMap := make(map[string]int)
for _, astInfo := range astInfoList {
for _, dylibSym := range dylibSymbols { for _, dylibSym := range dylibSymbols {
if strings.TrimPrefix(dylibSym.Name, "_") == astInfo.Symbol { symName := strings.TrimPrefix(dylibSym.Name, "_")
cppName := generateCPPName(astInfo) if goName, ok := symbolMap[symName]; ok {
functionNameMap[cppName]++ symbolInfo := &types.SymbolInfo{
symbolInfo := types.SymbolInfo{ Mangle: symName,
Mangle: strings.TrimPrefix(dylibSym.Name, "_"), CPP: decodeSymbol(dylibSym.Name),
CPP: cppName, Go: goName,
Go: generateMangle(astInfo, functionNameMap[cppName], prefix),
} }
commonSymbols = append(commonSymbols, symbolInfo) commonSymbols = append(commonSymbols, symbolInfo)
break
} }
} }
}
return commonSymbols return commonSymbols
} }
func generateCPPName(astInfo types.ASTInformation) string { func genSymbolTableFile(symbolInfos []*types.SymbolInfo) error {
cppName := astInfo.Name
if astInfo.Class != "" {
cppName = astInfo.Class + "::" + astInfo.Name
}
return cppName
}
func generateMangle(astInfo types.ASTInformation, count int, prefixes []string) string {
astInfo.Class = removePrefix(astInfo.Class, prefixes)
astInfo.Name = removePrefix(astInfo.Name, prefixes)
res := ""
if astInfo.Class != "" {
if astInfo.Class == astInfo.Name {
res = "(*" + astInfo.Class + ")." + "Init"
if count > 1 {
res += "__" + strconv.Itoa(count-1)
}
} else if astInfo.Name == "~"+astInfo.Class {
res = "(*" + astInfo.Class + ")." + "Dispose"
if count > 1 {
res += "__" + strconv.Itoa(count-1)
}
} else {
res = "(*" + astInfo.Class + ")." + astInfo.Name
if count > 1 {
res += "__" + strconv.Itoa(count-1)
}
}
} else {
res = astInfo.Name
if count > 1 {
res += "__" + strconv.Itoa(count-1)
}
}
return res
}
func removePrefix(str string, prefixes []string) string {
for _, prefix := range prefixes {
if strings.HasPrefix(str, prefix) {
return strings.TrimPrefix(str, prefix)
}
}
return str
}
func genSymbolTableFile(symbolInfos []types.SymbolInfo) error {
// keep open follow code block can run successfully
for i := range symbolInfos {
println("symbol", symbolInfos[i].Go)
}
fileName := "llcppg.symb.json" fileName := "llcppg.symb.json"
existingSymbols, err := readExistingSymbolTable(fileName) existingSymbols, err := readExistingSymbolTable(fileName)
if err != nil { if err != nil {
@@ -269,6 +191,7 @@ func genSymbolTableFile(symbolInfos []types.SymbolInfo) error {
} }
return nil return nil
} }
func readExistingSymbolTable(fileName string) (map[string]types.SymbolInfo, error) { func readExistingSymbolTable(fileName string) (map[string]types.SymbolInfo, error) {
existingSymbols := make(map[string]types.SymbolInfo) existingSymbols := make(map[string]types.SymbolInfo)

View File

@@ -3,23 +3,27 @@ package parse
import ( import (
"errors" "errors"
"strconv" "strconv"
"strings"
"unsafe" "unsafe"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/clang" "github.com/goplus/llgo/c/clang"
"github.com/goplus/llgo/chore/llcppg/types"
) )
type Context struct { type Context struct {
namespaceName string namespaceName string
className string className string
astInfo []types.ASTInformation prefixes []string
symbolMap map[string]string
currentFile string currentFile string
nameCounts map[string]int
} }
func newContext() *Context { func newContext(prefixes []string) *Context {
return &Context{ return &Context{
astInfo: make([]types.ASTInformation, 0), prefixes: prefixes,
symbolMap: make(map[string]string),
nameCounts: make(map[string]int),
} }
} }
@@ -35,70 +39,83 @@ func (c *Context) setCurrentFile(filename string) {
c.currentFile = filename c.currentFile = filename
} }
var context = newContext() func (c *Context) removePrefix(str string) string {
for _, prefix := range c.prefixes {
if strings.HasPrefix(str, prefix) {
return strings.TrimPrefix(str, prefix)
}
}
return str
}
func collectFuncInfo(cursor clang.Cursor) types.ASTInformation { func (c *Context) genGoName(name string) string {
class := c.removePrefix(c.className)
name = c.removePrefix(name)
info := types.ASTInformation{ var baseName string
Namespace: context.namespaceName, if class == "" {
Class: context.className, baseName = name
} else {
baseName = c.genMethodName(class, name)
} }
return c.addSuffix(baseName)
}
func (c *Context) genMethodName(class, name string) string {
prefix := "(*" + class + ")."
if class == name {
return prefix + "Init"
}
if name == "~"+class {
return prefix + "Dispose"
}
return prefix + name
}
func (c *Context) addSuffix(name string) string {
c.nameCounts[name]++
count := c.nameCounts[name]
if count > 1 {
return name + "__" + strconv.Itoa(count-1)
}
return name
}
var context = newContext([]string{})
func collectFuncInfo(cursor clang.Cursor) {
cursorStr := cursor.String() cursorStr := cursor.String()
symbol := cursor.Mangling() symbol := cursor.Mangling()
info.Name = c.GoString(cursorStr.CStr()) name := c.GoString(cursorStr.CStr())
symbolName := c.GoString(symbol.CStr())
info.Symbol = c.GoString(symbol.CStr()) if len(symbolName) >= 1 && symbolName[0] == '_' {
if len(info.Symbol) >= 1 { symbolName = symbolName[1:]
if info.Symbol[0] == '_' {
info.Symbol = info.Symbol[1:]
} }
}
defer symbol.Dispose() defer symbol.Dispose()
defer cursorStr.Dispose() defer cursorStr.Dispose()
if context.namespaceName != "" { goName := context.genGoName(name)
info.Namespace = context.namespaceName context.symbolMap[symbolName] = goName
}
if context.className != "" {
info.Class = context.className
}
typeStr := cursor.ResultType().String()
defer typeStr.Dispose()
info.ReturnType = c.GoString(typeStr.CStr())
info.Parameters = make([]types.Parameter, cursor.NumArguments())
for i := 0; i < int(cursor.NumArguments()); i++ {
argCurSor := cursor.Argument(c.Uint(i))
argType := argCurSor.Type().String()
argName := argCurSor.String()
info.Parameters[i] = types.Parameter{
Name: c.GoString(argName.CStr()),
Type: c.GoString(argType.CStr()),
}
argType.Dispose()
argName.Dispose()
}
return info
} }
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult { func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
if cursor.Kind == clang.Namespace { if cursor.Kind == clang.CursorNamespace {
nameStr := cursor.String() nameStr := cursor.String()
defer nameStr.Dispose()
context.setNamespaceName(c.GoString(nameStr.CStr())) context.setNamespaceName(c.GoString(nameStr.CStr()))
clang.VisitChildren(cursor, visit, nil) clang.VisitChildren(cursor, visit, nil)
context.setNamespaceName("") context.setNamespaceName("")
} else if cursor.Kind == clang.ClassDecl { } else if cursor.Kind == clang.CursorClassDecl {
nameStr := cursor.String() nameStr := cursor.String()
defer nameStr.Dispose()
context.setClassName(c.GoString(nameStr.CStr())) context.setClassName(c.GoString(nameStr.CStr()))
clang.VisitChildren(cursor, visit, nil) clang.VisitChildren(cursor, visit, nil)
context.setClassName("") context.setClassName("")
} else if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl || cursor.Kind == clang.Constructor || cursor.Kind == clang.Destructor { } else if cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorFunctionDecl || cursor.Kind == clang.CursorConstructor || cursor.Kind == clang.CursorDestructor {
loc := cursor.Location() loc := cursor.Location()
var file clang.File var file clang.File
var line, column c.Uint var line, column c.Uint
@@ -107,9 +124,7 @@ func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitRe
filename := file.FileName() filename := file.FileName()
if c.Strcmp(filename.CStr(), c.AllocaCStr(context.currentFile)) == 0 { if c.Strcmp(filename.CStr(), c.AllocaCStr(context.currentFile)) == 0 {
info := collectFuncInfo(cursor) collectFuncInfo(cursor)
info.Location = c.GoString(filename.CStr()) + ":" + strconv.Itoa(int(line)) + ":" + strconv.Itoa(int(column))
context.astInfo = append(context.astInfo, info)
} }
defer filename.Dispose() defer filename.Dispose()
@@ -118,14 +133,13 @@ func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitRe
return clang.ChildVisit_Continue return clang.ChildVisit_Continue
} }
func ParseHeaderFile(filepaths []string) ([]types.ASTInformation, error) { func ParseHeaderFile(filepaths []string, prefixes []string) (map[string]string, error) {
index := clang.CreateIndex(0, 0) index := clang.CreateIndex(0, 0)
args := make([]*c.Char, 3) args := make([]*c.Char, 3)
args[0] = c.Str("-x") args[0] = c.Str("-x")
args[1] = c.Str("c++") args[1] = c.Str("c++")
args[2] = c.Str("-std=c++11") args[2] = c.Str("-std=c++11")
context = newContext() context = newContext(prefixes)
for _, filename := range filepaths { for _, filename := range filepaths {
unit := index.ParseTranslationUnit( unit := index.ParseTranslationUnit(
@@ -149,5 +163,5 @@ func ParseHeaderFile(filepaths []string) ([]types.ASTInformation, error) {
index.Dispose() index.Dispose()
return context.astInfo, nil return context.symbolMap, nil
} }

378
chore/llcppg/ast/ast.go Normal file
View File

@@ -0,0 +1,378 @@
/*
* 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 ast
import "github.com/goplus/llgo/chore/llcppg/token"
// =============================================================================
type Node interface {
}
type Expr interface {
Node
exprNode()
}
type Decl interface {
Node
declNode()
}
type Stmt interface {
Node
stmtNode()
}
type PPD interface { // preprocessing directive
Node
ppdNode()
}
// =============================================================================
type AccessSpecifier uint
const (
Invalid AccessSpecifier = iota
Public
Protected
Private
)
// =============================================================================
// Expressions (Types are also expressions)
type BasicLitKind uint
const (
IntLit BasicLitKind = iota
FloatLit
CharLit
StringLit
)
type BasicLit struct {
Kind BasicLitKind
Value string
}
func (*BasicLit) exprNode() {}
// ------------------------------------------------
type TypeKind uint
const (
Void TypeKind = iota
Bool
Char
Char16
Char32
WChar
Int
Int128
Float
Float16
Float128
Complex
)
type TypeFlag uint
const (
Signed TypeFlag = 1 << iota
Unsigned
Long
LongLong
Double
Short
)
// [signed/unsigned/short/long/long long/double] [int]/char/float/complex/bool
type BuiltinType struct {
Kind TypeKind
Flags TypeFlag
}
func (*BuiltinType) exprNode() {}
// ------------------------------------------------
// Name
type Ident struct {
Name string
}
func (*Ident) exprNode() {}
// ------------------------------------------------
type Tag int
const (
Struct Tag = iota
Union
Enum
Class
)
// struct/union/enum/class (A::B::)Name
type TagExpr struct {
Tag Tag
Name Expr // ScopingExpr, Ident
}
func (*TagExpr) exprNode() {}
// ------------------------------------------------
// type a, ...
type Variadic struct {
}
func (*Variadic) exprNode() {}
// ------------------------------------------------
// (X)
type ParenExpr struct {
X Expr
}
func (*ParenExpr) exprNode() {}
// ------------------------------------------------
// Parent::X
type ScopingExpr struct {
Parent Expr
X Expr
}
func (*ScopingExpr) exprNode() {}
// ------------------------------------------------
// X*
type PointerType struct {
X Expr
}
func (*PointerType) exprNode() {}
// ------------------------------------------------
// X&
type LvalueRefType struct {
X Expr
}
func (*LvalueRefType) exprNode() {}
// X&&
type RvalueRefType struct {
X Expr
}
func (*RvalueRefType) exprNode() {}
// ------------------------------------------------
// Elt[Len]
// Elt[]
type ArrayType struct {
Elt Expr
Len Expr // optional
}
func (*ArrayType) exprNode() {}
// ------------------------------------------------
type Comment struct {
Text string // comment text (excluding '\n' for //-style comments)
}
func (*Comment) exprNode() {}
type CommentGroup struct {
List []*Comment // len(List) > 0
}
func (*CommentGroup) exprNode() {}
// ------------------------------------------------
type Field struct {
Doc *CommentGroup // associated documentation; or nil
Type Expr // field/method/parameter type; or nil
Names []*Ident // field/method/(type) parameter names; or nil
Comment *CommentGroup // line comments; or nil
Access AccessSpecifier // field access(Record Type); Struct Field default is Public,Class Field default is Private
IsStatic bool // static field
}
func (*Field) exprNode() {}
type FieldList struct {
List []*Field // field list; or nil
}
func (*FieldList) exprNode() {}
// ------------------------------------------------
// Ret (*)(Params)
type FuncType struct {
Params *FieldList
Ret Expr
}
func (*FuncType) exprNode() {}
// ------------------------------------------------
type RecordType struct {
Tag Tag
Fields *FieldList
Methods []*FuncDecl
}
func (*RecordType) exprNode() {}
// ------------------------------------------------
// Template<Arg1, Arg2, ...>
type InstantiationType struct {
Template Expr
Args *FieldList
}
func (*InstantiationType) exprNode() {}
// =============================================================================
// Declarations
type Location struct {
File string
}
type DeclBase struct {
Doc *CommentGroup // associated documentation; or nil
Loc *Location
Parent Expr // namespace or class
}
// ------------------------------------------------
// typedef Type Name;
type TypedefDecl struct {
DeclBase
Type Expr
Name *Ident
}
func (*TypedefDecl) declNode() {}
// ------------------------------------------------
type EnumItem struct {
Name *Ident
Value Expr // optional
}
func (*EnumItem) exprNode() {}
type EnumType struct {
Items []*EnumItem
}
func (*EnumType) exprNode() {}
// enum Name { Item1, Item2, ... };
type EnumTypeDecl struct {
DeclBase
Name *Ident
Type *EnumType
}
func (*EnumTypeDecl) declNode() {}
// ------------------------------------------------
// Ret Name(Params);
type FuncDecl struct {
DeclBase
Name *Ident
Type *FuncType
IsInline bool
IsStatic bool
// Class method specific fields
IsConst bool // const member function
IsExplicit bool // explicit constructor
IsConstructor bool
IsDestructor bool
IsVirtual bool
IsOverride bool
}
func (*FuncDecl) declNode() {}
// ------------------------------------------------
// struct/union/class Name { Field1, Field2, ... };
type TypeDecl struct {
DeclBase
Name *Ident
Type *RecordType
}
func (*TypeDecl) declNode() {}
// =============================================================================
// AST File
type Include struct {
Path string `json:"path"`
}
func (*Include) ppdNode() {}
// ------------------------------------------------
type Token struct {
Token token.Token
Lit string
}
type Macro struct {
Name string
Tokens []*Token // Tokens[0].Lit is the macro name
}
func (*Macro) ppdNode() {}
// ------------------------------------------------
type File struct {
Decls []Decl `json:"decls"`
Includes []*Include `json:"includes,omitempty"`
Macros []*Macro `json:"macros,omitempty"`
}
// =============================================================================

View File

@@ -18,7 +18,8 @@ If `config-file` is not specified, a `llcppg.cfg` file is used in current direct
"AnotherHeaderFile.h" "AnotherHeaderFile.h"
], ],
"libs": "$(pkg-config --libs inireader)", "libs": "$(pkg-config --libs inireader)",
"trimPrefixes": ["Ini", "INI"] "trimPrefixes": ["Ini", "INI"],
"cplusplus":true
} }
``` ```
@@ -59,8 +60,21 @@ llcppsigfetch - # read config from stdin
It fetches information of C/C++ symbols and print to stdout. Its format is as follows: It fetches information of C/C++ symbols and print to stdout. Its format is as follows:
``` ```json
TODO: see llgo/xtool/clang/ast [
{
"path": "/path/to/file.h",
"doc": {
"decls": [],
"macros": [],
"includes": [
{
"path": "incfile.h"
}
]
}
}
]
``` ```
### gogensig ### gogensig
@@ -69,252 +83,3 @@ TODO: see llgo/xtool/clang/ast
gogensig ast-file gogensig ast-file
gogensig - # read AST from stdin gogensig - # read AST from stdin
``` ```
## Overall
### Process
1. The Parsing Module reads `llcppg.cfg` to obtain dynamic libraries, header files, and the package name. After parsing, it writes the generated `llcppg.symb.json` path into `llcppg.cfg`.
2. The Function Declaration Generation Module reads `llcppg.cfg` to get the package name, header files, and the previously generated `llcppg.symb.json`. After parsing, it generates the function prototype `llcppg.function.json`.
3. Reads the previously generated `llcppg.information.json`, stores it as a structure, and uses gogen to generate code based on the structure.
## Parsing Module
### Input
Obtains the paths to header files and dynamic library files by reading the JSON file `llcppg.cfg`.
```json
{
"name": "inih",
"cflags": "$(pkg-config --cflags INIReader)",
"include": [
"INIReader.h",
"AnotherHeaderFile.h"
],
"libs": "$(pkg-config --libs INIReader)",
"trimPrefixes": ["Ini", "INI"]
}
```
```bash
llcppsymg config-file
```
### Implementation Steps
1. Parse dylib and store:
```go
// types.go
type CPPSymbol struct {
Symbol string `json:"symbol"`
Type string `json:"type"`
Name string `json:"name"`
}
// parser_dylib.go
func parseDylibSymbols(lib string) ([]common.CPPSymbol, error)
```
2. Parse header files and store:
```go
// common.go
type ASTInformation struct {
Namespace string `json:"namespace"`
Class string `json:"class"`
Name string `json:"name"`
BaseClasses []string `json:"baseClasses"`
ReturnType string `json:"returnType"`
Location string `json:"location"`
Parameters []Parameter `json:"parameters"`
Symbol string `json:"symbol"`
}
type Parameter struct {
Name string `json:"name"`
Type string `json:"type"`
}
// parser_ast.go
func parseHeaderFile(config types.Config) ([]common.ASTInformation, error)
```
3. Cross-reference data from the first two steps to get the final output
```go
// common.go
type SymbolInfo struct {
Mangle string `json:"mangle"` // C++ Symbol
CPP string `json:"c++"` // C++ function name
Go string `json:"go"` // Go function name
}
// common_symbols.go
func getCommonSymbols(dylibSymbols []common.CPPSymbol, astInfoList []common.ASTInformation) []common.SymbolInfo {
```
4. Generate `llcppg.symb.json` file and store the JSON file path into `llcppg.cfg`
```go
func generateJSON([]CommonSymbolInfo)
```
5. Example `llcppg.symb.json` file
```json
{
"FunctionName": "A::B::C",
"Symbol": "_ZN9INIReaderC1ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE",
"Location": "a.h",
"UserFunctionName": "CFromA"
}
```
## Function Declaration Generation Module
### Input
No input required, directly reads the `llcppg.cfg` file
### Implementation Steps
1. Execute the executable
```bash
llcppsigfetch config-file
```
2. Parse header files
```go
// common.go
type ASTInformation struct {
Namespace string `json:"namespace"`
Class string `json:"class"`
Name string `json:"name"`
BaseClasses []string `json:"baseClasses"`
ReturnType string `json:"returnType"`
Location string `json:"location"`
Parameters []Parameter `json:"parameters"`
Symbol string `json:"symbol"`
}
type Parameter struct {
Name string `json:"name"`
Type string `json:"type"`
}
// parser_ast.go
func ParseHeaderFile(filePath string) ([]common.ASTInformation, error)
```
3. Generate the final JSON mapping file `llcppg.information.json`
```go
func GenerateJSONFile(info []common.ASTInformation)
```
```json
{
"functionName": "A::B::C",
"symbol": "_ZN9INIReaderC1ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE",
"location": "a.h",
"returnType": "int",
"userFunctionName": "CFromA",
"parameters": [
{
"arg1": "int"
},
{
"arg2": "*char"
}
]
}
```
## Code Generation Module
### Input
No input required, directly reads `llcppg.information.json` file
### Implementation Steps
1. Execute the executable
```bash
gogensig ast-file
```
2. Parse JSON file
```go
// common.go
type HeaderFileInfo struct {
FunctionName string `json:"functionName"`
Symbol string `json:"symbol"`
Location string `json:"location"`
UserFunctionName string `json:"userFunctionName"`
Parameters map[string]string `json:"parameters"`
}
// parse_json.go
func ParseJSON(jsonFilePath string) ([]common.HeaderFileInfo, error)
```
3. Generate code using the parsed structure with gogen
```go
// generator.go
func GenerateCode(info []common.HeaderFileInfo) {
pkg := gogen.NewPackage("", PackageName, nil)
cm := comment(fmt.Sprintf("llgo:link %s %s", funcName1, symbol1))
pkg.NewFunc(recv, funcName, params, results, variadic).SetComments(pkg, cm).BodyStart(pkg).End()
}
```
### Output
1. Directory structure
```bash
package_name/
├── _demo
├── demo1.go
└── llgo_link.go
└── a.go
└── b.go
└── c.go
```
Note that `demo1.go` file needs to be written by the user
2. `llgo_link.go` is responsible for linking configuration
```go
package inih
const (
LLGoFiles = "$(pkg-config --cflags INIReader): _wrap/reader.cpp"
LLGoPackage = "link: $(pkg-config --libs inih INIReader); -linih -lINIReader"
)
```
3. Example content for `a.go`
```go
package inih
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
//go:linkname Parse C.ini_parse
func Parse(filename *c.Char, handler func(user c.Pointer, section *c.Char, name *c.Char, value *c.Char) c.Int, user c.Pointer) c.Int
//go:linkname ParseFile C.ini_parse_file
func ParseFile(file c.FilePtr, handler func(user c.Pointer, section *c.Char, name *c.Char, value *c.Char) c.Int, user c.Pointer) c.Int
//go:linkname ParseString C.ini_parse_string
func ParseString(str *c.Char, handler func(user c.Pointer, section *c.Char, name *c.Char, value *c.Char) c.Int, user c.Pointer) c.Int
```

View File

@@ -0,0 +1,32 @@
package token
type Token uint
const (
ILLEGAL Token = iota
/**
* A token that contains some kind of punctuation.
*/
PUNCT
/**
* A language keyword.
*/
KEYWORD
/**
* An identifier (that is not a keyword).
*/
IDENT
/**
* A numeric, string, or character literal.
*/
LITERAL
/**
* A comment.
*/
COMMENT
)

View File

@@ -16,10 +16,6 @@
package types package types
import (
"github.com/goplus/llgo/xtool/nm"
)
// Config represents a configuration for the llcppg tool. // Config represents a configuration for the llcppg tool.
type Config struct { type Config struct {
Name string `json:"name"` Name string `json:"name"`
@@ -27,27 +23,7 @@ type Config struct {
Libs string `json:"libs"` Libs string `json:"libs"`
Include []string `json:"include"` Include []string `json:"include"`
TrimPrefixes []string `json:"trimPrefixes"` TrimPrefixes []string `json:"trimPrefixes"`
} Cplusplus bool `json:"cplusplus"`
type CPPSymbol struct {
DemangleName string
*nm.Symbol
}
type ASTInformation struct {
Namespace string `json:"namespace"`
Class string `json:"class"`
Name string `json:"name"`
BaseClasses []string `json:"baseClasses"`
ReturnType string `json:"returnType"`
Location string `json:"location"`
Parameters []Parameter `json:"parameters"`
Symbol string `json:"symbol"`
}
type Parameter struct {
Name string `json:"name"`
Type string `json:"type"`
} }
type SymbolInfo struct { type SymbolInfo struct {

View File

@@ -0,0 +1,7 @@
//go:build llgo
// +build llgo
package llgotag
func Foo() {
}

View File

@@ -0,0 +1,22 @@
; ModuleID = 'llgotag'
source_filename = "llgotag"
@"llgotag.init$guard" = global i1 false, align 1
define void @llgotag.Foo() {
_llgo_0:
ret void
}
define void @llgotag.init() {
_llgo_0:
%0 = load i1, ptr @"llgotag.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"llgotag.init$guard", align 1
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}

View File

@@ -543,10 +543,12 @@ _llgo_0:
define void @"main.init#7"() { define void @"main.init#7"() {
_llgo_0: _llgo_0:
%0 = load ptr, ptr @"map[_llgo_int]_llgo_string", align 8 %0 = load ptr, ptr @_llgo_int, align 8
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.MakeMap"(ptr %0, i64 0) %1 = load ptr, ptr @_llgo_string, align 8
%2 = icmp ne ptr %1, null %2 = load ptr, ptr @"map[_llgo_int]_llgo_string", align 8
call void @main.assert(i1 %2) %3 = call ptr @"github.com/goplus/llgo/internal/runtime.MakeMap"(ptr %2, i64 0)
%4 = icmp ne ptr %3, null
call void @main.assert(i1 %4)
call void @main.assert(i1 true) call void @main.assert(i1 true)
ret void ret void
} }

View File

@@ -10,15 +10,15 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/abi.Imethod" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr } %"github.com/goplus/llgo/internal/abi.Imethod" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr }
@"main.init$guard" = global i1 false, align 1 @"main.init$guard" = global i1 false, align 1
@_llgo_main.errorString = global ptr null, align 8 @_llgo_main.errorString = linkonce global ptr null, align 8
@"main.struct$QTufDJA9wEDzuzgkA-ZSrLqW-B6lWN8O25mTSglAoLQ" = global ptr null, align 8 @"main.struct$QTufDJA9wEDzuzgkA-ZSrLqW-B6lWN8O25mTSglAoLQ" = linkonce global ptr null, align 8
@0 = private unnamed_addr constant [1 x i8] c"s", align 1 @0 = private unnamed_addr constant [1 x i8] c"s", align 1
@1 = private unnamed_addr constant [4 x i8] c"main", align 1 @1 = private unnamed_addr constant [4 x i8] c"main", align 1
@2 = private unnamed_addr constant [5 x i8] c"Error", align 1 @2 = private unnamed_addr constant [5 x i8] c"Error", align 1
@"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to" = linkonce global ptr null, align 8 @"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to" = linkonce global ptr null, align 8
@_llgo_string = linkonce global ptr null, align 8 @_llgo_string = linkonce global ptr null, align 8
@3 = private unnamed_addr constant [11 x i8] c"errorString", align 1 @3 = private unnamed_addr constant [11 x i8] c"errorString", align 1
@"*_llgo_main.errorString" = global ptr null, align 8 @"*_llgo_main.errorString" = linkonce global ptr null, align 8
@"_llgo_iface$Fh8eUJ-Gw4e6TYuajcFIOSCuqSPKAt5nS4ow7xeGXEU" = linkonce global ptr null, align 8 @"_llgo_iface$Fh8eUJ-Gw4e6TYuajcFIOSCuqSPKAt5nS4ow7xeGXEU" = linkonce global ptr null, align 8
@__llgo_argc = global i32 0, align 4 @__llgo_argc = global i32 0, align 4
@__llgo_argv = global ptr null, align 8 @__llgo_argv = global ptr null, align 8

View File

@@ -2,6 +2,7 @@
source_filename = "main" source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/c/pthread.RoutineFunc" = type { ptr, ptr }
@"main.init$guard" = global i1 false, align 1 @"main.init$guard" = global i1 false, align 1
@__llgo_argc = global i32 0, align 4 @__llgo_argc = global i32 0, align 4
@@ -51,25 +52,31 @@ _llgo_0:
%15 = getelementptr inbounds { { ptr, ptr }, %"github.com/goplus/llgo/internal/runtime.String" }, ptr %13, i32 0, i32 1 %15 = getelementptr inbounds { { ptr, ptr }, %"github.com/goplus/llgo/internal/runtime.String" }, ptr %13, i32 0, i32 1
store %"github.com/goplus/llgo/internal/runtime.String" %12, ptr %15, align 8 store %"github.com/goplus/llgo/internal/runtime.String" %12, ptr %15, align 8
%16 = alloca i8, i64 8, align 1 %16 = alloca i8, i64 8, align 1
%17 = call i32 @pthread_create(ptr %16, ptr null, ptr @"main._llgo_routine$1", ptr %13) %17 = alloca %"github.com/goplus/llgo/c/pthread.RoutineFunc", align 8
%18 = getelementptr inbounds %"github.com/goplus/llgo/c/pthread.RoutineFunc", ptr %17, i32 0, i32 0
store ptr @"__llgo_stub.main._llgo_routine$1", ptr %18, align 8
%19 = getelementptr inbounds %"github.com/goplus/llgo/c/pthread.RoutineFunc", ptr %17, i32 0, i32 1
store ptr null, ptr %19, align 8
%20 = load %"github.com/goplus/llgo/c/pthread.RoutineFunc", ptr %17, align 8
%21 = call i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr %16, ptr null, %"github.com/goplus/llgo/c/pthread.RoutineFunc" %20, ptr %13)
br label %_llgo_3 br label %_llgo_3
_llgo_1: ; preds = %_llgo_3 _llgo_1: ; preds = %_llgo_3
%18 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %22 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i32 0, i32 0 %23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 0
store ptr @1, ptr %19, align 8 store ptr @1, ptr %23, align 8
%20 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i32 0, i32 1 %24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 1
store i64 1, ptr %20, align 4 store i64 1, ptr %24, align 4
%21 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %18, align 8 %25 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %22, align 8
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %21) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %25)
br label %_llgo_3 br label %_llgo_3
_llgo_2: ; preds = %_llgo_3 _llgo_2: ; preds = %_llgo_3
ret i32 0 ret i32 0
_llgo_3: ; preds = %_llgo_1, %_llgo_0 _llgo_3: ; preds = %_llgo_1, %_llgo_0
%22 = load i1, ptr %2, align 1 %26 = load i1, ptr %2, align 1
br i1 %22, label %_llgo_2, label %_llgo_1 br i1 %26, label %_llgo_2, label %_llgo_1
} }
define void @"main.main$1"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1) { define void @"main.main$1"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1) {
@@ -104,7 +111,13 @@ _llgo_0:
declare void @free(ptr) declare void @free(ptr)
declare i32 @pthread_create(ptr, ptr, ptr, ptr) declare i32 @"github.com/goplus/llgo/internal/runtime.CreateThread"(ptr, ptr, %"github.com/goplus/llgo/c/pthread.RoutineFunc", ptr)
define linkonce ptr @"__llgo_stub.main._llgo_routine$1"(ptr %0, ptr %1) {
_llgo_0:
%2 = tail call ptr @"main._llgo_routine$1"(ptr %1)
ret ptr %2
}
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")

View File

@@ -23,12 +23,12 @@ source_filename = "main"
@"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac" = linkonce global ptr null, align 8 @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac" = linkonce global ptr null, align 8
@3 = private unnamed_addr constant [6 x i8] c"main.f", align 1 @3 = private unnamed_addr constant [6 x i8] c"main.f", align 1
@4 = private unnamed_addr constant [7 x i8] c"main.I1", align 1 @4 = private unnamed_addr constant [7 x i8] c"main.I1", align 1
@"main.iface$brpgdLtIeRlPi8QUoTgPCXzlehUkncg7v9aITo-GsF4" = global ptr null, align 8 @"main.iface$brpgdLtIeRlPi8QUoTgPCXzlehUkncg7v9aITo-GsF4" = linkonce global ptr null, align 8
@5 = private unnamed_addr constant [21 x i8] c"nil i1.(I1) succeeded", align 1 @5 = private unnamed_addr constant [21 x i8] c"nil i1.(I1) succeeded", align 1
@_llgo_main.I2 = linkonce global ptr null, align 8 @_llgo_main.I2 = linkonce global ptr null, align 8
@6 = private unnamed_addr constant [6 x i8] c"main.g", align 1 @6 = private unnamed_addr constant [6 x i8] c"main.g", align 1
@7 = private unnamed_addr constant [7 x i8] c"main.I2", align 1 @7 = private unnamed_addr constant [7 x i8] c"main.I2", align 1
@"main.iface$gZBF8fFlqIMZ9M6lT2VWPyc3eu5Co6j0WoKGIEgDPAw" = global ptr null, align 8 @"main.iface$gZBF8fFlqIMZ9M6lT2VWPyc3eu5Co6j0WoKGIEgDPAw" = linkonce global ptr null, align 8
@8 = private unnamed_addr constant [21 x i8] c"nil i2.(I2) succeeded", align 1 @8 = private unnamed_addr constant [21 x i8] c"nil i2.(I2) succeeded", align 1
@_llgo_main.C1 = linkonce global ptr null, align 8 @_llgo_main.C1 = linkonce global ptr null, align 8
@"_llgo_struct$n1H8J_3prDN3firMwPxBLVTkE5hJ9Di-AqNvaC9jczw" = linkonce global ptr null, align 8 @"_llgo_struct$n1H8J_3prDN3firMwPxBLVTkE5hJ9Di-AqNvaC9jczw" = linkonce global ptr null, align 8

View File

@@ -15,7 +15,7 @@ source_filename = "main"
@0 = private unnamed_addr constant [3 x i8] c"two", align 1 @0 = private unnamed_addr constant [3 x i8] c"two", align 1
@__llgo_argc = global i32 0, align 4 @__llgo_argc = global i32 0, align 4
@__llgo_argv = global ptr null, align 8 @__llgo_argv = global ptr null, align 8
@_llgo_main.impl = global ptr null, align 8 @_llgo_main.impl = linkonce global ptr null, align 8
@"_llgo_struct$n1H8J_3prDN3firMwPxBLVTkE5hJ9Di-AqNvaC9jczw" = linkonce global ptr null, align 8 @"_llgo_struct$n1H8J_3prDN3firMwPxBLVTkE5hJ9Di-AqNvaC9jczw" = linkonce global ptr null, align 8
@1 = private unnamed_addr constant [4 x i8] c"main", align 1 @1 = private unnamed_addr constant [4 x i8] c"main", align 1
@2 = private unnamed_addr constant [3 x i8] c"one", align 1 @2 = private unnamed_addr constant [3 x i8] c"one", align 1
@@ -26,7 +26,7 @@ source_filename = "main"
@"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to" = linkonce global ptr null, align 8 @"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to" = linkonce global ptr null, align 8
@_llgo_string = linkonce global ptr null, align 8 @_llgo_string = linkonce global ptr null, align 8
@5 = private unnamed_addr constant [4 x i8] c"impl", align 1 @5 = private unnamed_addr constant [4 x i8] c"impl", align 1
@"main.iface$zZ89tENb5h_KNjvpxf1TXPfaWFYn0IZrZwyVf42lRtA" = global ptr null, align 8 @"main.iface$zZ89tENb5h_KNjvpxf1TXPfaWFYn0IZrZwyVf42lRtA" = linkonce global ptr null, align 8
@_llgo_main.I = linkonce global ptr null, align 8 @_llgo_main.I = linkonce global ptr null, align 8
@6 = private unnamed_addr constant [6 x i8] c"main.I", align 1 @6 = private unnamed_addr constant [6 x i8] c"main.I", align 1
@7 = private unnamed_addr constant [21 x i8] c"type assertion failed", align 1 @7 = private unnamed_addr constant [21 x i8] c"type assertion failed", align 1

View File

@@ -31,7 +31,7 @@ source_filename = "main"
@"_llgo_github.com/goplus/llgo/cl/internal/foo.Gamer" = linkonce global ptr null, align 8 @"_llgo_github.com/goplus/llgo/cl/internal/foo.Gamer" = linkonce global ptr null, align 8
@8 = private unnamed_addr constant [38 x i8] c"github.com/goplus/llgo/cl/internal/foo", align 1 @8 = private unnamed_addr constant [38 x i8] c"github.com/goplus/llgo/cl/internal/foo", align 1
@9 = private unnamed_addr constant [44 x i8] c"github.com/goplus/llgo/cl/internal/foo.Gamer", align 1 @9 = private unnamed_addr constant [44 x i8] c"github.com/goplus/llgo/cl/internal/foo.Gamer", align 1
@"main.iface$sO8a1LvuUsjXwiwaC6sR9-L4DiYgiOnZi7iosyShJXg" = global ptr null, align 8 @"main.iface$sO8a1LvuUsjXwiwaC6sR9-L4DiYgiOnZi7iosyShJXg" = linkonce global ptr null, align 8
@10 = private unnamed_addr constant [2 x i8] c"OK", align 1 @10 = private unnamed_addr constant [2 x i8] c"OK", align 1
@11 = private unnamed_addr constant [4 x i8] c"FAIL", align 1 @11 = private unnamed_addr constant [4 x i8] c"FAIL", align 1

View File

@@ -24,7 +24,7 @@ source_filename = "main"
@__llgo_argv = global ptr null, align 8 @__llgo_argv = global ptr null, align 8
@7 = private unnamed_addr constant [5 x i8] c"hello", align 1 @7 = private unnamed_addr constant [5 x i8] c"hello", align 1
@_llgo_main.T = linkonce global ptr null, align 8 @_llgo_main.T = linkonce global ptr null, align 8
@"main.struct$QTufDJA9wEDzuzgkA-ZSrLqW-B6lWN8O25mTSglAoLQ" = global ptr null, align 8 @"main.struct$QTufDJA9wEDzuzgkA-ZSrLqW-B6lWN8O25mTSglAoLQ" = linkonce global ptr null, align 8
@8 = private unnamed_addr constant [1 x i8] c"s", align 1 @8 = private unnamed_addr constant [1 x i8] c"s", align 1
@9 = private unnamed_addr constant [4 x i8] c"main", align 1 @9 = private unnamed_addr constant [4 x i8] c"main", align 1
@10 = private unnamed_addr constant [6 x i8] c"Invoke", align 1 @10 = private unnamed_addr constant [6 x i8] c"Invoke", align 1
@@ -51,12 +51,12 @@ source_filename = "main"
@16 = private unnamed_addr constant [2 x i8] c"T4", align 1 @16 = private unnamed_addr constant [2 x i8] c"T4", align 1
@"*_llgo_main.T4" = linkonce global ptr null, align 8 @"*_llgo_main.T4" = linkonce global ptr null, align 8
@_llgo_main.T5 = linkonce global ptr null, align 8 @_llgo_main.T5 = linkonce global ptr null, align 8
@"main.struct$eovYmOhZg4X0zMSsuscSshndnbbAGvB2E3cyG8E7Y4U" = global ptr null, align 8 @"main.struct$eovYmOhZg4X0zMSsuscSshndnbbAGvB2E3cyG8E7Y4U" = linkonce global ptr null, align 8
@17 = private unnamed_addr constant [1 x i8] c"n", align 1 @17 = private unnamed_addr constant [1 x i8] c"n", align 1
@18 = private unnamed_addr constant [2 x i8] c"T5", align 1 @18 = private unnamed_addr constant [2 x i8] c"T5", align 1
@"*_llgo_main.T5" = linkonce global ptr null, align 8 @"*_llgo_main.T5" = linkonce global ptr null, align 8
@_llgo_main.T6 = linkonce global ptr null, align 8 @_llgo_main.T6 = linkonce global ptr null, align 8
@"main.struct$2bSfJcCYDdttnIT-JASAjsTNUZvojBt4mPXFJdH4M10" = global ptr null, align 8 @"main.struct$2bSfJcCYDdttnIT-JASAjsTNUZvojBt4mPXFJdH4M10" = linkonce global ptr null, align 8
@_llgo_Pointer = linkonce global ptr null, align 8 @_llgo_Pointer = linkonce global ptr null, align 8
@19 = private unnamed_addr constant [1 x i8] c"f", align 1 @19 = private unnamed_addr constant [1 x i8] c"f", align 1
@20 = private unnamed_addr constant [4 x i8] c"data", align 1 @20 = private unnamed_addr constant [4 x i8] c"data", align 1

View File

@@ -34,7 +34,7 @@ source_filename = "main"
@5 = private unnamed_addr constant [7 x i8] c"WriteTo", align 1 @5 = private unnamed_addr constant [7 x i8] c"WriteTo", align 1
@6 = private unnamed_addr constant [13 x i8] c"main.WriterTo", align 1 @6 = private unnamed_addr constant [13 x i8] c"main.WriterTo", align 1
@"_llgo_iface$eN81k1zqixGTyagHw_4nqH4mGfwwehTOCTXUlbT9kzk" = linkonce global ptr null, align 8 @"_llgo_iface$eN81k1zqixGTyagHw_4nqH4mGfwwehTOCTXUlbT9kzk" = linkonce global ptr null, align 8
@_llgo_main.nopCloserWriterTo = global ptr null, align 8 @_llgo_main.nopCloserWriterTo = linkonce global ptr null, align 8
@"_llgo_struct$_3ow4zXXILqvC0WDqDRNq5DPhjE1DInJgN924VHWc2Y" = linkonce global ptr null, align 8 @"_llgo_struct$_3ow4zXXILqvC0WDqDRNq5DPhjE1DInJgN924VHWc2Y" = linkonce global ptr null, align 8
@7 = private unnamed_addr constant [6 x i8] c"Reader", align 1 @7 = private unnamed_addr constant [6 x i8] c"Reader", align 1
@8 = private unnamed_addr constant [4 x i8] c"Read", align 1 @8 = private unnamed_addr constant [4 x i8] c"Read", align 1
@@ -43,7 +43,7 @@ source_filename = "main"
@"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w" = linkonce global ptr null, align 8 @"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w" = linkonce global ptr null, align 8
@11 = private unnamed_addr constant [17 x i8] c"nopCloserWriterTo", align 1 @11 = private unnamed_addr constant [17 x i8] c"nopCloserWriterTo", align 1
@"_llgo_iface$L2Ik-AJcd0jsoBw5fQ07pQpfUM-kh78Wn2bOeak6M3I" = linkonce global ptr null, align 8 @"_llgo_iface$L2Ik-AJcd0jsoBw5fQ07pQpfUM-kh78Wn2bOeak6M3I" = linkonce global ptr null, align 8
@_llgo_main.nopCloser = global ptr null, align 8 @_llgo_main.nopCloser = linkonce global ptr null, align 8
@12 = private unnamed_addr constant [9 x i8] c"nopCloser", align 1 @12 = private unnamed_addr constant [9 x i8] c"nopCloser", align 1
@_llgo_main.StringWriter = linkonce global ptr null, align 8 @_llgo_main.StringWriter = linkonce global ptr null, align 8
@"_llgo_func$thH5FBpdXzJNnCpSfiLU5ItTntFU6LWp0RJhDm2XJjw" = linkonce global ptr null, align 8 @"_llgo_func$thH5FBpdXzJNnCpSfiLU5ItTntFU6LWp0RJhDm2XJjw" = linkonce global ptr null, align 8
@@ -55,8 +55,8 @@ source_filename = "main"
@__llgo_argc = global i32 0, align 4 @__llgo_argc = global i32 0, align 4
@__llgo_argv = global ptr null, align 8 @__llgo_argv = global ptr null, align 8
@17 = private unnamed_addr constant [11 x i8] c"hello world", align 1 @17 = private unnamed_addr constant [11 x i8] c"hello world", align 1
@_llgo_main.stringReader = global ptr null, align 8 @_llgo_main.stringReader = linkonce global ptr null, align 8
@"main.struct$Mdt84yjYYwxF9D2i4cRmpEPiWaO6tsjtrbGUjyESypk" = global ptr null, align 8 @"main.struct$Mdt84yjYYwxF9D2i4cRmpEPiWaO6tsjtrbGUjyESypk" = linkonce global ptr null, align 8
@18 = private unnamed_addr constant [1 x i8] c"s", align 1 @18 = private unnamed_addr constant [1 x i8] c"s", align 1
@19 = private unnamed_addr constant [1 x i8] c"i", align 1 @19 = private unnamed_addr constant [1 x i8] c"i", align 1
@20 = private unnamed_addr constant [8 x i8] c"prevRune", align 1 @20 = private unnamed_addr constant [8 x i8] c"prevRune", align 1
@@ -77,12 +77,12 @@ source_filename = "main"
@27 = private unnamed_addr constant [10 x i8] c"UnreadByte", align 1 @27 = private unnamed_addr constant [10 x i8] c"UnreadByte", align 1
@28 = private unnamed_addr constant [10 x i8] c"UnreadRune", align 1 @28 = private unnamed_addr constant [10 x i8] c"UnreadRune", align 1
@29 = private unnamed_addr constant [12 x i8] c"stringReader", align 1 @29 = private unnamed_addr constant [12 x i8] c"stringReader", align 1
@"*_llgo_main.stringReader" = global ptr null, align 8 @"*_llgo_main.stringReader" = linkonce global ptr null, align 8
@"_llgo_iface$OFO8Us9n8ajWCabGedeuoJ-Za2zAMk4Jh0FunAcUCFE" = linkonce global ptr null, align 8 @"_llgo_iface$OFO8Us9n8ajWCabGedeuoJ-Za2zAMk4Jh0FunAcUCFE" = linkonce global ptr null, align 8
@_llgo_main.errorString = global ptr null, align 8 @_llgo_main.errorString = linkonce global ptr null, align 8
@"main.struct$QTufDJA9wEDzuzgkA-ZSrLqW-B6lWN8O25mTSglAoLQ" = global ptr null, align 8 @"main.struct$QTufDJA9wEDzuzgkA-ZSrLqW-B6lWN8O25mTSglAoLQ" = linkonce global ptr null, align 8
@30 = private unnamed_addr constant [11 x i8] c"errorString", align 1 @30 = private unnamed_addr constant [11 x i8] c"errorString", align 1
@"*_llgo_main.errorString" = global ptr null, align 8 @"*_llgo_main.errorString" = linkonce global ptr null, align 8
@"_llgo_iface$Fh8eUJ-Gw4e6TYuajcFIOSCuqSPKAt5nS4ow7xeGXEU" = linkonce global ptr null, align 8 @"_llgo_iface$Fh8eUJ-Gw4e6TYuajcFIOSCuqSPKAt5nS4ow7xeGXEU" = linkonce global ptr null, align 8
@31 = private unnamed_addr constant [21 x i8] c"type assertion failed", align 1 @31 = private unnamed_addr constant [21 x i8] c"type assertion failed", align 1
@32 = private unnamed_addr constant [37 x i8] c"stringsReader.ReadAt: negative offset", align 1 @32 = private unnamed_addr constant [37 x i8] c"stringsReader.ReadAt: negative offset", align 1

24
cl/_testgo/sigsegv/in.go Normal file
View File

@@ -0,0 +1,24 @@
package main
type T struct {
s int
}
func f() *T {
return nil
}
func init() {
println("init")
defer func() {
r := recover()
if e, ok := r.(error); ok {
println("recover", e.Error())
}
}()
println(f().s)
}
func main() {
println("main")
}

View File

@@ -0,0 +1 @@
;

View File

@@ -7,7 +7,7 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } %"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
@"main.init$guard" = global i1 false, align 1 @"main.init$guard" = global i1 false, align 1
@"main.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88" = global ptr null, align 8 @"main.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88" = linkonce global ptr null, align 8
@0 = private unnamed_addr constant [1 x i8] c"v", align 1 @0 = private unnamed_addr constant [1 x i8] c"v", align 1
@1 = private unnamed_addr constant [4 x i8] c"main", align 1 @1 = private unnamed_addr constant [4 x i8] c"main", align 1
@__llgo_argc = global i32 0, align 4 @__llgo_argc = global i32 0, align 4

View File

@@ -11,7 +11,7 @@ source_filename = "main"
@"main.init$guard" = global i1 false, align 1 @"main.init$guard" = global i1 false, align 1
@"_llgo_github.com/goplus/llgo/cl/internal/foo.Foo" = linkonce global ptr null, align 8 @"_llgo_github.com/goplus/llgo/cl/internal/foo.Foo" = linkonce global ptr null, align 8
@"main.struct$qQwZyFy_4JRalRxVVsVD8R09X5t58tWjTrtJPtHbEjs" = global ptr null, align 8 @"main.struct$qQwZyFy_4JRalRxVVsVD8R09X5t58tWjTrtJPtHbEjs" = linkonce global ptr null, align 8
@0 = private unnamed_addr constant [2 x i8] c"pb", align 1 @0 = private unnamed_addr constant [2 x i8] c"pb", align 1
@1 = private unnamed_addr constant [1 x i8] c"F", align 1 @1 = private unnamed_addr constant [1 x i8] c"F", align 1
@2 = private unnamed_addr constant [4 x i8] c"main", align 1 @2 = private unnamed_addr constant [4 x i8] c"main", align 1
@@ -21,8 +21,8 @@ source_filename = "main"
@"*_llgo_byte" = linkonce global ptr null, align 8 @"*_llgo_byte" = linkonce global ptr null, align 8
@4 = private unnamed_addr constant [38 x i8] c"github.com/goplus/llgo/cl/internal/foo", align 1 @4 = private unnamed_addr constant [38 x i8] c"github.com/goplus/llgo/cl/internal/foo", align 1
@5 = private unnamed_addr constant [3 x i8] c"Foo", align 1 @5 = private unnamed_addr constant [3 x i8] c"Foo", align 1
@_llgo_main.bar = global ptr null, align 8 @_llgo_main.bar = linkonce global ptr null, align 8
@"main.struct$Ci43nzKYkRLddRL_N4mkykxLXfJlqJGS5n04LKThPNo" = global ptr null, align 8 @"main.struct$Ci43nzKYkRLddRL_N4mkykxLXfJlqJGS5n04LKThPNo" = linkonce global ptr null, align 8
@6 = private unnamed_addr constant [1 x i8] c"f", align 1 @6 = private unnamed_addr constant [1 x i8] c"f", align 1
@7 = private unnamed_addr constant [3 x i8] c"bar", align 1 @7 = private unnamed_addr constant [3 x i8] c"bar", align 1
@__llgo_argc = global i32 0, align 4 @__llgo_argc = global i32 0, align 4

View File

@@ -58,7 +58,7 @@ declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
define i64 @"main.index[int]"(%"github.com/goplus/llgo/internal/runtime.Slice" %0, i64 %1) { define linkonce i64 @"main.index[int]"(%"github.com/goplus/llgo/internal/runtime.Slice" %0, i64 %1) {
_llgo_0: _llgo_0:
%2 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1 %2 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
br label %_llgo_1 br label %_llgo_1

26
cl/_testgo/tpnamed/in.go Normal file
View File

@@ -0,0 +1,26 @@
package main
type Void = [0]byte
type Future[T any] func() T
type IO[T any] func() Future[T]
func WriteFile(fileName string) IO[error] {
return func() Future[error] {
return func() error {
return nil
}
}
}
func RunIO[T any](call IO[T]) T {
return call()()
}
func main() {
RunIO[Void](func() Future[Void] {
return func() (ret Void) {
return
}
})
}

122
cl/_testgo/tpnamed/out.ll Normal file
View File

@@ -0,0 +1,122 @@
; ModuleID = 'main'
source_filename = "main"
%"main.IO[error]" = type { ptr, ptr }
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"main.Future[error]" = type { ptr, ptr }
%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr }
%"main.IO[[0]byte]" = type { ptr, ptr }
%"main.Future[[0]byte]" = type { ptr, ptr }
@"main.init$guard" = global i1 false, align 1
@__llgo_argc = global i32 0, align 4
@__llgo_argv = global ptr null, align 8
define %"main.IO[error]" @main.WriteFile(%"github.com/goplus/llgo/internal/runtime.String" %0) {
_llgo_0:
%1 = alloca %"main.IO[error]", align 8
%2 = getelementptr inbounds %"main.IO[error]", ptr %1, i32 0, i32 0
store ptr @"__llgo_stub.main.WriteFile$1", ptr %2, align 8
%3 = getelementptr inbounds %"main.IO[error]", ptr %1, i32 0, i32 1
store ptr null, ptr %3, align 8
%4 = load %"main.IO[error]", ptr %1, align 8
ret %"main.IO[error]" %4
}
define %"main.Future[error]" @"main.WriteFile$1"() {
_llgo_0:
%0 = alloca %"main.Future[error]", align 8
%1 = getelementptr inbounds %"main.Future[error]", ptr %0, i32 0, i32 0
store ptr @"__llgo_stub.main.WriteFile$1$1", ptr %1, align 8
%2 = getelementptr inbounds %"main.Future[error]", ptr %0, i32 0, i32 1
store ptr null, ptr %2, align 8
%3 = load %"main.Future[error]", ptr %0, align 8
ret %"main.Future[error]" %3
}
define %"github.com/goplus/llgo/internal/runtime.iface" @"main.WriteFile$1$1"() {
_llgo_0:
ret %"github.com/goplus/llgo/internal/runtime.iface" zeroinitializer
}
define void @main.init() {
_llgo_0:
%0 = load i1, ptr @"main.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i32 @main(i32 %0, ptr %1) {
_llgo_0:
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
%2 = alloca %"main.IO[[0]byte]", align 8
%3 = getelementptr inbounds %"main.IO[[0]byte]", ptr %2, i32 0, i32 0
store ptr @"__llgo_stub.main.main$1", ptr %3, align 8
%4 = getelementptr inbounds %"main.IO[[0]byte]", ptr %2, i32 0, i32 1
store ptr null, ptr %4, align 8
%5 = load %"main.IO[[0]byte]", ptr %2, align 8
%6 = call [0 x i8] @"main.RunIO[[0]byte]"(%"main.IO[[0]byte]" %5)
ret i32 0
}
define %"main.Future[[0]byte]" @"main.main$1"() {
_llgo_0:
%0 = alloca %"main.Future[[0]byte]", align 8
%1 = getelementptr inbounds %"main.Future[[0]byte]", ptr %0, i32 0, i32 0
store ptr @"__llgo_stub.main.main$1$1", ptr %1, align 8
%2 = getelementptr inbounds %"main.Future[[0]byte]", ptr %0, i32 0, i32 1
store ptr null, ptr %2, align 8
%3 = load %"main.Future[[0]byte]", ptr %0, align 8
ret %"main.Future[[0]byte]" %3
}
define [0 x i8] @"main.main$1$1"() {
_llgo_0:
ret [0 x i8] zeroinitializer
}
define linkonce %"main.Future[error]" @"__llgo_stub.main.WriteFile$1"(ptr %0) {
_llgo_0:
%1 = tail call %"main.Future[error]" @"main.WriteFile$1"()
ret %"main.Future[error]" %1
}
define linkonce %"github.com/goplus/llgo/internal/runtime.iface" @"__llgo_stub.main.WriteFile$1$1"(ptr %0) {
_llgo_0:
%1 = tail call %"github.com/goplus/llgo/internal/runtime.iface" @"main.WriteFile$1$1"()
ret %"github.com/goplus/llgo/internal/runtime.iface" %1
}
declare void @"github.com/goplus/llgo/internal/runtime.init"()
define linkonce %"main.Future[[0]byte]" @"__llgo_stub.main.main$1"(ptr %0) {
_llgo_0:
%1 = tail call %"main.Future[[0]byte]" @"main.main$1"()
ret %"main.Future[[0]byte]" %1
}
define linkonce [0 x i8] @"main.RunIO[[0]byte]"(%"main.IO[[0]byte]" %0) {
_llgo_0:
%1 = extractvalue %"main.IO[[0]byte]" %0, 1
%2 = extractvalue %"main.IO[[0]byte]" %0, 0
%3 = call %"main.Future[[0]byte]" %2(ptr %1)
%4 = extractvalue %"main.Future[[0]byte]" %3, 1
%5 = extractvalue %"main.Future[[0]byte]" %3, 0
%6 = call [0 x i8] %5(ptr %4)
ret [0 x i8] %6
}
define linkonce [0 x i8] @"__llgo_stub.main.main$1$1"(ptr %0) {
_llgo_0:
%1 = tail call [0 x i8] @"main.main$1$1"()
ret [0 x i8] %1
}

View File

@@ -66,7 +66,7 @@ _llgo_2: ; preds = %_llgo_0
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
define i64 @"main.recur1[main.T]"(i64 %0) { define linkonce i64 @"main.recur1[main.T]"(i64 %0) {
_llgo_0: _llgo_0:
%1 = icmp eq i64 %0, 0 %1 = icmp eq i64 %0, 0
br i1 %1, label %_llgo_1, label %_llgo_3 br i1 %1, label %_llgo_1, label %_llgo_3
@@ -106,7 +106,7 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface") declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface")
define i64 @"main.recur2[main.T]"(i64 %0) { define linkonce i64 @"main.recur2[main.T]"(i64 %0) {
_llgo_0: _llgo_0:
%1 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.MakeSlice"(i64 %0, i64 %0, i64 8) %1 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.MakeSlice"(i64 %0, i64 %0, i64 8)
%2 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 1 %2 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 1

View File

@@ -5,8 +5,8 @@ source_filename = "main"
%"main.Data[string]" = type { %"github.com/goplus/llgo/internal/runtime.String" } %"main.Data[string]" = type { %"github.com/goplus/llgo/internal/runtime.String" }
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } %"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
%"main.Slice[[]int, int]" = type { %"github.com/goplus/llgo/internal/runtime.Slice" } %"main.Slice[[]int,int]" = type { %"github.com/goplus/llgo/internal/runtime.Slice" }
%"main.Slice[[]string, string]" = type { %"github.com/goplus/llgo/internal/runtime.Slice" } %"main.Slice[[]string,string]" = type { %"github.com/goplus/llgo/internal/runtime.Slice" }
@"main.init$guard" = global i1 false, align 1 @"main.init$guard" = global i1 false, align 1
@__llgo_argc = global i32 0, align 4 @__llgo_argc = global i32 0, align 4
@@ -90,7 +90,7 @@ _llgo_0:
%36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %33, i32 0, i32 2 %36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %33, i32 0, i32 2
store i64 1, ptr %36, align 4 store i64 1, ptr %36, align 4
%37 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %33, align 8 %37 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %33, align 8
%38 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice).Append[[]int, int]"(ptr %30, %"github.com/goplus/llgo/internal/runtime.Slice" %37) %38 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice[[]int,int]).Append"(ptr %30, %"github.com/goplus/llgo/internal/runtime.Slice" %37)
%39 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 24) %39 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 24)
%40 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16) %40 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
%41 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %40, i64 0 %41 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %40, i64 0
@@ -109,7 +109,7 @@ _llgo_0:
%49 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %46, i32 0, i32 2 %49 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %46, i32 0, i32 2
store i64 1, ptr %49, align 4 store i64 1, ptr %49, align 4
%50 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %46, align 8 %50 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %46, align 8
%51 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice).Append[[]string, string]"(ptr %39, %"github.com/goplus/llgo/internal/runtime.Slice" %50) %51 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice[[]string,string]).Append"(ptr %39, %"github.com/goplus/llgo/internal/runtime.Slice" %50)
%52 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 24) %52 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 24)
%53 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) %53 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%54 = getelementptr inbounds i64, ptr %53, i64 0 %54 = getelementptr inbounds i64, ptr %53, i64 0
@@ -128,7 +128,7 @@ _llgo_0:
%61 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %58, i32 0, i32 2 %61 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %58, i32 0, i32 2
store i64 4, ptr %61, align 4 store i64 4, ptr %61, align 4
%62 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %58, align 8 %62 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %58, align 8
%63 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice).Append[[]int, int]"(ptr %52, %"github.com/goplus/llgo/internal/runtime.Slice" %62) %63 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice[[]int,int]).Append"(ptr %52, %"github.com/goplus/llgo/internal/runtime.Slice" %62)
%64 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) %64 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%65 = getelementptr inbounds i64, ptr %64, i64 0 %65 = getelementptr inbounds i64, ptr %64, i64 0
store i64 1, ptr %65, align 4 store i64 1, ptr %65, align 4
@@ -146,10 +146,10 @@ _llgo_0:
%72 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %69, i32 0, i32 2 %72 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %69, i32 0, i32 2
store i64 4, ptr %72, align 4 store i64 4, ptr %72, align 4
%73 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %69, align 8 %73 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %69, align 8
%74 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice).Append2[[]int, int]"(ptr %52, %"github.com/goplus/llgo/internal/runtime.Slice" %73) %74 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice[[]int,int]).Append2"(ptr %52, %"github.com/goplus/llgo/internal/runtime.Slice" %73)
%75 = getelementptr inbounds %"main.Slice[[]int, int]", ptr %30, i32 0, i32 0 %75 = getelementptr inbounds %"main.Slice[[]int,int]", ptr %30, i32 0, i32 0
%76 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %75, align 8 %76 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %75, align 8
%77 = getelementptr inbounds %"main.Slice[[]int, int]", ptr %30, i32 0, i32 0 %77 = getelementptr inbounds %"main.Slice[[]int,int]", ptr %30, i32 0, i32 0
%78 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %77, align 8 %78 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %77, align 8
%79 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %78, 0 %79 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %78, 0
%80 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %78, 1 %80 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %78, 1
@@ -161,9 +161,9 @@ _llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %83) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %83)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%84 = getelementptr inbounds %"main.Slice[[]string, string]", ptr %39, i32 0, i32 0 %84 = getelementptr inbounds %"main.Slice[[]string,string]", ptr %39, i32 0, i32 0
%85 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %84, align 8 %85 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %84, align 8
%86 = getelementptr inbounds %"main.Slice[[]string, string]", ptr %39, i32 0, i32 0 %86 = getelementptr inbounds %"main.Slice[[]string,string]", ptr %39, i32 0, i32 0
%87 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %86, align 8 %87 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %86, align 8
%88 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %87, 0 %88 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %87, 0
%89 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %87, 1 %89 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %87, 1
@@ -175,9 +175,9 @@ _llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %92) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %92)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%93 = getelementptr inbounds %"main.Slice[[]int, int]", ptr %52, i32 0, i32 0 %93 = getelementptr inbounds %"main.Slice[[]int,int]", ptr %52, i32 0, i32 0
%94 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %93, align 8 %94 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %93, align 8
%95 = getelementptr inbounds %"main.Slice[[]int, int]", ptr %52, i32 0, i32 0 %95 = getelementptr inbounds %"main.Slice[[]int,int]", ptr %52, i32 0, i32 0
%96 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %95, align 8 %96 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %95, align 8
%97 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %96, 0 %97 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %96, 0
%98 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %96, 1 %98 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %96, 1
@@ -204,44 +204,44 @@ declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
define %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice).Append[[]int, int]"(ptr %0, %"github.com/goplus/llgo/internal/runtime.Slice" %1) { define linkonce %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice[[]int,int]).Append"(ptr %0, %"github.com/goplus/llgo/internal/runtime.Slice" %1) {
_llgo_0: _llgo_0:
%2 = getelementptr inbounds %"main.Slice[[]int, int]", ptr %0, i32 0, i32 0 %2 = getelementptr inbounds %"main.Slice[[]int,int]", ptr %0, i32 0, i32 0
%3 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %2, align 8 %3 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %2, align 8
%4 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 0 %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 0
%5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 1 %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 1
%6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %3, ptr %4, i64 %5, i64 8) %6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %3, ptr %4, i64 %5, i64 8)
%7 = getelementptr inbounds %"main.Slice[[]int, int]", ptr %0, i32 0, i32 0 %7 = getelementptr inbounds %"main.Slice[[]int,int]", ptr %0, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.Slice" %6, ptr %7, align 8 store %"github.com/goplus/llgo/internal/runtime.Slice" %6, ptr %7, align 8
%8 = getelementptr inbounds %"main.Slice[[]int, int]", ptr %0, i32 0, i32 0 %8 = getelementptr inbounds %"main.Slice[[]int,int]", ptr %0, i32 0, i32 0
%9 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %8, align 8 %9 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %8, align 8
ret %"github.com/goplus/llgo/internal/runtime.Slice" %9 ret %"github.com/goplus/llgo/internal/runtime.Slice" %9
} }
define %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice).Append[[]string, string]"(ptr %0, %"github.com/goplus/llgo/internal/runtime.Slice" %1) { define linkonce %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice[[]string,string]).Append"(ptr %0, %"github.com/goplus/llgo/internal/runtime.Slice" %1) {
_llgo_0: _llgo_0:
%2 = getelementptr inbounds %"main.Slice[[]string, string]", ptr %0, i32 0, i32 0 %2 = getelementptr inbounds %"main.Slice[[]string,string]", ptr %0, i32 0, i32 0
%3 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %2, align 8 %3 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %2, align 8
%4 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 0 %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 0
%5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 1 %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 1
%6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %3, ptr %4, i64 %5, i64 16) %6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %3, ptr %4, i64 %5, i64 16)
%7 = getelementptr inbounds %"main.Slice[[]string, string]", ptr %0, i32 0, i32 0 %7 = getelementptr inbounds %"main.Slice[[]string,string]", ptr %0, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.Slice" %6, ptr %7, align 8 store %"github.com/goplus/llgo/internal/runtime.Slice" %6, ptr %7, align 8
%8 = getelementptr inbounds %"main.Slice[[]string, string]", ptr %0, i32 0, i32 0 %8 = getelementptr inbounds %"main.Slice[[]string,string]", ptr %0, i32 0, i32 0
%9 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %8, align 8 %9 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %8, align 8
ret %"github.com/goplus/llgo/internal/runtime.Slice" %9 ret %"github.com/goplus/llgo/internal/runtime.Slice" %9
} }
define %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice).Append2[[]int, int]"(ptr %0, %"github.com/goplus/llgo/internal/runtime.Slice" %1) { define linkonce %"github.com/goplus/llgo/internal/runtime.Slice" @"main.(*Slice[[]int,int]).Append2"(ptr %0, %"github.com/goplus/llgo/internal/runtime.Slice" %1) {
_llgo_0: _llgo_0:
%2 = getelementptr inbounds %"main.Slice[[]int, int]", ptr %0, i32 0, i32 0 %2 = getelementptr inbounds %"main.Slice[[]int,int]", ptr %0, i32 0, i32 0
%3 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %2, align 8 %3 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %2, align 8
%4 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 0 %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 0
%5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 1 %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %1, 1
%6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %3, ptr %4, i64 %5, i64 8) %6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %3, ptr %4, i64 %5, i64 8)
%7 = getelementptr inbounds %"main.Slice[[]int, int]", ptr %0, i32 0, i32 0 %7 = getelementptr inbounds %"main.Slice[[]int,int]", ptr %0, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.Slice" %6, ptr %7, align 8 store %"github.com/goplus/llgo/internal/runtime.Slice" %6, ptr %7, align 8
%8 = getelementptr inbounds %"main.Slice[[]int, int]", ptr %0, i32 0, i32 0 %8 = getelementptr inbounds %"main.Slice[[]int,int]", ptr %0, i32 0, i32 0
%9 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %8, align 8 %9 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %8, align 8
ret %"github.com/goplus/llgo/internal/runtime.Slice" %9 ret %"github.com/goplus/llgo/internal/runtime.Slice" %9
} }

View File

@@ -0,0 +1,7 @@
package main
import "net/textproto"
func main() {
println(textproto.CanonicalMIMEHeaderKey("host"))
}

View File

@@ -0,0 +1,51 @@
; ModuleID = 'main'
source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
@"main.init$guard" = global i1 false, align 1
@__llgo_argc = global i32 0, align 4
@__llgo_argv = global ptr null, align 8
@0 = private unnamed_addr constant [4 x i8] c"host", align 1
define void @main.init() {
_llgo_0:
%0 = load i1, ptr @"main.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1
call void @"net/textproto.init"()
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i32 @main(i32 %0, ptr %1) {
_llgo_0:
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
%2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 0
store ptr @0, ptr %3, align 8
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1
store i64 4, ptr %4, align 4
%5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8
%6 = call %"github.com/goplus/llgo/internal/runtime.String" @"net/textproto.CanonicalMIMEHeaderKey"(%"github.com/goplus/llgo/internal/runtime.String" %5)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %6)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret i32 0
}
declare void @"net/textproto.init"()
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare %"github.com/goplus/llgo/internal/runtime.String" @"net/textproto.CanonicalMIMEHeaderKey"(%"github.com/goplus/llgo/internal/runtime.String")
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)

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