Compare commits

..

3 Commits

46 changed files with 1465 additions and 6831 deletions

463
Cargo.lock generated
View File

@ -50,9 +50,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]] [[package]]
name = "bit-set" name = "bit-set"
version = "0.5.3" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
dependencies = [ dependencies = [
"bit-vec", "bit-vec",
] ]
@ -89,9 +89,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "console" name = "console"
version = "0.15.1" version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847" checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31"
dependencies = [ dependencies = [
"encode_unicode", "encode_unicode",
"libc", "libc",
@ -102,9 +102,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam" name = "crossbeam"
version = "0.8.2" version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crossbeam-channel", "crossbeam-channel",
@ -116,9 +116,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-channel" name = "crossbeam-channel"
version = "0.5.6" version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crossbeam-utils", "crossbeam-utils",
@ -126,9 +126,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-deque" name = "crossbeam-deque"
version = "0.8.2" version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crossbeam-epoch", "crossbeam-epoch",
@ -137,23 +137,23 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-epoch" name = "crossbeam-epoch"
version = "0.9.10" version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"cfg-if", "cfg-if",
"crossbeam-utils", "crossbeam-utils",
"lazy_static",
"memoffset", "memoffset",
"once_cell",
"scopeguard", "scopeguard",
] ]
[[package]] [[package]]
name = "crossbeam-queue" name = "crossbeam-queue"
version = "0.3.6" version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7" checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crossbeam-utils", "crossbeam-utils",
@ -161,12 +161,12 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.11" version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "lazy_static",
] ]
[[package]] [[package]]
@ -177,9 +177,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]] [[package]]
name = "diff" name = "diff"
version = "0.1.13" version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
[[package]] [[package]]
name = "dirs-next" name = "dirs-next"
@ -204,9 +204,9 @@ dependencies = [
[[package]] [[package]]
name = "either" name = "either"
version = "1.7.0" version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]] [[package]]
name = "ena" name = "ena"
@ -225,18 +225,18 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "1.8.0" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
dependencies = [ dependencies = [
"instant", "instant",
] ]
[[package]] [[package]]
name = "fixedbitset" name = "fixedbitset"
version = "0.4.2" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
[[package]] [[package]]
name = "fxhash" name = "fxhash"
@ -249,9 +249,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.7" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -267,12 +267,6 @@ dependencies = [
"ahash", "ahash",
] ]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.19" version = "0.1.19"
@ -284,37 +278,66 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.9.1" version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown 0.12.3", "hashbrown",
] ]
[[package]] [[package]]
name = "indoc" name = "indoc"
version = "1.0.7" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adab1eaa3408fb7f0c777a73e7465fd5656136fc93b670eb6df3c88c2c1344e3" checksum = "47741a8bc60fb26eb8d6e0238bbb26d8575ff623fdc97b1a2c00c050b9684ed8"
dependencies = [
"indoc-impl",
"proc-macro-hack",
]
[[package]]
name = "indoc"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7906a9fababaeacb774f72410e497a1d18de916322e33797bb2cd29baa23c9e"
dependencies = [
"unindent",
]
[[package]]
name = "indoc-impl"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce046d161f000fffde5f432a0d034d0341dc152643b2598ed5bfce44c4f3a8f0"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
"unindent",
]
[[package]] [[package]]
name = "inkwell" name = "inkwell"
version = "0.1.0" version = "0.1.0-beta.4"
source = "git+https://github.com/TheDan64/inkwell.git#25b9fc5870370211504e874e7c81dc53573bca79" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2223d0eba0ae6d40a3e4680c6a3209143471e1f38b41746ea309aa36dde9f90b"
dependencies = [ dependencies = [
"either", "either",
"inkwell_internals", "inkwell_internals",
"libc", "libc",
"llvm-sys", "llvm-sys",
"once_cell", "once_cell",
"parking_lot", "parking_lot 0.11.2",
"regex",
] ]
[[package]] [[package]]
name = "inkwell_internals" name = "inkwell_internals"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/TheDan64/inkwell.git#25b9fc5870370211504e874e7c81dc53573bca79" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c7090af3d300424caa81976b8c97bca41cd70e861272c072e188ae082fb49f9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -355,15 +378,15 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.3" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]] [[package]]
name = "lalrpop" name = "lalrpop"
version = "0.19.8" version = "0.19.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b30455341b0e18f276fa64540aff54deafb54c589de6aca68659c63dd2d5d823" checksum = "852b75a095da6b69da8c5557731c3afd06525d4f655a4fc1c799e2ec8bc4dce4"
dependencies = [ dependencies = [
"ascii-canvas", "ascii-canvas",
"atty", "atty",
@ -384,9 +407,9 @@ dependencies = [
[[package]] [[package]]
name = "lalrpop-util" name = "lalrpop-util"
version = "0.19.8" version = "0.19.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf796c978e9b4d983414f4caedc9273aa33ee214c5b887bd55fde84c85d2dc4" checksum = "d6d265705249fe209280676d8f68887859fa42e1d34f342fc05bd47726a5e188"
dependencies = [ dependencies = [
"regex", "regex",
] ]
@ -399,9 +422,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.127" version = "0.2.122"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b" checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259"
[[package]] [[package]]
name = "libloading" name = "libloading"
@ -415,15 +438,15 @@ dependencies = [
[[package]] [[package]]
name = "linked-hash-map" name = "linked-hash-map"
version = "0.5.6" version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]] [[package]]
name = "llvm-sys" name = "llvm-sys"
version = "140.0.2" version = "130.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a4ad24a72823cb06764e04a008d4aedc1be56d2be87aa4212b12a3e9f77bb10" checksum = "95eb03b4f7ae21f48ef7c565a3e3aa22c50616aea64645fb1fd7f6f56b51c274"
dependencies = [ dependencies = [
"cc", "cc",
"lazy_static", "lazy_static",
@ -444,18 +467,18 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.17" version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.5.0" version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]] [[package]]
name = "memoffset" name = "memoffset"
@ -472,9 +495,8 @@ version = "0.1.0"
dependencies = [ dependencies = [
"inkwell", "inkwell",
"nac3core", "nac3core",
"nac3ld",
"nac3parser", "nac3parser",
"parking_lot", "parking_lot 0.11.2",
"pyo3", "pyo3",
"tempfile", "tempfile",
] ]
@ -485,7 +507,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"fxhash", "fxhash",
"lazy_static", "lazy_static",
"parking_lot", "parking_lot 0.11.2",
"string-interner", "string-interner",
] ]
@ -494,25 +516,17 @@ name = "nac3core"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"crossbeam", "crossbeam",
"indoc", "indoc 1.0.4",
"inkwell", "inkwell",
"insta", "insta",
"itertools", "itertools",
"lazy_static",
"nac3parser", "nac3parser",
"parking_lot", "parking_lot 0.11.2",
"rayon", "rayon",
"regex", "regex",
"test-case", "test-case",
] ]
[[package]]
name = "nac3ld"
version = "0.1.0"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "nac3parser" name = "nac3parser"
version = "0.1.2" version = "0.1.2"
@ -536,7 +550,7 @@ dependencies = [
"inkwell", "inkwell",
"nac3core", "nac3core",
"nac3parser", "nac3parser",
"parking_lot", "parking_lot 0.11.2",
] ]
[[package]] [[package]]
@ -557,25 +571,50 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.13.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.1" version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core 0.8.5",
]
[[package]]
name = "parking_lot"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
dependencies = [ dependencies = [
"lock_api", "lock_api",
"parking_lot_core", "parking_lot_core 0.9.2",
] ]
[[package]] [[package]]
name = "parking_lot_core" name = "parking_lot_core"
version = "0.9.3" version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
dependencies = [
"cfg-if",
"instant",
"libc",
"redox_syscall",
"smallvec",
"winapi",
]
[[package]]
name = "parking_lot_core"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -585,10 +624,38 @@ dependencies = [
] ]
[[package]] [[package]]
name = "petgraph" name = "paste"
version = "0.6.2" version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
dependencies = [
"paste-impl",
"proc-macro-hack",
]
[[package]]
name = "paste-impl"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
dependencies = [
"proc-macro-hack",
]
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
[[package]]
name = "petgraph"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
dependencies = [ dependencies = [
"fixedbitset", "fixedbitset",
"indexmap", "indexmap",
@ -596,32 +663,34 @@ dependencies = [
[[package]] [[package]]
name = "phf" name = "phf"
version = "0.11.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4724fa946c8d1e7cd881bd3dbee63ce32fc1e9e191e35786b3dc1320a3f68131" checksum = "b2ac8b67553a7ca9457ce0e526948cad581819238f4a9d1ea74545851fa24f37"
dependencies = [ dependencies = [
"phf_macros", "phf_macros",
"phf_shared 0.11.0", "phf_shared 0.9.0",
"proc-macro-hack",
] ]
[[package]] [[package]]
name = "phf_generator" name = "phf_generator"
version = "0.11.0" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b450720b6f75cfbfabc195814bd3765f337a4f9a83186f8537297cac12f6705" checksum = "d43f3220d96e0080cc9ea234978ccd80d904eafb17be31bb0f76daaea6493082"
dependencies = [ dependencies = [
"phf_shared 0.11.0", "phf_shared 0.9.0",
"rand", "rand",
] ]
[[package]] [[package]]
name = "phf_macros" name = "phf_macros"
version = "0.11.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd94351ac44e70e56b59883e15029a5135f902a8a3020f9c18d580a420e526aa" checksum = "b706f5936eb50ed880ae3009395b43ed19db5bff2ebd459c95e7bf013a89ab86"
dependencies = [ dependencies = [
"phf_generator", "phf_generator",
"phf_shared 0.11.0", "phf_shared 0.9.0",
"proc-macro-hack",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
@ -629,18 +698,18 @@ dependencies = [
[[package]] [[package]]
name = "phf_shared" name = "phf_shared"
version = "0.10.0" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" checksum = "a68318426de33640f02be62b4ae8eb1261be2efbc337b60c54d845bf4484e0d9"
dependencies = [ dependencies = [
"siphasher", "siphasher",
] ]
[[package]] [[package]]
name = "phf_shared" name = "phf_shared"
version = "0.11.0" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd5609d4b2df87167f908a32e1b146ce309c16cf35df76bc11f440b756048e4" checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
dependencies = [ dependencies = [
"siphasher", "siphasher",
] ]
@ -664,57 +733,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro-hack"
version = "1.0.43" version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
dependencies = [ dependencies = [
"unicode-ident", "unicode-xid",
] ]
[[package]] [[package]]
name = "pyo3" name = "pyo3"
version = "0.16.5" version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e6302e85060011447471887705bb7838f14aba43fcb06957d823739a496b3dc" checksum = "35100f9347670a566a67aa623369293703322bb9db77d99d7df7313b575ae0c8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"indoc", "indoc 0.3.6",
"libc", "libc",
"parking_lot", "parking_lot 0.11.2",
"paste",
"pyo3-build-config", "pyo3-build-config",
"pyo3-ffi",
"pyo3-macros", "pyo3-macros",
"unindent", "unindent",
] ]
[[package]] [[package]]
name = "pyo3-build-config" name = "pyo3-build-config"
version = "0.16.5" version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b65b546c35d8a3b1b2f0ddbac7c6a569d759f357f2b9df884f5d6b719152c8" checksum = "d12961738cacbd7f91b7c43bc25cfeeaa2698ad07a04b3be0aa88b950865738f"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"target-lexicon",
]
[[package]]
name = "pyo3-ffi"
version = "0.16.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c275a07127c1aca33031a563e384ffdd485aee34ef131116fcd58e3430d1742b"
dependencies = [
"libc",
"pyo3-build-config",
] ]
[[package]] [[package]]
name = "pyo3-macros" name = "pyo3-macros"
version = "0.16.5" version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284fc4485bfbcc9850a6d661d627783f18d19c2ab55880b021671c4ba83e90f7" checksum = "fc0bc5215d704824dfddddc03f93cb572e1155c68b6761c37005e1c288808ea8"
dependencies = [ dependencies = [
"proc-macro2",
"pyo3-macros-backend", "pyo3-macros-backend",
"quote", "quote",
"syn", "syn",
@ -722,20 +785,21 @@ dependencies = [
[[package]] [[package]]
name = "pyo3-macros-backend" name = "pyo3-macros-backend"
version = "0.16.5" version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53bda0f58f73f5c5429693c96ed57f7abdb38fdfc28ae06da4101a257adb7faf" checksum = "71623fc593224afaab918aa3afcaf86ed2f43d34f6afde7f3922608f253240df"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"pyo3-build-config",
"quote", "quote",
"syn", "syn",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.21" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -772,9 +836,9 @@ dependencies = [
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.5.3" version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"crossbeam-deque", "crossbeam-deque",
@ -784,21 +848,22 @@ dependencies = [
[[package]] [[package]]
name = "rayon-core" name = "rayon-core"
version = "1.9.3" version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [ dependencies = [
"crossbeam-channel", "crossbeam-channel",
"crossbeam-deque", "crossbeam-deque",
"crossbeam-utils", "crossbeam-utils",
"lazy_static",
"num_cpus", "num_cpus",
] ]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.16" version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
@ -816,9 +881,9 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.6.0" version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@ -827,9 +892,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.27" version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
@ -849,15 +914,15 @@ dependencies = [
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.9" version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.11" version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
@ -867,24 +932,36 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.13" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
dependencies = [
"pest",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.142" version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2" checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.142" version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34b5b8d809babe02f538c2cfec6f2c1ed10804c0e5a6a041a049a4f5588ccc2e" checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -893,9 +970,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.83" version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -904,9 +981,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_yaml" name = "serde_yaml"
version = "0.8.26" version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"ryu", "ryu",
@ -916,9 +993,9 @@ dependencies = [
[[package]] [[package]]
name = "similar" name = "similar"
version = "2.2.0" version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62ac7f900db32bf3fd12e0117dd3dc4da74bc52ebaac97f39668446d89694803" checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3"
[[package]] [[package]]
name = "siphasher" name = "siphasher"
@ -928,18 +1005,18 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.9.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]] [[package]]
name = "string-interner" name = "string-interner"
version = "0.14.0" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e2531d8525b29b514d25e275a43581320d587b86db302b9a7e464bac579648" checksum = "ecc77d3a5728ef82235df1f9b9430507f555c7404797f42b49c2403d4c1d8c6c"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"hashbrown 0.11.2", "hashbrown",
"serde", "serde",
] ]
@ -951,28 +1028,22 @@ checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08"
dependencies = [ dependencies = [
"new_debug_unreachable", "new_debug_unreachable",
"once_cell", "once_cell",
"parking_lot", "parking_lot 0.12.0",
"phf_shared 0.10.0", "phf_shared 0.10.0",
"precomputed-hash", "precomputed-hash",
] ]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.99" version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-ident", "unicode-xid",
] ]
[[package]]
name = "target-lexicon"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.3.0" version = "3.3.0"
@ -1023,18 +1094,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.32" version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.32" version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1050,6 +1121,12 @@ dependencies = [
"crunchy", "crunchy",
] ]
[[package]]
name = "ucd-trie"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]] [[package]]
name = "unic-char-property" name = "unic-char-property"
version = "0.9.0" version = "0.9.0"
@ -1102,29 +1179,23 @@ dependencies = [
"unic-common", "unic-common",
] ]
[[package]]
name = "unicode-ident"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.3" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]] [[package]]
name = "unicode_names2" name = "unicode_names2"
version = "0.5.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eec8e807a365e5c972debc47b8f06d361b37b94cfd18d48f7adc715fb86404dd" checksum = "87d6678d7916394abad0d4b19df4d3802e1fd84abd7d701f39b75ee71b9e8cf1"
[[package]] [[package]]
name = "unindent" name = "unindent"
version = "0.1.10" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58ee9362deb4a96cef4d437d1ad49cffc9b9e92d202b6995674e928ce684f112" checksum = "514672a55d7380da379785a4d70ca8386c8883ff7eaae877be4d2081cebe73d8"
[[package]] [[package]]
name = "version_check" name = "version_check"
@ -1134,9 +1205,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]] [[package]]
name = "winapi" name = "winapi"
@ -1162,9 +1233,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.36.1" version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
dependencies = [ dependencies = [
"windows_aarch64_msvc", "windows_aarch64_msvc",
"windows_i686_gnu", "windows_i686_gnu",
@ -1175,33 +1246,33 @@ dependencies = [
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.36.1" version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.36.1" version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.36.1" version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.36.1" version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.36.1" version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
[[package]] [[package]]
name = "yaml-rust" name = "yaml-rust"

View File

@ -1,6 +1,5 @@
[workspace] [workspace]
members = [ members = [
"nac3ld",
"nac3ast", "nac3ast",
"nac3parser", "nac3parser",
"nac3core", "nac3core",

View File

@ -1,10 +1,5 @@
<div align="center">
![icon](https://git.m-labs.hk/M-Labs/nac3/raw/branch/master/nac3.svg)
</div>
# NAC3 # NAC3
NAC3 is a major, backward-incompatible rewrite of the compiler for the [ARTIQ](https://m-labs.hk/artiq) physics experiment control and data acquisition system. It features greatly improved compilation speeds, a much better type system, and more predictable and transparent operation. NAC3 is a major, backward-incompatible rewrite of the compiler for the [ARTIQ](https://m-labs.hk/artiq) physics experiment control and data acquisition system. It features greatly improved compilation speeds, a much better type system, and more predictable and transparent operation.
NAC3 has a modular design and its applicability reaches beyond ARTIQ. The ``nac3core`` module does not contain anything specific to ARTIQ, and can be used in any project that requires compiling Python to machine code. NAC3 has a modular design and its applicability reaches beyond ARTIQ. The ``nac3core`` module does not contain anything specific to ARTIQ, and can be used in any project that requires compiling Python to machine code.
@ -13,7 +8,7 @@ NAC3 has a modular design and its applicability reaches beyond ARTIQ. The ``nac3
## Packaging ## Packaging
NAC3 is packaged using the [Nix](https://nixos.org) Flakes system. Install Nix 2.8+ and enable flakes by adding ``experimental-features = nix-command flakes`` to ``nix.conf`` (e.g. ``~/.config/nix/nix.conf``). NAC3 is packaged using the [Nix](https://nixos.org) Flakes system. Install Nix 2.4+ and enable flakes by adding ``experimental-features = nix-command flakes`` to ``nix.conf`` (e.g. ``~/.config/nix/nix.conf``).
## Try NAC3 ## Try NAC3
@ -36,6 +31,12 @@ pacman -Syu
pacman -S mingw-w64-x86_64-artiq pacman -S mingw-w64-x86_64-artiq
``` ```
Install ``lld-msys2`` manually:
```
wget https://nixbld.m-labs.hk/build/115527/download/1/ld.lld.exe
mv ld.lld.exe C:/msys64/mingw64/bin
```
Note: This build of NAC3 cannot be used with Anaconda Python nor the python.org binaries for Windows. Those Python versions are compiled with Visual Studio (MSVC) and their ABI is incompatible with the GNU ABI used in this build. We have no plans to support Visual Studio nor the MSVC ABI. If you need a MSVC build, please install the requisite bloated spyware from Microsoft and compile NAC3 yourself. Note: This build of NAC3 cannot be used with Anaconda Python nor the python.org binaries for Windows. Those Python versions are compiled with Visual Studio (MSVC) and their ABI is incompatible with the GNU ABI used in this build. We have no plans to support Visual Studio nor the MSVC ABI. If you need a MSVC build, please install the requisite bloated spyware from Microsoft and compile NAC3 yourself.
## For developers ## For developers
@ -45,7 +46,6 @@ This repository contains:
- ``nac3parser``: Python parser (based on RustPython). - ``nac3parser``: Python parser (based on RustPython).
- ``nac3core``: Core compiler library, containing type-checking and code generation. - ``nac3core``: Core compiler library, containing type-checking and code generation.
- ``nac3standalone``: Standalone compiler tool (core language only). - ``nac3standalone``: Standalone compiler tool (core language only).
- ``nac3ld``: Minimalist RISC-V and ARM linker.
- ``nac3artiq``: Integration with ARTIQ and implementation of ARTIQ-specific extensions to the core language. - ``nac3artiq``: Integration with ARTIQ and implementation of ARTIQ-specific extensions to the core language.
- ``runkernel``: Simple program that runs compiled ARTIQ kernels on the host and displays RTIO operations. Useful for testing without hardware. - ``runkernel``: Simple program that runs compiled ARTIQ kernels on the host and displays RTIO operations. Useful for testing without hardware.

View File

@ -2,16 +2,16 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1659689094, "lastModified": 1649619156,
"narHash": "sha256-cXrWxpPYpV1PeEhtpQf9W++8aCgwzxpx2PzfszPofJE=", "narHash": "sha256-p0q4zpuKMwrzGF+5ZU7Thnpac5TinhDI9jr2mBxhV4w=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "697fc6ae98d077f6448cada3ecd63465c48c6af5", "rev": "e7d63bd0d50df412f5a1d8acfa3caae75522e347",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "master", "ref": "nixos-21.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }

View File

@ -1,7 +1,7 @@
{ {
description = "The third-generation ARTIQ compiler"; description = "The third-generation ARTIQ compiler";
inputs.nixpkgs.url = github:NixOS/nixpkgs/master; inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-21.11;
outputs = { self, nixpkgs }: outputs = { self, nixpkgs }:
let let
@ -10,18 +10,12 @@
packages.x86_64-linux = rec { packages.x86_64-linux = rec {
llvm-nac3 = pkgs.callPackage ./nix/llvm {}; llvm-nac3 = pkgs.callPackage ./nix/llvm {};
nac3artiq = pkgs.python3Packages.toPythonModule ( nac3artiq = pkgs.python3Packages.toPythonModule (
pkgs.rustPlatform.buildRustPackage rec { pkgs.rustPlatform.buildRustPackage {
name = "nac3artiq"; name = "nac3artiq";
outputs = [ "out" "runkernel" "standalone" ]; outputs = [ "out" "runkernel" "standalone" ];
src = self; src = self;
cargoLock = { cargoLock = { lockFile = ./Cargo.lock; };
lockFile = ./Cargo.lock; nativeBuildInputs = [ pkgs.python3 pkgs.llvmPackages_13.clang-unwrapped llvm-nac3 ];
outputHashes = {
"inkwell-0.1.0" = "sha256-+ih3SO0n6YmZ/mcf+rLDwPAy/1MEZ/A+tI4pM1pUhvU=";
};
};
passthru.cargoLock = cargoLock;
nativeBuildInputs = [ pkgs.python3 pkgs.llvmPackages_14.clang-unwrapped pkgs.llvmPackages_14.llvm.out llvm-nac3 ];
buildInputs = [ pkgs.python3 llvm-nac3 ]; buildInputs = [ pkgs.python3 llvm-nac3 ];
checkInputs = [ (pkgs.python3.withPackages(ps: [ ps.numpy ])) ]; checkInputs = [ (pkgs.python3.withPackages(ps: [ ps.numpy ])) ];
checkPhase = checkPhase =
@ -55,21 +49,21 @@
# LLVM PGO support # LLVM PGO support
llvm-nac3-instrumented = pkgs.callPackage ./nix/llvm { llvm-nac3-instrumented = pkgs.callPackage ./nix/llvm {
stdenv = pkgs.llvmPackages_14.stdenv; stdenv = pkgs.llvmPackages_13.stdenv;
extraCmakeFlags = [ "-DLLVM_BUILD_INSTRUMENTED=IR" ]; extraCmakeFlags = [ "-DLLVM_BUILD_INSTRUMENTED=IR" ];
}; };
nac3artiq-instrumented = pkgs.python3Packages.toPythonModule ( nac3artiq-instrumented = pkgs.python3Packages.toPythonModule (
pkgs.rustPlatform.buildRustPackage { pkgs.rustPlatform.buildRustPackage {
name = "nac3artiq-instrumented"; name = "nac3artiq-instrumented";
src = self; src = self;
inherit (nac3artiq) cargoLock; cargoLock = { lockFile = ./Cargo.lock; };
nativeBuildInputs = [ pkgs.python3 pkgs.llvmPackages_14.clang-unwrapped pkgs.llvmPackages_14.llvm.out llvm-nac3-instrumented ]; nativeBuildInputs = [ pkgs.python3 pkgs.llvmPackages_13.clang-unwrapped llvm-nac3-instrumented ];
buildInputs = [ pkgs.python3 llvm-nac3-instrumented ]; buildInputs = [ pkgs.python3 llvm-nac3-instrumented ];
cargoBuildFlags = [ "--package" "nac3artiq" "--features" "init-llvm-profile" ]; cargoBuildFlags = [ "--package" "nac3artiq" "--features" "init-llvm-profile" ];
doCheck = false; doCheck = false;
configurePhase = configurePhase =
'' ''
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=-L${pkgs.llvmPackages_14.compiler-rt}/lib/linux -C link-arg=-lclang_rt.profile-x86_64" export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=-L${pkgs.llvmPackages_13.compiler-rt}/lib/linux -C link-arg=-lclang_rt.profile-x86_64"
''; '';
installPhase = installPhase =
'' ''
@ -81,35 +75,11 @@
); );
nac3artiq-profile = pkgs.stdenvNoCC.mkDerivation { nac3artiq-profile = pkgs.stdenvNoCC.mkDerivation {
name = "nac3artiq-profile"; name = "nac3artiq-profile";
srcs = [ src = self;
(pkgs.fetchFromGitHub { buildInputs = [ (python3-mimalloc.withPackages(ps: [ ps.numpy nac3artiq-instrumented ])) pkgs.lld_13 pkgs.llvmPackages_13.libllvm ];
owner = "m-labs";
repo = "sipyco";
rev = "939f84f9b5eef7efbf7423c735d1834783b6140e";
sha256 = "sha256-15Nun4EY35j+6SPZkjzZtyH/ncxLS60KuGJjFh5kSTc=";
})
(pkgs.fetchFromGitHub {
owner = "m-labs";
repo = "artiq";
rev = "dd57fdc530baf926a5f354dc1c2bd90564affd96";
sha256 = "sha256-hcqVcToYWkc3oDFkKr9wZUF65ydiSYVHdmiGiu2Mc1c=";
})
];
buildInputs = [
(python3-mimalloc.withPackages(ps: [ ps.numpy ps.jsonschema nac3artiq-instrumented ]))
pkgs.llvmPackages_14.llvm.out
];
phases = [ "buildPhase" "installPhase" ]; phases = [ "buildPhase" "installPhase" ];
buildPhase = # TODO: get more representative code.
'' buildPhase = "python $src/nac3artiq/demo/demo.py";
srcs=($srcs)
sipyco=''${srcs[0]}
artiq=''${srcs[1]}
export PYTHONPATH=$sipyco:$artiq
python -m artiq.frontend.artiq_ddb_template $artiq/artiq/examples/nac3devices/nac3devices.json > device_db.py
cp $artiq/artiq/examples/nac3devices/nac3devices.py .
python -m artiq.frontend.artiq_compile nac3devices.py
'';
installPhase = installPhase =
'' ''
mkdir $out mkdir $out
@ -117,15 +87,15 @@
''; '';
}; };
llvm-nac3-pgo = pkgs.callPackage ./nix/llvm { llvm-nac3-pgo = pkgs.callPackage ./nix/llvm {
stdenv = pkgs.llvmPackages_14.stdenv; stdenv = pkgs.llvmPackages_13.stdenv;
extraCmakeFlags = [ "-DLLVM_PROFDATA_FILE=${nac3artiq-profile}/llvm.profdata" ]; extraCmakeFlags = [ "-DLLVM_PROFDATA_FILE=${nac3artiq-profile}/llvm.profdata" ];
}; };
nac3artiq-pgo = pkgs.python3Packages.toPythonModule ( nac3artiq-pgo = pkgs.python3Packages.toPythonModule (
pkgs.rustPlatform.buildRustPackage { pkgs.rustPlatform.buildRustPackage {
name = "nac3artiq-pgo"; name = "nac3artiq-pgo";
src = self; src = self;
inherit (nac3artiq) cargoLock; cargoLock = { lockFile = ./Cargo.lock; };
nativeBuildInputs = [ pkgs.python3 pkgs.llvmPackages_14.clang-unwrapped pkgs.llvmPackages_14.llvm.out llvm-nac3-pgo ]; nativeBuildInputs = [ pkgs.python3 pkgs.llvmPackages_13.clang-unwrapped llvm-nac3-pgo ];
buildInputs = [ pkgs.python3 llvm-nac3-pgo ]; buildInputs = [ pkgs.python3 llvm-nac3-pgo ];
cargoBuildFlags = [ "--package" "nac3artiq" ]; cargoBuildFlags = [ "--package" "nac3artiq" ];
cargoTestFlags = [ "--package" "nac3ast" "--package" "nac3parser" "--package" "nac3core" "--package" "nac3artiq" ]; cargoTestFlags = [ "--package" "nac3ast" "--package" "nac3parser" "--package" "nac3core" "--package" "nac3artiq" ];
@ -146,12 +116,11 @@
buildInputs = with pkgs; [ buildInputs = with pkgs; [
# build dependencies # build dependencies
packages.x86_64-linux.llvm-nac3 packages.x86_64-linux.llvm-nac3
llvmPackages_14.clang-unwrapped # IRRT llvmPackages_13.clang-unwrapped # IRRT
pkgs.llvmPackages_14.llvm.out # IRRT
cargo cargo
rustc rustc
# runtime dependencies # runtime dependencies
lld_14 # for running kernels on the host lld_13
(packages.x86_64-linux.python3-mimalloc.withPackages(ps: [ ps.numpy ])) (packages.x86_64-linux.python3-mimalloc.withPackages(ps: [ ps.numpy ]))
# development tools # development tools
cargo-insta cargo-insta
@ -170,15 +139,16 @@
}; };
hydraJobs = { hydraJobs = {
inherit (packages.x86_64-linux) llvm-nac3 nac3artiq nac3artiq-pgo; inherit (packages.x86_64-linux) llvm-nac3 nac3artiq;
llvm-nac3-msys2 = packages.x86_64-w64-mingw32.llvm-nac3; llvm-nac3-msys2 = packages.x86_64-w64-mingw32.llvm-nac3;
nac3artiq-msys2 = packages.x86_64-w64-mingw32.nac3artiq; nac3artiq-msys2 = packages.x86_64-w64-mingw32.nac3artiq;
nac3artiq-msys2-pkg = packages.x86_64-w64-mingw32.nac3artiq-pkg; nac3artiq-msys2-pkg = packages.x86_64-w64-mingw32.nac3artiq-pkg;
lld-msys2 = packages.x86_64-w64-mingw32.lld;
}; };
}; };
nixConfig = { nixConfig = {
extra-trusted-public-keys = "nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="; binaryCachePublicKeys = ["nixbld.m-labs.hk-1:5aSRVA5b320xbNvu30tqxVPXpld73bhtOeH6uAjRyHc="];
extra-substituters = "https://nixbld.m-labs.hk"; binaryCaches = ["https://nixbld.m-labs.hk" "https://cache.nixos.org"];
}; };
} }

View File

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="a"
width="128"
height="128"
viewBox="0 0 95.99999 95.99999"
version="1.1"
sodipodi:docname="nac3.svg"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs11" />
<sodipodi:namedview
id="namedview9"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
units="px"
width="128px"
inkscape:zoom="5.9448568"
inkscape:cx="60.472441"
inkscape:cy="60.556547"
inkscape:window-width="2560"
inkscape:window-height="1371"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="a" />
<rect
x="40.072601"
y="-26.776209"
width="55.668747"
height="55.668747"
transform="matrix(0.71803815,0.69600374,-0.71803815,0.69600374,0,0)"
style="fill:#be211e;stroke:#000000;stroke-width:4.37375px;stroke-linecap:round;stroke-linejoin:round"
id="rect2" />
<line
x1="38.00692"
y1="63.457153"
x2="57.993061"
y2="63.457153"
style="fill:none;stroke:#000000;stroke-width:4.37269px;stroke-linecap:round;stroke-linejoin:round"
id="line4" />
<path
d="m 48.007301,57.843329 c -1.943097,0 -3.877522,-0.41727 -5.686157,-1.246007 -3.218257,-1.474616 -5.650382,-4.075418 -6.849639,-7.323671 -2.065624,-5.588921 -1.192751,-10.226647 2.575258,-13.827 0.611554,-0.584909 1.518048,-0.773041 2.323689,-0.488206 0.80673,0.286405 1.369495,0.998486 1.447563,1.827234 0.237469,2.549302 2.439719,5.917376 4.28414,6.55273 0.396859,0.13506 0.820953,-0.05859 1.097084,-0.35222 0.339254,-0.360754 0.451065,-0.961893 -1.013597,-3.191372 -2.089851,-3.181137 -4.638728,-8.754903 -0.262407,-15.069853 0.494457,-0.713491 1.384673,-1.068907 2.256469,-0.909156 0.871795,0.161332 1.583757,0.806404 1.752251,1.651189 0.716448,3.591862 2.962357,6.151755 5.199306,8.023138 1.935503,1.61861 4.344688,3.867387 5.435687,7.096643 2.283183,6.758017 -1.202511,14.114988 -8.060822,16.494025 -1.467083,0.509226 -2.98513,0.762536 -4.498836,0.762536 z M 39.358865,40.002192 c -0.304711,0.696206 -0.541636,2.080524 -0.56865,2.237454 -0.330316,1.918771 0.168305,3.803963 0.846157,5.539951 0.856828,2.19436 2.437543,3.942467 4.583411,4.925713 2.143691,0.981675 4.554131,1.097816 6.789992,0.322666 4.571485,-1.586549 6.977584,-6.532238 5.363036,-11.02597 v -5.27e-4 C 55.455481,39.447968 54.023463,38.162043 52.221335,36.65432 50.876945,35.529534 49.409662,33.987726 48.417983,32.135555 48.01343,31.37996 47.79547,30.34303 47.76669,29.413263 c -0.187481,0.669514 -0.212441,2.325923 -0.150396,2.93691 0.179209,1.764456 1.333476,3.644546 2.340611,5.171243 1.311568,1.988179 2.72058,6.037272 0.459681,8.367985 -1.54192,1.58953 -4.038511,2.052034 -5.839973,1.38492 -2.398314,-0.888147 -3.942744,-2.690627 -4.941118,-4.768029 -0.121194,-0.25217 -0.532464,-1.174187 -0.276619,-2.5041 z"
id="path6"
style="stroke-width:1.09317" />
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -9,17 +9,16 @@ name = "nac3artiq"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
pyo3 = { version = "0.16", features = ["extension-module"] } pyo3 = { version = "0.14", features = ["extension-module"] }
parking_lot = "0.12" parking_lot = "0.11"
tempfile = "3" tempfile = "3"
nac3parser = { path = "../nac3parser" } nac3parser = { path = "../nac3parser" }
nac3core = { path = "../nac3core" } nac3core = { path = "../nac3core" }
nac3ld = { path = "../nac3ld" }
[dependencies.inkwell] [dependencies.inkwell]
git = "https://github.com/TheDan64/inkwell.git" version = "0.1.0-beta.4"
default-features = false default-features = false
features = ["llvm14-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] features = ["llvm13-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"]
[features] [features]
init-llvm-profile = [] init-llvm-profile = []

View File

@ -1,13 +1,11 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::fs; use std::fs;
use std::io::Write;
use std::process::Command; use std::process::Command;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use inkwell::{ use inkwell::{
memory_buffer::MemoryBuffer, memory_buffer::MemoryBuffer,
module::{Linkage, Module},
passes::{PassManager, PassManagerBuilder}, passes::{PassManager, PassManagerBuilder},
targets::*, targets::*,
OptimizationLevel, OptimizationLevel,
@ -37,8 +35,6 @@ use nac3core::{
typecheck::{type_inferencer::PrimitiveStore, typedef::Type}, typecheck::{type_inferencer::PrimitiveStore, typedef::Type},
}; };
use nac3ld::Linker;
use tempfile::{self, TempDir}; use tempfile::{self, TempDir};
use crate::codegen::attributes_writeback; use crate::codegen::attributes_writeback;
@ -266,457 +262,6 @@ impl Nac3 {
} }
None None
} }
fn compile_method<T>(
&self,
obj: &PyAny,
method_name: &str,
args: Vec<&PyAny>,
embedding_map: &PyAny,
py: Python,
link_fn: &dyn Fn(&Module) -> PyResult<T>,
) -> PyResult<T> {
let (mut composer, mut builtins_def, mut builtins_ty) = TopLevelComposer::new(
self.builtins.clone(),
ComposerConfig { kernel_ann: Some("Kernel"), kernel_invariant_ann: "KernelInvariant" },
);
let builtins = PyModule::import(py, "builtins")?;
let typings = PyModule::import(py, "typing")?;
let id_fn = builtins.getattr("id")?;
let issubclass = builtins.getattr("issubclass")?;
let exn_class = builtins.getattr("Exception")?;
let store_obj = embedding_map.getattr("store_object").unwrap().to_object(py);
let store_str = embedding_map.getattr("store_str").unwrap().to_object(py);
let store_fun = embedding_map.getattr("store_function").unwrap().to_object(py);
let host_attributes = embedding_map.getattr("attributes_writeback").unwrap().to_object(py);
let global_value_ids: Arc<RwLock<HashMap<_, _>>> = Arc::new(RwLock::new(HashMap::new()));
let helper = PythonHelper {
id_fn: builtins.getattr("id").unwrap().to_object(py),
len_fn: builtins.getattr("len").unwrap().to_object(py),
type_fn: builtins.getattr("type").unwrap().to_object(py),
origin_ty_fn: typings.getattr("get_origin").unwrap().to_object(py),
args_ty_fn: typings.getattr("get_args").unwrap().to_object(py),
store_obj: store_obj.clone(),
store_str,
};
let pyid_to_type = Arc::new(RwLock::new(HashMap::<u64, Type>::new()));
let exception_names = [
"ZeroDivisionError",
"IndexError",
"ValueError",
"RuntimeError",
"AssertionError",
"KeyError",
"NotImplementedError",
"OverflowError",
"IOError",
"UnwrapNoneError",
];
add_exceptions(&mut composer, &mut builtins_def, &mut builtins_ty, &exception_names);
let mut module_to_resolver_cache: HashMap<u64, _> = HashMap::new();
let mut rpc_ids = vec![];
for (stmt, path, module) in self.top_levels.iter() {
let py_module: &PyAny = module.extract(py)?;
let module_id: u64 = id_fn.call1((py_module,))?.extract()?;
let helper = helper.clone();
let class_obj;
if let StmtKind::ClassDef { name, .. } = &stmt.node {
let class = py_module.getattr(name.to_string()).unwrap();
if issubclass.call1((class, exn_class)).unwrap().extract().unwrap() &&
class.getattr("artiq_builtin").is_err() {
class_obj = Some(class);
} else {
class_obj = None;
}
} else {
class_obj = None;
}
let (name_to_pyid, resolver) =
module_to_resolver_cache.get(&module_id).cloned().unwrap_or_else(|| {
let mut name_to_pyid: HashMap<StrRef, u64> = HashMap::new();
let members: &PyDict =
py_module.getattr("__dict__").unwrap().cast_as().unwrap();
for (key, val) in members.iter() {
let key: &str = key.extract().unwrap();
let val = id_fn.call1((val,)).unwrap().extract().unwrap();
name_to_pyid.insert(key.into(), val);
}
let resolver = Arc::new(Resolver(Arc::new(InnerResolver {
id_to_type: builtins_ty.clone().into(),
id_to_def: builtins_def.clone().into(),
pyid_to_def: self.pyid_to_def.clone(),
pyid_to_type: pyid_to_type.clone(),
primitive_ids: self.primitive_ids.clone(),
global_value_ids: global_value_ids.clone(),
class_names: Default::default(),
name_to_pyid: name_to_pyid.clone(),
module: module.clone(),
id_to_pyval: Default::default(),
id_to_primitive: Default::default(),
field_to_val: Default::default(),
helper,
string_store: self.string_store.clone(),
exception_ids: self.exception_ids.clone(),
deferred_eval_store: self.deferred_eval_store.clone(),
})))
as Arc<dyn SymbolResolver + Send + Sync>;
let name_to_pyid = Rc::new(name_to_pyid);
module_to_resolver_cache
.insert(module_id, (name_to_pyid.clone(), resolver.clone()));
(name_to_pyid, resolver)
});
let (name, def_id, ty) = composer
.register_top_level(stmt.clone(), Some(resolver.clone()), path.clone(), false)
.map_err(|e| {
CompileError::new_err(format!(
"compilation failed\n----------\n{}",
e
))
})?;
if let Some(class_obj) = class_obj {
self.exception_ids.write().insert(def_id.0, store_obj.call1(py, (class_obj, ))?.extract(py)?);
}
match &stmt.node {
StmtKind::FunctionDef { decorator_list, .. } => {
if decorator_list.iter().any(|decorator| matches!(decorator.node, ExprKind::Name { id, .. } if id == "rpc".into())) {
store_fun.call1(py, (def_id.0.into_py(py), module.getattr(py, name.to_string()).unwrap())).unwrap();
rpc_ids.push((None, def_id));
}
}
StmtKind::ClassDef { name, body, .. } => {
let class_name = name.to_string();
let class_obj = module.getattr(py, &class_name).unwrap();
for stmt in body.iter() {
if let StmtKind::FunctionDef { name, decorator_list, .. } = &stmt.node {
if decorator_list.iter().any(|decorator| matches!(decorator.node, ExprKind::Name { id, .. } if id == "rpc".into())) {
if name == &"__init__".into() {
return Err(CompileError::new_err(format!(
"compilation failed\n----------\nThe constructor of class {} should not be decorated with rpc decorator (at {})",
class_name, stmt.location
)));
}
rpc_ids.push((Some((class_obj.clone(), *name)), def_id));
}
}
}
}
_ => ()
}
let id = *name_to_pyid.get(&name).unwrap();
self.pyid_to_def.write().insert(id, def_id);
{
let mut pyid_to_ty = pyid_to_type.write();
if let Some(ty) = ty {
pyid_to_ty.insert(id, ty);
}
}
}
let id_fun = PyModule::import(py, "builtins")?.getattr("id")?;
let mut name_to_pyid: HashMap<StrRef, u64> = HashMap::new();
let module = PyModule::new(py, "tmp")?;
module.add("base", obj)?;
name_to_pyid.insert("base".into(), id_fun.call1((obj,))?.extract()?);
let mut arg_names = vec![];
for (i, arg) in args.into_iter().enumerate() {
let name = format!("tmp{}", i);
module.add(&name, arg)?;
name_to_pyid.insert(name.clone().into(), id_fun.call1((arg,))?.extract()?);
arg_names.push(name);
}
let synthesized = if method_name.is_empty() {
format!("def __modinit__():\n base({})", arg_names.join(", "))
} else {
format!("def __modinit__():\n base.{}({})", method_name, arg_names.join(", "))
};
let mut synthesized =
parse_program(&synthesized, "<nac3_synthesized_modinit>".to_string().into()).unwrap();
let inner_resolver = Arc::new(InnerResolver {
id_to_type: builtins_ty.clone().into(),
id_to_def: builtins_def.clone().into(),
pyid_to_def: self.pyid_to_def.clone(),
pyid_to_type: pyid_to_type.clone(),
primitive_ids: self.primitive_ids.clone(),
global_value_ids: global_value_ids.clone(),
class_names: Default::default(),
id_to_pyval: Default::default(),
id_to_primitive: Default::default(),
field_to_val: Default::default(),
name_to_pyid,
module: module.to_object(py),
helper,
string_store: self.string_store.clone(),
exception_ids: self.exception_ids.clone(),
deferred_eval_store: self.deferred_eval_store.clone(),
});
let resolver = Arc::new(Resolver(inner_resolver.clone())) as Arc<dyn SymbolResolver + Send + Sync>;
let (_, def_id, _) = composer
.register_top_level(synthesized.pop().unwrap(), Some(resolver.clone()), "".into(), false)
.unwrap();
let fun_signature =
FunSignature { args: vec![], ret: self.primitive.none, vars: HashMap::new() };
let mut store = ConcreteTypeStore::new();
let mut cache = HashMap::new();
let signature =
store.from_signature(&mut composer.unifier, &self.primitive, &fun_signature, &mut cache);
let signature = store.add_cty(signature);
if let Err(e) = composer.start_analysis(true) {
// report error of __modinit__ separately
if !e.contains("<nac3_synthesized_modinit>") {
return Err(CompileError::new_err(format!(
"compilation failed\n----------\n{}",
e
)));
} else {
let msg = Self::report_modinit(
&arg_names,
method_name,
resolver.clone(),
&composer.extract_def_list(),
&mut composer.unifier,
&self.primitive,
);
return Err(CompileError::new_err(format!(
"compilation failed\n----------\n{}",
msg.unwrap_or(e)
)));
}
}
let top_level = Arc::new(composer.make_top_level_context());
{
let rpc_codegen = rpc_codegen_callback();
let defs = top_level.definitions.read();
for (class_data, id) in rpc_ids.iter() {
let mut def = defs[id.0].write();
match &mut *def {
TopLevelDef::Function { codegen_callback, .. } => {
*codegen_callback = Some(rpc_codegen.clone());
}
TopLevelDef::Class { methods, .. } => {
let (class_def, method_name) = class_data.as_ref().unwrap();
for (name, _, id) in methods.iter() {
if name != method_name {
continue;
}
if let TopLevelDef::Function { codegen_callback, .. } =
&mut *defs[id.0].write()
{
*codegen_callback = Some(rpc_codegen.clone());
store_fun
.call1(
py,
(
id.0.into_py(py),
class_def.getattr(py, name.to_string()).unwrap(),
),
)
.unwrap();
}
}
}
}
}
}
let instance = {
let defs = top_level.definitions.read();
let mut definition = defs[def_id.0].write();
if let TopLevelDef::Function { instance_to_stmt, instance_to_symbol, .. } =
&mut *definition
{
instance_to_symbol.insert("".to_string(), "__modinit__".into());
instance_to_stmt[""].clone()
} else {
unreachable!()
}
};
let task = CodeGenTask {
subst: Default::default(),
symbol_name: "__modinit__".to_string(),
body: instance.body,
signature,
resolver: resolver.clone(),
store,
unifier_index: instance.unifier_id,
calls: instance.calls,
id: 0,
};
let mut store = ConcreteTypeStore::new();
let mut cache = HashMap::new();
let signature =
store.from_signature(&mut composer.unifier, &self.primitive, &fun_signature, &mut cache);
let signature = store.add_cty(signature);
let attributes_writeback_task = CodeGenTask {
subst: Default::default(),
symbol_name: "attributes_writeback".to_string(),
body: Arc::new(Default::default()),
signature,
resolver,
store,
unifier_index: instance.unifier_id,
calls: Arc::new(Default::default()),
id: 0,
};
let membuffers: Arc<Mutex<Vec<Vec<u8>>>> = Default::default();
let membuffer = membuffers.clone();
let f = Arc::new(WithCall::new(Box::new(move |module| {
let buffer = module.write_bitcode_to_memory();
let buffer = buffer.as_slice().into();
membuffer.lock().push(buffer);
})));
let size_t = if self.isa == Isa::Host { 64 } else { 32 };
let thread_names: Vec<String> = (0..4).map(|_| "main".to_string()).collect();
let threads: Vec<_> = thread_names
.iter()
.map(|s| Box::new(ArtiqCodeGenerator::new(s.to_string(), size_t, self.time_fns)))
.collect();
let membuffer = membuffers.clone();
py.allow_threads(|| {
let (registry, handles) = WorkerRegistry::create_workers(threads, top_level.clone(), f);
registry.add_task(task);
registry.wait_tasks_complete(handles);
let mut generator = ArtiqCodeGenerator::new("attributes_writeback".to_string(), size_t, self.time_fns);
let context = inkwell::context::Context::create();
let module = context.create_module("attributes_writeback");
let builder = context.create_builder();
let (_, module, _) = gen_func_impl(&context, &mut generator, &registry, builder, module,
attributes_writeback_task, |generator, ctx| {
attributes_writeback(ctx, generator, inner_resolver.as_ref(), host_attributes)
}).unwrap();
let buffer = module.write_bitcode_to_memory();
let buffer = buffer.as_slice().into();
membuffer.lock().push(buffer);
});
let context = inkwell::context::Context::create();
let buffers = membuffers.lock();
let main = context
.create_module_from_ir(MemoryBuffer::create_from_memory_range(&buffers[0], "main"))
.unwrap();
for buffer in buffers.iter().skip(1) {
let other = context
.create_module_from_ir(MemoryBuffer::create_from_memory_range(buffer, "main"))
.unwrap();
main.link_in_module(other)
.map_err(|err| CompileError::new_err(err.to_string()))?;
}
let builder = context.create_builder();
let modinit_return = main.get_function("__modinit__").unwrap().get_last_basic_block().unwrap().get_terminator().unwrap();
builder.position_before(&modinit_return);
builder.build_call(main.get_function("attributes_writeback").unwrap(), &[], "attributes_writeback");
main.link_in_module(load_irrt(&context))
.map_err(|err| CompileError::new_err(err.to_string()))?;
let mut function_iter = main.get_first_function();
while let Some(func) = function_iter {
if func.count_basic_blocks() > 0 && func.get_name().to_str().unwrap() != "__modinit__" {
func.set_linkage(inkwell::module::Linkage::Private);
}
function_iter = func.get_next_function();
}
// Demote all global variables that will not be referenced in the kernel to private
let preserved_symbols: Vec<&'static [u8]> = vec![
b"typeinfo",
b"now",
];
let mut global_option = main.get_first_global();
while let Some(global) = global_option {
if !preserved_symbols.contains(&(global.get_name().to_bytes())) {
global.set_linkage(Linkage::Private);
}
global_option = global.get_next_global();
}
let builder = PassManagerBuilder::create();
builder.set_optimization_level(OptimizationLevel::Aggressive);
let passes = PassManager::create(());
builder.set_inliner_with_threshold(255);
builder.populate_module_pass_manager(&passes);
passes.run_on(&main);
link_fn(&main)
}
fn get_llvm_target_machine(
&self,
) -> TargetMachine {
let (triple, features) = match self.isa {
Isa::Host => (
TargetMachine::get_default_triple(),
TargetMachine::get_host_cpu_features().to_string(),
),
Isa::RiscV32G => {
(TargetTriple::create("riscv32-unknown-linux"), "+a,+m,+f,+d".to_string())
}
Isa::RiscV32IMA => (TargetTriple::create("riscv32-unknown-linux"), "+a,+m".to_string()),
Isa::CortexA9 => (
TargetTriple::create("armv7-unknown-linux-gnueabihf"),
"+dsp,+fp16,+neon,+vfp3,+long-calls".to_string(),
),
};
let target =
Target::from_triple(&triple).expect("couldn't create target from target triple");
target
.create_target_machine(
&triple,
"",
&features,
OptimizationLevel::Default,
RelocMode::PIC,
CodeModel::Default,
)
.expect("couldn't create target machine")
}
}
fn link_with_lld(
elf_filename: String,
obj_filename: String,
) -> PyResult<()>{
let linker_args = vec![
"-shared".to_string(),
"--eh-frame-hdr".to_string(),
"-x".to_string(),
"-o".to_string(),
elf_filename,
obj_filename,
];
#[cfg(not(windows))]
let lld_command = "ld.lld";
#[cfg(windows)]
let lld_command = "ld.lld.exe";
if let Ok(linker_status) = Command::new(lld_command).args(linker_args).status() {
if !linker_status.success() {
return Err(CompileError::new_err("failed to start linker"));
}
} else {
return Err(CompileError::new_err(
"linker returned non-zero status code",
));
}
Ok(())
} }
fn add_exceptions( fn add_exceptions(
@ -924,41 +469,423 @@ impl Nac3 {
embedding_map: &PyAny, embedding_map: &PyAny,
py: Python, py: Python,
) -> PyResult<()> { ) -> PyResult<()> {
let target_machine = self.get_llvm_target_machine(); let (mut composer, mut builtins_def, mut builtins_ty) = TopLevelComposer::new(
self.builtins.clone(),
ComposerConfig { kernel_ann: Some("Kernel"), kernel_invariant_ann: "KernelInvariant" },
);
if self.isa == Isa::Host { let builtins = PyModule::import(py, "builtins")?;
let link_fn = |module: &Module| { let typings = PyModule::import(py, "typing")?;
let working_directory = self.working_directory.path().to_owned(); let id_fn = builtins.getattr("id")?;
target_machine let issubclass = builtins.getattr("issubclass")?;
.write_to_file(module, FileType::Object, &working_directory.join("module.o")) let exn_class = builtins.getattr("Exception")?;
.expect("couldn't write module to file"); let store_obj = embedding_map.getattr("store_object").unwrap().to_object(py);
link_with_lld( let store_str = embedding_map.getattr("store_str").unwrap().to_object(py);
filename.to_string(), let store_fun = embedding_map.getattr("store_function").unwrap().to_object(py);
working_directory.join("module.o").to_string_lossy().to_string() let host_attributes = embedding_map.getattr("attributes_writeback").unwrap().to_object(py);
)?; let global_value_ids: Arc<RwLock<HashMap<_, _>>> = Arc::new(RwLock::new(HashMap::new()));
Ok(()) let helper = PythonHelper {
}; id_fn: builtins.getattr("id").unwrap().to_object(py),
len_fn: builtins.getattr("len").unwrap().to_object(py),
type_fn: builtins.getattr("type").unwrap().to_object(py),
origin_ty_fn: typings.getattr("get_origin").unwrap().to_object(py),
args_ty_fn: typings.getattr("get_args").unwrap().to_object(py),
store_obj: store_obj.clone(),
store_str,
};
self.compile_method(obj, method_name, args, embedding_map, py, &link_fn) let pyid_to_type = Arc::new(RwLock::new(HashMap::<u64, Type>::new()));
} else { let exception_names = [
let link_fn = |module: &Module| { "ZeroDivisionError",
let object_mem = target_machine "IndexError",
.write_to_memory_buffer(module, FileType::Object) "ValueError",
.expect("couldn't write module to object file buffer"); "RuntimeError",
if let Ok(dyn_lib) = Linker::ld(object_mem.as_slice()) { "AssertionError",
if let Ok(mut file) = fs::File::create(filename) { "KeyError",
file.write_all(&dyn_lib).expect("couldn't write linked library to file"); "NotImplementedError",
Ok(()) "OverflowError",
} else { "IOError",
Err(CompileError::new_err("failed to create file")) "UnwrapNoneError",
} ];
add_exceptions(&mut composer, &mut builtins_def, &mut builtins_ty, &exception_names);
let mut module_to_resolver_cache: HashMap<u64, _> = HashMap::new();
let mut rpc_ids = vec![];
for (stmt, path, module) in self.top_levels.iter() {
let py_module: &PyAny = module.extract(py)?;
let module_id: u64 = id_fn.call1((py_module,))?.extract()?;
let helper = helper.clone();
let class_obj;
if let StmtKind::ClassDef { name, .. } = &stmt.node {
let class = py_module.getattr(name.to_string()).unwrap();
if issubclass.call1((class, exn_class)).unwrap().extract().unwrap() &&
class.getattr("artiq_builtin").is_err() {
class_obj = Some(class);
} else { } else {
Err(CompileError::new_err("linker failed to process object file")) class_obj = None;
} }
}; } else {
class_obj = None;
}
let (name_to_pyid, resolver) =
module_to_resolver_cache.get(&module_id).cloned().unwrap_or_else(|| {
let mut name_to_pyid: HashMap<StrRef, u64> = HashMap::new();
let members: &PyDict =
py_module.getattr("__dict__").unwrap().cast_as().unwrap();
for (key, val) in members.iter() {
let key: &str = key.extract().unwrap();
let val = id_fn.call1((val,)).unwrap().extract().unwrap();
name_to_pyid.insert(key.into(), val);
}
let resolver = Arc::new(Resolver(Arc::new(InnerResolver {
id_to_type: builtins_ty.clone().into(),
id_to_def: builtins_def.clone().into(),
pyid_to_def: self.pyid_to_def.clone(),
pyid_to_type: pyid_to_type.clone(),
primitive_ids: self.primitive_ids.clone(),
global_value_ids: global_value_ids.clone(),
class_names: Default::default(),
name_to_pyid: name_to_pyid.clone(),
module: module.clone(),
id_to_pyval: Default::default(),
id_to_primitive: Default::default(),
field_to_val: Default::default(),
helper,
string_store: self.string_store.clone(),
exception_ids: self.exception_ids.clone(),
deferred_eval_store: self.deferred_eval_store.clone(),
})))
as Arc<dyn SymbolResolver + Send + Sync>;
let name_to_pyid = Rc::new(name_to_pyid);
module_to_resolver_cache
.insert(module_id, (name_to_pyid.clone(), resolver.clone()));
(name_to_pyid, resolver)
});
self.compile_method(obj, method_name, args, embedding_map, py, &link_fn) let (name, def_id, ty) = composer
.register_top_level(stmt.clone(), Some(resolver.clone()), path.clone())
.map_err(|e| {
CompileError::new_err(format!(
"compilation failed\n----------\n{}",
e
))
})?;
if let Some(class_obj) = class_obj {
self.exception_ids.write().insert(def_id.0, store_obj.call1(py, (class_obj, ))?.extract(py)?);
}
match &stmt.node {
StmtKind::FunctionDef { decorator_list, .. } => {
if decorator_list.iter().any(|decorator| matches!(decorator.node, ExprKind::Name { id, .. } if id == "rpc".into())) {
store_fun.call1(py, (def_id.0.into_py(py), module.getattr(py, name.to_string()).unwrap())).unwrap();
rpc_ids.push((None, def_id));
}
}
StmtKind::ClassDef { name, body, .. } => {
let class_obj = module.getattr(py, name.to_string()).unwrap();
for stmt in body.iter() {
if let StmtKind::FunctionDef { name, decorator_list, .. } = &stmt.node {
if decorator_list.iter().any(|decorator| matches!(decorator.node, ExprKind::Name { id, .. } if id == "rpc".into())) {
rpc_ids.push((Some((class_obj.clone(), *name)), def_id));
}
}
}
}
_ => ()
}
let id = *name_to_pyid.get(&name).unwrap();
self.pyid_to_def.write().insert(id, def_id);
{
let mut pyid_to_ty = pyid_to_type.write();
if let Some(ty) = ty {
pyid_to_ty.insert(id, ty);
}
}
} }
let id_fun = PyModule::import(py, "builtins")?.getattr("id")?;
let mut name_to_pyid: HashMap<StrRef, u64> = HashMap::new();
let module = PyModule::new(py, "tmp")?;
module.add("base", obj)?;
name_to_pyid.insert("base".into(), id_fun.call1((obj,))?.extract()?);
let mut arg_names = vec![];
for (i, arg) in args.into_iter().enumerate() {
let name = format!("tmp{}", i);
module.add(&name, arg)?;
name_to_pyid.insert(name.clone().into(), id_fun.call1((arg,))?.extract()?);
arg_names.push(name);
}
let synthesized = if method_name.is_empty() {
format!("def __modinit__():\n base({})", arg_names.join(", "))
} else {
format!("def __modinit__():\n base.{}({})", method_name, arg_names.join(", "))
};
let mut synthesized =
parse_program(&synthesized, "__nac3_synthesized_modinit__".to_string().into()).unwrap();
let inner_resolver = Arc::new(InnerResolver {
id_to_type: builtins_ty.clone().into(),
id_to_def: builtins_def.clone().into(),
pyid_to_def: self.pyid_to_def.clone(),
pyid_to_type: pyid_to_type.clone(),
primitive_ids: self.primitive_ids.clone(),
global_value_ids: global_value_ids.clone(),
class_names: Default::default(),
id_to_pyval: Default::default(),
id_to_primitive: Default::default(),
field_to_val: Default::default(),
name_to_pyid,
module: module.to_object(py),
helper,
string_store: self.string_store.clone(),
exception_ids: self.exception_ids.clone(),
deferred_eval_store: self.deferred_eval_store.clone(),
});
let resolver = Arc::new(Resolver(inner_resolver.clone())) as Arc<dyn SymbolResolver + Send + Sync>;
let (_, def_id, _) = composer
.register_top_level(synthesized.pop().unwrap(), Some(resolver.clone()), "".into())
.unwrap();
let fun_signature =
FunSignature { args: vec![], ret: self.primitive.none, vars: HashMap::new() };
let mut store = ConcreteTypeStore::new();
let mut cache = HashMap::new();
let signature =
store.from_signature(&mut composer.unifier, &self.primitive, &fun_signature, &mut cache);
let signature = store.add_cty(signature);
if let Err(e) = composer.start_analysis(true) {
// report error of __modinit__ separately
if !e.contains("__nac3_synthesized_modinit__") {
return Err(CompileError::new_err(format!(
"compilation failed\n----------\n{}",
e
)));
} else {
let msg = Self::report_modinit(
&arg_names,
method_name,
resolver.clone(),
&composer.extract_def_list(),
&mut composer.unifier,
&self.primitive,
);
return Err(CompileError::new_err(msg.unwrap_or(e)));
}
}
let top_level = Arc::new(composer.make_top_level_context());
{
let rpc_codegen = rpc_codegen_callback();
let defs = top_level.definitions.read();
for (class_data, id) in rpc_ids.iter() {
let mut def = defs[id.0].write();
match &mut *def {
TopLevelDef::Function { codegen_callback, .. } => {
*codegen_callback = Some(rpc_codegen.clone());
}
TopLevelDef::Class { methods, .. } => {
let (class_def, method_name) = class_data.as_ref().unwrap();
for (name, _, id) in methods.iter() {
if name != method_name {
continue;
}
if let TopLevelDef::Function { codegen_callback, .. } =
&mut *defs[id.0].write()
{
*codegen_callback = Some(rpc_codegen.clone());
store_fun
.call1(
py,
(
id.0.into_py(py),
class_def.getattr(py, name.to_string()).unwrap(),
),
)
.unwrap();
}
}
}
}
}
}
let instance = {
let defs = top_level.definitions.read();
let mut definition = defs[def_id.0].write();
if let TopLevelDef::Function { instance_to_stmt, instance_to_symbol, .. } =
&mut *definition
{
instance_to_symbol.insert("".to_string(), "__modinit__".into());
instance_to_stmt[""].clone()
} else {
unreachable!()
}
};
let task = CodeGenTask {
subst: Default::default(),
symbol_name: "__modinit__".to_string(),
body: instance.body,
signature,
resolver: resolver.clone(),
store,
unifier_index: instance.unifier_id,
calls: instance.calls,
id: 0,
};
let mut store = ConcreteTypeStore::new();
let mut cache = HashMap::new();
let signature =
store.from_signature(&mut composer.unifier, &self.primitive, &fun_signature, &mut cache);
let signature = store.add_cty(signature);
let attributes_writeback_task = CodeGenTask {
subst: Default::default(),
symbol_name: "attributes_writeback".to_string(),
body: Arc::new(Default::default()),
signature,
resolver,
store,
unifier_index: instance.unifier_id,
calls: Arc::new(Default::default()),
id: 0,
};
let isa = self.isa;
let working_directory = self.working_directory.path().to_owned();
let membuffers: Arc<Mutex<Vec<Vec<u8>>>> = Default::default();
let membuffer = membuffers.clone();
let f = Arc::new(WithCall::new(Box::new(move |module| {
let buffer = module.write_bitcode_to_memory();
let buffer = buffer.as_slice().into();
membuffer.lock().push(buffer);
})));
let size_t = if self.isa == Isa::Host { 64 } else { 32 };
let thread_names: Vec<String> = (0..4).map(|_| "main".to_string()).collect();
let threads: Vec<_> = thread_names
.iter()
.map(|s| Box::new(ArtiqCodeGenerator::new(s.to_string(), size_t, self.time_fns)))
.collect();
let membuffer = membuffers.clone();
py.allow_threads(|| {
let (registry, handles) = WorkerRegistry::create_workers(threads, top_level.clone(), f);
registry.add_task(task);
registry.wait_tasks_complete(handles);
let mut generator = ArtiqCodeGenerator::new("attributes_writeback".to_string(), size_t, self.time_fns);
let context = inkwell::context::Context::create();
let module = context.create_module("attributes_writeback");
let builder = context.create_builder();
let (_, module, _) = gen_func_impl(&context, &mut generator, &registry, builder, module,
attributes_writeback_task, |generator, ctx| {
attributes_writeback(ctx, generator, inner_resolver.as_ref(), host_attributes)
}).unwrap();
let buffer = module.write_bitcode_to_memory();
let buffer = buffer.as_slice().into();
membuffer.lock().push(buffer);
});
let context = inkwell::context::Context::create();
let buffers = membuffers.lock();
let main = context
.create_module_from_ir(MemoryBuffer::create_from_memory_range(&buffers[0], "main"))
.unwrap();
for buffer in buffers.iter().skip(1) {
let other = context
.create_module_from_ir(MemoryBuffer::create_from_memory_range(buffer, "main"))
.unwrap();
main.link_in_module(other)
.map_err(|err| CompileError::new_err(err.to_string()))?;
}
let builder = context.create_builder();
let modinit_return = main.get_function("__modinit__").unwrap().get_last_basic_block().unwrap().get_terminator().unwrap();
builder.position_before(&modinit_return);
builder.build_call(main.get_function("attributes_writeback").unwrap(), &[], "attributes_writeback");
main.link_in_module(load_irrt(&context))
.map_err(|err| CompileError::new_err(err.to_string()))?;
let mut function_iter = main.get_first_function();
while let Some(func) = function_iter {
if func.count_basic_blocks() > 0 && func.get_name().to_str().unwrap() != "__modinit__" {
func.set_linkage(inkwell::module::Linkage::Private);
}
function_iter = func.get_next_function();
}
let builder = PassManagerBuilder::create();
builder.set_optimization_level(OptimizationLevel::Aggressive);
let passes = PassManager::create(());
builder.set_inliner_with_threshold(255);
builder.populate_module_pass_manager(&passes);
passes.run_on(&main);
let (triple, features) = match isa {
Isa::Host => (
TargetMachine::get_default_triple(),
TargetMachine::get_host_cpu_features().to_string(),
),
Isa::RiscV32G => {
(TargetTriple::create("riscv32-unknown-linux"), "+a,+m,+f,+d".to_string())
}
Isa::RiscV32IMA => (TargetTriple::create("riscv32-unknown-linux"), "+a,+m".to_string()),
Isa::CortexA9 => (
TargetTriple::create("armv7-unknown-linux-gnueabihf"),
"+dsp,+fp16,+neon,+vfp3".to_string(),
),
};
let target =
Target::from_triple(&triple).expect("couldn't create target from target triple");
let target_machine = target
.create_target_machine(
&triple,
"",
&features,
OptimizationLevel::Default,
RelocMode::PIC,
CodeModel::Default,
)
.expect("couldn't create target machine");
target_machine
.write_to_file(&main, FileType::Object, &working_directory.join("module.o"))
.expect("couldn't write module to file");
let mut linker_args = vec![
"-shared".to_string(),
"--eh-frame-hdr".to_string(),
"-x".to_string(),
"-o".to_string(),
filename.to_string(),
working_directory.join("module.o").to_string_lossy().to_string(),
];
if isa != Isa::Host {
linker_args.push(
"-T".to_string()
+ self.working_directory.path().join("kernel.ld").to_str().unwrap(),
);
}
#[cfg(not(windows))]
let lld_command = "ld.lld";
#[cfg(windows)]
let lld_command = "ld.lld.exe";
if let Ok(linker_status) = Command::new(lld_command).args(linker_args).status() {
if !linker_status.success() {
return Err(CompileError::new_err("failed to start linker"));
}
} else {
return Err(CompileError::new_err(
"linker returned non-zero status code",
));
}
Ok(())
} }
fn compile_method_to_mem( fn compile_method_to_mem(
@ -969,40 +896,10 @@ impl Nac3 {
embedding_map: &PyAny, embedding_map: &PyAny,
py: Python, py: Python,
) -> PyResult<PyObject> { ) -> PyResult<PyObject> {
let target_machine = self.get_llvm_target_machine(); let filename_path = self.working_directory.path().join("module.elf");
let filename = filename_path.to_str().unwrap();
if self.isa == Isa::Host { self.compile_method_to_file(obj, method_name, args, filename, embedding_map, py)?;
let link_fn = |module: &Module| { Ok(PyBytes::new(py, &fs::read(filename).unwrap()).into())
let working_directory = self.working_directory.path().to_owned();
target_machine
.write_to_file(&module, FileType::Object, &working_directory.join("module.o"))
.expect("couldn't write module to file");
let filename_path = self.working_directory.path().join("module.elf");
let filename = filename_path.to_str().unwrap();
link_with_lld(
filename.to_string(),
working_directory.join("module.o").to_string_lossy().to_string()
)?;
Ok(PyBytes::new(py, &fs::read(filename).unwrap()).into())
};
self.compile_method(obj, method_name, args, embedding_map, py, &link_fn)
} else {
let link_fn = |module: &Module| {
let object_mem = target_machine
.write_to_memory_buffer(&module, FileType::Object)
.expect("couldn't write module to object file buffer");
if let Ok(dyn_lib) = Linker::ld(object_mem.as_slice()) {
Ok(PyBytes::new(py, &dyn_lib).into())
} else {
Err(CompileError::new_err("linker failed to process object file"))
}
};
self.compile_method(obj, method_name, args, embedding_map, py, &link_fn)
}
} }
} }

View File

@ -99,7 +99,7 @@ impl StaticValue for PythonValue {
_: &mut dyn CodeGenerator, _: &mut dyn CodeGenerator,
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
ctx.module ctx.module
.get_global(format!("{}_const", self.id).as_str()) .get_global(self.id.to_string().as_str())
.map(|val| val.as_pointer_value().into()) .map(|val| val.as_pointer_value().into())
.unwrap_or_else(|| { .unwrap_or_else(|| {
Python::with_gil(|py| -> PyResult<BasicValueEnum<'ctx>> { Python::with_gil(|py| -> PyResult<BasicValueEnum<'ctx>> {
@ -115,7 +115,13 @@ impl StaticValue for PythonValue {
&[ctx.ctx.i32_type().const_int(id as u64, false).into()], &[ctx.ctx.i32_type().const_int(id as u64, false).into()],
false, false,
)); ));
Ok(global.as_pointer_value().into()) let global2 = ctx.module.add_global(
struct_type.ptr_type(AddressSpace::Generic),
None,
format!("{}_const2", self.id).as_str(),
);
global2.set_initializer(&global.as_pointer_value());
Ok(global2.as_pointer_value().into())
}) })
.unwrap() .unwrap()
}) })
@ -214,7 +220,7 @@ impl StaticValue for PythonValue {
let ty_id: u64 = helper.id_fn.call1(py, (ty,))?.extract(py)?; let ty_id: u64 = helper.id_fn.call1(py, (ty,))?.extract(py)?;
assert_eq!(ty_id, self.resolver.primitive_ids.tuple); assert_eq!(ty_id, self.resolver.primitive_ids.tuple);
let tup: &PyTuple = self.value.extract(py)?; let tup: &PyTuple = self.value.extract(py)?;
let elem = tup.get_item(index as usize)?; let elem = tup.get_item(index as usize);
let id = self.resolver.helper.id_fn.call1(py, (elem,))?.extract(py)?; let id = self.resolver.helper.id_fn.call1(py, (elem,))?.extract(py)?;
Ok(Some((id, elem.into()))) Ok(Some((id, elem.into())))
}) })
@ -351,7 +357,7 @@ impl InnerResolver {
let constraints = pyty.getattr("__constraints__").unwrap(); let constraints = pyty.getattr("__constraints__").unwrap();
let mut result: Vec<Type> = vec![]; let mut result: Vec<Type> = vec![];
let needs_defer = self.deferred_eval_store.needs_defer.load(Relaxed); let needs_defer = self.deferred_eval_store.needs_defer.load(Relaxed);
for i in 0usize.. { for i in 0.. {
if let Ok(constr) = constraints.get_item(i) { if let Ok(constr) = constraints.get_item(i) {
if needs_defer { if needs_defer {
result.push(unifier.get_dummy_var().0); result.push(unifier.get_dummy_var().0);
@ -409,7 +415,7 @@ impl InnerResolver {
if args.len() == 1 { if args.len() == 1 {
let ty = match self.get_pyty_obj_type( let ty = match self.get_pyty_obj_type(
py, py,
args.get_item(0)?, args.get_item(0),
unifier, unifier,
defs, defs,
primitives, primitives,
@ -490,7 +496,7 @@ impl InnerResolver {
if args.len() == 1 { if args.len() == 1 {
let ty = match self.get_pyty_obj_type( let ty = match self.get_pyty_obj_type(
py, py,
args.get_item(0)?, args.get_item(0),
unifier, unifier,
defs, defs,
primitives, primitives,
@ -545,31 +551,6 @@ impl InnerResolver {
if let Some(ty) = self.pyid_to_type.read().get(&py_obj_id) { if let Some(ty) = self.pyid_to_type.read().get(&py_obj_id) {
return Ok(Ok(*ty)) return Ok(Ok(*ty))
} }
// check if constructor function exists in the methods list
let pyid_to_def = self.pyid_to_def.read();
let constructor_ty = pyid_to_def
.get(&py_obj_id)
.and_then(|def_id| {
defs
.iter()
.find_map(|def| {
if let TopLevelDef::Class {
object_id, methods, constructor, ..
} = &*def.read() {
if object_id == def_id && constructor.is_some() && methods.iter().any(|(s, _, _)| s == &"__init__".into()) {
return constructor.clone();
}
}
None
})
});
if let Some(ty) = constructor_ty {
self.pyid_to_type.write().insert(py_obj_id, ty);
return Ok(Ok(ty))
}
let (extracted_ty, inst_check) = match self.get_pyty_obj_type( let (extracted_ty, inst_check) = match self.get_pyty_obj_type(
py, py,
{ {
@ -695,10 +676,7 @@ impl InnerResolver {
if let TypeEnum::TFunc(..) = &*unifier.get_ty(field.1.0) { if let TypeEnum::TFunc(..) = &*unifier.get_ty(field.1.0) {
continue; continue;
} else { } else {
let field_data = match obj.getattr(&name) { let field_data = obj.getattr(&name)?;
Ok(d) => d,
Err(e) => return Ok(Err(format!("{}", e))),
};
let ty = match self let ty = match self
.get_obj_type(py, field_data, unifier, defs, primitives)? .get_obj_type(py, field_data, unifier, defs, primitives)?
{ {
@ -739,42 +717,7 @@ impl InnerResolver {
}; };
result result
} }
_ => { _ => Ok(Ok(extracted_ty)),
// check integer bounds
if unifier.unioned(extracted_ty, primitives.int32) {
obj.extract::<i32>().map_or_else(
|_| Ok(Err(format!("{} is not in the range of int32", obj))),
|_| Ok(Ok(extracted_ty))
)
} else if unifier.unioned(extracted_ty, primitives.int64) {
obj.extract::<i64>().map_or_else(
|_| Ok(Err(format!("{} is not in the range of int64", obj))),
|_| Ok(Ok(extracted_ty))
)
} else if unifier.unioned(extracted_ty, primitives.uint32) {
obj.extract::<u32>().map_or_else(
|_| Ok(Err(format!("{} is not in the range of uint32", obj))),
|_| Ok(Ok(extracted_ty))
)
} else if unifier.unioned(extracted_ty, primitives.uint64) {
obj.extract::<u64>().map_or_else(
|_| Ok(Err(format!("{} is not in the range of uint64", obj))),
|_| Ok(Ok(extracted_ty))
)
} else if unifier.unioned(extracted_ty, primitives.bool) {
obj.extract::<bool>().map_or_else(
|_| Ok(Err(format!("{} is not in the range of bool", obj))),
|_| Ok(Ok(extracted_ty))
)
} else if unifier.unioned(extracted_ty, primitives.float) {
obj.extract::<f64>().map_or_else(
|_| Ok(Err(format!("{} is not in the range of float64", obj))),
|_| Ok(Ok(extracted_ty))
)
} else {
Ok(Ok(extracted_ty))
}
}
} }
} }
@ -790,27 +733,33 @@ impl InnerResolver {
self.helper.id_fn.call1(py, (self.helper.type_fn.call1(py, (obj,))?,))?.extract(py)?; self.helper.id_fn.call1(py, (self.helper.type_fn.call1(py, (obj,))?,))?.extract(py)?;
let id: u64 = self.helper.id_fn.call1(py, (obj,))?.extract(py)?; let id: u64 = self.helper.id_fn.call1(py, (obj,))?.extract(py)?;
if ty_id == self.primitive_ids.int || ty_id == self.primitive_ids.int32 { if ty_id == self.primitive_ids.int || ty_id == self.primitive_ids.int32 {
let val: i32 = obj.extract().unwrap(); let val: i32 = obj.extract().map_err(|_| super::CompileError::new_err(
format!("{} is not in the range of int32", obj)))?;
self.id_to_primitive.write().insert(id, PrimitiveValue::I32(val)); self.id_to_primitive.write().insert(id, PrimitiveValue::I32(val));
Ok(Some(ctx.ctx.i32_type().const_int(val as u64, false).into())) Ok(Some(ctx.ctx.i32_type().const_int(val as u64, false).into()))
} else if ty_id == self.primitive_ids.int64 { } else if ty_id == self.primitive_ids.int64 {
let val: i64 = obj.extract().unwrap(); let val: i64 = obj.extract().map_err(|_| super::CompileError::new_err(
format!("{} is not in the range of int64", obj)))?;
self.id_to_primitive.write().insert(id, PrimitiveValue::I64(val)); self.id_to_primitive.write().insert(id, PrimitiveValue::I64(val));
Ok(Some(ctx.ctx.i64_type().const_int(val as u64, false).into())) Ok(Some(ctx.ctx.i64_type().const_int(val as u64, false).into()))
} else if ty_id == self.primitive_ids.uint32 { } else if ty_id == self.primitive_ids.uint32 {
let val: u32 = obj.extract().unwrap(); let val: u32 = obj.extract().map_err(|_| super::CompileError::new_err(
format!("{} is not in the range of uint32", obj)))?;
self.id_to_primitive.write().insert(id, PrimitiveValue::U32(val)); self.id_to_primitive.write().insert(id, PrimitiveValue::U32(val));
Ok(Some(ctx.ctx.i32_type().const_int(val as u64, false).into())) Ok(Some(ctx.ctx.i32_type().const_int(val as u64, false).into()))
} else if ty_id == self.primitive_ids.uint64 { } else if ty_id == self.primitive_ids.uint64 {
let val: u64 = obj.extract().unwrap(); let val: u64 = obj.extract().map_err(|_| super::CompileError::new_err(
format!("{} is not in the range of uint64", obj)))?;
self.id_to_primitive.write().insert(id, PrimitiveValue::U64(val)); self.id_to_primitive.write().insert(id, PrimitiveValue::U64(val));
Ok(Some(ctx.ctx.i64_type().const_int(val, false).into())) Ok(Some(ctx.ctx.i64_type().const_int(val, false).into()))
} else if ty_id == self.primitive_ids.bool { } else if ty_id == self.primitive_ids.bool {
let val: bool = obj.extract().unwrap(); let val: bool = obj.extract().map_err(|_| super::CompileError::new_err(
format!("{} is not in the range of bool", obj)))?;
self.id_to_primitive.write().insert(id, PrimitiveValue::Bool(val)); self.id_to_primitive.write().insert(id, PrimitiveValue::Bool(val));
Ok(Some(ctx.ctx.bool_type().const_int(val as u64, false).into())) Ok(Some(ctx.ctx.bool_type().const_int(val as u64, false).into()))
} else if ty_id == self.primitive_ids.float || ty_id == self.primitive_ids.float64 { } else if ty_id == self.primitive_ids.float || ty_id == self.primitive_ids.float64 {
let val: f64 = obj.extract().unwrap(); let val: f64 = obj.extract().map_err(|_| super::CompileError::new_err(
format!("{} is not in the range of float64", obj)))?;
self.id_to_primitive.write().insert(id, PrimitiveValue::F64(val)); self.id_to_primitive.write().insert(id, PrimitiveValue::F64(val));
Ok(Some(ctx.ctx.f64_type().const_float(val).into())) Ok(Some(ctx.ctx.f64_type().const_float(val).into()))
} else if ty_id == self.primitive_ids.list { } else if ty_id == self.primitive_ids.list {

View File

@ -10,7 +10,7 @@ constant-optimization = ["fold"]
fold = [] fold = []
[dependencies] [dependencies]
lazy_static = "1.4" lazy_static = "1.4.0"
parking_lot = "0.12" parking_lot = "0.11.1"
string-interner = "0.14" string-interner = "0.13.0"
fxhash = "0.2" fxhash = "0.2.1"

View File

@ -8,7 +8,7 @@ use parking_lot::{Mutex, MutexGuard};
use string_interner::{DefaultBackend, DefaultSymbol, StringInterner, symbol::SymbolU32}; use string_interner::{DefaultBackend, DefaultSymbol, StringInterner, symbol::SymbolU32};
use fxhash::FxBuildHasher; use fxhash::FxBuildHasher;
pub type Interner = StringInterner<DefaultBackend<DefaultSymbol>, FxBuildHasher>; pub type Interner = StringInterner<DefaultSymbol, DefaultBackend<DefaultSymbol>, FxBuildHasher>;
lazy_static! { lazy_static! {
static ref INTERNER: Mutex<Interner> = Mutex::new(StringInterner::with_hasher(FxBuildHasher::default())); static ref INTERNER: Mutex<Interner> = Mutex::new(StringInterner::with_hasher(FxBuildHasher::default()));
} }

View File

@ -5,17 +5,16 @@ authors = ["M-Labs"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
itertools = "0.10" itertools = "0.10.1"
crossbeam = "0.8" crossbeam = "0.8.1"
parking_lot = "0.12" parking_lot = "0.11.1"
rayon = "1.5" rayon = "1.5.1"
nac3parser = { path = "../nac3parser" } nac3parser = { path = "../nac3parser" }
lazy_static = "1.4"
[dependencies.inkwell] [dependencies.inkwell]
git = "https://github.com/TheDan64/inkwell.git" version = "0.1.0-beta.4"
default-features = false default-features = false
features = ["llvm14-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] features = ["llvm13-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"]
[dev-dependencies] [dev-dependencies]
test-case = "1.2.0" test-case = "1.2.0"

View File

@ -10,10 +10,7 @@ use crate::{
}, },
symbol_resolver::{SymbolValue, ValueEnum}, symbol_resolver::{SymbolValue, ValueEnum},
toplevel::{DefinitionId, TopLevelDef}, toplevel::{DefinitionId, TopLevelDef},
typecheck::{ typecheck::typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier},
typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier},
magic_methods::{binop_name, binop_assign_name},
},
}; };
use inkwell::{ use inkwell::{
AddressSpace, AddressSpace,
@ -165,7 +162,6 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
) -> BasicTypeEnum<'ctx> { ) -> BasicTypeEnum<'ctx> {
get_llvm_type( get_llvm_type(
self.ctx, self.ctx,
&self.module,
generator, generator,
&mut self.unifier, &mut self.unifier,
self.top_level, self.top_level,
@ -362,31 +358,17 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
} }
} }
} }
let params = if loc_params.is_empty() { params } else { &loc_params }; let params = if loc_params.is_empty() {
let params = fun params
.get_type() } else {
.get_param_types() &loc_params
.into_iter() };
.zip(params.iter())
.map(|(ty, val)| match (ty, val.get_type()) {
(BasicTypeEnum::PointerType(arg_ty), BasicTypeEnum::PointerType(val_ty))
if {
ty != val.get_type()
&& arg_ty.get_element_type().is_struct_type()
&& val_ty.get_element_type().is_struct_type()
} =>
{
self.builder.build_bitcast(*val, arg_ty, "call_arg_cast")
}
_ => *val,
})
.collect_vec();
let result = if let Some(target) = self.unwind_target { let result = if let Some(target) = self.unwind_target {
let current = self.builder.get_insert_block().unwrap().get_parent().unwrap(); let current = self.builder.get_insert_block().unwrap().get_parent().unwrap();
let then_block = self.ctx.append_basic_block(current, &format!("after.{}", call_name)); let then_block = self.ctx.append_basic_block(current, &format!("after.{}", call_name));
let result = self let result = self
.builder .builder
.build_invoke(fun, &params, then_block, target, call_name) .build_invoke(fun, params, then_block, target, call_name)
.try_as_basic_value() .try_as_basic_value()
.left(); .left();
self.builder.position_at_end(then_block); self.builder.position_at_end(then_block);
@ -475,7 +457,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
let i1_true = i1.const_all_ones(); let i1_true = i1.const_all_ones();
let expect_fun = self.module.get_function("llvm.expect.i1").unwrap_or_else(|| { let expect_fun = self.module.get_function("llvm.expect.i1").unwrap_or_else(|| {
self.module.add_function( self.module.add_function(
"llvm.expect.i1", "llvm.expect",
i1.fn_type(&[i1.into(), i1.into()], false), i1.fn_type(&[i1.into(), i1.into()], false),
None, None,
) )
@ -511,7 +493,12 @@ pub fn gen_constructor<'ctx, 'a, G: CodeGenerator>(
match def { match def {
TopLevelDef::Class { methods, .. } => { TopLevelDef::Class { methods, .. } => {
// TODO: what about other fields that require alloca? // TODO: what about other fields that require alloca?
let fun_id = methods.iter().find(|method| method.0 == "__init__".into()).and_then(|method| Some(method.2)); let mut fun_id = None;
for (name, _, id) in methods.iter() {
if name == &"__init__".into() {
fun_id = Some(*id);
}
}
let ty = ctx.get_llvm_type(generator, signature.ret).into_pointer_type(); let ty = ctx.get_llvm_type(generator, signature.ret).into_pointer_type();
let zelf_ty: BasicTypeEnum = ty.get_element_type().try_into().unwrap(); let zelf_ty: BasicTypeEnum = ty.get_element_type().try_into().unwrap();
let zelf: BasicValueEnum<'ctx> = ctx.builder.build_alloca(zelf_ty, "alloca").into(); let zelf: BasicValueEnum<'ctx> = ctx.builder.build_alloca(zelf_ty, "alloca").into();
@ -940,29 +927,21 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>(
left: &Expr<Option<Type>>, left: &Expr<Option<Type>>,
op: &Operator, op: &Operator,
right: &Expr<Option<Type>>, right: &Expr<Option<Type>>,
loc: Location, ) -> Result<ValueEnum<'ctx>, String> {
is_aug_assign: bool,
) -> Result<Option<ValueEnum<'ctx>>, String> {
let ty1 = ctx.unifier.get_representative(left.custom.unwrap()); let ty1 = ctx.unifier.get_representative(left.custom.unwrap());
let ty2 = ctx.unifier.get_representative(right.custom.unwrap()); let ty2 = ctx.unifier.get_representative(right.custom.unwrap());
let left_val = generator let left = generator.gen_expr(ctx, left)?.unwrap().to_basic_value_enum(ctx, generator, left.custom.unwrap())?;
.gen_expr(ctx, left)? let right = generator.gen_expr(ctx, right)?.unwrap().to_basic_value_enum(ctx, generator, right.custom.unwrap())?;
.unwrap()
.to_basic_value_enum(ctx, generator, left.custom.unwrap())?;
let right_val = generator
.gen_expr(ctx, right)?
.unwrap()
.to_basic_value_enum(ctx, generator, right.custom.unwrap())?;
// we can directly compare the types, because we've got their representatives // we can directly compare the types, because we've got their representatives
// which would be unchanged until further unification, which we would never do // which would be unchanged until further unification, which we would never do
// when doing code generation for function instances // when doing code generation for function instances
if ty1 == ty2 && [ctx.primitives.int32, ctx.primitives.int64].contains(&ty1) { Ok(if ty1 == ty2 && [ctx.primitives.int32, ctx.primitives.int64].contains(&ty1) {
Ok(Some(ctx.gen_int_ops(generator, op, left_val, right_val, true).into())) ctx.gen_int_ops(generator, op, left, right, true)
} else if ty1 == ty2 && [ctx.primitives.uint32, ctx.primitives.uint64].contains(&ty1) { } else if ty1 == ty2 && [ctx.primitives.uint32, ctx.primitives.uint64].contains(&ty1) {
Ok(Some(ctx.gen_int_ops(generator, op, left_val, right_val, false).into())) ctx.gen_int_ops(generator, op, left, right, false)
} else if ty1 == ty2 && ctx.primitives.float == ty1 { } else if ty1 == ty2 && ctx.primitives.float == ty1 {
Ok(Some(ctx.gen_float_ops(op, left_val, right_val).into())) ctx.gen_float_ops(op, left, right)
} else if ty1 == ctx.primitives.float && ty2 == ctx.primitives.int32 { } else if ty1 == ctx.primitives.float && ty2 == ctx.primitives.int32 {
// Pow is the only operator that would pass typecheck between float and int // Pow is the only operator that would pass typecheck between float and int
assert!(*op == Operator::Pow); assert!(*op == Operator::Pow);
@ -972,62 +951,14 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>(
let ty = f64_t.fn_type(&[f64_t.into(), i32_t.into()], false); let ty = f64_t.fn_type(&[f64_t.into(), i32_t.into()], false);
ctx.module.add_function("llvm.powi.f64.i32", ty, None) ctx.module.add_function("llvm.powi.f64.i32", ty, None)
}); });
let res = ctx.builder ctx.builder
.build_call(pow_intr, &[left_val.into(), right_val.into()], "f_pow_i") .build_call(pow_intr, &[left.into(), right.into()], "f_pow_i")
.try_as_basic_value() .try_as_basic_value()
.unwrap_left(); .unwrap_left()
Ok(Some(res.into()))
} else { } else {
let (op_name, id) = if let TypeEnum::TObj { fields, obj_id, .. } = unimplemented!()
ctx.unifier.get_ty_immutable(left.custom.unwrap()).as_ref()
{
let (binop_name, binop_assign_name) = (
binop_name(op).into(),
binop_assign_name(op).into()
);
// if is aug_assign, try aug_assign operator first
if is_aug_assign && fields.contains_key(&binop_assign_name) {
(binop_assign_name, *obj_id)
} else {
(binop_name, *obj_id)
}
} else {
unreachable!("must be tobj")
};
let signature = match ctx.calls.get(&loc.into()) {
Some(call) => ctx.unifier.get_call_signature(*call).unwrap(),
None => {
if let TypeEnum::TObj { fields, .. } =
ctx.unifier.get_ty_immutable(left.custom.unwrap()).as_ref()
{
let fn_ty = fields.get(&op_name).unwrap().0;
if let TypeEnum::TFunc(sig) = ctx.unifier.get_ty_immutable(fn_ty).as_ref() {
sig.clone()
} else {
unreachable!("must be func sig")
}
} else {
unreachable!("must be tobj")
}
},
};
let fun_id = {
let defs = ctx.top_level.definitions.read();
let obj_def = defs.get(id.0).unwrap().read();
if let TopLevelDef::Class { methods, .. } = &*obj_def {
methods.iter().find(|method| method.0 == op_name).unwrap().2
} else {
unreachable!()
}
};
generator
.gen_call(
ctx,
Some((left.custom.unwrap(), left_val.into())),
(&signature, fun_id),
vec![(None, right_val.into())],
).map(|f| f.map(|f| f.into()))
} }
.into())
} }
pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
@ -1038,16 +969,6 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
ctx.current_loc = expr.location; ctx.current_loc = expr.location;
let int32 = ctx.ctx.i32_type(); let int32 = ctx.ctx.i32_type();
let zero = int32.const_int(0, false); let zero = int32.const_int(0, false);
let loc = ctx.debug_info.0.create_debug_location(
ctx.ctx,
ctx.current_loc.row as u32,
ctx.current_loc.column as u32,
ctx.debug_info.2,
None,
);
ctx.builder.set_current_debug_location(ctx.ctx, loc);
Ok(Some(match &expr.node { Ok(Some(match &expr.node {
ExprKind::Constant { value, .. } => { ExprKind::Constant { value, .. } => {
let ty = expr.custom.unwrap(); let ty = expr.custom.unwrap();
@ -1204,9 +1125,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
phi.add_incoming(&[(&a, a_bb), (&b, b_bb)]); phi.add_incoming(&[(&a, a_bb), (&b, b_bb)]);
phi.as_basic_value().into() phi.as_basic_value().into()
} }
ExprKind::BinOp { op, left, right } => { ExprKind::BinOp { op, left, right } => gen_binop_expr(generator, ctx, left, op, right)?,
return gen_binop_expr(generator, ctx, left, op, right, expr.location, false);
}
ExprKind::UnaryOp { op, operand } => { ExprKind::UnaryOp { op, operand } => {
let ty = ctx.unifier.get_representative(operand.custom.unwrap()); let ty = ctx.unifier.get_representative(operand.custom.unwrap());
let val = let val =
@ -1423,7 +1342,13 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
let defs = ctx.top_level.definitions.read(); let defs = ctx.top_level.definitions.read();
let obj_def = defs.get(id.0).unwrap().read(); let obj_def = defs.get(id.0).unwrap().read();
if let TopLevelDef::Class { methods, .. } = &*obj_def { if let TopLevelDef::Class { methods, .. } = &*obj_def {
methods.iter().find(|method| method.0 == *attr).unwrap().2 let mut fun_id = None;
for (name, _, id) in methods.iter() {
if name == attr {
fun_id = Some(*id);
}
}
fun_id.unwrap()
} else { } else {
unreachable!() unreachable!()
} }

View File

@ -36,7 +36,7 @@ pub trait CodeGenerator {
} }
/// Generate object constructor and returns the constructed object. /// Generate object constructor and returns the constructed object.
/// - signature: Function signature of the constructor. /// - signature: Function signature of the contructor.
/// - def: Class definition for the constructor class. /// - def: Class definition for the constructor class.
/// - params: Function parameters. /// - params: Function parameters.
fn gen_constructor<'ctx, 'a>( fn gen_constructor<'ctx, 'a>(

View File

@ -17,10 +17,7 @@ use inkwell::{
module::Module, module::Module,
passes::{PassManager, PassManagerBuilder}, passes::{PassManager, PassManagerBuilder},
types::{AnyType, BasicType, BasicTypeEnum}, types::{AnyType, BasicType, BasicTypeEnum},
values::{BasicValueEnum, FunctionValue, PhiValue, PointerValue}, values::{BasicValueEnum, FunctionValue, PhiValue, PointerValue}
debug_info::{
DebugInfoBuilder, DICompileUnit, DISubprogram, AsDIScope, DIFlagsConstants, DIScope
},
}; };
use itertools::Itertools; use itertools::Itertools;
use nac3parser::ast::{Stmt, StrRef, Location}; use nac3parser::ast::{Stmt, StrRef, Location};
@ -31,7 +28,6 @@ use std::sync::{
Arc, Arc,
}; };
use std::thread; use std::thread;
use lazy_static::lazy_static;
pub mod concrete_type; pub mod concrete_type;
pub mod expr; pub mod expr;
@ -53,16 +49,9 @@ pub struct StaticValueStore {
pub type VarValue<'ctx> = (PointerValue<'ctx>, Option<Arc<dyn StaticValue + Send + Sync>>, i64); pub type VarValue<'ctx> = (PointerValue<'ctx>, Option<Arc<dyn StaticValue + Send + Sync>>, i64);
lazy_static!(
// HACK: The Mutex is a work-around for issue
// https://git.m-labs.hk/M-Labs/nac3/issues/275
static ref PASSES_INIT_LOCK: Mutex<AtomicBool> = Mutex::new(AtomicBool::new(true));
);
pub struct CodeGenContext<'ctx, 'a> { pub struct CodeGenContext<'ctx, 'a> {
pub ctx: &'ctx Context, pub ctx: &'ctx Context,
pub builder: Builder<'ctx>, pub builder: Builder<'ctx>,
pub debug_info: (DebugInfoBuilder<'ctx>, DICompileUnit<'ctx>, DIScope<'ctx>),
pub module: Module<'ctx>, pub module: Module<'ctx>,
pub top_level: &'a TopLevelContext, pub top_level: &'a TopLevelContext,
pub unifier: Unifier, pub unifier: Unifier,
@ -212,43 +201,25 @@ impl WorkerRegistry {
fn worker_thread<G: CodeGenerator>(&self, generator: &mut G, f: Arc<WithCall>) { fn worker_thread<G: CodeGenerator>(&self, generator: &mut G, f: Arc<WithCall>) {
let context = Context::create(); let context = Context::create();
let mut builder = context.create_builder(); let mut builder = context.create_builder();
let mut module = context.create_module(generator.get_name()); let module = context.create_module(generator.get_name());
module.add_basic_value_flag(
"Debug Info Version",
inkwell::module::FlagBehavior::Warning,
context.i32_type().const_int(3, false),
);
module.add_basic_value_flag(
"Dwarf Version",
inkwell::module::FlagBehavior::Warning,
context.i32_type().const_int(4, false),
);
let pass_builder = PassManagerBuilder::create();
pass_builder.set_optimization_level(OptimizationLevel::Default);
let passes = PassManager::create(&module); let passes = PassManager::create(&module);
pass_builder.populate_function_pass_manager(&passes);
// HACK: This critical section is a work-around for issue
// https://git.m-labs.hk/M-Labs/nac3/issues/275
{
let _data = PASSES_INIT_LOCK.lock();
let pass_builder = PassManagerBuilder::create();
pass_builder.set_optimization_level(OptimizationLevel::Default);
pass_builder.populate_function_pass_manager(&passes);
}
let mut errors = HashSet::new(); let mut errors = HashSet::new();
while let Some(task) = self.receiver.recv().unwrap() { while let Some(task) = self.receiver.recv().unwrap() {
match gen_func(&context, generator, self, builder, module, task) { let tmp_module = context.create_module("tmp");
match gen_func(&context, generator, self, builder, tmp_module, task) {
Ok(result) => { Ok(result) => {
builder = result.0; builder = result.0;
passes.run_on(&result.2); passes.run_on(&result.2);
module = result.1; module.link_in_module(result.1).unwrap();
} }
Err((old_builder, e)) => { Err((old_builder, e)) => {
builder = old_builder; builder = old_builder;
errors.insert(e); errors.insert(e);
// create a new empty module just to continue codegen and collect errors
module = context.create_module(&format!("{}_recover", generator.get_name()));
} }
} }
*self.task_count.lock() -= 1; *self.task_count.lock() -= 1;
@ -261,7 +232,7 @@ impl WorkerRegistry {
let result = module.verify(); let result = module.verify();
if let Err(err) = result { if let Err(err) = result {
println!("{}", module.print_to_string().to_str().unwrap()); println!("{}", module.print_to_string().to_str().unwrap());
println!("{}", err.to_string()); println!("{}", err);
panic!() panic!()
} }
f.run(&module); f.run(&module);
@ -285,7 +256,6 @@ pub struct CodeGenTask {
fn get_llvm_type<'ctx>( fn get_llvm_type<'ctx>(
ctx: &'ctx Context, ctx: &'ctx Context,
module: &Module<'ctx>,
generator: &mut dyn CodeGenerator, generator: &mut dyn CodeGenerator,
unifier: &mut Unifier, unifier: &mut Unifier,
top_level: &TopLevelContext, top_level: &TopLevelContext,
@ -310,7 +280,6 @@ fn get_llvm_type<'ctx>(
) if *obj_id == *opt_id => { ) if *obj_id == *opt_id => {
return get_llvm_type( return get_llvm_type(
ctx, ctx,
module,
generator, generator,
unifier, unifier,
top_level, top_level,
@ -327,37 +296,27 @@ fn get_llvm_type<'ctx>(
// a struct with fields in the order of declaration // a struct with fields in the order of declaration
let top_level_defs = top_level.definitions.read(); let top_level_defs = top_level.definitions.read();
let definition = top_level_defs.get(obj_id.0).unwrap(); let definition = top_level_defs.get(obj_id.0).unwrap();
let ty = if let TopLevelDef::Class { fields: fields_list, .. } = let ty = if let TopLevelDef::Class { name, fields: fields_list, .. } =
&*definition.read() &*definition.read()
{ {
let name = unifier.stringify(ty); let struct_type = ctx.opaque_struct_type(&name.to_string());
match module.get_struct_type(&name) { type_cache.insert(unifier.get_representative(ty), struct_type.ptr_type(AddressSpace::Generic).into());
Some(t) => t.ptr_type(AddressSpace::Generic).into(), let fields = fields_list
None => { .iter()
let struct_type = ctx.opaque_struct_type(&name); .map(|f| {
type_cache.insert( get_llvm_type(
unifier.get_representative(ty), ctx,
struct_type.ptr_type(AddressSpace::Generic).into() generator,
); unifier,
let fields = fields_list top_level,
.iter() type_cache,
.map(|f| { primitives,
get_llvm_type( fields[&f.0].0,
ctx, )
module, })
generator, .collect_vec();
unifier, struct_type.set_body(&fields, false);
top_level, struct_type.ptr_type(AddressSpace::Generic).into()
type_cache,
primitives,
fields[&f.0].0,
)
})
.collect_vec();
struct_type.set_body(&fields, false);
struct_type.ptr_type(AddressSpace::Generic).into()
}
}
} else { } else {
unreachable!() unreachable!()
}; };
@ -367,19 +326,14 @@ fn get_llvm_type<'ctx>(
// a struct with fields in the order present in the tuple // a struct with fields in the order present in the tuple
let fields = ty let fields = ty
.iter() .iter()
.map(|ty| { .map(|ty| get_llvm_type(ctx, generator, unifier, top_level, type_cache, primitives, *ty))
get_llvm_type(
ctx, module, generator, unifier, top_level, type_cache, primitives, *ty,
)
})
.collect_vec(); .collect_vec();
ctx.struct_type(&fields, false).into() ctx.struct_type(&fields, false).into()
} }
TList { ty } => { TList { ty } => {
// a struct with an integer and a pointer to an array // a struct with an integer and a pointer to an array
let element_type = get_llvm_type( let element_type =
ctx, module, generator, unifier, top_level, type_cache, primitives, *ty, get_llvm_type(ctx, generator, unifier, top_level, type_cache, primitives, *ty);
);
let fields = [ let fields = [
element_type.ptr_type(AddressSpace::Generic).into(), element_type.ptr_type(AddressSpace::Generic).into(),
generator.get_size_type(ctx).into(), generator.get_size_type(ctx).into(),
@ -465,40 +419,28 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
(primitives.float, context.f64_type().into()), (primitives.float, context.f64_type().into()),
(primitives.bool, context.bool_type().into()), (primitives.bool, context.bool_type().into()),
(primitives.str, { (primitives.str, {
let name = "str"; let str_type = context.opaque_struct_type("str");
match module.get_struct_type(name) { let fields = [
None => { context.i8_type().ptr_type(AddressSpace::Generic).into(),
let str_type = context.opaque_struct_type("str"); generator.get_size_type(context).into(),
let fields = [ ];
context.i8_type().ptr_type(AddressSpace::Generic).into(), str_type.set_body(&fields, false);
generator.get_size_type(context).into(), str_type.into()
];
str_type.set_body(&fields, false);
str_type.into()
}
Some(t) => t.as_basic_type_enum()
}
}), }),
(primitives.range, context.i32_type().array_type(3).ptr_type(AddressSpace::Generic).into()), (primitives.range, context.i32_type().array_type(3).ptr_type(AddressSpace::Generic).into()),
(primitives.exception, {
let name = "Exception";
match module.get_struct_type(name) {
Some(t) => t.ptr_type(AddressSpace::Generic).as_basic_type_enum(),
None => {
let exception = context.opaque_struct_type("Exception");
let int32 = context.i32_type().into();
let int64 = context.i64_type().into();
let str_ty = module.get_struct_type("str").unwrap().as_basic_type_enum();
let fields = [int32, str_ty, int32, int32, str_ty, str_ty, int64, int64, int64];
exception.set_body(&fields, false);
exception.ptr_type(AddressSpace::Generic).as_basic_type_enum()
}
}
})
] ]
.iter() .iter()
.cloned() .cloned()
.collect(); .collect();
type_cache.insert(primitives.exception, {
let exception = context.opaque_struct_type("Exception");
let int32 = context.i32_type().into();
let int64 = context.i64_type().into();
let str_ty = *type_cache.get(&primitives.str).unwrap();
let fields = [int32, str_ty, int32, int32, str_ty, str_ty, int64, int64, int64];
exception.set_body(&fields, false);
exception.ptr_type(AddressSpace::Generic).into()
});
// NOTE: special handling of option cannot use this type cache since it contains type var, // NOTE: special handling of option cannot use this type cache since it contains type var,
// handled inside get_llvm_type instead // handled inside get_llvm_type instead
@ -521,7 +463,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
let ret_type = if unifier.unioned(ret, primitives.none) { let ret_type = if unifier.unioned(ret, primitives.none) {
None None
} else { } else {
Some(get_llvm_type(context, &module, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, &primitives, ret)) Some(get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, &primitives, ret))
}; };
let has_sret = ret_type.map_or(false, |ty| need_sret(context, ty)); let has_sret = ret_type.map_or(false, |ty| need_sret(context, ty));
@ -530,7 +472,6 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
.map(|arg| { .map(|arg| {
get_llvm_type( get_llvm_type(
context, context,
&module,
generator, generator,
&mut unifier, &mut unifier,
top_level_ctx.as_ref(), top_level_ctx.as_ref(),
@ -579,7 +520,6 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
let alloca = builder.build_alloca( let alloca = builder.build_alloca(
get_llvm_type( get_llvm_type(
context, context,
&module,
generator, generator,
&mut unifier, &mut unifier,
top_level_ctx.as_ref(), top_level_ctx.as_ref(),
@ -611,58 +551,6 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
builder.build_unconditional_branch(body_bb); builder.build_unconditional_branch(body_bb);
builder.position_at_end(body_bb); builder.position_at_end(body_bb);
let (dibuilder, compile_unit) = module.create_debug_info_builder(
/* allow_unresolved */ true,
/* language */ inkwell::debug_info::DWARFSourceLanguage::Python,
/* filename */
&task
.body
.get(0)
.map_or_else(
|| "<nac3_internal>".to_string(),
|f| f.location.file.0.to_string(),
),
/* directory */ "",
/* producer */ "NAC3",
/* is_optimized */ true,
/* compiler command line flags */ "",
/* runtime_ver */ 0,
/* split_name */ "",
/* kind */ inkwell::debug_info::DWARFEmissionKind::Full,
/* dwo_id */ 0,
/* split_debug_inling */ true,
/* debug_info_for_profiling */ false,
/* sysroot */ "",
/* sdk */ "",
);
let subroutine_type = dibuilder.create_subroutine_type(
compile_unit.get_file(),
Some(
dibuilder
.create_basic_type("_", 0_u64, 0x00, inkwell::debug_info::DIFlags::PUBLIC)
.unwrap()
.as_type(),
),
&[],
inkwell::debug_info::DIFlags::PUBLIC,
);
let (row, col) =
task.body.get(0).map_or_else(|| (0, 0), |b| (b.location.row, b.location.column));
let func_scope: DISubprogram<'_> = dibuilder.create_function(
/* scope */ compile_unit.as_debug_info_scope(),
/* func name */ symbol,
/* linkage_name */ None,
/* file */ compile_unit.get_file(),
/* line_no */ row as u32,
/* DIType */ subroutine_type,
/* is_local_to_unit */ false,
/* is_definition */ true,
/* scope_line */ row as u32,
/* flags */ inkwell::debug_info::DIFlags::PUBLIC,
/* is_optimized */ true,
);
fn_val.set_subprogram(func_scope);
let mut code_gen_context = CodeGenContext { let mut code_gen_context = CodeGenContext {
ctx: context, ctx: context,
resolver: task.resolver, resolver: task.resolver,
@ -685,18 +573,8 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
static_value_store, static_value_store,
need_sret: has_sret, need_sret: has_sret,
current_loc: Default::default(), current_loc: Default::default(),
debug_info: (dibuilder, compile_unit, func_scope.as_debug_info_scope()),
}; };
let loc = code_gen_context.debug_info.0.create_debug_location(
context,
row as u32,
col as u32,
func_scope.as_debug_info_scope(),
None
);
code_gen_context.builder.set_current_debug_location(context, loc);
let result = codegen_function(generator, &mut code_gen_context); let result = codegen_function(generator, &mut code_gen_context);
// after static analysis, only void functions can have no return at the end. // after static analysis, only void functions can have no return at the end.
@ -704,9 +582,6 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
code_gen_context.builder.build_return(None); code_gen_context.builder.build_return(None);
} }
code_gen_context.builder.unset_current_debug_location();
code_gen_context.debug_info.0.finalize();
let CodeGenContext { builder, module, .. } = code_gen_context; let CodeGenContext { builder, module, .. } = code_gen_context;
if let Err(e) = result { if let Err(e) = result {
return Err((builder, e)); return Err((builder, e));

View File

@ -42,18 +42,15 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
// very similar to gen_expr, but we don't do an extra load at the end // very similar to gen_expr, but we don't do an extra load at the end
// and we flatten nested tuples // and we flatten nested tuples
Ok(match &pattern.node { Ok(match &pattern.node {
ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) { ExprKind::Name { id, .. } => {
None => { ctx.var_assignment.get(id).map(|v| Ok(v.0) as Result<_, String>).unwrap_or_else(
let ptr_ty = ctx.get_llvm_type(generator, pattern.custom.unwrap()); || {
let ptr = generator.gen_var_alloc(ctx, ptr_ty)?; let ptr_ty = ctx.get_llvm_type(generator, pattern.custom.unwrap());
ctx.var_assignment.insert(*id, (ptr, None, 0)); let ptr = generator.gen_var_alloc(ctx, ptr_ty)?;
ptr ctx.var_assignment.insert(*id, (ptr, None, 0));
} Ok(ptr)
Some(v) => { },
let (ptr, counter) = (v.0, v.2); )?
ctx.var_assignment.insert(*id, (ptr, None, counter));
ptr
}
} }
ExprKind::Attribute { value, attr, .. } => { ExprKind::Attribute { value, attr, .. } => {
let index = ctx.get_attr_index(value.custom.unwrap(), *attr); let index = ctx.get_attr_index(value.custom.unwrap(), *attr);
@ -497,7 +494,7 @@ pub fn get_builtins<'ctx, 'a>(
if symbol == "__nac3_raise" || symbol == "__nac3_resume" { if symbol == "__nac3_raise" || symbol == "__nac3_resume" {
fun.add_attribute( fun.add_attribute(
AttributeLoc::Function, AttributeLoc::Function,
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id("noreturn"), 0), ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id("noreturn"), 1),
); );
} }
fun fun
@ -992,16 +989,6 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>(
stmt: &Stmt<Option<Type>>, stmt: &Stmt<Option<Type>>,
) -> Result<(), String> { ) -> Result<(), String> {
ctx.current_loc = stmt.location; ctx.current_loc = stmt.location;
let loc = ctx.debug_info.0.create_debug_location(
ctx.ctx,
ctx.current_loc.row as u32,
ctx.current_loc.column as u32,
ctx.debug_info.2,
None,
);
ctx.builder.set_current_debug_location(ctx.ctx, loc);
match &stmt.node { match &stmt.node {
StmtKind::Pass { .. } => {} StmtKind::Pass { .. } => {}
StmtKind::Expr { value, .. } => { StmtKind::Expr { value, .. } => {
@ -1033,8 +1020,8 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>(
StmtKind::For { .. } => generator.gen_for(ctx, stmt)?, StmtKind::For { .. } => generator.gen_for(ctx, stmt)?,
StmtKind::With { .. } => generator.gen_with(ctx, stmt)?, StmtKind::With { .. } => generator.gen_with(ctx, stmt)?,
StmtKind::AugAssign { target, op, value, .. } => { StmtKind::AugAssign { target, op, value, .. } => {
let value = gen_binop_expr(generator, ctx, target, op, value, stmt.location, true)?; let value = gen_binop_expr(generator, ctx, target, op, value)?;
generator.gen_assign(ctx, target, value.unwrap())?; generator.gen_assign(ctx, target, value)?;
} }
StmtKind::Try { .. } => gen_try(generator, ctx, stmt)?, StmtKind::Try { .. } => gen_try(generator, ctx, stmt)?,
StmtKind::Raise { exc, .. } => { StmtKind::Raise { exc, .. } => {

View File

@ -181,42 +181,23 @@ fn test_primitives() {
; ModuleID = 'test' ; ModuleID = 'test'
source_filename = \"test\" source_filename = \"test\"
define i32 @testing(i32 %0, i32 %1) !dbg !4 { define i32 @testing(i32 %0, i32 %1) {
init: init:
%add = add i32 %0, %1, !dbg !9 %add = add i32 %0, %1
%cmp = icmp eq i32 %add, 1, !dbg !10 %cmp = icmp eq i32 %add, 1
br i1 %cmp, label %then, label %else, !dbg !10 br i1 %cmp, label %then, label %else
then: ; preds = %init then: ; preds = %init
br label %cont, !dbg !11 br label %cont
else: ; preds = %init else: ; preds = %init
br label %cont, !dbg !12 br label %cont
cont: ; preds = %else, %then cont: ; preds = %else, %then
%if_exp_result.0 = phi i32 [ %0, %then ], [ 0, %else ], !dbg !13 %if_exp_result.0 = phi i32 [ %0, %then ], [ 0, %else ]
ret i32 %if_exp_result.0, !dbg !14 ret i32 %if_exp_result.0
} }
"}
!llvm.module.flags = !{!0, !1}
!llvm.dbg.cu = !{!2}
!0 = !{i32 2, !\"Debug Info Version\", i32 3}
!1 = !{i32 2, !\"Dwarf Version\", i32 4}
!2 = distinct !DICompileUnit(language: DW_LANG_Python, file: !3, producer: \"NAC3\", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
!3 = !DIFile(filename: \"unknown\", directory: \"\")
!4 = distinct !DISubprogram(name: \"testing\", linkageName: \"testing\", scope: null, file: !3, line: 1, type: !5, scopeLine: 1, flags: DIFlagPublic, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !8)
!5 = !DISubroutineType(flags: DIFlagPublic, types: !6)
!6 = !{!7}
!7 = !DIBasicType(name: \"_\", flags: DIFlagPublic)
!8 = !{}
!9 = !DILocation(line: 1, column: 9, scope: !4)
!10 = !DILocation(line: 2, column: 15, scope: !4)
!11 = !DILocation(line: 2, column: 5, scope: !4)
!12 = !DILocation(line: 2, column: 22, scope: !4)
!13 = !DILocation(line: 0, scope: !4)
!14 = !DILocation(line: 3, column: 8, scope: !4)
"}
.trim(); .trim();
assert_eq!(expected, module.print_to_string().to_str().unwrap().trim()); assert_eq!(expected, module.print_to_string().to_str().unwrap().trim());
}))); })));
@ -361,37 +342,19 @@ fn test_simple_call() {
; ModuleID = 'test' ; ModuleID = 'test'
source_filename = \"test\" source_filename = \"test\"
define i32 @testing(i32 %0) !dbg !5 { define i32 @testing(i32 %0) {
init: init:
%call = call i32 @foo.0(i32 %0), !dbg !10 %call = call i32 @foo.0(i32 %0)
%mul = mul i32 %call, 2, !dbg !11 %mul = mul i32 %call, 2
ret i32 %mul, !dbg !11 ret i32 %mul
} }
define i32 @foo.0(i32 %0) !dbg !12 { define i32 @foo.0(i32 %0) {
init: init:
%add = add i32 %0, 1, !dbg !13 %add = add i32 %0, 1
ret i32 %add, !dbg !13 ret i32 %add
} }
"}
!llvm.module.flags = !{!0, !1}
!llvm.dbg.cu = !{!2, !4}
!0 = !{i32 2, !\"Debug Info Version\", i32 3}
!1 = !{i32 2, !\"Dwarf Version\", i32 4}
!2 = distinct !DICompileUnit(language: DW_LANG_Python, file: !3, producer: \"NAC3\", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
!3 = !DIFile(filename: \"unknown\", directory: \"\")
!4 = distinct !DICompileUnit(language: DW_LANG_Python, file: !3, producer: \"NAC3\", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
!5 = distinct !DISubprogram(name: \"testing\", linkageName: \"testing\", scope: null, file: !3, line: 1, type: !6, scopeLine: 1, flags: DIFlagPublic, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !9)
!6 = !DISubroutineType(flags: DIFlagPublic, types: !7)
!7 = !{!8}
!8 = !DIBasicType(name: \"_\", flags: DIFlagPublic)
!9 = !{}
!10 = !DILocation(line: 1, column: 9, scope: !5)
!11 = !DILocation(line: 2, column: 12, scope: !5)
!12 = distinct !DISubprogram(name: \"foo.0\", linkageName: \"foo.0\", scope: null, file: !3, line: 1, type: !6, scopeLine: 1, flags: DIFlagPublic, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !4, retainedNodes: !9)
!13 = !DILocation(line: 1, column: 12, scope: !12)
"}
.trim(); .trim();
assert_eq!(expected, module.print_to_string().to_str().unwrap().trim()); assert_eq!(expected, module.print_to_string().to_str().unwrap().trim());
}))); })));

View File

@ -66,7 +66,6 @@ pub fn get_exn_constructor(
object_id: DefinitionId(class_id), object_id: DefinitionId(class_id),
type_vars: Default::default(), type_vars: Default::default(),
fields: exception_fields, fields: exception_fields,
static_fields: Default::default(),
methods: vec![("__init__".into(), signature, DefinitionId(cons_id))], methods: vec![("__init__".into(), signature, DefinitionId(cons_id))],
ancestors: vec![ ancestors: vec![
TypeAnnotation::CustomClass { id: DefinitionId(class_id), params: Default::default() }, TypeAnnotation::CustomClass { id: DefinitionId(class_id), params: Default::default() },
@ -176,7 +175,6 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
type_vars: Default::default(), type_vars: Default::default(),
fields: exception_fields, fields: exception_fields,
methods: Default::default(), methods: Default::default(),
static_fields: Default::default(),
ancestors: vec![], ancestors: vec![],
constructor: None, constructor: None,
resolver: None, resolver: None,
@ -202,7 +200,6 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
object_id: DefinitionId(10), object_id: DefinitionId(10),
type_vars: vec![option_ty_var], type_vars: vec![option_ty_var],
fields: vec![], fields: vec![],
static_fields: vec![],
methods: vec![ methods: vec![
("is_some".into(), is_some_ty.0, DefinitionId(11)), ("is_some".into(), is_some_ty.0, DefinitionId(11)),
("is_none".into(), is_some_ty.0, DefinitionId(12)), ("is_none".into(), is_some_ty.0, DefinitionId(12)),

View File

@ -164,7 +164,6 @@ impl TopLevelComposer {
ast: ast::Stmt<()>, ast: ast::Stmt<()>,
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>, resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
mod_path: String, mod_path: String,
allow_no_constructor: bool,
) -> Result<(StrRef, DefinitionId, Option<Type>), String> { ) -> Result<(StrRef, DefinitionId, Option<Type>), String> {
let defined_names = &mut self.defined_names; let defined_names = &mut self.defined_names;
match &ast.node { match &ast.node {
@ -229,6 +228,7 @@ impl TopLevelComposer {
// subclass of other exception classes. // subclass of other exception classes.
let mut contains_constructor = bases let mut contains_constructor = bases
.iter().any(|base| matches!(base.node, ast::ExprKind::Name { id, .. } if id == exception_id)); .iter().any(|base| matches!(base.node, ast::ExprKind::Name { id, .. } if id == exception_id));
for b in body { for b in body {
if let ast::StmtKind::FunctionDef { name: method_name, .. } = &b.node { if let ast::StmtKind::FunctionDef { name: method_name, .. } = &b.node {
if method_name == &init_id { if method_name == &init_id {
@ -299,7 +299,9 @@ impl TopLevelComposer {
self.definition_ast_list.push((def, Some(ast))); self.definition_ast_list.push((def, Some(ast)));
} }
let result_ty = if allow_no_constructor || contains_constructor { Some(constructor_ty) } else { None }; // Quick way to fix #221, contains constructor can be used in the future for some implementation if required.
let result_ty = if contains_constructor { Some(constructor_ty) } else { Some(constructor_ty) };
Ok((class_name, DefinitionId(class_def_id), result_ty)) Ok((class_name, DefinitionId(class_def_id), result_ty))
} }
@ -435,11 +437,11 @@ impl TopLevelComposer {
// check if all are unique type vars // check if all are unique type vars
let all_unique_type_var = { let all_unique_type_var = {
let mut occurred_type_var_id: HashSet<u32> = HashSet::new(); let mut occured_type_var_id: HashSet<u32> = HashSet::new();
type_vars.iter().all(|x| { type_vars.iter().all(|x| {
let ty = unifier.get_ty(*x); let ty = unifier.get_ty(*x);
if let TypeEnum::TVar { id, .. } = ty.as_ref() { if let TypeEnum::TVar { id, .. } = ty.as_ref() {
occurred_type_var_id.insert(*id) occured_type_var_id.insert(*id)
} else { } else {
false false
} }
@ -537,7 +539,7 @@ impl TopLevelComposer {
} }
has_base = true; has_base = true;
// the function parse_ast_to make sure that no type var occurred in // the function parse_ast_to make sure that no type var occured in
// bast_ty if it is a CustomClassKind // bast_ty if it is a CustomClassKind
let base_ty = parse_ast_to_type_annotation_kinds( let base_ty = parse_ast_to_type_annotation_kinds(
class_resolver, class_resolver,
@ -697,7 +699,7 @@ impl TopLevelComposer {
return Err(errors.into_iter().sorted().join("\n----------\n")); return Err(errors.into_iter().sorted().join("\n----------\n"));
} }
// handle the inherited methods and fields // handle the inheritanced methods and fields
// Note: we cannot defer error handling til the end of the loop, because there is loop // Note: we cannot defer error handling til the end of the loop, because there is loop
// carried dependency, ignoring the error (temporarily) will cause all assumptions to break // carried dependency, ignoring the error (temporarily) will cause all assumptions to break
// and produce weird error messages // and produce weird error messages
@ -826,9 +828,9 @@ impl TopLevelComposer {
let mut function_var_map: HashMap<u32, Type> = HashMap::new(); let mut function_var_map: HashMap<u32, Type> = HashMap::new();
let arg_types = { let arg_types = {
// make sure no duplicate parameter // make sure no duplicate parameter
let mut defined_parameter_name: HashSet<_> = HashSet::new(); let mut defined_paramter_name: HashSet<_> = HashSet::new();
for x in args.args.iter() { for x in args.args.iter() {
if !defined_parameter_name.insert(x.node.arg) if !defined_paramter_name.insert(x.node.arg)
|| keyword_list.contains(&x.node.arg) || keyword_list.contains(&x.node.arg)
{ {
return Err(format!( return Err(format!(
@ -1040,7 +1042,6 @@ impl TopLevelComposer {
class_body_ast, class_body_ast,
_class_ancestor_def, _class_ancestor_def,
class_fields_def, class_fields_def,
class_static_fields_def,
class_methods_def, class_methods_def,
class_type_vars_def, class_type_vars_def,
class_resolver, class_resolver,
@ -1048,7 +1049,6 @@ impl TopLevelComposer {
object_id, object_id,
ancestors, ancestors,
fields, fields,
static_fields,
methods, methods,
resolver, resolver,
type_vars, type_vars,
@ -1056,7 +1056,7 @@ impl TopLevelComposer {
} = &mut *class_def } = &mut *class_def
{ {
if let ast::StmtKind::ClassDef { name, bases, body, .. } = &class_ast { if let ast::StmtKind::ClassDef { name, bases, body, .. } = &class_ast {
(*object_id, *name, bases, body, ancestors, fields, static_fields, methods, type_vars, resolver) (*object_id, *name, bases, body, ancestors, fields, methods, type_vars, resolver)
} else { } else {
unreachable!("here must be class def ast"); unreachable!("here must be class def ast");
} }
@ -1077,10 +1077,10 @@ impl TopLevelComposer {
let arg_types: Vec<FuncArg> = { let arg_types: Vec<FuncArg> = {
// check method parameters cannot have same name // check method parameters cannot have same name
let mut defined_parameter_name: HashSet<_> = HashSet::new(); let mut defined_paramter_name: HashSet<_> = HashSet::new();
let zelf: StrRef = "self".into(); let zelf: StrRef = "self".into();
for x in args.args.iter() { for x in args.args.iter() {
if !defined_parameter_name.insert(x.node.arg) if !defined_paramter_name.insert(x.node.arg)
|| (keyword_list.contains(&x.node.arg) && x.node.arg != zelf) || (keyword_list.contains(&x.node.arg) && x.node.arg != zelf)
{ {
return Err(format!( return Err(format!(
@ -1091,13 +1091,13 @@ impl TopLevelComposer {
} }
} }
if name == &"__init__".into() && !defined_parameter_name.contains(&zelf) { if name == &"__init__".into() && !defined_paramter_name.contains(&zelf) {
return Err(format!( return Err(format!(
"__init__ method must have a `self` parameter (at {})", "__init__ method must have a `self` parameter (at {})",
b.location b.location
)); ));
} }
if !defined_parameter_name.contains(&zelf) { if !defined_paramter_name.contains(&zelf) {
return Err(format!( return Err(format!(
"class method must have a `self` parameter (at {})", "class method must have a `self` parameter (at {})",
b.location b.location
@ -1230,7 +1230,7 @@ impl TopLevelComposer {
dummy_return_type dummy_return_type
} else { } else {
// if do not have return annotation, return none // if do not have return annotation, return none
// for uniform handling, still use type annotation // for uniform handling, still use type annoatation
let dummy_return_type = unifier.get_dummy_var().0; let dummy_return_type = unifier.get_dummy_var().0;
type_var_to_concrete_def.insert( type_var_to_concrete_def.insert(
dummy_return_type, dummy_return_type,
@ -1270,7 +1270,7 @@ impl TopLevelComposer {
.unify(method_dummy_ty, method_type) .unify(method_dummy_ty, method_type)
.map_err(|e| e.to_display(unifier).to_string())?; .map_err(|e| e.to_display(unifier).to_string())?;
} }
ast::StmtKind::AnnAssign { target, annotation, value, .. } => { ast::StmtKind::AnnAssign { target, annotation, value: None, .. } => {
if let ast::ExprKind::Name { id: attr, .. } = &target.node { if let ast::ExprKind::Name { id: attr, .. } = &target.node {
if defined_fields.insert(attr.to_string()) { if defined_fields.insert(attr.to_string()) {
let dummy_field_type = unifier.get_dummy_var().0; let dummy_field_type = unifier.get_dummy_var().0;
@ -1296,9 +1296,6 @@ impl TopLevelComposer {
_ if core_config.kernel_ann.is_none() => (annotation, true), _ if core_config.kernel_ann.is_none() => (annotation, true),
_ => continue, // ignore fields annotated otherwise _ => continue, // ignore fields annotated otherwise
}; };
if let Option::Some(..) = &value{
class_static_fields_def.push((*attr, dummy_field_type, mutable));
}
class_fields_def.push((*attr, dummy_field_type, mutable)); class_fields_def.push((*attr, dummy_field_type, mutable));
let parsed_annotation = parse_ast_to_type_annotation_kinds( let parsed_annotation = parse_ast_to_type_annotation_kinds(
@ -1329,7 +1326,7 @@ impl TopLevelComposer {
type_var_to_concrete_def.insert(dummy_field_type, parsed_annotation); type_var_to_concrete_def.insert(dummy_field_type, parsed_annotation);
} else { } else {
return Err(format!( return Err(format!(
"same class field `{}` defined twice (at {})", "same class fields `{}` defined twice (at {})",
attr, target.location attr, target.location
)); ));
} }
@ -1340,27 +1337,7 @@ impl TopLevelComposer {
)); ));
} }
} }
ast::StmtKind::Assign { targets, value, .. } => { ast::StmtKind::Assign { .. } => {}, // we don't class attributes
for target in targets {
if let ast::ExprKind::Name { id: attr, .. } = &target.node {
if defined_fields.insert(attr.to_string()) {
let dummy_field_type = unifier.get_dummy_var().0;
class_static_fields_def.push((*attr, dummy_field_type, true));
class_fields_def.push((*attr, dummy_field_type, true));
} else {
return Err(format!(
"same class field `{}` defined twice (at {})",
attr, target.location
));
}
} else {
return Err(format!(
"unsupported statement type in class definition body (at {})",
target.location
));
}
}
},
ast::StmtKind::Pass { .. } => {} ast::StmtKind::Pass { .. } => {}
ast::StmtKind::Expr { value: _, .. } => {} // typically a docstring; ignoring all expressions matches CPython behavior ast::StmtKind::Expr { value: _, .. } => {} // typically a docstring; ignoring all expressions matches CPython behavior
_ => { _ => {
@ -1494,7 +1471,7 @@ impl TopLevelComposer {
Ok(()) Ok(())
} }
/// step 5, analyze and call type inferencer to fill the `instance_to_stmt` of topleveldef::function /// step 5, analyze and call type inferecer to fill the `instance_to_stmt` of topleveldef::function
fn analyze_function_instance(&mut self) -> Result<(), String> { fn analyze_function_instance(&mut self) -> Result<(), String> {
// first get the class constructor type correct for the following type check in function body // first get the class constructor type correct for the following type check in function body
// also do class field instantiation check // also do class field instantiation check
@ -1541,7 +1518,6 @@ impl TopLevelComposer {
ancestors, ancestors,
methods, methods,
fields, fields,
static_fields,
type_vars, type_vars,
name: class_name, name: class_name,
object_id, object_id,
@ -1644,11 +1620,11 @@ impl TopLevelComposer {
unreachable!("must be init function here") unreachable!("must be init function here")
} }
let all_inited = Self::get_all_assigned_field(body.as_slice())?; let all_inited = Self::get_all_assigned_field(body.as_slice())?;
for f in fields { for (f, _, _) in fields {
if !all_inited.contains(&f.0) && !static_fields.contains(&f) { if !all_inited.contains(f) {
return Err(format!( return Err(format!(
"fields `{}` of class `{}` not fully initialized in the initializer (at {})", "fields `{}` of class `{}` not fully initialized in the initializer (at {})",
&f.0, f,
class_name, class_name,
body[0].location, body[0].location,
)); ));

View File

@ -84,7 +84,7 @@ impl TopLevelComposer {
obj_id: DefinitionId(7), obj_id: DefinitionId(7),
fields: vec![ fields: vec![
("__name__".into(), (int32, true)), ("__name__".into(), (int32, true)),
("__file__".into(), (str, true)), ("__file__".into(), (int32, true)),
("__line__".into(), (int32, true)), ("__line__".into(), (int32, true)),
("__col__".into(), (int32, true)), ("__col__".into(), (int32, true)),
("__func__".into(), (str, true)), ("__func__".into(), (str, true)),
@ -149,7 +149,7 @@ impl TopLevelComposer {
} }
/// already include the definition_id of itself inside the ancestors vector /// already include the definition_id of itself inside the ancestors vector
/// when first registering, the type_vars, fields, methods, ancestors are invalid /// when first regitering, the type_vars, fields, methods, ancestors are invalid
pub fn make_top_level_class_def( pub fn make_top_level_class_def(
index: usize, index: usize,
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>, resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
@ -162,7 +162,6 @@ impl TopLevelComposer {
object_id: DefinitionId(index), object_id: DefinitionId(index),
type_vars: Default::default(), type_vars: Default::default(),
fields: Default::default(), fields: Default::default(),
static_fields: Default::default(),
methods: Default::default(), methods: Default::default(),
ancestors: Default::default(), ancestors: Default::default(),
constructor, constructor,

View File

@ -91,8 +91,6 @@ pub enum TopLevelDef {
// class fields // class fields
// name, type, is mutable // name, type, is mutable
fields: Vec<(StrRef, Type, bool)>, fields: Vec<(StrRef, Type, bool)>,
// list of static data members
static_fields: Vec<(StrRef, Type, bool)>,
// class methods, pointing to the corresponding function definition. // class methods, pointing to the corresponding function definition.
methods: Vec<(StrRef, Type, DefinitionId)>, methods: Vec<(StrRef, Type, DefinitionId)>,
// ancestor classes, including itself. // ancestor classes, including itself.

View File

@ -105,7 +105,7 @@ impl SymbolResolver for Resolver {
def __init__(self): def __init__(self):
self.c: int32 = 4 self.c: int32 = 4
self.a: bool = True self.a: bool = True
"}, "}
]; ];
"register" "register"
)] )]
@ -116,26 +116,10 @@ fn test_simple_register(source: Vec<&str>) {
let ast = parse_program(s, Default::default()).unwrap(); let ast = parse_program(s, Default::default()).unwrap();
let ast = ast[0].clone(); let ast = ast[0].clone();
composer.register_top_level(ast, None, "".into(), false).unwrap(); composer.register_top_level(ast, None, "".into()).unwrap();
} }
} }
#[test_case(
indoc! {"
class A:
def foo(self):
pass
a = A()
"};
"register"
)]
fn test_simple_register_without_constructor(source: &str) {
let mut composer: TopLevelComposer = Default::default();
let ast = parse_program(source, Default::default()).unwrap();
let ast = ast[0].clone();
composer.register_top_level(ast, None, "".into(), true).unwrap();
}
#[test_case( #[test_case(
vec![ vec![
indoc! {" indoc! {"
@ -179,7 +163,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
let ast = ast[0].clone(); let ast = ast[0].clone();
let (id, def_id, ty) = let (id, def_id, ty) =
composer.register_top_level(ast, Some(resolver.clone()), "".into(), false).unwrap(); composer.register_top_level(ast, Some(resolver.clone()), "".into()).unwrap();
internal_resolver.add_id_def(id, def_id); internal_resolver.add_id_def(id, def_id);
if let Some(ty) = ty { if let Some(ty) = ty {
internal_resolver.add_id_type(id, ty); internal_resolver.add_id_type(id, ty);
@ -531,7 +515,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
let ast = ast[0].clone(); let ast = ast[0].clone();
let (id, def_id, ty) = { let (id, def_id, ty) = {
match composer.register_top_level(ast, Some(resolver.clone()), "".into(), false) { match composer.register_top_level(ast, Some(resolver.clone()), "".into()) {
Ok(x) => x, Ok(x) => x,
Err(msg) => { Err(msg) => {
if print { if print {
@ -715,7 +699,7 @@ fn test_inference(source: Vec<&str>, res: Vec<&str>) {
let ast = ast[0].clone(); let ast = ast[0].clone();
let (id, def_id, ty) = { let (id, def_id, ty) = {
match composer.register_top_level(ast, Some(resolver.clone()), "".into(), false) { match composer.register_top_level(ast, Some(resolver.clone()), "".into()) {
Ok(x) => x, Ok(x) => x,
Err(msg) => { Err(msg) => {
if print { if print {

View File

@ -436,7 +436,7 @@ pub fn get_type_from_type_annotation_kinds(
/// the type of `self` should be similar to `A[T, V]`, where `T`, `V` /// the type of `self` should be similar to `A[T, V]`, where `T`, `V`
/// considered to be type variables associated with the class \ /// considered to be type variables associated with the class \
/// \ /// \
/// But note that here we do not make a duplication of `T`, `V`, we directly /// But note that here we do not make a duplication of `T`, `V`, we direclty
/// use them as they are in the TopLevelDef::Class since those in the /// use them as they are in the TopLevelDef::Class since those in the
/// TopLevelDef::Class.type_vars will be substitute later when seeing applications/instantiations /// TopLevelDef::Class.type_vars will be substitute later when seeing applications/instantiations
/// the Type of their fields and methods will also be subst when application/instantiation /// the Type of their fields and methods will also be subst when application/instantiation

View File

@ -83,7 +83,7 @@ where
pub fn impl_binop( pub fn impl_binop(
unifier: &mut Unifier, unifier: &mut Unifier,
_store: &PrimitiveStore, store: &PrimitiveStore,
ty: Type, ty: Type,
other_ty: &[Type], other_ty: &[Type],
ret_ty: Type, ret_ty: Type,
@ -120,7 +120,7 @@ pub fn impl_binop(
fields.insert(binop_assign_name(op).into(), { fields.insert(binop_assign_name(op).into(), {
( (
unifier.add_ty(TypeEnum::TFunc(FunSignature { unifier.add_ty(TypeEnum::TFunc(FunSignature {
ret: ret_ty, ret: store.none,
vars: function_vars.clone(), vars: function_vars.clone(),
args: vec![FuncArg { args: vec![FuncArg {
ty: other_ty, ty: other_ty,

View File

@ -423,7 +423,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
(None, None) => {} (None, None) => {}
}, },
ast::StmtKind::AugAssign { target, op, value, .. } => { ast::StmtKind::AugAssign { target, op, value, .. } => {
let res_ty = self.infer_bin_ops(stmt.location, target, op, value, true)?; let res_ty = self.infer_bin_ops(stmt.location, target, op, value)?;
self.unify(res_ty, target.custom.unwrap(), &stmt.location)?; self.unify(res_ty, target.custom.unwrap(), &stmt.location)?;
} }
ast::StmtKind::Assert { test, msg, .. } => { ast::StmtKind::Assert { test, msg, .. } => {
@ -505,7 +505,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
} }
ast::ExprKind::BoolOp { values, .. } => Some(self.infer_bool_ops(values)?), ast::ExprKind::BoolOp { values, .. } => Some(self.infer_bool_ops(values)?),
ast::ExprKind::BinOp { left, op, right } => { ast::ExprKind::BinOp { left, op, right } => {
Some(self.infer_bin_ops(expr.location, left, op, right, false)?) Some(self.infer_bin_ops(expr.location, left, op, right)?)
} }
ast::ExprKind::UnaryOp { op, operand } => Some(self.infer_unary_ops(op, operand)?), ast::ExprKind::UnaryOp { op, operand } => Some(self.infer_unary_ops(op, operand)?),
ast::ExprKind::Compare { left, ops, comparators } => { ast::ExprKind::Compare { left, ops, comparators } => {
@ -1028,24 +1028,8 @@ impl<'a> Inferencer<'a> {
left: &ast::Expr<Option<Type>>, left: &ast::Expr<Option<Type>>,
op: &ast::Operator, op: &ast::Operator,
right: &ast::Expr<Option<Type>>, right: &ast::Expr<Option<Type>>,
is_aug_assign: bool,
) -> InferenceResult { ) -> InferenceResult {
let method = if let TypeEnum::TObj { fields, .. } = let method = binop_name(op).into();
self.unifier.get_ty_immutable(left.custom.unwrap()).as_ref()
{
let (binop_name, binop_assign_name) = (
binop_name(op).into(),
binop_assign_name(op).into()
);
// if is aug_assign, try aug_assign operator first
if is_aug_assign && fields.contains_key(&binop_assign_name) {
binop_assign_name
} else {
binop_name
}
} else {
binop_name(op).into()
};
self.build_method_call( self.build_method_call(
location, location,
method, method,

View File

@ -16,7 +16,7 @@ use crate::toplevel::{DefinitionId, TopLevelContext, TopLevelDef};
#[cfg(test)] #[cfg(test)]
mod test; mod test;
/// Handle for a type, implemented as a key in the unification table. /// Handle for a type, implementated as a key in the unification table.
pub type Type = UnificationKey; pub type Type = UnificationKey;
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
@ -657,16 +657,12 @@ impl Unifier {
return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None)); return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None));
} }
for (x, y) in ty1.iter().zip(ty2.iter()) { for (x, y) in ty1.iter().zip(ty2.iter()) {
if self.unify_impl(*x, *y, false).is_err() { self.unify_impl(*x, *y, false)?;
return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None));
}
} }
self.set_a_to_b(a, b); self.set_a_to_b(a, b);
} }
(TList { ty: ty1 }, TList { ty: ty2 }) => { (TList { ty: ty1 }, TList { ty: ty2 }) => {
if self.unify_impl(*ty1, *ty2, false).is_err() { self.unify_impl(*ty1, *ty2, false)?;
return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None));
}
self.set_a_to_b(a, b); self.set_a_to_b(a, b);
} }
(TVar { fields: Some(map), range, .. }, TObj { fields, .. }) => { (TVar { fields: Some(map), range, .. }, TObj { fields, .. }) => {
@ -747,16 +743,12 @@ impl Unifier {
self.incompatible_types(a, b)?; self.incompatible_types(a, b)?;
} }
for (x, y) in zip(params1.values(), params2.values()) { for (x, y) in zip(params1.values(), params2.values()) {
if self.unify_impl(*x, *y, false).is_err() { self.unify_impl(*x, *y, false)?;
return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None));
};
} }
self.set_a_to_b(a, b); self.set_a_to_b(a, b);
} }
(TVirtual { ty: ty1 }, TVirtual { ty: ty2 }) => { (TVirtual { ty: ty1 }, TVirtual { ty: ty2 }) => {
if self.unify_impl(*ty1, *ty2, false).is_err() { self.unify_impl(*ty1, *ty2, false)?;
return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None));
};
self.set_a_to_b(a, b); self.set_a_to_b(a, b);
} }
(TCall(calls1), TCall(calls2)) => { (TCall(calls1), TCall(calls2)) => {
@ -792,13 +784,9 @@ impl Unifier {
if x.name != y.name || x.default_value != y.default_value { if x.name != y.name || x.default_value != y.default_value {
return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None)); return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None));
} }
if self.unify_impl(x.ty, y.ty, false).is_err() { self.unify_impl(x.ty, y.ty, false)?;
return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None));
};
} }
if self.unify_impl(sign1.ret, sign2.ret, false).is_err() { self.unify_impl(sign1.ret, sign2.ret, false)?;
return Err(TypeError::new(TypeErrorKind::IncompatibleTypes(a, b), None));
};
self.set_a_to_b(a, b); self.set_a_to_b(a, b);
} }
(TVar { fields: Some(fields), .. }, _) => { (TVar { fields: Some(fields), .. }, _) => {

View File

@ -286,7 +286,7 @@ fn test_unify(
("v1", "tuple[int]"), ("v1", "tuple[int]"),
("v2", "tuple[float]"), ("v2", "tuple[float]"),
], ],
(("v1", "v2"), "Incompatible types: tuple[0] and tuple[1]") (("v1", "v2"), "Incompatible types: 0 and 1")
; "tuple parameter mismatch" ; "tuple parameter mismatch"
)] )]
#[test_case(2, #[test_case(2,
@ -309,7 +309,7 @@ fn test_unify(
fn test_invalid_unification( fn test_invalid_unification(
variable_count: u32, variable_count: u32,
unify_pairs: &[(&'static str, &'static str)], unify_pairs: &[(&'static str, &'static str)],
erroneous_pair: ((&'static str, &'static str), &'static str), errornous_pair: ((&'static str, &'static str), &'static str),
) { ) {
let mut env = TestEnvironment::new(); let mut env = TestEnvironment::new();
let mut mapping = HashMap::new(); let mut mapping = HashMap::new();
@ -326,11 +326,11 @@ fn test_invalid_unification(
pairs.push((t1, t2)); pairs.push((t1, t2));
} }
let (t1, t2) = let (t1, t2) =
(env.parse(erroneous_pair.0 .0, &mapping), env.parse(erroneous_pair.0 .1, &mapping)); (env.parse(errornous_pair.0 .0, &mapping), env.parse(errornous_pair.0 .1, &mapping));
for (a, b) in pairs { for (a, b) in pairs {
env.unifier.unify(a, b).unwrap(); env.unifier.unify(a, b).unwrap();
} }
assert_eq!(env.unify(t1, t2), Err(erroneous_pair.1.to_string())); assert_eq!(env.unify(t1, t2), Err(errornous_pair.1.to_string()));
} }
#[test] #[test]
@ -478,8 +478,7 @@ fn test_typevar_range() {
let int_list = env.unifier.add_ty(TypeEnum::TList { ty: int }); let int_list = env.unifier.add_ty(TypeEnum::TList { ty: int });
assert_eq!( assert_eq!(
env.unify(a_list, int_list), env.unify(a_list, int_list),
Err("Incompatible types: list[typevar22] and list[0]\ Err("Expected any one of these types: 1, but got 0".into())
\n\nNotes:\n typevar22 {1}".into())
); );
let a = env.unifier.get_fresh_var_with_range(&[int, float], None, None).0; let a = env.unifier.get_fresh_var_with_range(&[int, float], None, None).0;
@ -507,7 +506,7 @@ fn test_rigid_var() {
assert_eq!(env.unify(a, b), Err("Incompatible types: typevar3 and typevar2".to_string())); assert_eq!(env.unify(a, b), Err("Incompatible types: typevar3 and typevar2".to_string()));
env.unifier.unify(list_a, list_x).unwrap(); env.unifier.unify(list_a, list_x).unwrap();
assert_eq!(env.unify(list_x, list_int), Err("Incompatible types: list[typevar2] and list[0]".to_string())); assert_eq!(env.unify(list_x, list_int), Err("Incompatible types: 0 and typevar2".to_string()));
env.unifier.replace_rigid_var(a, int); env.unifier.replace_rigid_var(a, int);
env.unifier.unify(list_x, list_int).unwrap(); env.unifier.unify(list_x, list_int).unwrap();

View File

@ -1,8 +0,0 @@
[package]
name = "nac3ld"
version = "0.1.0"
authors = ["M-Labs"]
edition = "2018"
[dependencies]
byteorder = { version = "1.4", default-features = false }

View File

@ -1,392 +0,0 @@
#![allow(non_camel_case_types, non_upper_case_globals)]
use std::mem;
use byteorder::{ByteOrder, LittleEndian};
pub const DW_EH_PE_omit: u8 = 0xFF;
pub const DW_EH_PE_absptr: u8 = 0x00;
pub const DW_EH_PE_uleb128: u8 = 0x01;
pub const DW_EH_PE_udata2: u8 = 0x02;
pub const DW_EH_PE_udata4: u8 = 0x03;
pub const DW_EH_PE_udata8: u8 = 0x04;
pub const DW_EH_PE_sleb128: u8 = 0x09;
pub const DW_EH_PE_sdata2: u8 = 0x0A;
pub const DW_EH_PE_sdata4: u8 = 0x0B;
pub const DW_EH_PE_sdata8: u8 = 0x0C;
pub const DW_EH_PE_pcrel: u8 = 0x10;
pub const DW_EH_PE_textrel: u8 = 0x20;
pub const DW_EH_PE_datarel: u8 = 0x30;
pub const DW_EH_PE_funcrel: u8 = 0x40;
pub const DW_EH_PE_aligned: u8 = 0x50;
pub const DW_EH_PE_indirect: u8 = 0x80;
pub struct DwarfReader<'a> {
pub slice: &'a [u8],
pub virt_addr: u32,
}
impl<'a> DwarfReader<'a> {
pub fn new(slice: &[u8], virt_addr: u32) -> DwarfReader {
DwarfReader { slice, virt_addr }
}
pub fn offset(&mut self, offset: i32) {
self.slice = &self.slice[offset as usize..];
self.virt_addr = self.virt_addr.wrapping_add(offset as u32);
}
// ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
// Length Data".
pub fn read_uleb128(&mut self) -> u64 {
let mut shift: usize = 0;
let mut result: u64 = 0;
let mut byte: u8;
loop {
byte = self.read_u8();
result |= ((byte & 0x7F) as u64) << shift;
shift += 7;
if byte & 0x80 == 0 {
break;
}
}
result
}
pub fn read_sleb128(&mut self) -> i64 {
let mut shift: u32 = 0;
let mut result: u64 = 0;
let mut byte: u8;
loop {
byte = self.read_u8();
result |= ((byte & 0x7F) as u64) << shift;
shift += 7;
if byte & 0x80 == 0 {
break;
}
}
// sign-extend
if shift < u64::BITS && (byte & 0x40) != 0 {
result |= (!0 as u64) << shift;
}
result as i64
}
pub fn read_u8(&mut self) -> u8 {
let val = self.slice[0];
self.slice = &self.slice[1..];
val
}
}
macro_rules! impl_read_fn {
( $($type: ty, $byteorder_fn: ident);* ) => {
impl<'a> DwarfReader<'a> {
$(
pub fn $byteorder_fn(&mut self) -> $type {
let val = LittleEndian::$byteorder_fn(self.slice);
self.slice = &self.slice[mem::size_of::<$type>()..];
val
}
)*
}
}
}
impl_read_fn!(
u16, read_u16;
u32, read_u32;
u64, read_u64;
i16, read_i16;
i32, read_i32;
i64, read_i64
);
pub struct DwarfWriter<'a> {
pub slice: &'a mut [u8],
pub offset: usize,
}
impl<'a> DwarfWriter<'a> {
pub fn new(slice: &mut [u8]) -> DwarfWriter {
DwarfWriter { slice, offset: 0 }
}
pub fn write_u8(&mut self, data: u8) {
self.slice[self.offset] = data;
self.offset += 1;
}
pub fn write_u32(&mut self, data: u32) {
LittleEndian::write_u32(&mut self.slice[self.offset..], data);
self.offset += 4;
}
}
fn read_encoded_pointer(reader: &mut DwarfReader, encoding: u8) -> Result<usize, ()> {
if encoding == DW_EH_PE_omit {
return Err(());
}
// DW_EH_PE_aligned implies it's an absolute pointer value
// However, we are linking library for 32-bits architecture
// The size of variable should be 4 bytes instead
if encoding == DW_EH_PE_aligned {
let shifted_virt_addr = round_up(reader.virt_addr as usize, mem::size_of::<u32>())?;
let addr_inc = shifted_virt_addr - reader.virt_addr as usize;
reader.slice = &reader.slice[addr_inc..];
reader.virt_addr = shifted_virt_addr as u32;
return Ok(reader.read_u32() as usize);
}
match encoding & 0x0F {
DW_EH_PE_absptr => Ok(reader.read_u32() as usize),
DW_EH_PE_uleb128 => Ok(reader.read_uleb128() as usize),
DW_EH_PE_udata2 => Ok(reader.read_u16() as usize),
DW_EH_PE_udata4 => Ok(reader.read_u32() as usize),
DW_EH_PE_udata8 => Ok(reader.read_u64() as usize),
DW_EH_PE_sleb128 => Ok(reader.read_sleb128() as usize),
DW_EH_PE_sdata2 => Ok(reader.read_i16() as usize),
DW_EH_PE_sdata4 => Ok(reader.read_i32() as usize),
DW_EH_PE_sdata8 => Ok(reader.read_i64() as usize),
_ => Err(()),
}
}
fn read_encoded_pointer_with_pc(
reader: &mut DwarfReader,
encoding: u8,
) -> Result<usize, ()> {
let entry_virt_addr = reader.virt_addr;
let mut result = read_encoded_pointer(reader, encoding)?;
// DW_EH_PE_aligned implies it's an absolute pointer value
if encoding == DW_EH_PE_aligned {
return Ok(result);
}
result = match encoding & 0x70 {
DW_EH_PE_pcrel => result.wrapping_add(entry_virt_addr as usize),
// .eh_frame normally would not have these kinds of relocations
// These would not be supported by a dedicated linker relocation schemes for RISC-V
DW_EH_PE_textrel | DW_EH_PE_datarel | DW_EH_PE_funcrel | DW_EH_PE_aligned => {
unimplemented!()
}
// Other values should be impossible
_ => unreachable!(),
};
if encoding & DW_EH_PE_indirect != 0 {
// There should not be a need for indirect addressing, as assembly code from
// the dynamic library should not be freely moved relative to the EH frame.
unreachable!()
}
Ok(result)
}
#[inline]
fn round_up(unrounded: usize, align: usize) -> Result<usize, ()> {
if align.is_power_of_two() {
Ok((unrounded + align - 1) & !(align - 1))
} else {
Err(())
}
}
// Minimalistic structure to store everything needed for parsing FDEs to synthesize
// .eh_frame_hdr section. Since we are only linking 1 object file, there should only be 1 call
// frame information (CFI) record, so there should be only 1 common information entry (CIE).
// So the class parses the only CIE on init, cache the encoding info, then parse the FDE on
// iterations based on the cached encoding format.
pub struct EH_Frame<'a> {
// It refers to the augmentation data that corresponds to 'R' in the augmentation string
pub fde_pointer_encoding: u8,
pub fde_reader: DwarfReader<'a>,
pub fde_sz: usize,
}
impl<'a> EH_Frame<'a> {
pub fn new(eh_frame_slice: &[u8], eh_frame_addr: u32) -> Result<EH_Frame, ()> {
let mut cie_reader = DwarfReader::new(eh_frame_slice, eh_frame_addr);
let eh_frame_size = eh_frame_slice.len();
let length = cie_reader.read_u32();
let fde_reader = match length {
// eh_frame with 0 lengths means the CIE is terminated
// while length == u32::MAX means that the length is only representable with 64 bits,
// which does not make sense in a system with 32-bit address.
0 | 0xFFFFFFFF => unimplemented!(),
_ => {
let mut fde_reader = DwarfReader::new(cie_reader.slice, cie_reader.virt_addr);
fde_reader.offset(length as i32);
fde_reader
}
};
let fde_sz = eh_frame_size - mem::size_of::<u32>() - length as usize;
// Routine check on the .eh_frame well-formness, in terms of CIE ID & Version args.
assert_eq!(cie_reader.read_u32(), 0);
assert_eq!(cie_reader.read_u8(), 1);
// Parse augmentation string
// The first character must be 'z', there is no way to proceed otherwise
assert_eq!(cie_reader.read_u8(), b'z');
// Establish a pointer that skips ahead of the string
// Skip code/data alignment factors & return address register along the way as well
// We only tackle the case where 'z' and 'R' are part of the augmentation string, otherwise
// we cannot get the addresses to make .eh_frame_hdr
let mut aug_data_reader = DwarfReader::new(cie_reader.slice, cie_reader.virt_addr);
let mut aug_str_len = 0;
loop {
if aug_data_reader.read_u8() == b'\0' {
break;
}
aug_str_len += 1;
}
if aug_str_len == 0 {
unimplemented!();
}
aug_data_reader.read_uleb128(); // Code alignment factor
aug_data_reader.read_sleb128(); // Data alignment factor
aug_data_reader.read_uleb128(); // Return address register
aug_data_reader.read_uleb128(); // Augmentation data length
let mut fde_pointer_encoding = DW_EH_PE_omit;
for _ in 0..aug_str_len {
match cie_reader.read_u8() {
b'L' => {
aug_data_reader.read_u8();
}
b'P' => {
let encoding = aug_data_reader.read_u8();
read_encoded_pointer(&mut aug_data_reader, encoding)?;
}
b'R' => {
fde_pointer_encoding = aug_data_reader.read_u8();
}
// Other characters are not supported
_ => unimplemented!(),
}
}
assert_ne!(fde_pointer_encoding, DW_EH_PE_omit);
Ok(EH_Frame { fde_pointer_encoding, fde_reader, fde_sz })
}
pub fn iterate_fde(&self, callback: &mut dyn FnMut(u32, u32)) -> Result<(), ()> {
// Parse each FDE to obtain the starting address that the FDE applies to
// Send the FDE offset and the mentioned address to a callback that write up the
// .eh_frame_hdr section
let mut remaining_len = self.fde_sz;
let mut reader = DwarfReader::new(self.fde_reader.slice, self.fde_reader.virt_addr);
loop {
if remaining_len == 0 {
break;
}
let fde_virt_addr = reader.virt_addr;
let length = match reader.read_u32() {
0 | 0xFFFFFFFF => unimplemented!(),
other => other,
};
// Remove the length of the header and the content from the counter
remaining_len -= length as usize + mem::size_of::<u32>();
let mut next_fde_reader = DwarfReader::new(reader.slice, reader.virt_addr);
next_fde_reader.offset(length as i32);
// Skip CIE pointer offset
reader.read_u32();
// Parse PC Begin using the encoding scheme mentioned in the CIE
let pc_begin = read_encoded_pointer_with_pc(&mut reader, self.fde_pointer_encoding)?;
callback(pc_begin as u32, fde_virt_addr);
reader = next_fde_reader;
}
Ok(())
}
}
pub struct EH_Frame_Hdr<'a> {
fde_writer: DwarfWriter<'a>,
eh_frame_hdr_addr: u32,
fdes: Vec<(u32, u32)>,
}
impl<'a> EH_Frame_Hdr<'a> {
// Create a EH_Frame_Hdr object, and write out the fixed fields of .eh_frame_hdr to memory
// eh_frame_ptr_enc will be 0x1B (PC-relative, 4 bytes)
// table_enc will be 0x3B (Relative to the start of .eh_frame_hdr, 4 bytes)
// Load address is not known at this point.
pub fn new(
eh_frame_hdr_slice: &mut [u8],
eh_frame_hdr_addr: u32,
eh_frame_addr: u32,
) -> EH_Frame_Hdr {
let mut writer = DwarfWriter::new(eh_frame_hdr_slice);
writer.write_u8(1);
writer.write_u8(0x1B);
writer.write_u8(0x03);
writer.write_u8(0x3B);
let eh_frame_offset =
(eh_frame_addr).wrapping_sub(eh_frame_hdr_addr + ((mem::size_of::<u8>() as u32) * 4));
writer.write_u32(eh_frame_offset);
writer.write_u32(0);
EH_Frame_Hdr { fde_writer: writer, eh_frame_hdr_addr, fdes: Vec::new() }
}
fn fde_count_offset() -> usize {
8
}
pub fn add_fde(&mut self, init_loc: u32, addr: u32) {
self.fdes.push((
init_loc.wrapping_sub(self.eh_frame_hdr_addr),
addr.wrapping_sub(self.eh_frame_hdr_addr),
));
}
pub fn finalize_fde(mut self) {
self.fdes
.sort_by(|(left_init_loc, _), (right_init_loc, _)| left_init_loc.cmp(right_init_loc));
for (init_loc, addr) in &self.fdes {
self.fde_writer.write_u32(*init_loc);
self.fde_writer.write_u32(*addr);
}
LittleEndian::write_u32(&mut self.fde_writer.slice[Self::fde_count_offset()..], self.fdes.len() as u32);
}
pub fn size_from_eh_frame(eh_frame: &[u8]) -> usize {
// The virtual address of the EH frame does not matter in this case
// Calculation of size does not involve modifying any headers
let mut reader = DwarfReader::new(eh_frame, 0);
let mut fde_count = 0;
while !reader.slice.is_empty() {
// The original length field should be able to hold the entire value.
// The device memory space is limited to 32-bits addresses anyway.
let entry_length = reader.read_u32();
if entry_length == 0 || entry_length == 0xFFFFFFFF {
unimplemented!()
}
if reader.read_u32() != 0 {
fde_count += 1;
}
reader.offset(entry_length as i32 - mem::size_of::<u32>() as i32)
}
12 + fde_count * 8
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,17 +8,17 @@ license = "MIT"
edition = "2018" edition = "2018"
[build-dependencies] [build-dependencies]
lalrpop = "0.19" lalrpop = "0.19.6"
[dependencies] [dependencies]
nac3ast = { path = "../nac3ast" } nac3ast = { path = "../nac3ast" }
lalrpop-util = "0.19" lalrpop-util = "0.19.6"
log = "0.4" log = "0.4.1"
unic-emoji-char = "0.9" unic-emoji-char = "0.9"
unic-ucd-ident = "0.9" unic-ucd-ident = "0.9"
unicode_names2 = "0.5" unicode_names2 = "0.4"
phf = { version = "0.11", features = ["macros"] } phf = { version = "0.9", features = ["macros"] }
ahash = "0.7" ahash = "0.7.2"
[dev-dependencies] [dev-dependencies]
insta = "=1.11.0" insta = "=1.11.0"

View File

@ -5,11 +5,11 @@ authors = ["M-Labs"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
parking_lot = "0.12" parking_lot = "0.11.1"
nac3parser = { path = "../nac3parser" } nac3parser = { path = "../nac3parser" }
nac3core = { path = "../nac3core" } nac3core = { path = "../nac3core" }
[dependencies.inkwell] [dependencies.inkwell]
git = "https://github.com/TheDan64/inkwell.git" version = "0.1.0-beta.4"
default-features = false default-features = false
features = ["llvm14-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] features = ["llvm13-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"]

View File

@ -1,32 +0,0 @@
from __future__ import annotations
@extern
def output_int32(x: int32):
...
class A:
a: int32
def __init__(self, a: int32):
self.a = a
def f1(self):
self.f2()
def f2(self):
output_int32(self.a)
class B(A):
b: int32
def __init__(self, b: int32):
self.a = b + 1
self.b = b
def run() -> int32:
aaa = A(5)
bbb = B(2)
aaa.f1()
bbb.f1()
return 0

View File

@ -0,0 +1,13 @@
@extern
def output_int32(x: int32):
...
class A:
def foo(self):
output_int32(1)
def run() -> int32:
inst = A()
inst.foo()
output_int32(1)
return 0

View File

@ -1,257 +0,0 @@
from __future__ import annotations
@extern
def output_int32(x: int32):
...
@extern
def output_uint32(x: uint32):
...
@extern
def output_int64(x: int64):
...
@extern
def output_uint64(x: uint64):
...
@extern
def output_float64(x: float):
...
def run() -> int32:
test_int32()
test_uint32()
test_int64()
test_uint64()
test_A()
test_B()
return 0
def test_int32():
a = 17
b = 3
output_int32(a + b)
output_int32(a - b)
output_int32(a * b)
output_int32(a // b)
output_int32(a % b)
output_int32(a | b)
output_int32(a ^ b)
output_int32(a & b)
output_int32(a << b)
output_int32(a >> b)
output_float64(a / b)
a += b
output_int32(a)
a -= b
output_int32(a)
a *= b
output_int32(a)
a //= b
output_int32(a)
a %= b
output_int32(a)
a |= b
output_int32(a)
a ^= b
output_int32(a)
a &= b
output_int32(a)
a <<= b
output_int32(a)
a >>= b
output_int32(a)
# fail because (a / b) is float
# a /= b
def test_uint32():
a = uint32(17)
b = uint32(3)
output_uint32(a + b)
output_uint32(a - b)
output_uint32(a * b)
output_uint32(a // b)
output_uint32(a % b)
output_uint32(a | b)
output_uint32(a ^ b)
output_uint32(a & b)
output_uint32(a << b)
output_uint32(a >> b)
output_float64(a / b)
a += b
output_uint32(a)
a -= b
output_uint32(a)
a *= b
output_uint32(a)
a //= b
output_uint32(a)
a %= b
output_uint32(a)
a |= b
output_uint32(a)
a ^= b
output_uint32(a)
a &= b
output_uint32(a)
a <<= b
output_uint32(a)
a >>= b
output_uint32(a)
def test_int64():
a = int64(17)
b = int64(3)
output_int64(a + b)
output_int64(a - b)
output_int64(a * b)
output_int64(a // b)
output_int64(a % b)
output_int64(a | b)
output_int64(a ^ b)
output_int64(a & b)
output_int64(a << b)
output_int64(a >> b)
output_float64(a / b)
a += b
output_int64(a)
a -= b
output_int64(a)
a *= b
output_int64(a)
a //= b
output_int64(a)
a %= b
output_int64(a)
a |= b
output_int64(a)
a ^= b
output_int64(a)
a &= b
output_int64(a)
a <<= b
output_int64(a)
a >>= b
output_int64(a)
def test_uint64():
a = uint64(17)
b = uint64(3)
output_uint64(a + b)
output_uint64(a - b)
output_uint64(a * b)
output_uint64(a // b)
output_uint64(a % b)
output_uint64(a | b)
output_uint64(a ^ b)
output_uint64(a & b)
output_uint64(a << b)
output_uint64(a >> b)
output_float64(a / b)
a += b
output_uint64(a)
a -= b
output_uint64(a)
a *= b
output_uint64(a)
a //= b
output_uint64(a)
a %= b
output_uint64(a)
a |= b
output_uint64(a)
a ^= b
output_uint64(a)
a &= b
output_uint64(a)
a <<= b
output_uint64(a)
a >>= b
output_uint64(a)
class A:
a: int32
def __init__(self, a: int32):
self.a = a
def __add__(self, other: A) -> A:
output_int32(self.a + other.a)
return A(self.a + other.a)
def __sub__(self, other: A) -> A:
output_int32(self.a - other.a)
return A(self.a - other.a)
def test_A():
a = A(17)
b = A(3)
c = a + b
# fail due to alloca in __add__ function
# output_int32(c.a)
a += b
# fail due to alloca in __add__ function
# output_int32(a.a)
a = A(17)
b = A(3)
d = a - b
# fail due to alloca in __add__ function
# output_int32(c.a)
a -= b
# fail due to alloca in __add__ function
# output_int32(a.a)
a = A(17)
b = A(3)
a.__add__(b)
a.__sub__(b)
class B:
a: int32
def __init__(self, a: int32):
self.a = a
def __add__(self, other: B) -> B:
output_int32(self.a + other.a)
return B(self.a + other.a)
def __sub__(self, other: B) -> B:
output_int32(self.a - other.a)
return B(self.a - other.a)
def __iadd__(self, other: B) -> B:
output_int32(self.a + other.a + 24)
return B(self.a + other.a + 24)
def __isub__(self, other: B) -> B:
output_int32(self.a - other.a - 24)
return B(self.a - other.a - 24)
def test_B():
a = B(17)
b = B(3)
c = a + b
# fail due to alloca in __add__ function
# output_int32(c.a)
a += b
# fail due to alloca in __add__ function
# output_int32(a.a)
a = B(17)
b = B(3)
d = a - b
# fail due to alloca in __add__ function
# output_int32(c.a)
a -= b
# fail due to alloca in __add__ function
# output_int32(a.a)
a = B(17)
b = B(3)
a.__add__(b)
a.__sub__(b)

View File

@ -1,36 +0,0 @@
from __future__ import annotations
@extern
def output_int32(a: int32):
...
class A:
d: int32
a: list[B]
def __init__(self, b: list[B]):
self.d = 123
self.a = b
def f(self):
output_int32(self.d)
class B:
a: A
def __init__(self, a: A):
self.a = a
def ff(self):
self.a.f()
class Demo:
a: A
def __init__(self, a: A):
self.a = a
def run() -> int32:
aa = A([])
bb = B(aa)
aa.a = [bb]
d = Demo(aa)
d.a.a[0].ff()
return 0

View File

@ -34,9 +34,5 @@ def run() -> int32:
insta = A() insta = A()
inst = C(insta) inst = C(insta)
inst.foo() inst.foo()
insta2 = B()
inst2 = C(insta2)
inst2.foo()
return 0 return 0

View File

@ -30,130 +30,6 @@ use nac3parser::{
mod basic_symbol_resolver; mod basic_symbol_resolver;
use basic_symbol_resolver::*; use basic_symbol_resolver::*;
fn handle_typevar_definition(
var: &Expr,
resolver: &(dyn SymbolResolver + Send + Sync),
def_list: &[Arc<RwLock<TopLevelDef>>],
unifier: &mut Unifier,
primitives: &PrimitiveStore,
) -> Result<Type, String> {
if let ExprKind::Call { func, args, .. } = &var.node {
if matches!(&func.node, ExprKind::Name { id, .. } if id == &"TypeVar".into()) {
let constraints = args
.iter()
.skip(1)
.map(|x| -> Result<Type, String> {
let ty = parse_ast_to_type_annotation_kinds(
resolver,
def_list,
unifier,
primitives,
x,
Default::default(),
)?;
get_type_from_type_annotation_kinds(
def_list, unifier, primitives, &ty, &mut None
)
})
.collect::<Result<Vec<_>, _>>()?;
Ok(unifier.get_fresh_var_with_range(&constraints, None, None).0)
} else {
Err(format!(
"expression {:?} cannot be handled as a TypeVar in global scope",
var
))
}
} else {
Err(format!(
"expression {:?} cannot be handled as a TypeVar in global scope",
var
))
}
}
fn handle_assignment_pattern(
targets: &[Expr],
value: &Expr,
resolver: &(dyn SymbolResolver + Send + Sync),
internal_resolver: &ResolverInternal,
def_list: &[Arc<RwLock<TopLevelDef>>],
unifier: &mut Unifier,
primitives: &PrimitiveStore,
) -> Result<(), String> {
if targets.len() == 1 {
match &targets[0].node {
ExprKind::Name { id, .. } => {
if let Ok(var) = handle_typevar_definition(
value.borrow(),
resolver,
def_list,
unifier,
primitives,
) {
internal_resolver.add_id_type(*id, var);
Ok(())
} else if let Ok(val) =
parse_parameter_default_value(value.borrow(), resolver)
{
internal_resolver.add_module_global(*id, val);
Ok(())
} else {
Err(format!("fails to evaluate this expression `{:?}` as a constant or TypeVar at {}",
targets[0].node,
targets[0].location,
))
}
}
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => {
handle_assignment_pattern(
elts,
value,
resolver,
internal_resolver,
def_list,
unifier,
primitives,
)?;
Ok(())
}
_ => Err(format!(
"assignment to {:?} is not supported at {}",
targets[0], targets[0].location
)),
}
} else {
match &value.node {
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => {
if elts.len() != targets.len() {
Err(format!(
"number of elements to unpack does not match (expect {}, found {}) at {}",
targets.len(),
elts.len(),
value.location
))
} else {
for (tar, val) in targets.iter().zip(elts) {
handle_assignment_pattern(
std::slice::from_ref(tar),
val,
resolver,
internal_resolver,
def_list,
unifier,
primitives,
)?;
}
Ok(())
}
}
_ => Err(format!(
"unpack of this expression is not supported at {}",
value.location
)),
}
}
}
fn main() { fn main() {
let file_name = env::args().nth(1).unwrap(); let file_name = env::args().nth(1).unwrap();
let threads: u32 = env::args().nth(2).map(|s| str::parse(&s).unwrap()).unwrap_or(1); let threads: u32 = env::args().nth(2).map(|s| str::parse(&s).unwrap()).unwrap_or(1);
@ -178,42 +54,163 @@ fn main() {
class_names: Default::default(), class_names: Default::default(),
module_globals: Default::default(), module_globals: Default::default(),
str_store: Default::default(), str_store: Default::default(),
}.into(); }
.into();
let resolver = let resolver =
Arc::new(Resolver(internal_resolver.clone())) as Arc<dyn SymbolResolver + Send + Sync>; Arc::new(Resolver(internal_resolver.clone())) as Arc<dyn SymbolResolver + Send + Sync>;
let parser_result = parser::parse_program(&program, file_name.into()).unwrap(); let parser_result = parser::parse_program(&program, file_name.into()).unwrap();
for stmt in parser_result.into_iter() { for stmt in parser_result.into_iter() {
match &stmt.node { if let StmtKind::Assign { targets, value, .. } = &stmt.node {
StmtKind::Assign { targets, value, .. } => { fn handle_typevar_definition(
let def_list = composer.extract_def_list(); var: &Expr,
let unifier = &mut composer.unifier; resolver: &(dyn SymbolResolver + Send + Sync),
let primitives = &composer.primitives_ty; def_list: &[Arc<RwLock<TopLevelDef>>],
if let Err(err) = handle_assignment_pattern( unifier: &mut Unifier,
targets, primitives: &PrimitiveStore,
value, ) -> Result<Type, String> {
resolver.as_ref(), if let ExprKind::Call { func, args, .. } = &var.node {
internal_resolver.as_ref(), if matches!(&func.node, ExprKind::Name { id, .. } if id == &"TypeVar".into()) {
&def_list, let constraints = args
unifier, .iter()
primitives, .skip(1)
) { .map(|x| -> Result<Type, String> {
eprintln!("{}", err); let ty = parse_ast_to_type_annotation_kinds(
return; resolver,
} def_list,
}, unifier,
// allow (and ignore) "from __future__ import annotations" primitives,
StmtKind::ImportFrom { module, names, .. } x,
if module == &Some("__future__".into()) && names.len() == 1 && names[0].name == "annotations".into() => (), Default::default(),
_ => { )?;
let (name, def_id, ty) = get_type_from_type_annotation_kinds(
composer.register_top_level(stmt, Some(resolver.clone()), "__main__".into(), true).unwrap(); def_list, unifier, primitives, &ty, &mut None
internal_resolver.add_id_def(name, def_id); )
if let Some(ty) = ty { })
internal_resolver.add_id_type(name, ty); .collect::<Result<Vec<_>, _>>()?;
Ok(unifier.get_fresh_var_with_range(&constraints, None, None).0)
} else {
Err(format!(
"expression {:?} cannot be handled as a TypeVar in global scope",
var
))
}
} else {
Err(format!(
"expression {:?} cannot be handled as a TypeVar in global scope",
var
))
} }
} }
fn handle_assignment_pattern(
targets: &[Expr],
value: &Expr,
resolver: &(dyn SymbolResolver + Send + Sync),
internal_resolver: &ResolverInternal,
def_list: &[Arc<RwLock<TopLevelDef>>],
unifier: &mut Unifier,
primitives: &PrimitiveStore,
) -> Result<(), String> {
if targets.len() == 1 {
match &targets[0].node {
ExprKind::Name { id, .. } => {
if let Ok(var) = handle_typevar_definition(
value.borrow(),
resolver,
def_list,
unifier,
primitives,
) {
internal_resolver.add_id_type(*id, var);
Ok(())
} else if let Ok(val) =
parse_parameter_default_value(value.borrow(), resolver)
{
internal_resolver.add_module_global(*id, val);
Ok(())
} else {
Err(format!("fails to evaluate this expression `{:?}` as a constant or TypeVar at {}",
targets[0].node,
targets[0].location,
))
}
}
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => {
handle_assignment_pattern(
elts,
value,
resolver,
internal_resolver,
def_list,
unifier,
primitives,
)?;
Ok(())
}
_ => Err(format!(
"assignment to {:?} is not supported at {}",
targets[0], targets[0].location
)),
}
} else {
match &value.node {
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => {
if elts.len() != targets.len() {
Err(format!(
"number of elements to unpack does not match (expect {}, found {}) at {}",
targets.len(),
elts.len(),
value.location
))
} else {
for (tar, val) in targets.iter().zip(elts) {
handle_assignment_pattern(
std::slice::from_ref(tar),
val,
resolver,
internal_resolver,
def_list,
unifier,
primitives,
)?;
}
Ok(())
}
}
_ => Err(format!(
"unpack of this expression is not supported at {}",
value.location
)),
}
}
}
let def_list = composer.extract_def_list();
let unifier = &mut composer.unifier;
let primitives = &composer.primitives_ty;
if let Err(err) = handle_assignment_pattern(
targets,
value,
resolver.as_ref(),
internal_resolver.as_ref(),
&def_list,
unifier,
primitives,
) {
eprintln!("{}", err);
return;
}
continue;
}
let (name, def_id, ty) =
composer.register_top_level(stmt, Some(resolver.clone()), "__main__".into()).unwrap();
internal_resolver.add_id_def(name, def_id);
if let Some(ty) = ty {
internal_resolver.add_id_type(name, ty);
} }
} }

View File

@ -8,6 +8,7 @@
, ncurses , ncurses
, zlib , zlib
, which , which
, llvmPackages_13
, debugVersion ? false , debugVersion ? false
, enableManpages ? false , enableManpages ? false
, enableSharedLibraries ? false , enableSharedLibraries ? false
@ -17,7 +18,7 @@
let let
inherit (lib) optional optionals optionalString; inherit (lib) optional optionals optionalString;
release_version = "14.0.6"; release_version = "13.0.1";
candidate = ""; # empty or "rcN" candidate = ""; # empty or "rcN"
dash-candidate = lib.optionalString (candidate != "") "-${candidate}"; dash-candidate = lib.optionalString (candidate != "") "-${candidate}";
version = "${release_version}${dash-candidate}"; # differentiating these (variables) is important for RCs version = "${release_version}${dash-candidate}"; # differentiating these (variables) is important for RCs
@ -34,7 +35,7 @@ in stdenv.mkDerivation (rec {
pname = "llvm"; pname = "llvm";
inherit version; inherit version;
src = fetch pname "sha256-BQki7KrKV4H99mMeqSvHFRg/IC+dLxUUcibwI0FPYZo="; src = fetch pname "sha256-7GuA2Cw4SsrS3BkpA6bPLNuv+4ibhL+5janXHmMPyDQ=";
unpackPhase = '' unpackPhase = ''
unpackFile $src unpackFile $src
@ -49,12 +50,19 @@ in stdenv.mkDerivation (rec {
buildInputs = [ ]; buildInputs = [ ];
propagatedBuildInputs = [ ncurses zlib ]; propagatedBuildInputs = optionals (stdenv.buildPlatform == stdenv.hostPlatform) [ ncurses ]
++ [ zlib ];
checkInputs = [ which ]; checkInputs = [ which ];
patches = [ patches = [
./gnu-install-dirs.patch ./gnu-install-dirs.patch
# Fix random compiler crashes: https://bugs.llvm.org/show_bug.cgi?id=50611
(fetchpatch {
url = "https://raw.githubusercontent.com/archlinux/svntogit-packages/4764a4f8c920912a2bfd8b0eea57273acfe0d8a8/trunk/no-strict-aliasing-DwarfCompileUnit.patch";
sha256 = "18l6mrvm2vmwm77ckcnbjvh6ybvn72rhrb799d4qzwac4x2ifl7g";
stripLen = 1;
})
./llvm-future-riscv-abi.diff ./llvm-future-riscv-abi.diff
]; ];
@ -113,8 +121,6 @@ in stdenv.mkDerivation (rec {
"-DLLVM_DEFAULT_TARGET_TRIPLE=${stdenv.hostPlatform.config}" "-DLLVM_DEFAULT_TARGET_TRIPLE=${stdenv.hostPlatform.config}"
"-DLLVM_ENABLE_UNWIND_TABLES=OFF" "-DLLVM_ENABLE_UNWIND_TABLES=OFF"
"-DLLVM_ENABLE_THREADS=OFF" "-DLLVM_ENABLE_THREADS=OFF"
"-DLLVM_INCLUDE_BENCHMARKS=OFF"
"-DLLVM_BUILD_TOOLS=OFF"
"-DLLVM_TARGETS_TO_BUILD=X86;ARM;RISCV" "-DLLVM_TARGETS_TO_BUILD=X86;ARM;RISCV"
] ++ optionals enableSharedLibraries [ ] ++ optionals enableSharedLibraries [
"-DLLVM_LINK_LLVM_DYLIB=ON" "-DLLVM_LINK_LLVM_DYLIB=ON"
@ -131,6 +137,7 @@ in stdenv.mkDerivation (rec {
"-DCAN_TARGET_i386=false" "-DCAN_TARGET_i386=false"
] ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ ] ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
"-DCMAKE_CROSSCOMPILING=True" "-DCMAKE_CROSSCOMPILING=True"
"-DLLVM_TABLEGEN=${llvmPackages_13.tools.llvm}/bin/llvm-tblgen"
( (
let let
nativeCC = pkgsBuildBuild.targetPackages.stdenv.cc; nativeCC = pkgsBuildBuild.targetPackages.stdenv.cc;
@ -147,7 +154,6 @@ in stdenv.mkDerivation (rec {
] ++ extraCmakeFlags; ] ++ extraCmakeFlags;
postBuild = '' postBuild = ''
make llvm-config
rm -fR $out rm -fR $out
''; '';
@ -156,7 +162,6 @@ in stdenv.mkDerivation (rec {
''; '';
postInstall = '' postInstall = ''
cp bin/llvm-config $out/bin
mkdir -p $python/share mkdir -p $python/share
mv $out/share/opt-viewer $python/share/opt-viewer mv $out/share/opt-viewer $python/share/opt-viewer
moveToOutput "bin/llvm-config*" "$dev" moveToOutput "bin/llvm-config*" "$dev"

View File

@ -1,10 +1,23 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt
index fec956091cd5..5a766f5c5d7c 100644 index 135036f509d2..265c36f8211b 100644
--- a/CMakeLists.txt --- a/CMakeLists.txt
+++ b/CMakeLists.txt +++ b/CMakeLists.txt
@@ -303,6 +303,9 @@ set(LLVM_EXAMPLES_INSTALL_DIR "examples" CACHE STRING @@ -270,15 +270,21 @@ if (CMAKE_BUILD_TYPE AND
"Path for examples subdirectory (enabled by LLVM_BUILD_EXAMPLES=ON) (defaults to 'examples')") message(FATAL_ERROR "Invalid value for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
mark_as_advanced(LLVM_EXAMPLES_INSTALL_DIR) endif()
+include(GNUInstallDirs)
+
set(LLVM_LIBDIR_SUFFIX "" CACHE STRING "Define suffix of library directory name (32/64)" )
-set(LLVM_TOOLS_INSTALL_DIR "bin" CACHE STRING "Path for binary subdirectory (defaults to 'bin')")
+set(LLVM_TOOLS_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}" CACHE STRING
+ "Path for binary subdirectory (defaults to 'bin')")
mark_as_advanced(LLVM_TOOLS_INSTALL_DIR)
set(LLVM_UTILS_INSTALL_DIR "${LLVM_TOOLS_INSTALL_DIR}" CACHE STRING
"Path to install LLVM utilities (enabled by LLVM_INSTALL_UTILS=ON) (defaults to LLVM_TOOLS_INSTALL_DIR)")
mark_as_advanced(LLVM_UTILS_INSTALL_DIR)
+set(LLVM_INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/cmake/llvm" CACHE STRING +set(LLVM_INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/cmake/llvm" CACHE STRING
+ "Path for CMake subdirectory (defaults to lib/cmake/llvm)" ) + "Path for CMake subdirectory (defaults to lib/cmake/llvm)" )
@ -12,22 +25,70 @@ index fec956091cd5..5a766f5c5d7c 100644
# They are used as destination of target generators. # They are used as destination of target generators.
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})
@@ -581,9 +587,9 @@ option (LLVM_ENABLE_SPHINX "Use Sphinx to generate llvm documentation." OFF)
option (LLVM_ENABLE_OCAMLDOC "Build OCaml bindings documentation." ON)
option (LLVM_ENABLE_BINDINGS "Build bindings." ON)
-set(LLVM_INSTALL_DOXYGEN_HTML_DIR "share/doc/llvm/doxygen-html"
+set(LLVM_INSTALL_DOXYGEN_HTML_DIR "${CMAKE_INSTALL_DOCDIR}/${project}/doxygen-html"
CACHE STRING "Doxygen-generated HTML documentation install directory")
-set(LLVM_INSTALL_OCAMLDOC_HTML_DIR "share/doc/llvm/ocaml-html"
+set(LLVM_INSTALL_OCAMLDOC_HTML_DIR "${CMAKE_INSTALL_DOCDIR}/${project}/ocaml-html"
CACHE STRING "OCamldoc-generated HTML documentation install directory")
option (LLVM_BUILD_EXTERNAL_COMPILER_RT
@@ -1048,7 +1054,7 @@ endif()
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
install(DIRECTORY include/llvm include/llvm-c
- DESTINATION include
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT llvm-headers
FILES_MATCHING
PATTERN "*.def"
@@ -1059,7 +1065,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
)
install(DIRECTORY ${LLVM_INCLUDE_DIR}/llvm ${LLVM_INCLUDE_DIR}/llvm-c
- DESTINATION include
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT llvm-headers
FILES_MATCHING
PATTERN "*.def"
@@ -1073,13 +1079,13 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
if (LLVM_INSTALL_MODULEMAPS)
install(DIRECTORY include/llvm include/llvm-c
- DESTINATION include
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT llvm-headers
FILES_MATCHING
PATTERN "module.modulemap"
)
install(FILES include/llvm/module.install.modulemap
- DESTINATION include/llvm
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/llvm
COMPONENT llvm-headers
RENAME "module.extern.modulemap"
)
diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake
index fed1fec7d72e..4baed19b9e98 100644 index 9c2b85374307..5531ceeb2eeb 100644
--- a/cmake/modules/AddLLVM.cmake --- a/cmake/modules/AddLLVM.cmake
+++ b/cmake/modules/AddLLVM.cmake +++ b/cmake/modules/AddLLVM.cmake
@@ -838,8 +838,8 @@ macro(add_llvm_library name) @@ -818,9 +818,9 @@ macro(add_llvm_library name)
get_target_export_arg(${name} LLVM export_to_llvmexports ${umbrella}) get_target_export_arg(${name} LLVM export_to_llvmexports ${umbrella})
install(TARGETS ${name} install(TARGETS ${name}
${export_to_llvmexports} ${export_to_llvmexports}
- LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name} - LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name}
- ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name} - ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name}
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" COMPONENT ${name} - RUNTIME DESTINATION bin COMPONENT ${name})
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" COMPONENT ${name} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX} COMPONENT ${name}
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT ${name}) + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX} COMPONENT ${name}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${name})
if (NOT LLVM_ENABLE_IDE) if (NOT LLVM_ENABLE_IDE)
@@ -1056,7 +1056,7 @@ function(process_llvm_pass_plugins) add_llvm_install_targets(install-${name}
@@ -1036,7 +1036,7 @@ function(process_llvm_pass_plugins)
"set(LLVM_STATIC_EXTENSIONS ${LLVM_STATIC_EXTENSIONS})") "set(LLVM_STATIC_EXTENSIONS ${LLVM_STATIC_EXTENSIONS})")
install(FILES install(FILES
${llvm_cmake_builddir}/LLVMConfigExtensions.cmake ${llvm_cmake_builddir}/LLVMConfigExtensions.cmake
@ -36,7 +97,16 @@ index fed1fec7d72e..4baed19b9e98 100644
COMPONENT cmake-exports) COMPONENT cmake-exports)
set(ExtensionDef "${LLVM_BINARY_DIR}/include/llvm/Support/Extension.def") set(ExtensionDef "${LLVM_BINARY_DIR}/include/llvm/Support/Extension.def")
@@ -1902,7 +1902,7 @@ function(llvm_install_library_symlink name dest type) @@ -1250,7 +1250,7 @@ macro(add_llvm_example name)
endif()
add_llvm_executable(${name} ${ARGN})
if( LLVM_BUILD_EXAMPLES )
- install(TARGETS ${name} RUNTIME DESTINATION examples)
+ install(TARGETS ${name} RUNTIME DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples)
endif()
set_target_properties(${name} PROPERTIES FOLDER "Examples")
endmacro(add_llvm_example name)
@@ -1868,7 +1868,7 @@ function(llvm_install_library_symlink name dest type)
set(full_name ${CMAKE_${type}_LIBRARY_PREFIX}${name}${CMAKE_${type}_LIBRARY_SUFFIX}) set(full_name ${CMAKE_${type}_LIBRARY_PREFIX}${name}${CMAKE_${type}_LIBRARY_SUFFIX})
set(full_dest ${CMAKE_${type}_LIBRARY_PREFIX}${dest}${CMAKE_${type}_LIBRARY_SUFFIX}) set(full_dest ${CMAKE_${type}_LIBRARY_PREFIX}${dest}${CMAKE_${type}_LIBRARY_SUFFIX})
@ -45,7 +115,7 @@ index fed1fec7d72e..4baed19b9e98 100644
if(WIN32 AND "${type}" STREQUAL "SHARED") if(WIN32 AND "${type}" STREQUAL "SHARED")
set(output_dir bin) set(output_dir bin)
endif() endif()
@@ -1913,7 +1913,7 @@ function(llvm_install_library_symlink name dest type) @@ -1879,7 +1879,7 @@ function(llvm_install_library_symlink name dest type)
endfunction() endfunction()
@ -54,7 +124,7 @@ index fed1fec7d72e..4baed19b9e98 100644
cmake_parse_arguments(ARG "ALWAYS_GENERATE" "COMPONENT" "" ${ARGN}) cmake_parse_arguments(ARG "ALWAYS_GENERATE" "COMPONENT" "" ${ARGN})
foreach(path ${CMAKE_MODULE_PATH}) foreach(path ${CMAKE_MODULE_PATH})
if(EXISTS ${path}/LLVMInstallSymlink.cmake) if(EXISTS ${path}/LLVMInstallSymlink.cmake)
@@ -1936,7 +1936,7 @@ function(llvm_install_symlink name dest) @@ -1902,7 +1902,7 @@ function(llvm_install_symlink name dest)
set(full_dest ${dest}${CMAKE_EXECUTABLE_SUFFIX}) set(full_dest ${dest}${CMAKE_EXECUTABLE_SUFFIX})
install(SCRIPT ${INSTALL_SYMLINK} install(SCRIPT ${INSTALL_SYMLINK}
@ -63,7 +133,7 @@ index fed1fec7d72e..4baed19b9e98 100644
COMPONENT ${component}) COMPONENT ${component})
if (NOT LLVM_ENABLE_IDE AND NOT ARG_ALWAYS_GENERATE) if (NOT LLVM_ENABLE_IDE AND NOT ARG_ALWAYS_GENERATE)
@@ -2019,7 +2019,8 @@ function(add_llvm_tool_symlink link_name target) @@ -1985,7 +1985,8 @@ function(add_llvm_tool_symlink link_name target)
endif() endif()
if ((TOOL_IS_TOOLCHAIN OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) AND LLVM_BUILD_TOOLS) if ((TOOL_IS_TOOLCHAIN OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) AND LLVM_BUILD_TOOLS)
@ -73,7 +143,7 @@ index fed1fec7d72e..4baed19b9e98 100644
endif() endif()
endif() endif()
endfunction() endfunction()
@@ -2148,9 +2149,9 @@ function(llvm_setup_rpath name) @@ -2114,9 +2115,9 @@ function(llvm_setup_rpath name)
# Since BUILD_SHARED_LIBS is only recommended for use by developers, # Since BUILD_SHARED_LIBS is only recommended for use by developers,
# hardcode the rpath to build/install lib dir first in this mode. # hardcode the rpath to build/install lib dir first in this mode.
# FIXME: update this when there is better solution. # FIXME: update this when there is better solution.
@ -86,10 +156,10 @@ index fed1fec7d72e..4baed19b9e98 100644
set_property(TARGET ${name} APPEND_STRING PROPERTY set_property(TARGET ${name} APPEND_STRING PROPERTY
LINK_FLAGS " -Wl,-z,origin ") LINK_FLAGS " -Wl,-z,origin ")
diff --git a/cmake/modules/AddOCaml.cmake b/cmake/modules/AddOCaml.cmake diff --git a/cmake/modules/AddOCaml.cmake b/cmake/modules/AddOCaml.cmake
index 891c9e6d618c..8d963f3b0069 100644 index 554046b20edf..4d1ad980641e 100644
--- a/cmake/modules/AddOCaml.cmake --- a/cmake/modules/AddOCaml.cmake
+++ b/cmake/modules/AddOCaml.cmake +++ b/cmake/modules/AddOCaml.cmake
@@ -147,9 +147,9 @@ function(add_ocaml_library name) @@ -144,9 +144,9 @@ function(add_ocaml_library name)
endforeach() endforeach()
if( APPLE ) if( APPLE )
@ -101,55 +171,86 @@ index 891c9e6d618c..8d963f3b0069 100644
endif() endif()
list(APPEND ocaml_flags "-ldopt" "-Wl,-rpath,${ocaml_rpath}") list(APPEND ocaml_flags "-ldopt" "-Wl,-rpath,${ocaml_rpath}")
diff --git a/cmake/modules/AddSphinxTarget.cmake b/cmake/modules/AddSphinxTarget.cmake
index e80c3b5c1cac..482f6d715ef5 100644
--- a/cmake/modules/AddSphinxTarget.cmake
+++ b/cmake/modules/AddSphinxTarget.cmake
@@ -90,7 +90,7 @@ function (add_sphinx_target builder project)
endif()
elseif (builder STREQUAL html)
string(TOUPPER "${project}" project_upper)
- set(${project_upper}_INSTALL_SPHINX_HTML_DIR "share/doc/${project}/html"
+ set(${project_upper}_INSTALL_SPHINX_HTML_DIR "${CMAKE_INSTALL_DOCDIR}/${project}/html"
CACHE STRING "HTML documentation install directory for ${project}")
# '/.' indicates: copy the contents of the directory directly into
diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt
index cea0c1df0a14..eedcd9450312 100644 index 51b6a4fdc284..4adc2acfc074 100644
--- a/cmake/modules/CMakeLists.txt --- a/cmake/modules/CMakeLists.txt
+++ b/cmake/modules/CMakeLists.txt +++ b/cmake/modules/CMakeLists.txt
@@ -2,7 +2,7 @@ include(ExtendPath) @@ -1,6 +1,6 @@
include(LLVMDistributionSupport) include(LLVMDistributionSupport)
include(FindPrefixFromConfig)
-set(LLVM_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm) -set(LLVM_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm)
+set(LLVM_INSTALL_PACKAGE_DIR ${LLVM_INSTALL_CMAKE_DIR} CACHE STRING "Path for CMake subdirectory (defaults to 'cmake/llvm')") +set(LLVM_INSTALL_PACKAGE_DIR ${LLVM_INSTALL_CMAKE_DIR} CACHE STRING "Path for CMake subdirectory (defaults to 'cmake/llvm')")
set(llvm_cmake_builddir "${LLVM_BINARY_DIR}/${LLVM_INSTALL_PACKAGE_DIR}") set(llvm_cmake_builddir "${LLVM_BINARY_DIR}/${LLVM_INSTALL_PACKAGE_DIR}")
# First for users who use an installed LLVM, create the LLVMExports.cmake file. # First for users who use an installed LLVM, create the LLVMExports.cmake file.
@@ -122,7 +122,7 @@ set(LLVM_CONFIG_INCLUDE_DIRS @@ -109,13 +109,13 @@ foreach(p ${_count})
) set(LLVM_CONFIG_CODE "${LLVM_CONFIG_CODE}
list(REMOVE_DUPLICATES LLVM_CONFIG_INCLUDE_DIRS) get_filename_component(LLVM_INSTALL_PREFIX \"\${LLVM_INSTALL_PREFIX}\" PATH)")
endforeach(p)
-set(LLVM_CONFIG_INCLUDE_DIRS "\${LLVM_INSTALL_PREFIX}/include")
+set(LLVM_CONFIG_INCLUDE_DIRS "\${LLVM_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}")
set(LLVM_CONFIG_INCLUDE_DIR "${LLVM_CONFIG_INCLUDE_DIRS}")
set(LLVM_CONFIG_MAIN_INCLUDE_DIR "${LLVM_CONFIG_INCLUDE_DIRS}")
-set(LLVM_CONFIG_LIBRARY_DIRS "\${LLVM_INSTALL_PREFIX}/lib\${LLVM_LIBDIR_SUFFIX}")
+set(LLVM_CONFIG_LIBRARY_DIRS "\${LLVM_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}\${LLVM_LIBDIR_SUFFIX}")
set(LLVM_CONFIG_CMAKE_DIR "\${LLVM_INSTALL_PREFIX}/${LLVM_INSTALL_PACKAGE_DIR}")
set(LLVM_CONFIG_BINARY_DIR "\${LLVM_INSTALL_PREFIX}")
-set(LLVM_CONFIG_TOOLS_BINARY_DIR "\${LLVM_INSTALL_PREFIX}/bin")
+set(LLVM_CONFIG_TOOLS_BINARY_DIR "\${LLVM_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}")
-extend_path(LLVM_CONFIG_LIBRARY_DIR "\${LLVM_INSTALL_PREFIX}" "lib\${LLVM_LIBDIR_SUFFIX}") # Generate a default location for lit
+extend_path(LLVM_CONFIG_LIBRARY_DIR "\${LLVM_INSTALL_PREFIX}" "${CMAKE_INSTALL_LIBDIR}\${LLVM_LIBDIR_SUFFIX}") if (LLVM_INSTALL_UTILS AND LLVM_BUILD_UTILS)
set(LLVM_CONFIG_LIBRARY_DIRS
"${LLVM_CONFIG_LIBRARY_DIR}"
# FIXME: Should there be other entries here?
diff --git a/cmake/modules/LLVMInstallSymlink.cmake b/cmake/modules/LLVMInstallSymlink.cmake diff --git a/cmake/modules/LLVMInstallSymlink.cmake b/cmake/modules/LLVMInstallSymlink.cmake
index b5c35f706cb7..9261ab797de6 100644 index 3e6a2c9a2648..52e14d955c60 100644
--- a/cmake/modules/LLVMInstallSymlink.cmake --- a/cmake/modules/LLVMInstallSymlink.cmake
+++ b/cmake/modules/LLVMInstallSymlink.cmake +++ b/cmake/modules/LLVMInstallSymlink.cmake
@@ -6,7 +6,7 @@ include(GNUInstallDirs) @@ -4,7 +4,7 @@
function(install_symlink name target outdir) function(install_symlink name target outdir)
set(DESTDIR $ENV{DESTDIR}) set(DESTDIR $ENV{DESTDIR})
- set(bindir "${DESTDIR}${CMAKE_INSTALL_PREFIX}/${outdir}") - set(bindir "${DESTDIR}${CMAKE_INSTALL_PREFIX}/${outdir}/")
+ set(bindir "${DESTDIR}${outdir}/") + set(bindir "${DESTDIR}${outdir}/")
message(STATUS "Creating ${name}") message(STATUS "Creating ${name}")
diff --git a/docs/CMake.rst b/docs/CMake.rst diff --git a/docs/CMake.rst b/docs/CMake.rst
index 044ec8a4d39d..504d0eac3ade 100644 index f1ac2c7d4934..c6e1469b5e13 100644
--- a/docs/CMake.rst --- a/docs/CMake.rst
+++ b/docs/CMake.rst +++ b/docs/CMake.rst
@@ -224,7 +224,7 @@ description is in `LLVM-related variables`_ below. @@ -202,7 +202,7 @@ CMake manual, or execute ``cmake --help-variable VARIABLE_NAME``.
**LLVM_LIBDIR_SUFFIX**:STRING **LLVM_LIBDIR_SUFFIX**:STRING
Extra suffix to append to the directory where libraries are to be Extra suffix to append to the directory where libraries are to be
installed. On a 64-bit architecture, one could use ``-DLLVM_LIBDIR_SUFFIX=64`` installed. On a 64-bit architecture, one could use ``-DLLVM_LIBDIR_SUFFIX=64``
- to install libraries to ``/usr/lib64``. - to install libraries to ``/usr/lib64``.
+ to install libraries to ``/usr/lib64``. See also ``CMAKE_INSTALL_LIBDIR``. + to install libraries to ``/usr/lib64``. See also ``CMAKE_INSTALL_LIBDIR``.
**LLVM_PARALLEL_{COMPILE,LINK}_JOBS**:STRING Rarely-used CMake variables
Building the llvm toolchain can use a lot of resources, particularly ---------------------------
@@ -910,9 +910,11 @@ the ``cmake`` command or by setting it directly in ``ccmake`` or ``cmake-gui``). @@ -551,8 +551,8 @@ LLVM-specific variables
**LLVM_INSTALL_DOXYGEN_HTML_DIR**:STRING
The path to install Doxygen-generated HTML documentation to. This path can
- either be absolute or relative to the CMAKE_INSTALL_PREFIX. Defaults to
- `share/doc/llvm/doxygen-html`.
+ either be absolute or relative to the ``CMAKE_INSTALL_PREFIX``. Defaults to
+ `${CMAKE_INSTALL_DOCDIR}/${project}/doxygen-html`.
**LLVM_LINK_LLVM_DYLIB**:BOOL
If enabled, tools will be linked with the libLLVM shared library. Defaults
@@ -792,9 +792,11 @@ the ``cmake`` command or by setting it directly in ``ccmake`` or ``cmake-gui``).
This file is available in two different locations. This file is available in two different locations.
@ -164,6 +265,18 @@ index 044ec8a4d39d..504d0eac3ade 100644
* ``<LLVM_BUILD_ROOT>/lib/cmake/llvm/LLVMConfig.cmake`` where * ``<LLVM_BUILD_ROOT>/lib/cmake/llvm/LLVMConfig.cmake`` where
``<LLVM_BUILD_ROOT>`` is the root of the LLVM build tree. **Note: this is only ``<LLVM_BUILD_ROOT>`` is the root of the LLVM build tree. **Note: this is only
diff --git a/examples/Bye/CMakeLists.txt b/examples/Bye/CMakeLists.txt
index bb96edb4b4bf..678c22fb43c8 100644
--- a/examples/Bye/CMakeLists.txt
+++ b/examples/Bye/CMakeLists.txt
@@ -14,6 +14,6 @@ if (NOT WIN32)
BUILDTREE_ONLY
)
- install(TARGETS ${name} RUNTIME DESTINATION examples)
+ install(TARGETS ${name} RUNTIME DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples)
set_target_properties(${name} PROPERTIES FOLDER "Examples")
endif()
diff --git a/include/llvm/CMakeLists.txt b/include/llvm/CMakeLists.txt diff --git a/include/llvm/CMakeLists.txt b/include/llvm/CMakeLists.txt
index b46319f24fc8..2feabd1954e4 100644 index b46319f24fc8..2feabd1954e4 100644
--- a/include/llvm/CMakeLists.txt --- a/include/llvm/CMakeLists.txt
@ -176,45 +289,93 @@ index b46319f24fc8..2feabd1954e4 100644
+ configure_file(module.modulemap.build ${LLVM_INCLUDE_DIR}/module.modulemap COPYONLY) + configure_file(module.modulemap.build ${LLVM_INCLUDE_DIR}/module.modulemap COPYONLY)
endif (NOT "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") endif (NOT "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
diff --git a/tools/llvm-config/BuildVariables.inc.in b/tools/llvm-config/BuildVariables.inc.in diff --git a/tools/llvm-config/BuildVariables.inc.in b/tools/llvm-config/BuildVariables.inc.in
index abbb8a450da6..70c497be12f5 100644 index ebe5b73a5c65..70c497be12f5 100644
--- a/tools/llvm-config/BuildVariables.inc.in --- a/tools/llvm-config/BuildVariables.inc.in
+++ b/tools/llvm-config/BuildVariables.inc.in +++ b/tools/llvm-config/BuildVariables.inc.in
@@ -23,7 +23,10 @@ @@ -23,6 +23,10 @@
#define LLVM_CXXFLAGS "@LLVM_CXXFLAGS@" #define LLVM_CXXFLAGS "@LLVM_CXXFLAGS@"
#define LLVM_BUILDMODE "@LLVM_BUILDMODE@" #define LLVM_BUILDMODE "@LLVM_BUILDMODE@"
#define LLVM_LIBDIR_SUFFIX "@LLVM_LIBDIR_SUFFIX@" #define LLVM_LIBDIR_SUFFIX "@LLVM_LIBDIR_SUFFIX@"
+#define LLVM_INSTALL_BINDIR "@CMAKE_INSTALL_BINDIR@" +#define LLVM_INSTALL_BINDIR "@CMAKE_INSTALL_BINDIR@"
+#define LLVM_INSTALL_LIBDIR "@CMAKE_INSTALL_LIBDIR@" +#define LLVM_INSTALL_LIBDIR "@CMAKE_INSTALL_LIBDIR@"
#define LLVM_INSTALL_INCLUDEDIR "@CMAKE_INSTALL_INCLUDEDIR@" +#define LLVM_INSTALL_INCLUDEDIR "@CMAKE_INSTALL_INCLUDEDIR@"
+#define LLVM_INSTALL_CMAKEDIR "@LLVM_INSTALL_CMAKE_DIR@" +#define LLVM_INSTALL_CMAKEDIR "@LLVM_INSTALL_CMAKE_DIR@"
#define LLVM_TARGETS_BUILT "@LLVM_TARGETS_BUILT@" #define LLVM_TARGETS_BUILT "@LLVM_TARGETS_BUILT@"
#define LLVM_SYSTEM_LIBS "@LLVM_SYSTEM_LIBS@" #define LLVM_SYSTEM_LIBS "@LLVM_SYSTEM_LIBS@"
#define LLVM_BUILD_SYSTEM "@LLVM_BUILD_SYSTEM@" #define LLVM_BUILD_SYSTEM "@LLVM_BUILD_SYSTEM@"
diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp
index 8ed88f33ead4..5e7184bab90d 100644 index 1a2f04552d13..44fa7d3eec6b 100644
--- a/tools/llvm-config/llvm-config.cpp --- a/tools/llvm-config/llvm-config.cpp
+++ b/tools/llvm-config/llvm-config.cpp +++ b/tools/llvm-config/llvm-config.cpp
@@ -363,12 +363,20 @@ int main(int argc, char **argv) { @@ -357,12 +357,26 @@ int main(int argc, char **argv) {
ActiveIncludeDir = std::string(Path.str()); ("-I" + ActiveIncludeDir + " " + "-I" + ActiveObjRoot + "/include");
} } else {
{ ActivePrefix = CurrentExecPrefix;
- SmallString<256> Path(LLVM_TOOLS_INSTALL_DIR); - ActiveIncludeDir = ActivePrefix + "/include";
+ SmallString<256> Path(LLVM_INSTALL_BINDIR); - SmallString<256> path(StringRef(LLVM_TOOLS_INSTALL_DIR));
sys::fs::make_absolute(ActivePrefix, Path); - sys::fs::make_absolute(ActivePrefix, path);
ActiveBinDir = std::string(Path.str()); - ActiveBinDir = std::string(path.str());
}
- ActiveLibDir = ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX; - ActiveLibDir = ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX;
- ActiveCMakeDir = ActiveLibDir + "/cmake/llvm"; - ActiveCMakeDir = ActiveLibDir + "/cmake/llvm";
+ { + {
+ SmallString<256> Path(LLVM_INSTALL_LIBDIR LLVM_LIBDIR_SUFFIX); + SmallString<256> path(StringRef(LLVM_INSTALL_INCLUDEDIR));
+ sys::fs::make_absolute(ActivePrefix, Path); + sys::fs::make_absolute(ActivePrefix, path);
+ ActiveLibDir = std::string(Path.str()); + ActiveIncludeDir = std::string(path.str());
+ } + }
+ { + {
+ SmallString<256> Path(LLVM_INSTALL_CMAKEDIR); + SmallString<256> path(StringRef(LLVM_INSTALL_BINDIR));
+ sys::fs::make_absolute(ActivePrefix, Path); + sys::fs::make_absolute(ActivePrefix, path);
+ ActiveCMakeDir = std::string(Path.str()); + ActiveBinDir = std::string(path.str());
+ }
+ {
+ SmallString<256> path(StringRef(LLVM_INSTALL_LIBDIR LLVM_LIBDIR_SUFFIX));
+ sys::fs::make_absolute(ActivePrefix, path);
+ ActiveLibDir = std::string(path.str());
+ }
+ {
+ SmallString<256> path(StringRef(LLVM_INSTALL_CMAKEDIR));
+ sys::fs::make_absolute(ActivePrefix, path);
+ ActiveCMakeDir = std::string(path.str());
+ } + }
ActiveIncludeOption = "-I" + ActiveIncludeDir; ActiveIncludeOption = "-I" + ActiveIncludeDir;
} }
diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt
index 0af29ad762c5..37b99b83e35c 100644
--- a/tools/lto/CMakeLists.txt
+++ b/tools/lto/CMakeLists.txt
@@ -33,7 +33,7 @@ add_llvm_library(${LTO_LIBRARY_NAME} ${LTO_LIBRARY_TYPE} INSTALL_WITH_TOOLCHAIN
${SOURCES} DEPENDS intrinsics_gen)
install(FILES ${LLVM_MAIN_INCLUDE_DIR}/llvm-c/lto.h
- DESTINATION include/llvm-c
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/llvm-c
COMPONENT LTO)
if (APPLE)
diff --git a/tools/opt-viewer/CMakeLists.txt b/tools/opt-viewer/CMakeLists.txt
index ead73ec13a8f..250362021f17 100644
--- a/tools/opt-viewer/CMakeLists.txt
+++ b/tools/opt-viewer/CMakeLists.txt
@@ -8,7 +8,7 @@ set (files
foreach (file ${files})
install(PROGRAMS ${file}
- DESTINATION share/opt-viewer
+ DESTINATION ${CMAKE_INSTALL_DATADIR}/opt-viewer
COMPONENT opt-viewer)
endforeach (file)
diff --git a/tools/remarks-shlib/CMakeLists.txt b/tools/remarks-shlib/CMakeLists.txt
index 865436247270..ce1daa62f6ab 100644
--- a/tools/remarks-shlib/CMakeLists.txt
+++ b/tools/remarks-shlib/CMakeLists.txt
@@ -19,7 +19,7 @@ if(LLVM_ENABLE_PIC)
endif()
install(FILES ${LLVM_MAIN_INCLUDE_DIR}/llvm-c/Remarks.h
- DESTINATION include/llvm-c
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/llvm-c
COMPONENT Remarks)
if (APPLE)

View File

@ -21,6 +21,6 @@ build() {
} }
package() { package() {
mkdir -p $pkgdir/mingw64/lib/python3.10/site-packages mkdir -p $pkgdir/mingw64/lib/python3.9/site-packages
cp ${srcdir}/nac3artiq.pyd $pkgdir/mingw64/lib/python3.10/site-packages cp ${srcdir}/nac3artiq.pyd $pkgdir/mingw64/lib/python3.9/site-packages
} }

View File

@ -21,10 +21,10 @@ let
text = text =
'' ''
implementation=CPython implementation=CPython
version=3.10 version=3.9
shared=true shared=true
abi3=false abi3=false
lib_name=python3.10 lib_name=python3.9
lib_dir=${msys2-env}/mingw64/lib lib_dir=${msys2-env}/mingw64/lib
pointer_width=64 pointer_width=64
build_flags=WITH_THREAD build_flags=WITH_THREAD
@ -34,14 +34,14 @@ let
in rec { in rec {
llvm-nac3 = pkgs.stdenvNoCC.mkDerivation rec { llvm-nac3 = pkgs.stdenvNoCC.mkDerivation rec {
pname = "llvm-nac3-msys2"; pname = "llvm-nac3-msys2";
version = "14.0.6"; version = "13.0.1";
src-llvm = pkgs.fetchurl { src-llvm = pkgs.fetchurl {
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/llvm-${version}.src.tar.xz"; url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/llvm-${version}.src.tar.xz";
sha256 = "sha256-BQki7KrKV4H99mMeqSvHFRg/IC+dLxUUcibwI0FPYZo="; sha256 = "sha256-7GuA2Cw4SsrS3BkpA6bPLNuv+4ibhL+5janXHmMPyDQ=";
}; };
src-clang = pkgs.fetchurl { src-clang = pkgs.fetchurl {
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/clang-${version}.src.tar.xz"; url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/clang-${version}.src.tar.xz";
sha256 = "sha256-K1hHtqYxGLnv5chVSDY8gf/glrZsOzZ16VPiY0KuQDE="; sha256 = "sha256-eHqeLZn1yHIKoXc+S+AJRhzTDTvUD90kWR5HNGfJF8k=";
}; };
buildInputs = [ pkgs.wineWowPackages.stable ]; buildInputs = [ pkgs.wineWowPackages.stable ];
phases = [ "unpackPhase" "patchPhase" "configurePhase" "buildPhase" "installPhase" ]; phases = [ "unpackPhase" "patchPhase" "configurePhase" "buildPhase" "installPhase" ];
@ -49,7 +49,6 @@ in rec {
'' ''
mkdir llvm mkdir llvm
tar xf ${src-llvm} -C llvm --strip-components=1 tar xf ${src-llvm} -C llvm --strip-components=1
mv llvm/Modules/* llvm/cmake/modules # work around https://github.com/llvm/llvm-project/issues/53281
mkdir clang mkdir clang
tar xf ${src-clang} -C clang --strip-components=1 tar xf ${src-clang} -C clang --strip-components=1
cd llvm cd llvm
@ -65,11 +64,11 @@ in rec {
${silenceFontconfig} ${silenceFontconfig}
mkdir build mkdir build
cd build cd build
wine64 cmake .. -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_UNWIND_TABLES=OFF -DLLVM_ENABLE_THREADS=OFF -DLLVM_TARGETS_TO_BUILD=X86\;ARM\;RISCV -DLLVM_LINK_LLVM_DYLIB=OFF -DLLVM_ENABLE_FFI=OFF -DFFI_INCLUDE_DIR=fck-cmake -DFFI_LIBRARY_DIR=fck-cmake -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_INSTALL_PREFIX=Z:$out wine64 cmake .. -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_UNWIND_TABLES=OFF -DLLVM_ENABLE_THREADS=OFF -DLLVM_TARGETS_TO_BUILD=X86\;ARM\;RISCV -DLLVM_LINK_LLVM_DYLIB=OFF -DLLVM_ENABLE_FFI=OFF -DFFI_INCLUDE_DIR=fck-cmake -DFFI_LIBRARY_DIR=fck-cmake -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_INSTALL_PREFIX=Z:$out
''; '';
buildPhase = buildPhase =
'' ''
wine64 ninja -j $NIX_BUILD_CORES wine64 ninja
''; '';
installPhase = installPhase =
'' ''
@ -80,12 +79,7 @@ in rec {
nac3artiq = pkgs.rustPlatform.buildRustPackage { nac3artiq = pkgs.rustPlatform.buildRustPackage {
name = "nac3artiq-msys2"; name = "nac3artiq-msys2";
src = ../../.; src = ../../.;
cargoLock = { cargoLock = { lockFile = ../../Cargo.lock; };
lockFile = ../../Cargo.lock;
outputHashes = {
"inkwell-0.1.0" = "sha256-+ih3SO0n6YmZ/mcf+rLDwPAy/1MEZ/A+tI4pM1pUhvU=";
};
};
nativeBuildInputs = [ pkgs.wineWowPackages.stable ]; nativeBuildInputs = [ pkgs.wineWowPackages.stable ];
buildPhase = buildPhase =
'' ''
@ -126,6 +120,38 @@ in rec {
echo file msys2 $out/*.pkg.tar.zst >> $out/nix-support/hydra-build-products echo file msys2 $out/*.pkg.tar.zst >> $out/nix-support/hydra-build-products
''; '';
}; };
lld = pkgs.stdenvNoCC.mkDerivation rec {
pname = "lld-msys2";
version = "13.0.1";
src = pkgs.fetchurl {
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/lld-${version}.src.tar.xz";
sha256 = "sha256-Zmr3Rei/e2gFM7TRi3ox3HyrV1sebk0mGSK7r9lkTPs=";
};
buildInputs = [ pkgs.wineWowPackages.stable ];
phases = [ "unpackPhase" "patchPhase" "configurePhase" "buildPhase" "installPhase" ];
patches = [ ./lld-disable-macho.diff ];
configurePhase =
''
export HOME=`mktemp -d`
export WINEDEBUG=-all
export WINEPATH=Z:${msys2-env}/mingw64/bin\;Z:${llvm-nac3}/bin
${silenceFontconfig}
mkdir build
cd build
wine64 cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=Z:$out
'';
buildPhase =
''
wine64 ninja
'';
installPhase =
''
mkdir -p $out $out/nix-support
cp bin/ld.lld.exe $out
echo file binary-dist $out/ld.lld.exe >> $out/nix-support/hydra-build-products
'';
dontFixup = true;
};
wine-msys2 = pkgs.writeShellScriptBin "wine-msys2" wine-msys2 = pkgs.writeShellScriptBin "wine-msys2"
'' ''
export WINEDEBUG=-all export WINEDEBUG=-all

View File

@ -0,0 +1,36 @@
diff '--color=auto' -Naur lld-13.0.1.src/CMakeLists.txt lld-13.0.1.src-new/CMakeLists.txt
--- lld-13.0.1.src/CMakeLists.txt 2022-01-21 05:31:59.000000000 +0800
+++ lld-13.0.1.src-new/CMakeLists.txt 2022-03-27 18:26:30.284921982 +0800
@@ -206,7 +206,6 @@
add_subdirectory(docs)
add_subdirectory(COFF)
add_subdirectory(ELF)
-add_subdirectory(MachO)
add_subdirectory(MinGW)
add_subdirectory(wasm)
diff '--color=auto' -Naur lld-13.0.1.src/tools/lld/CMakeLists.txt lld-13.0.1.src-new/tools/lld/CMakeLists.txt
--- lld-13.0.1.src/tools/lld/CMakeLists.txt 2022-01-21 05:31:59.000000000 +0800
+++ lld-13.0.1.src-new/tools/lld/CMakeLists.txt 2022-03-27 18:26:40.805046295 +0800
@@ -15,7 +15,6 @@
lldCOFF
lldDriver
lldELF
- lldMachO2
lldMinGW
lldWasm
)
diff '--color=auto' -Naur lld-13.0.1.src/tools/lld/lld.cpp lld-13.0.1.src-new/tools/lld/lld.cpp
--- lld-13.0.1.src/tools/lld/lld.cpp 2022-01-21 05:31:59.000000000 +0800
+++ lld-13.0.1.src-new/tools/lld/lld.cpp 2022-03-27 08:43:54.205524156 +0800
@@ -148,10 +148,6 @@
return !elf::link(args, exitEarly, stdoutOS, stderrOS);
case WinLink:
return !coff::link(args, exitEarly, stdoutOS, stderrOS);
- case Darwin:
- return !macho::link(args, exitEarly, stdoutOS, stderrOS);
- case DarwinOld:
- return !mach_o::link(args, exitEarly, stdoutOS, stderrOS);
case Wasm:
return !lld::wasm::link(args, exitEarly, stdoutOS, stderrOS);
default:

View File

@ -10,7 +10,7 @@ curl -L https://mirror.msys2.org/msys/x86_64/pacman-mirrors-20220205-1-any.pkg.t
curl -L https://raw.githubusercontent.com/msys2/MSYS2-packages/master/pacman/pacman.conf | grep -v SigLevel | sed s\|/etc/pacman.d\|$MSYS2DIR/etc/pacman.d\|g > $MSYS2DIR/etc/pacman.conf curl -L https://raw.githubusercontent.com/msys2/MSYS2-packages/master/pacman/pacman.conf | grep -v SigLevel | sed s\|/etc/pacman.d\|$MSYS2DIR/etc/pacman.d\|g > $MSYS2DIR/etc/pacman.conf
fakeroot pacman --root $MSYS2DIR --config $MSYS2DIR/etc/pacman.conf -Syy fakeroot pacman --root $MSYS2DIR --config $MSYS2DIR/etc/pacman.conf -Syy
pacman --root $MSYS2DIR --config $MSYS2DIR/etc/pacman.conf --cachedir $MSYS2DIR/msys/cache -Sp mingw-w64-x86_64-rust mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-python3.10 mingw-w64-x86_64-python-numpy mingw-w64-x86_64-python-setuptools > $MSYS2DIR/packages.txt pacman --root $MSYS2DIR --config $MSYS2DIR/etc/pacman.conf --cachedir $MSYS2DIR/msys/cache -Sp mingw-w64-x86_64-rust mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-python3.9 mingw-w64-x86_64-python-numpy mingw-w64-x86_64-python-setuptools > $MSYS2DIR/packages.txt
echo "{ pkgs } : [" > msys2_packages.nix echo "{ pkgs } : [" > msys2_packages.nix
while read package; do while read package; do

View File

@ -1,8 +1,8 @@
{ pkgs } : [ { pkgs } : [
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libiconv-1.17-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libiconv-1.16-2-any.pkg.tar.zst";
sha256 = "1pb1x5wrlmmpjdpzsc7rs5xk6ydlsd5mval0fwrqq54jf6dxdzpz"; sha256 = "0nr8gaqz7vhjsqq8ys3z63bd62fz548r9n0sncz513ra04wg7la4";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -11,18 +11,23 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-binutils-2.38-4-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-binutils-2.38-2-any.pkg.tar.zst";
sha256 = "18cgs1cvhr8hrq46g2av9as589wxn76rrshhzvx8max8iqzwprm3"; sha256 = "121jz2nmfk0qgkwjll8bg3kavmzpp14raid4az44p10vfdlla7f6";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-headers-git-10.0.0.r59.gaacb650be-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-headers-git-9.0.0.6454.b4445ee52-1-any.pkg.tar.zst";
sha256 = "0gq38zb880ar0xj62ddcggw8cqg7h6g1yw0x422i8cgak6x8qasp"; sha256 = "0wyg5ad3fh2lwd7avxvpncipj5wxmp647l43wzr1l3rrkd820yy3";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-crt-git-10.0.0.r59.gaacb650be-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-crt-git-9.0.0.6454.b4445ee52-1-any.pkg.tar.zst";
sha256 = "1safighnniwmjrklrig41m1kj1b40lrzaiv48xzf26ljb45fy6lq"; sha256 = "0bnzwgf395fbwbsq8900prj409b081hi0dd76kak6d971xqyy2r4";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-isl-0.24-1-any.pkg.tar.zst";
sha256 = "0dngp6p1yw3i9mvwg9rl888dqa7fjs8xczx1lqacw7lj98q1396d";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -30,11 +35,6 @@
sha256 = "170640c8j81gl67kp85kr8kmg5axsl1vqwn9g7cx6vcr638qax9c"; sha256 = "170640c8j81gl67kp85kr8kmg5axsl1vqwn9g7cx6vcr638qax9c";
}) })
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-isl-0.25-1-any.pkg.tar.zst";
sha256 = "0hky9gmd6iz1s3irmp9fk2j10cpqrrw8l810riwr58ynj3i10j2k";
})
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-mpfr-4.1.0.p13-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-mpfr-4.1.0.p13-1-any.pkg.tar.zst";
sha256 = "17klcf17mddd7hsrak920zglqh00drqjdh6dxh3v3c4y62xj1qr6"; sha256 = "17klcf17mddd7hsrak920zglqh00drqjdh6dxh3v3c4y62xj1qr6";
@ -46,13 +46,13 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libwinpthread-git-10.0.0.r59.gaacb650be-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libwinpthread-git-9.0.0.6454.b4445ee52-1-any.pkg.tar.zst";
sha256 = "0a9niq05s7ny0y1x625xy9p3dzakw5l4w8djajv09lkxqx36yp40"; sha256 = "181fm72bi6cs348hixkqjzivizzcsyn2lxvnbqprx4366prjf7nn";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-libs-12.1.0-3-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-libs-11.2.0-10-any.pkg.tar.zst";
sha256 = "0gxifzjl9v72z5fbr89j47j2b7l7ba9cf4xf49wb3khppqb2q9by"; sha256 = "1n8q09dwh0ghaw3p3bgxi3q0848gsjzd210bgp7qy05hv73b8kc1";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -61,8 +61,8 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-winpthreads-git-10.0.0.r59.gaacb650be-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-winpthreads-git-9.0.0.6454.b4445ee52-1-any.pkg.tar.zst";
sha256 = "1mhy806hdx27w3fzpb4zv9ia0c2r6n53ljcpkpcanwbqc3hhmj9f"; sha256 = "0n3pim85wlsc93y9sh06rnfraqgzbz300sp9hd8n7wgvcsmpj9rx";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -71,8 +71,8 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-12.1.0-3-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-11.2.0-10-any.pkg.tar.zst";
sha256 = "0j2p4516r7r9igcnfjcxyzzgppy60hx76gp78lqk0331aj1c5d1d"; sha256 = "0h6pi1xrxbrg27klbj5i5rjl8ydz78lpjfhb9pdayxjr8rs5nblq";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -81,8 +81,8 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-brotli-1.0.9-5-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-brotli-1.0.9-4-any.pkg.tar.zst";
sha256 = "044n36p4s2n73fxvac55cqqw6di19v4m92v2h0qnphazj6wcg1d0"; sha256 = "0vn42aqam6m9755vy32qr626xqglb6vsbmywdyvvagzmm8s5fxrg";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -96,13 +96,13 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libunistring-1.0-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libunistring-0.9.10-4-any.pkg.tar.zst";
sha256 = "1qks1gm8jscnn93sr7n1azkzcq4a8fybsikpqcf920m9b66cym4k"; sha256 = "0fimgakzgxrnnqk5rkvnbwl6lyqdrpgl2jcbcagqjv1swdmav97m";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libidn2-2.3.3-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libidn2-2.3.2-1-any.pkg.tar.zst";
sha256 = "1m3qgnhgf0g389kglrai26x4k64gs2cy9b3mjwlkw5xcs2r3smww"; sha256 = "0p694g8g716zyvcxc48xmdanjyrkp3ir4naqlradrw2szy9bj800";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -126,13 +126,13 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-ca-certificates-20211016-3-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-ca-certificates-20210119-1-any.pkg.tar.zst";
sha256 = "02x6dnbbyjm6mcl6ii61bc5rkwg3qsbaqd2lyzsp5732hxjcmmq4"; sha256 = "0ia48njn92shddlq3f707wz6dvj0j1k60iscs6vybybw33ijhgsq";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-openssl-1.1.1.q-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-openssl-1.1.1.n-1-any.pkg.tar.zst";
sha256 = "0rfb3z9jd0y6xjhv4qx1qqyyqgnzzlchbm07icpb4slgwjbm7cjg"; sha256 = "0gb6nswwm4b66w4x2zydha23fck967hzb5gckwlv05dws13hbh22";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -151,28 +151,28 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-xz-5.2.5-3-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-xz-5.2.5-2-any.pkg.tar.zst";
sha256 = "099j96iv49b2xddfaq7a69l0j818hw7cxyas6g7cm7iw3crsykfr"; sha256 = "1w12cbn6zq2szfa1wgr019i4ayv9x29d1nnh5vlq26l6fmzd3j1g";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libxml2-2.9.14-4-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libxml2-2.9.13-1-any.pkg.tar.zst";
sha256 = "1d6v37k0hiznlv0qnr25cpjgwa7rphahiwcrc7jf44qwdmbdasrv"; sha256 = "093fm3i8018mig0wy2p53z8izm0bfqlviacray79j2kv1bq8xyn6";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-nghttp2-1.48.0-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-nghttp2-1.47.0-1-any.pkg.tar.zst";
sha256 = "023lnhncm697sdbgnrzvc56c9lzcn29dsrl1m58hsxxjb7rrcrlf"; sha256 = "0lwylch8s7blr2hdngs2v0syh1gnicm0z4wpi28ifwdp4kzrh7mh";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-curl-7.84.0-2-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-curl-7.82.0-1-any.pkg.tar.zst";
sha256 = "0j6b3arlcsyk5fn2nr7x92j2pqkn26zyrg1zy3pc0qcd3q8hlbr0"; sha256 = "0czysrplb3lgd59v4c4v8sihbcs3hdih9d8iqrhkf28n7vds859i";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-rust-1.62.1-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-rust-1.59.0-1-any.pkg.tar.zst";
sha256 = "1bxnjgf1vx1qyf0nzmmc6s096jbw7354fkb1khhmldi15yb2f8h8"; sha256 = "1c1yr7w3h2ybbx6cywqgpns4ii0dws7jqcix8fiv0rbkjq5hxlsv";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -211,8 +211,13 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libarchive-3.6.1-2-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-nettle-3.7.3-3-any.pkg.tar.zst";
sha256 = "1wgv99pxk2pv4kr5cs111k7813bvlykphirksz8pr62kv8a1n47s"; sha256 = "10p1jlik2zhqnpphk3k1q6k2my6j0zig49r5fs21a8f6l0gakj1x";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-libarchive-3.6.0-1-any.pkg.tar.zst";
sha256 = "1jd0rj49il09a56dnvgyjzmjj37pdspqhkfm8smgakgsgn9wkm46";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -226,13 +231,13 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-ninja-1.11.0-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-cmake-3.23.0-1-any.pkg.tar.zst";
sha256 = "0s4zwj4cwzql5l7yx3rj6c8s9jkhjvqqfv5rg0a2grp4abcmv51m"; sha256 = "1gcmm3bd29zfd88ack6xdqwmbskyvhb4ymrfspayk4jfcj4svky5";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-cmake-3.24.0-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-ninja-1.10.2-3-any.pkg.tar.zst";
sha256 = "0aykg8g07jnsf549ws293ykgsxy2czbnv2yjix1dwilwc9a11w86"; sha256 = "1wsylz9m3hm6lq71qfyc3hc8rmxnv3kp602d1yvvh8nvb8pgza1y";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -241,8 +246,8 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-ncurses-6.3-5-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-ncurses-6.3-3-any.pkg.tar.zst";
sha256 = "029z63bw9pwhamw1zi75fr112pxk934nh08by2l54lwdais0vjq8"; sha256 = "1kicmq9xy4mh5rzzf107jikpmql0h78618b3xpks5l59c1hm8ril";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -251,8 +256,8 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-readline-8.1.002-2-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-readline-8.1.001-1-any.pkg.tar.zst";
sha256 = "136fp0cymxqzgs4s8dmal1f4v6ns2mw8jn4cbfihxqb2cmf9yil8"; sha256 = "0q04sz2ibvcd69hb681j4s6zyakm4i7zpk12qajj38l17v9qmlac";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -261,8 +266,8 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-sqlite3-3.39.1-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-sqlite3-3.38.2-1-any.pkg.tar.zst";
sha256 = "0nabw7iy5za5hdpflkgn1s1v93786h9zz6sxzjxm23wymfk1yxlg"; sha256 = "14agi4611h5400j7bqh1w5i5qbhp4hp6apzaddilxq97y37vj90q";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
@ -276,27 +281,27 @@
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-3.10.5-3-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-3.9.11-2-any.pkg.tar.zst";
sha256 = "1198p71k30c6kspi8mx6kmsk48fdblfr75291s0gmbmdgba7gfw4"; sha256 = "05znxaybrm8affs83a51872iksa9yd4qk692lr3rjdjy3cbxkhca";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-libgfortran-12.1.0-3-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-libgfortran-11.2.0-10-any.pkg.tar.zst";
sha256 = "11mawrmxp4habwsvbmfsalb136m4dmzlrjy3pcwp7rq8wxx2vnah"; sha256 = "13qdcb614sz7w10b2snmp05qh4c7wf24qmfmzssxjjz8ld6p8b90";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-openblas-0.3.20-3-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-openblas-0.3.20-2-any.pkg.tar.zst";
sha256 = "07d8cp8in2nbh6dsyis9cvy83y16gz5wfq5fp0fddgh1ak8ihyn2"; sha256 = "1cj0j06b2xhcvq9v6jx5cn130r8pkv2xa885f3z3z98kmrifjw0l";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-numpy-1.23.1-1-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-numpy-1.21.5-1-any.pkg.tar.zst";
sha256 = "05by2nm402jkvzaxcz7g3vmh93qmh6f2ddhambmpn4778np6n9bz"; sha256 = "10bhfq65nrzxipgy75bqaad74daif4ay06phwvbx70b9j0wm33c3";
}) })
(pkgs.fetchurl { (pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-setuptools-63.2.0-2-any.pkg.tar.zst"; url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-setuptools-59.8.0-2-any.pkg.tar.zst";
sha256 = "0280dajh9rvvg3zl4qrgbap6i6n3lxn172kscn6728ifhn3ap3bh"; sha256 = "1jbvsmh1r00yb6fm8by6z7xp9069f9lkj73jrsnxmflmvpdkjl5c";
}) })
] ]