forked from Rust-related/RustPython
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21e0ad6a2d | ||
|
|
8d510405f9 | ||
|
|
be42508cc6 | ||
|
|
f4c432b532 | ||
|
|
e0bfd18114 | ||
|
|
89d0e7f1e9 | ||
|
|
c8026f980e | ||
|
|
1929bc0953 |
5
.github/workflows/ci.yaml
vendored
5
.github/workflows/ci.yaml
vendored
@@ -161,11 +161,6 @@ jobs:
|
|||||||
run: python -m pip install flake8
|
run: python -m pip install flake8
|
||||||
- name: run lint
|
- name: run lint
|
||||||
run: flake8 . --count --exclude=./.*,./Lib,./vm/Lib,./benches/ --select=E9,F63,F7,F82 --show-source --statistics
|
run: flake8 . --count --exclude=./.*,./Lib,./vm/Lib,./benches/ --select=E9,F63,F7,F82 --show-source --statistics
|
||||||
- name: install prettier
|
|
||||||
run: yarn global add prettier && echo "$(yarn global bin)" >>$GITHUB_PATH
|
|
||||||
- name: check wasm code with prettier
|
|
||||||
# prettier doesn't handle ignore files very well: https://github.com/prettier/prettier/issues/8506
|
|
||||||
run: cd wasm && git ls-files -z | xargs -0 prettier --check -u
|
|
||||||
miri:
|
miri:
|
||||||
name: Run tests under miri
|
name: Run tests under miri
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
396
Cargo.lock
generated
396
Cargo.lock
generated
@@ -24,23 +24,6 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ahash"
|
|
||||||
version = "0.4.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ahash"
|
|
||||||
version = "0.6.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a75b7e6a93ecd6dbd2c225154d0fa7f86205574ecaa6c87429fb5f66ee677c44"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom 0.2.1",
|
|
||||||
"lazy_static 1.4.0",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.15"
|
version = "0.7.15"
|
||||||
@@ -74,6 +57,27 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arr_macro"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a105bfda48707cf19220129e78fca01e9639433ffaef4163546ed8fb04120a5"
|
||||||
|
dependencies = [
|
||||||
|
"arr_macro_impl",
|
||||||
|
"proc-macro-hack",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arr_macro_impl"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0609c78bd572f4edc74310dfb63a01f5609d53fa8b4dd7c4d98aef3b3e8d72d1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-hack",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
@@ -290,7 +294,7 @@ dependencies = [
|
|||||||
"ansi_term",
|
"ansi_term",
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"strsim",
|
"strsim 0.8.0",
|
||||||
"textwrap 0.11.0",
|
"textwrap 0.11.0",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"vec_map",
|
"vec_map",
|
||||||
@@ -336,9 +340,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift"
|
name = "cranelift"
|
||||||
version = "0.69.0"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "910322bd748b9b2450947659a48a928f35b8ba7212d80d719ff85e4b7cde62b7"
|
checksum = "60686f89c5145bc9a961dabbb83954baa429bde4c5977a0a5d3f8552f2990273"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"cranelift-frontend",
|
"cranelift-frontend",
|
||||||
@@ -346,18 +350,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-bforest"
|
name = "cranelift-bforest"
|
||||||
version = "0.69.0"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4066fd63b502d73eb8c5fa6bcab9c7962b05cd580f6b149ee83a8e730d8ce7fb"
|
checksum = "9221545c0507dc08a62b2d8b5ffe8e17ac580b0a74d1813b496b8d70b070fbd0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen"
|
name = "cranelift-codegen"
|
||||||
version = "0.69.0"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a54e4beb833a3c873a18a8fe735d73d732044004c7539a072c8faa35ccb0c60"
|
checksum = "7e9936ea608b6cd176f107037f6adbb4deac933466fc7231154f96598b2d3ab1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"cranelift-bforest",
|
"cranelift-bforest",
|
||||||
@@ -373,9 +377,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen-meta"
|
name = "cranelift-codegen-meta"
|
||||||
version = "0.69.0"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c54cac7cacb443658d8f0ff36a3545822613fa202c946c0891897843bc933810"
|
checksum = "4ef2b2768568306540f4c8db3acce9105534d34c4a1e440529c1e702d7f8c8d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen-shared",
|
"cranelift-codegen-shared",
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
@@ -383,21 +387,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen-shared"
|
name = "cranelift-codegen-shared"
|
||||||
version = "0.69.0"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a109760aff76788b2cdaeefad6875a73c2b450be13906524f6c2a81e05b8d83c"
|
checksum = "6759012d6d19c4caec95793f052613e9d4113e925e7f14154defbac0f1d4c938"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-entity"
|
name = "cranelift-entity"
|
||||||
version = "0.69.0"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b044234aa32531f89a08b487630ddc6744696ec04c8123a1ad388de837f5de3"
|
checksum = "86badbce14e15f52a45b666b38abe47b204969dd7f8fb7488cb55dd46b361fa6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-frontend"
|
name = "cranelift-frontend"
|
||||||
version = "0.69.0"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5452b3e4e97538ee5ef2cc071301c69a86c7adf2770916b9d04e9727096abd93"
|
checksum = "b608bb7656c554d0a4cf8f50c7a10b857e80306f6ff829ad6d468a7e2323c8d8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"log",
|
"log",
|
||||||
@@ -405,30 +409,11 @@ dependencies = [
|
|||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cranelift-jit"
|
|
||||||
version = "0.69.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3ffd9b060436974c7e777630ad459f3609ff1b868f43419ad63297be6bbf61ad"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"cranelift-codegen",
|
|
||||||
"cranelift-entity",
|
|
||||||
"cranelift-module",
|
|
||||||
"cranelift-native",
|
|
||||||
"errno",
|
|
||||||
"libc",
|
|
||||||
"log",
|
|
||||||
"region",
|
|
||||||
"target-lexicon",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-module"
|
name = "cranelift-module"
|
||||||
version = "0.69.0"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b17bc01cb9f176156d5cbd47ece19292e04e05a91a837dcf0ef69cc1e0e97a5a"
|
checksum = "fdaf0b5c93a610ff988fe5e2adbb7f6afa89cf702ca41acc3479dc35638d3a8d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
@@ -439,15 +424,33 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-native"
|
name = "cranelift-native"
|
||||||
version = "0.69.0"
|
version = "0.68.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f68035c10b2e80f26cc29c32fa824380877f38483504c2a47b54e7da311caaf3"
|
checksum = "5246a1af14b7812ee4d94a3f0c4b295ec02c370c08b0ecc3dec512890fdad175"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"raw-cpuid",
|
"raw-cpuid",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cranelift-simplejit"
|
||||||
|
version = "0.68.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2522ebdff6ba637c0b5e75bc3d40cc990ac1128e13547b740f10fc7b16d3991"
|
||||||
|
dependencies = [
|
||||||
|
"cranelift-codegen",
|
||||||
|
"cranelift-entity",
|
||||||
|
"cranelift-module",
|
||||||
|
"cranelift-native",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"region",
|
||||||
|
"target-lexicon",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc"
|
name = "crc"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
@@ -548,12 +551,6 @@ dependencies = [
|
|||||||
"lazy_static 1.4.0",
|
"lazy_static 1.4.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crunchy"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-mac"
|
name = "crypto-mac"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -673,6 +670,18 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "docopt"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f525a586d310c87df72ebcd98009e57f1cc030c8c268305287a476beb653969"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static 1.4.0",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"strsim 0.9.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dtoa"
|
name = "dtoa"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@@ -746,6 +755,26 @@ version = "0.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fehler"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d5729fe49ba028cd550747b6e62cd3d841beccab5390aa398538c31a2d983635"
|
||||||
|
dependencies = [
|
||||||
|
"fehler-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fehler-macros"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ccb5acb1045ebbfa222e2c50679e392a71dd77030b78fb0189f2d9c5974400f9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fixedbitset"
|
name = "fixedbitset"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -856,18 +885,6 @@ dependencies = [
|
|||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "getrandom"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 1.0.0",
|
|
||||||
"js-sys",
|
|
||||||
"libc",
|
|
||||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -882,9 +899,6 @@ name = "hashbrown"
|
|||||||
version = "0.9.1"
|
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 = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||||
dependencies = [
|
|
||||||
"ahash 0.4.7",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
@@ -997,35 +1011,34 @@ checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lalrpop"
|
name = "lalrpop"
|
||||||
version = "0.19.4"
|
version = "0.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a71d75b267b3299da9ccff4dd80d73325b5d8adcd76fe97cf92725eb7c6f122"
|
checksum = "60fb56191fb8ed5311597e5750debe6779c9fdb487dbaa5ff302592897d7a2c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ascii-canvas",
|
"ascii-canvas",
|
||||||
"atty",
|
"atty",
|
||||||
"bit-set",
|
"bit-set",
|
||||||
"diff",
|
"diff",
|
||||||
|
"docopt",
|
||||||
"ena",
|
"ena",
|
||||||
"itertools",
|
"itertools",
|
||||||
"lalrpop-util",
|
"lalrpop-util",
|
||||||
"petgraph",
|
"petgraph",
|
||||||
"pico-args",
|
|
||||||
"regex",
|
"regex",
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"sha2",
|
||||||
"string_cache",
|
"string_cache",
|
||||||
"term",
|
"term",
|
||||||
"tiny-keccak",
|
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lalrpop-util"
|
name = "lalrpop-util"
|
||||||
version = "0.19.4"
|
version = "0.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ebbd90154472db6267a7d28ca08fea7788e5619fef10f2398155cb74c08f77a"
|
checksum = "6771161eff561647fad8bb7e745e002c304864fb8f436b52b30acda51fca4408"
|
||||||
dependencies = [
|
|
||||||
"regex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
@@ -1054,9 +1067,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.81"
|
version = "0.2.80"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
|
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libffi"
|
name = "libffi"
|
||||||
@@ -1116,10 +1129,17 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lz4_flex"
|
name = "lz-fear"
|
||||||
version = "0.7.0"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9025814971d70dd729afe3b93b02d653c905dadb9821d5578458e12dea5148f"
|
checksum = "06aad1ce45e4ccf7a8d7d43e0c3ad38dc5d2255174a5f29a3c39d961fbc6181d"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"byteorder",
|
||||||
|
"fehler",
|
||||||
|
"thiserror",
|
||||||
|
"twox-hash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mach"
|
name = "mach"
|
||||||
@@ -1186,11 +1206,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mt19937"
|
name = "mt19937"
|
||||||
version = "2.0.0"
|
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 = "3e6dd1b4462edbfbc0c4ad4c3205d94623bb94b4819aa0888936988d38834158"
|
checksum = "c674293daac706360a8fa633c802ca15d27ee4a52394f12ecec2f6d2aa5508bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core 0.6.0",
|
"rand",
|
||||||
|
"rand_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1422,41 +1443,6 @@ dependencies = [
|
|||||||
"indexmap",
|
"indexmap",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
|
|
||||||
dependencies = [
|
|
||||||
"phf_macros",
|
|
||||||
"phf_shared",
|
|
||||||
"proc-macro-hack",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_generator"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
|
|
||||||
dependencies = [
|
|
||||||
"phf_shared",
|
|
||||||
"rand 0.7.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_macros"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"
|
|
||||||
dependencies = [
|
|
||||||
"phf_generator",
|
|
||||||
"phf_shared",
|
|
||||||
"proc-macro-hack",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf_shared"
|
name = "phf_shared"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@@ -1466,12 +1452,6 @@ dependencies = [
|
|||||||
"siphasher",
|
"siphasher",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pico-args"
|
|
||||||
version = "0.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "28b9b4df73455c861d7cbf8be42f01d3b373ed7f02e378d55fa84eafc6f638b1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.19"
|
version = "0.3.19"
|
||||||
@@ -1537,12 +1517,6 @@ dependencies = [
|
|||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "puruspe"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "96e65ac785a4b9fe1d1046da0a3b5fad0a2a1606c66e41f5bfb86be8851ea0c3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python3-sys"
|
name = "python3-sys"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@@ -1574,24 +1548,11 @@ version = "0.7.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.1.15",
|
"getrandom",
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha 0.2.2",
|
"rand_chacha",
|
||||||
"rand_core 0.5.1",
|
"rand_core",
|
||||||
"rand_hc 0.2.0",
|
"rand_hc",
|
||||||
"rand_pcg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a76330fb486679b4ace3670f117bbc9e16204005c4bde9c4bd372f45bed34f12"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"rand_chacha 0.3.0",
|
|
||||||
"rand_core 0.6.0",
|
|
||||||
"rand_hc 0.3.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1601,17 +1562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core 0.5.1",
|
"rand_core",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_chacha"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
|
|
||||||
dependencies = [
|
|
||||||
"ppv-lite86",
|
|
||||||
"rand_core 0.6.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1620,16 +1571,7 @@ version = "0.5.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.1.15",
|
"getrandom",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a8b34ba8cfb21243bd8df91854c830ff0d785fff2e82ebd4434c2644cb9ada18"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom 0.2.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1638,32 +1580,14 @@ 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 = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core 0.5.1",
|
"rand_core",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_hc"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.6.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_pcg"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.5.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "raw-cpuid"
|
name = "raw-cpuid"
|
||||||
version = "8.1.2"
|
version = "7.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fdf7d9dbd43f3d81d94a49c1c3df73cc2b3827995147e6cf7f89d4ec5483e73"
|
checksum = "b4a349ca83373cfa5d6dbb66fd76e58b2cca08da71a5f6400de0a0a6a9bceeaf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cc",
|
"cc",
|
||||||
@@ -1707,7 +1631,7 @@ 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 = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.1.15",
|
"getrandom",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"rust-argon2",
|
"rust-argon2",
|
||||||
]
|
]
|
||||||
@@ -1845,7 +1769,7 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
"bstr",
|
"bstr",
|
||||||
"itertools",
|
"itertools",
|
||||||
"lz4_flex",
|
"lz-fear",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-complex",
|
"num-complex",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1865,7 +1789,7 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"rand 0.8.0",
|
"rand",
|
||||||
"siphasher",
|
"siphasher",
|
||||||
"volatile",
|
"volatile",
|
||||||
]
|
]
|
||||||
@@ -1884,17 +1808,15 @@ dependencies = [
|
|||||||
name = "rustpython-compiler-core"
|
name = "rustpython-compiler-core"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash 0.6.2",
|
"arrayvec",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"insta",
|
"insta",
|
||||||
"itertools",
|
"itertools",
|
||||||
"log",
|
"log",
|
||||||
"num-complex",
|
"num-complex",
|
||||||
"num-traits",
|
|
||||||
"rustpython-ast",
|
"rustpython-ast",
|
||||||
"rustpython-bytecode",
|
"rustpython-bytecode",
|
||||||
"rustpython-parser",
|
"rustpython-parser",
|
||||||
"scopeguard",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1919,8 +1841,8 @@ version = "0.1.2"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"approx",
|
"approx",
|
||||||
"cranelift",
|
"cranelift",
|
||||||
"cranelift-jit",
|
|
||||||
"cranelift-module",
|
"cranelift-module",
|
||||||
|
"cranelift-simplejit",
|
||||||
"libffi",
|
"libffi",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"rustpython-bytecode",
|
"rustpython-bytecode",
|
||||||
@@ -1932,14 +1854,11 @@ dependencies = [
|
|||||||
name = "rustpython-parser"
|
name = "rustpython-parser"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash 0.6.2",
|
|
||||||
"hashbrown",
|
|
||||||
"lalrpop",
|
"lalrpop",
|
||||||
"lalrpop-util",
|
"lalrpop-util",
|
||||||
"log",
|
"log",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"phf",
|
|
||||||
"rustpython-ast",
|
"rustpython-ast",
|
||||||
"unic-emoji-char",
|
"unic-emoji-char",
|
||||||
"unic-ucd-ident",
|
"unic-ucd-ident",
|
||||||
@@ -1959,12 +1878,13 @@ name = "rustpython-vm"
|
|||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler32",
|
"adler32",
|
||||||
"ahash 0.6.2",
|
"arr_macro",
|
||||||
"atty",
|
"atty",
|
||||||
"base64",
|
"base64",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"blake2",
|
"blake2",
|
||||||
"bstr",
|
"bstr",
|
||||||
|
"byteorder",
|
||||||
"caseless",
|
"caseless",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -1980,8 +1900,7 @@ dependencies = [
|
|||||||
"flate2",
|
"flate2",
|
||||||
"foreign-types-shared",
|
"foreign-types-shared",
|
||||||
"gethostname",
|
"gethostname",
|
||||||
"getrandom 0.2.1",
|
"getrandom",
|
||||||
"half",
|
|
||||||
"hex",
|
"hex",
|
||||||
"hexf-parse",
|
"hexf-parse",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
@@ -1991,6 +1910,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"libz-sys",
|
"libz-sys",
|
||||||
"log",
|
"log",
|
||||||
|
"maplit",
|
||||||
"md-5",
|
"md-5",
|
||||||
"mt19937",
|
"mt19937",
|
||||||
"nix",
|
"nix",
|
||||||
@@ -2007,9 +1927,8 @@ dependencies = [
|
|||||||
"openssl-sys",
|
"openssl-sys",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"paste",
|
"paste",
|
||||||
"puruspe",
|
"rand",
|
||||||
"rand 0.8.0",
|
"rand_core",
|
||||||
"rand_core 0.6.0",
|
|
||||||
"regex",
|
"regex",
|
||||||
"result-like",
|
"result-like",
|
||||||
"rustc_version_runtime",
|
"rustc_version_runtime",
|
||||||
@@ -2029,6 +1948,7 @@ dependencies = [
|
|||||||
"sha3",
|
"sha3",
|
||||||
"socket2",
|
"socket2",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
|
"statrs",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
"timsort",
|
"timsort",
|
||||||
@@ -2244,12 +2164,13 @@ checksum = "ae524f056d7d770e174287294f562e95044c68e88dec909a00d2094805db9d75"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.3.19"
|
version = "0.3.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
|
checksum = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2259,6 +2180,15 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "statrs"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cce16f6de653e88beca7bd13780d08e09d4489dbca1f9210e041bc4852481382"
|
||||||
|
dependencies = [
|
||||||
|
"rand",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "string_cache"
|
name = "string_cache"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@@ -2269,6 +2199,7 @@ dependencies = [
|
|||||||
"new_debug_unreachable",
|
"new_debug_unreachable",
|
||||||
"phf_shared",
|
"phf_shared",
|
||||||
"precomputed-hash",
|
"precomputed-hash",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2277,6 +2208,12 @@ version = "0.8.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@@ -2423,15 +2360,6 @@ version = "0.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3cb4fa83bb73adf1c7219f4fe4bf3c0ac5635e4e51e070fad5df745a41bedfb8"
|
checksum = "3cb4fa83bb73adf1c7219f4fe4bf3c0ac5635e4e51e070fad5df745a41bedfb8"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tiny-keccak"
|
|
||||||
version = "2.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
|
||||||
dependencies = [
|
|
||||||
"crunchy",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinytemplate"
|
name = "tinytemplate"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -2466,6 +2394,16 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "twox-hash"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
@@ -2664,12 +2602,6 @@ version = "0.8.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.9.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "volatile"
|
name = "volatile"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|||||||
@@ -68,5 +68,9 @@ opt-level = 3
|
|||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
# REDOX START, Uncommment when you want to compile/check with redoxer
|
# REDOX START, Uncommment when you want to compile/check with redoxer
|
||||||
|
# # following patches are just waiting on a new version to be released to crates.io
|
||||||
|
# nix = { git = "https://github.com/nix-rust/nix" }
|
||||||
|
# crossbeam-utils = { git = "https://github.com/crossbeam-rs/crossbeam" }
|
||||||
|
# socket2 = { git = "https://github.com/alexcrichton/socket2-rs" }
|
||||||
# REDOX END
|
# REDOX END
|
||||||
|
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
Proc-Type: 4,ENCRYPTED
|
|
||||||
DEK-Info: DES-EDE3-CBC,E74528136B90D2DD
|
|
||||||
|
|
||||||
WRHVD2PJXPqjFSHg92HURIsUzvsTE4a9oi0SC5yMBFKNWA5Z933gK3XTifp6jul5
|
|
||||||
zpNYi8jBXZ2EqJJBxCuVcefmXSxL0q7CMej25TdIC4BVAFJVveeprHPUFkNB0IM1
|
|
||||||
go5Lg4YofYqTCg3OE3k7WvfR3Zg1cRYxksDKO+WNZgWyKBex5X4vjOiyUqDl3GKt
|
|
||||||
kQXnkg1VgPV2Vrx93S9XNdELNRTguwf+XG0fkhtYhp/zCto8uKTgy5elK2P/ulGp
|
|
||||||
7fe6uj7h/uN9L7EOC6CjRkitywfeBUER739mOcGT4imSFJ9G27TCqPzj2ea3uuaf
|
|
||||||
/v1xhkQ4M6lNY/gcRfgVpCXhW43aAQV8XXQRMJTqLmz5Y5hYTKn+Ugq5vJ/ngyRM
|
|
||||||
lu1gUJnYYaemBTb4hbm6aBvnYK9mORa891Pmf+vxU9rYuQIdVAhvvXh4KBreSEBI
|
|
||||||
1AFy6dFKXl8ZKs6Wrq5wPefmFFkRmZ8OBiiq0fp2ApCRGZw6LsjCgwrRM38JiY7d
|
|
||||||
3OdsJpKvRYufgUyuuzUE0xA+E4yMvD48M9pPq2fC8O5giuGL1uEekQWXJuq+6ZRI
|
|
||||||
XYKIeSkuQALbX3RAzCPXTUEMtCYXKm/gxrrwJ+Bet4ob2amf3MX0uvWwOuAq++Fk
|
|
||||||
J0HFSBxrwvIWOhyQXOPuJdAN8PXA7dWOXfOgOMF0hQYqZCl3T4TiVZJbwVQtg1sN
|
|
||||||
dO7oAD5ZPHiKzvveZuB6k1FlBG8j0TyAC+44ChxkPDD3jF4dd6zGe62sDf85p4/d
|
|
||||||
W80gxJeD3xnDxG0ePPns+GuKUpUaWS7WvHtDpeFW1JEhvOqf8p1Li9a7RzWVo8ML
|
|
||||||
mGTdQgBIYIf6/fk69pFKl0nKtBU75KaunZz4nAmd9bNED4naDurMBg44u5TvODbJ
|
|
||||||
vgYIYXIYjNvONbskJatVrrTS8zch2NwVIjCi8L/hecwBXbIXzo1pECpc6BU7sQT8
|
|
||||||
+i9sDKBeJcRipzfKZNHvnO19mUZaPCY8+a/f9c21DgKXz+bgLcJbohpSaeGM8Gfc
|
|
||||||
aZd3Vp9n3OJ3g2zQR1++HO9v1vR/wLELu6MeydkvMduHLmOPCn54gZ9z51ZNPAwa
|
|
||||||
qfFIsH+mLh9ks0H74ssF59uIlstkgB9zmZHv/Q0dK9ZfG/VEH6rSgdETWhZxhoMQ
|
|
||||||
Z92jXBEFT0zhI3rrIPNY+XS7eJCQIc1wc84Ea3cRk7SP+S1og3JtAxX56ykUwtkM
|
|
||||||
LQ/Dwwa6h1aqD0l2d5x1/BSdavtTuSegISRWQ4iOmSvEdlFP7H4g6RZk/okbLzMD
|
|
||||||
Evq5gNc7vlXhVawoQU8JCanJ5ZbbWnIRZfiXxBQS4lpYPKvJt4ML9z/x+82XxcXv
|
|
||||||
Z93N2Wep7wWW5OwS2LcQcOgZRDSIPompwo/0pMFGOS+5oort0ZDRHdmmGLjvBcCb
|
|
||||||
1KQmKQ4+8brI/3rjRzts6uDLjTGNxSCieNsnqhwHUv9Mg9WDSWupcGa+x27L89x3
|
|
||||||
rObf6+3umcFLSjIzU8wuv1hx/e/y98Kv7BDBNYpAr6kVMrLnzYjAfJbBmqlxkzkQ
|
|
||||||
IgQzgrk2QZoTdgwR+S374NAMO0AE5IlO+/qa6qp2SORGTDX64I3UNw==
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDWTCCAkGgAwIBAgIJAPm6B21bar2bMA0GCSqGSIb3DQEBCwUAMF8xCzAJBgNV
|
|
||||||
BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
|
|
||||||
IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xODAx
|
|
||||||
MTkxOTA5MDZaFw0yODAxMTcxOTA5MDZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH
|
|
||||||
DA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5k
|
|
||||||
YXRpb24xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
|
||||||
ADCCAQoCggEBAKvvsX2gEti4shve3iYMc+jE4Se7WHs1Bol2f21H8qNboDOFdeb1
|
|
||||||
RKHjmq3exHpajywOUEgne9nKHJY/3f2phR4Y5klqG6liLgiSpVyRlcBGbeT2qEAj
|
|
||||||
9oLiLFUXLGfGDds2mTwivQDLJBWi51j7ff5k2Pr58fN5ugYMn24T9FNyn0moT+qj
|
|
||||||
SFoBNm58l9jrdkJSlgWfqPlbiMa+mqDn/SFtrwLF2Trbfzu42Sd9UdIzMaSSrzbN
|
|
||||||
sGm53pNhCh8KndWUQ8GPP2IsLPoUU4qAtmZuTxCx2S1cXrN9EkmT69tlOH84YfSn
|
|
||||||
96Ih9bWRc7M5y5bfVdEVM+fKQl3hBRf05qMCAwEAAaMYMBYwFAYDVR0RBA0wC4IJ
|
|
||||||
bG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQAtQ8f37cCEk7/rAcbYR53ce3iK
|
|
||||||
Vpihb0U2ni1QjG9Tg9UIExkIGkwTiCm7kwQL+GEStBu9AG/QVrOjeTriRiddhWkk
|
|
||||||
ze8kRaI3AC/63t6Vh9Q1x6PESgeE4OtAO9JpJCf4GILglA789Y/b/GF8zJZQxR13
|
|
||||||
qpB4ZwWw7gCBhdEW59u6CFeBmfDa58hM8lWvuVoRrTi7bjUeC6PAn5HVMzZSykhu
|
|
||||||
4HaUfBp6bKFjuym2+h/VvM1n8C3chjVSmutsLb6ELdD8IK0vPV/yf5+LN256zSsS
|
|
||||||
dyUZYd8XwQaioEMKdbhLvnehyzHiWfQIUR3BdhONxoIJhHv/EAo8eCkHHYIF
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCr77F9oBLYuLIb
|
|
||||||
3t4mDHPoxOEnu1h7NQaJdn9tR/KjW6AzhXXm9USh45qt3sR6Wo8sDlBIJ3vZyhyW
|
|
||||||
P939qYUeGOZJahupYi4IkqVckZXARm3k9qhAI/aC4ixVFyxnxg3bNpk8Ir0AyyQV
|
|
||||||
oudY+33+ZNj6+fHzeboGDJ9uE/RTcp9JqE/qo0haATZufJfY63ZCUpYFn6j5W4jG
|
|
||||||
vpqg5/0hba8Cxdk62387uNknfVHSMzGkkq82zbBpud6TYQofCp3VlEPBjz9iLCz6
|
|
||||||
FFOKgLZmbk8QsdktXF6zfRJJk+vbZTh/OGH0p/eiIfW1kXOzOcuW31XRFTPnykJd
|
|
||||||
4QUX9OajAgMBAAECggEAHppmXDbuw9Z0FVPg9KLIysioTtsgz6VLiZIm8juZK4x2
|
|
||||||
glUh/D7xvWL2uDXrgN+3lh7iGUW13LkFx5SMncbbo9TIwI57Z/XKvcnkVwquve+L
|
|
||||||
RfLFVc1Q5lD9lROv2rS86KTaN4LzYz3FKXi6dvMkpPAsUtfEQhMLkmISypQQq/1z
|
|
||||||
EJaqo7r85OjN7e0wKazlKZpOzJEa5FQLMVRjTRFhLFNbHXX/tAet2jw+umATKbw8
|
|
||||||
hYgiuZ44TwSEd9JeIV/oSYWfI/3HetuYW0ru3caiztRF2NySNu8lcsWgNC7fIku9
|
|
||||||
mcHjtSNzs91QN1Qlu7GQvvhpt6OWDirNDCW+49WGaQKBgQDg9SDhfF0jRYslgYbH
|
|
||||||
cqO4ggaFdHjrAAYpwnAgvanhFZL/zEqm5G1E7l/e2fCkJ9VOSFO0A208chvwMcr+
|
|
||||||
dCjHE2tVdE81aQ2v/Eo83VdS1RcOV4Y75yPH48rMhxPaHvxWD/FFDbf0/P2mtPB7
|
|
||||||
SZ3kIeZMkE1wxdaO3AKUbQoozwKBgQDDqYgg7kVtygyICE1mB8Hwp6nUxFTczG7y
|
|
||||||
4XcsDqMIrKmw+PbQluvkoHoStxeVrsTloDhkTjIrpmYLyAiazg+PUJdkd6xrfLSj
|
|
||||||
VV6X93W0S/1egEb1F1CGFxtk8v/PWH4K76EPL2vxXdxjywz3GWlrL9yDYaB2szzS
|
|
||||||
DqgwVMqx7QKBgDCD7UF0Bsoyl13RX3XoPXLvZ+SkR+e2q52Z94C4JskKVBeiwX7Y
|
|
||||||
yNAS8M4pBoMArDoj0xmBm69rlKbqtjLGbnzwrTdSzDpim7cWnBQgUFLm7gAD1Elb
|
|
||||||
AhZ8BCK0Bw4FnLoa2hfga4oEfdfUMgEE0W5/+SEOBgWKRUmuHUhRc911AoGAY2EN
|
|
||||||
YmSDYSM5wDIvVb5k9B3EtevOiqNPSw/XnsoEZtiEC/44JnQxdltIBY93bDBrk5IQ
|
|
||||||
cmoBM4h91kgQjshQwOMXMhFSwvmBKmCm/hrTbvMVytTutXfVD3ZXFKwT4DW7N0TF
|
|
||||||
ElhsxBh/YzRz7mG62JVjtFt2zDN3ld2Z8YpvtXUCgYEA4EJ4ObS5YyvcXAKHJFo6
|
|
||||||
Fxmavyrf8LSm3MFA65uSnFvWukMVqqRMReQc5jvpxHKCis+XvnHzyOfL0gW9ZTi7
|
|
||||||
tWGGbBi0TRJCa8BkvgngUZxOxUlMfg/7cVxOIB0TPoUSgxFd/+qVz4GZMvr0dPu7
|
|
||||||
eAF7J/8ECVvb0wSPTUI1N3c=
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDWTCCAkGgAwIBAgIJAPm6B21bar2bMA0GCSqGSIb3DQEBCwUAMF8xCzAJBgNV
|
|
||||||
BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
|
|
||||||
IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xODAx
|
|
||||||
MTkxOTA5MDZaFw0yODAxMTcxOTA5MDZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH
|
|
||||||
DA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5k
|
|
||||||
YXRpb24xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
|
||||||
ADCCAQoCggEBAKvvsX2gEti4shve3iYMc+jE4Se7WHs1Bol2f21H8qNboDOFdeb1
|
|
||||||
RKHjmq3exHpajywOUEgne9nKHJY/3f2phR4Y5klqG6liLgiSpVyRlcBGbeT2qEAj
|
|
||||||
9oLiLFUXLGfGDds2mTwivQDLJBWi51j7ff5k2Pr58fN5ugYMn24T9FNyn0moT+qj
|
|
||||||
SFoBNm58l9jrdkJSlgWfqPlbiMa+mqDn/SFtrwLF2Trbfzu42Sd9UdIzMaSSrzbN
|
|
||||||
sGm53pNhCh8KndWUQ8GPP2IsLPoUU4qAtmZuTxCx2S1cXrN9EkmT69tlOH84YfSn
|
|
||||||
96Ih9bWRc7M5y5bfVdEVM+fKQl3hBRf05qMCAwEAAaMYMBYwFAYDVR0RBA0wC4IJ
|
|
||||||
bG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQAtQ8f37cCEk7/rAcbYR53ce3iK
|
|
||||||
Vpihb0U2ni1QjG9Tg9UIExkIGkwTiCm7kwQL+GEStBu9AG/QVrOjeTriRiddhWkk
|
|
||||||
ze8kRaI3AC/63t6Vh9Q1x6PESgeE4OtAO9JpJCf4GILglA789Y/b/GF8zJZQxR13
|
|
||||||
qpB4ZwWw7gCBhdEW59u6CFeBmfDa58hM8lWvuVoRrTi7bjUeC6PAn5HVMzZSykhu
|
|
||||||
4HaUfBp6bKFjuym2+h/VvM1n8C3chjVSmutsLb6ELdD8IK0vPV/yf5+LN256zSsS
|
|
||||||
dyUZYd8XwQaioEMKdbhLvnehyzHiWfQIUR3BdhONxoIJhHv/EAo8eCkHHYIF
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3ulRNfhbOAey/
|
|
||||||
B+wIVYx+d5az7EV4riR6yi/qE6G+bxbTvay2pqySHtDweuaYSh2cVmcasBKKIFJm
|
|
||||||
rCD1zR8UmLb5i2XFIina1t3eePCuBZMrvZZwkzlQUSM1AZtjGOO/W0I3FwO6y645
|
|
||||||
9xA5PduKI7SMYkH/VL3zE5W1JwMovv6bvNiT+GU5l6mB9ylCTgLpmUqoQhRqz/35
|
|
||||||
zCzVyoh+ppDvVcpWYfvXywsXsgQwbAF0QJm8SSFi0TZm5ykv4WE16afQp08yuZS0
|
|
||||||
3U4K3MJCa4rxO58edcxBopWYfQ29K3iINM8enRfr5q+u5mAAbALAEEvyFjgLWl/u
|
|
||||||
7arxn7bJAgMBAAECggEBAJfMt8KfHzBunrDnVrk8FayYGkfmOzAOkc1yKEx6k/TH
|
|
||||||
zFB+Mqlm5MaF95P5t3S0J+r36JBAUdEWC38RUNpF9BwMYYGlDxzlsTdCuGYL/q+J
|
|
||||||
o6NMLXQt7/jQUQqGnWAvPFzqhbcGqOo5R2ZVH25sEWv9PDuRI35XAepIkDTwWsfa
|
|
||||||
P6UcJJoP+4v9B++fb3sSL4zNwp1BqS4wxR8YTR0t1zQqOxJ5BGPw1J8aBMs1sq5t
|
|
||||||
qyosAQAT63kLrdqWotHaM26QxjqEQUMlh12XMWb5GdBXUxbvyGtEabsqskGa/f8B
|
|
||||||
RdHE437J8D8l+jxb2mZLzrlaH3dq2tbFGCe1rT8qLRECgYEA5CWIvoD/YnQydLGA
|
|
||||||
OlEhCSocqURuqcotg9Ev0nt/C60jkr/NHFLGppz9lhqjIDjixt3sIMGZMFzxRtwM
|
|
||||||
pSYal3XiR7rZuHau9iM35yDhpuytEiGbYy1ADakJRzY5jq/Qa8RfPP9Atua5xAeP
|
|
||||||
q6DiSnq9vhHv9G+O4MxzHBmrw9sCgYEAziiJWFthcwvuXn3Jv9xFYKEb/06puZAx
|
|
||||||
EgQCz/3rPzv5fmGD/sKVo1U/K4z/eA82DNeKG8QRTFJCxT8TCNRxOmGV7HdCYo/B
|
|
||||||
4BTNNvbKcdi3l0j75kKoADg+nt5CD5lz6gLG0GrUEnVO1y5HVfCTb3BEAfa36C85
|
|
||||||
9i0sfQGiwysCgYEAuus9k8cgdct5oz3iLuVVSark/JGCkT2B+OOkaLChsDFUWeEm
|
|
||||||
7TOsaclpwldkmvvAYOplkZjMJ2GelE2pVo1XcAw3LkmaI5WpVyQXoxe/iQGT8qzy
|
|
||||||
IFlsh0Scw2lb0tmcyw6CcPk4TiHOxRrkzNrtS9QwLM+JZx0XVHptPPKTVc0CgYAu
|
|
||||||
j/VFYY5G/8Dc0qhIjyWUR48dQNUQtkJ/ASzpcT46z/7vznKTjbtiYpSb74KbyUO5
|
|
||||||
7sygrM4DYOj3x+Eys1jHiNbly6HQxQtS4x/edCsRP5NntfI+9XsgYZOzKhvdjhki
|
|
||||||
F3J0DEzNxnUCIM+311hVaRPTJbgv1srOkTFlIoNydQKBgQC6/OHGaC/OewQqRlRK
|
|
||||||
Mg5KZm01/pk4iKrpA5nG7OTAeoa70NzXNtG8J3WnaJ4mWanNwNUOyRMAMrsUAy9q
|
|
||||||
EeGqHM5mMFpY4TeVuNLL21lu/x3KYw6mKL3Ctinn+JLAoYoqEy8deZnEA5/tjYlz
|
|
||||||
YhFBchnUicjoUN1chdpM6SpV2Q==
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDYjCCAkqgAwIBAgIJALJXRr8qF6oIMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV
|
|
||||||
BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
|
|
||||||
IFNvZnR3YXJlIEZvdW5kYXRpb24xFTATBgNVBAMMDGZha2Vob3N0bmFtZTAeFw0x
|
|
||||||
ODAxMTkxOTA5MDZaFw0yODAxMTcxOTA5MDZaMGIxCzAJBgNVBAYTAlhZMRcwFQYD
|
|
||||||
VQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZv
|
|
||||||
dW5kYXRpb24xFTATBgNVBAMMDGZha2Vob3N0bmFtZTCCASIwDQYJKoZIhvcNAQEB
|
|
||||||
BQADggEPADCCAQoCggEBALe6VE1+Fs4B7L8H7AhVjH53lrPsRXiuJHrKL+oTob5v
|
|
||||||
FtO9rLamrJIe0PB65phKHZxWZxqwEoogUmasIPXNHxSYtvmLZcUiKdrW3d548K4F
|
|
||||||
kyu9lnCTOVBRIzUBm2MY479bQjcXA7rLrjn3EDk924ojtIxiQf9UvfMTlbUnAyi+
|
|
||||||
/pu82JP4ZTmXqYH3KUJOAumZSqhCFGrP/fnMLNXKiH6mkO9VylZh+9fLCxeyBDBs
|
|
||||||
AXRAmbxJIWLRNmbnKS/hYTXpp9CnTzK5lLTdTgrcwkJrivE7nx51zEGilZh9Db0r
|
|
||||||
eIg0zx6dF+vmr67mYABsAsAQS/IWOAtaX+7tqvGftskCAwEAAaMbMBkwFwYDVR0R
|
|
||||||
BBAwDoIMZmFrZWhvc3RuYW1lMA0GCSqGSIb3DQEBCwUAA4IBAQCZhHhGItpkqhEq
|
|
||||||
ntMRd6Hv0GoOJixNvgeMwK4NJSRT/no3OirtUTzccn46h+SWibSa2eVssAV+pAVJ
|
|
||||||
HbzkN/DH27A1mMx1zJL1ekcOKA1AF6MXhUnrUGXMqW36YNtzHfXJLrwvpLJ13OQg
|
|
||||||
/Kxo4Nw68bGzM+PyRtKU/mpgYyfcvwR+ZSeIDh1fvUZK/IEVCf8ub42GPVs5wPfv
|
|
||||||
M+k5aHxWTxeif3K1byTRzxHupYNG2yWO4XEdnBGOuOwzzN4/iQyNcsuQKeuKHGrt
|
|
||||||
YvIlG/ri04CQ7xISZCj74yjTZ+/A2bXre2mQXAHqKPumHL7cl34+erzbUaxYxbTE
|
|
||||||
u5FcOmLQ
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgV4G+Zzf2DT5n
|
|
||||||
oAisIGFhn/bz7Vn5WiXUqbDsxROJOh/7BtOlduZka0pPhFylGbnxS8l1kEWHRI2T
|
|
||||||
6hOoWzumB6ItKiN+T5J30lAvSyo7iwdFoAQ/S5nPXQfhNARQe/NEOhRtpcuNdyx4
|
|
||||||
BWdPdPuJQA1ASNJCLwcLOoRxaLbKLvb2V5T5FCAkeNPtRvPuT4gKQItMmiHfAhoV
|
|
||||||
C8MZWF/GC0RukHINys5MwqeFexam8CznmQPMYrLdhmKTj3DTivCPoh97EDIFGlgZ
|
|
||||||
SCaaYDVQA+aqlo/q2pi52PFwC1KzhNEA7EeOqSwC1NQjwjHuhcnf9WbxrgTq2zh3
|
|
||||||
rv5YEW2ZAgMBAAECggEAPfSMtTumPcJskIumuXp7yk02EyliZrWZqwBuBwVqHsS5
|
|
||||||
nkbFXnXWrLbgn9MrDsFrE5NdgKUmPnQVMVs8sIr5jyGejSCNCs4I4iRn1pfIgwcj
|
|
||||||
K/xEEALd6GGF0pDd/CgvB5GOoLVf4KKf2kmLvWrOKJpSzoUN5A8+v8AaYYOMr4sC
|
|
||||||
czbvfGomzEIewEG+Rw9zOVUDlmwyEKPQZ47E7PQ+EEA7oeFdR+1Zj6eT9ndegf8B
|
|
||||||
54frySYCLRUCk/sHCpWhaJBtBrcpht7Y8CfY7hiH/7x866fvuLnYPz4YALtUb0wN
|
|
||||||
7zUCNS9ol3n4LbjFFKfZtiRjKaCBRzMjK0rz6ydFcQKBgQDyLI3oGbnW73vqcDe/
|
|
||||||
6eR0w++fiCAVhfMs3AO/gOaJi2la2JHlJ5u+cIHQIOFwEhn6Zq0AtdmnFx1TS5IQ
|
|
||||||
C0MdXI0XoQQw7rEF8EJcvfe85Z0QxENVhzydtdb8QpJfnQGfBfLyQlaaRYzRRHB6
|
|
||||||
VdYUHF3EIPVIhbjbghal+Qep/QKBgQDtJlRPHkWwTMevu0J0fYbWN1ywtVTFUR//
|
|
||||||
k7VyORSf8yuuSnaQRop4cbcqONxmDKH6Or1fl3NYBsAxtXkkOK1E2OZNo2sfQdRa
|
|
||||||
wpA7o7mPHRhztQFpT5vflp+8P6+PEFat8D04eBOhNwrwwfhiPjD4gv5KvN4XutRW
|
|
||||||
VWv/2pnmzQKBgHPvHGg2mJ7quvm6ixXW1MWJX1eSBToIjCe3lBvDi5nhIaiZ8Q4w
|
|
||||||
7gA3QA3xD7tlDwauzLeAVxgEmsdbcCs6GQEfY3QiYy1Bt4FOSZa4YrcNfSmfq1Rw
|
|
||||||
j3Y4rRjKjeQz96i3YlzToT3tecJc7zPBj+DEy6au2H3Fdn+vQURneWHJAoGBANG7
|
|
||||||
XES8mRVaUh/wlM1BVsaNH8SIGfiHzqzRjV7/bGYpQTBbWpAuUrhCmaMVtpXqBjav
|
|
||||||
TFwGLVRkZAWSYRjPpy2ERenT5SE3rv61o6mbGrifGsj6A82HQmtzYsGx8SmtYXtj
|
|
||||||
REF0sKebbmmOooUAS379GrguYJzL9o6D7YfRZNrhAoGAVfb/tiFU4S67DSpYpQey
|
|
||||||
ULhgfsFpDByICY6Potsg67gVFf9jIaB83NPTx3u/r6sHFgxFw7lQsuZcgSuWMu7t
|
|
||||||
glzOXVIP11Y5sl5CJ5OsfeK1/0umMZF5MWPyAQCx/qrPlZL86vXjt24Y/VaOxsAi
|
|
||||||
CZYdyJsjgOrJrWoMbo5ta54=
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
Certificate:
|
|
||||||
Data:
|
|
||||||
Version: 3 (0x2)
|
|
||||||
Serial Number:
|
|
||||||
82:ed:bf:41:c8:80:91:9c
|
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
|
||||||
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
|
||||||
Validity
|
|
||||||
Not Before: Jan 19 19:09:06 2018 GMT
|
|
||||||
Not After : Nov 28 19:09:06 2027 GMT
|
|
||||||
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=localhost
|
|
||||||
Subject Public Key Info:
|
|
||||||
Public Key Algorithm: rsaEncryption
|
|
||||||
Public-Key: (2048 bit)
|
|
||||||
Modulus:
|
|
||||||
00:e0:57:81:be:67:37:f6:0d:3e:67:a0:08:ac:20:
|
|
||||||
61:61:9f:f6:f3:ed:59:f9:5a:25:d4:a9:b0:ec:c5:
|
|
||||||
13:89:3a:1f:fb:06:d3:a5:76:e6:64:6b:4a:4f:84:
|
|
||||||
5c:a5:19:b9:f1:4b:c9:75:90:45:87:44:8d:93:ea:
|
|
||||||
13:a8:5b:3b:a6:07:a2:2d:2a:23:7e:4f:92:77:d2:
|
|
||||||
50:2f:4b:2a:3b:8b:07:45:a0:04:3f:4b:99:cf:5d:
|
|
||||||
07:e1:34:04:50:7b:f3:44:3a:14:6d:a5:cb:8d:77:
|
|
||||||
2c:78:05:67:4f:74:fb:89:40:0d:40:48:d2:42:2f:
|
|
||||||
07:0b:3a:84:71:68:b6:ca:2e:f6:f6:57:94:f9:14:
|
|
||||||
20:24:78:d3:ed:46:f3:ee:4f:88:0a:40:8b:4c:9a:
|
|
||||||
21:df:02:1a:15:0b:c3:19:58:5f:c6:0b:44:6e:90:
|
|
||||||
72:0d:ca:ce:4c:c2:a7:85:7b:16:a6:f0:2c:e7:99:
|
|
||||||
03:cc:62:b2:dd:86:62:93:8f:70:d3:8a:f0:8f:a2:
|
|
||||||
1f:7b:10:32:05:1a:58:19:48:26:9a:60:35:50:03:
|
|
||||||
e6:aa:96:8f:ea:da:98:b9:d8:f1:70:0b:52:b3:84:
|
|
||||||
d1:00:ec:47:8e:a9:2c:02:d4:d4:23:c2:31:ee:85:
|
|
||||||
c9:df:f5:66:f1:ae:04:ea:db:38:77:ae:fe:58:11:
|
|
||||||
6d:99
|
|
||||||
Exponent: 65537 (0x10001)
|
|
||||||
X509v3 extensions:
|
|
||||||
X509v3 Subject Alternative Name:
|
|
||||||
DNS:localhost
|
|
||||||
X509v3 Key Usage: critical
|
|
||||||
Digital Signature, Key Encipherment
|
|
||||||
X509v3 Extended Key Usage:
|
|
||||||
TLS Web Server Authentication, TLS Web Client Authentication
|
|
||||||
X509v3 Basic Constraints: critical
|
|
||||||
CA:FALSE
|
|
||||||
X509v3 Subject Key Identifier:
|
|
||||||
85:11:BE:16:47:04:D1:30:EE:86:8A:18:70:BE:A8:28:6F:82:3D:CE
|
|
||||||
X509v3 Authority Key Identifier:
|
|
||||||
keyid:9A:CF:CF:6E:EB:71:3D:DB:3C:F1:AE:88:6B:56:72:03:CB:08:A7:48
|
|
||||||
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
|
|
||||||
serial:82:ED:BF:41:C8:80:91:9B
|
|
||||||
|
|
||||||
Authority Information Access:
|
|
||||||
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
|
|
||||||
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
|
|
||||||
|
|
||||||
X509v3 CRL Distribution Points:
|
|
||||||
|
|
||||||
Full Name:
|
|
||||||
URI:http://testca.pythontest.net/testca/revocation.crl
|
|
||||||
|
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
|
||||||
7f:a1:7e:3e:68:01:b0:32:b8:57:b8:03:68:13:13:b3:e3:f4:
|
|
||||||
70:2f:15:e5:0f:87:b9:fd:e0:12:e3:16:f2:91:53:c7:4e:25:
|
|
||||||
af:ca:cb:a7:d9:9d:57:4d:bf:a2:80:d4:78:aa:04:31:fd:6d:
|
|
||||||
cc:6d:82:43:e9:62:16:0d:0e:26:8b:e7:f1:3d:57:5c:68:02:
|
|
||||||
9c:2b:b6:c9:fd:62:2f:10:85:88:cc:44:a5:e7:a2:3e:89:f2:
|
|
||||||
1f:02:6a:3f:d0:3c:6c:24:2d:bc:51:62:7a:ec:25:c5:86:87:
|
|
||||||
77:35:8f:f9:7e:d0:17:3d:77:56:bf:1a:0c:be:09:78:ee:ea:
|
|
||||||
73:97:65:60:94:91:35:b3:5c:46:8a:5e:6d:94:52:de:48:b7:
|
|
||||||
1f:6c:28:79:7f:ff:08:8d:e4:7d:d0:b9:0b:7c:ae:c4:1d:2a:
|
|
||||||
a1:b3:50:11:82:03:5e:6c:e7:26:fa:05:32:39:07:83:49:b9:
|
|
||||||
a2:fa:04:da:0d:e5:ff:4c:db:97:d0:c3:a7:43:37:4c:16:de:
|
|
||||||
3c:b5:e9:7e:82:d4:b3:10:df:d1:c1:66:72:9c:15:67:19:3b:
|
|
||||||
7b:91:0a:82:07:67:c5:06:03:5f:80:54:08:81:8a:b1:5c:7c:
|
|
||||||
4c:d2:07:38:92:eb:12:f5:71:ae:de:05:15:c8:e1:33:f0:e4:
|
|
||||||
96:0f:0f:1e
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIE8TCCA9mgAwIBAgIJAILtv0HIgJGcMA0GCSqGSIb3DQEBBQUAME0xCzAJBgNV
|
|
||||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
|
||||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODAxMTkxOTA5MDZaFw0yNzExMjgx
|
|
||||||
OTA5MDZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
|
|
||||||
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMMCWxv
|
|
||||||
Y2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOBXgb5nN/YN
|
|
||||||
PmegCKwgYWGf9vPtWflaJdSpsOzFE4k6H/sG06V25mRrSk+EXKUZufFLyXWQRYdE
|
|
||||||
jZPqE6hbO6YHoi0qI35PknfSUC9LKjuLB0WgBD9Lmc9dB+E0BFB780Q6FG2ly413
|
|
||||||
LHgFZ090+4lADUBI0kIvBws6hHFotsou9vZXlPkUICR40+1G8+5PiApAi0yaId8C
|
|
||||||
GhULwxlYX8YLRG6Qcg3KzkzCp4V7FqbwLOeZA8xist2GYpOPcNOK8I+iH3sQMgUa
|
|
||||||
WBlIJppgNVAD5qqWj+ramLnY8XALUrOE0QDsR46pLALU1CPCMe6Fyd/1ZvGuBOrb
|
|
||||||
OHeu/lgRbZkCAwEAAaOCAcAwggG8MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAOBgNV
|
|
||||||
HQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1Ud
|
|
||||||
EwEB/wQCMAAwHQYDVR0OBBYEFIURvhZHBNEw7oaKGHC+qChvgj3OMH0GA1UdIwR2
|
|
||||||
MHSAFJrPz27rcT3bPPGuiGtWcgPLCKdIoVGkTzBNMQswCQYDVQQGEwJYWTEmMCQG
|
|
||||||
A1UECgwdUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24gQ0ExFjAUBgNVBAMMDW91
|
|
||||||
ci1jYS1zZXJ2ZXKCCQCC7b9ByICRmzCBgwYIKwYBBQUHAQEEdzB1MDwGCCsGAQUF
|
|
||||||
BzAChjBodHRwOi8vdGVzdGNhLnB5dGhvbnRlc3QubmV0L3Rlc3RjYS9weWNhY2Vy
|
|
||||||
dC5jZXIwNQYIKwYBBQUHMAGGKWh0dHA6Ly90ZXN0Y2EucHl0aG9udGVzdC5uZXQv
|
|
||||||
dGVzdGNhL29jc3AvMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly90ZXN0Y2EucHl0
|
|
||||||
aG9udGVzdC5uZXQvdGVzdGNhL3Jldm9jYXRpb24uY3JsMA0GCSqGSIb3DQEBBQUA
|
|
||||||
A4IBAQB/oX4+aAGwMrhXuANoExOz4/RwLxXlD4e5/eAS4xbykVPHTiWvysun2Z1X
|
|
||||||
Tb+igNR4qgQx/W3MbYJD6WIWDQ4mi+fxPVdcaAKcK7bJ/WIvEIWIzESl56I+ifIf
|
|
||||||
Amo/0DxsJC28UWJ67CXFhod3NY/5ftAXPXdWvxoMvgl47upzl2VglJE1s1xGil5t
|
|
||||||
lFLeSLcfbCh5f/8IjeR90LkLfK7EHSqhs1ARggNebOcm+gUyOQeDSbmi+gTaDeX/
|
|
||||||
TNuX0MOnQzdMFt48tel+gtSzEN/RwWZynBVnGTt7kQqCB2fFBgNfgFQIgYqxXHxM
|
|
||||||
0gc4kusS9XGu3gUVyOEz8OSWDw8e
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDH/76hZAZH4cSV
|
|
||||||
CmVZa5HEqKCjCKrcPwBECs9BS+3ibwN4x9NnFNP+tCeFGgJXl7WGFoeXgg3oK+1p
|
|
||||||
FsOWpsRHuF3BdqkCnShSydmT8bLaGHwKeL0cPxJP5T/uW7ezPKW2VWXGMwmwRaRJ
|
|
||||||
9dj2VCUu20vDZWSGFr9zjnjoJczBtH3RsVUgpK7euEHuQ5pIM9QSOaCo+5FPR7s7
|
|
||||||
1nU7YqbFWtd+NhC8Og1G497B31DQlHciF6BRm6/cNGAmHaAErKUGBFdkGtFPHBn4
|
|
||||||
vktoEg9fwxJAZLvGpoTZWrB4HRsRwVTmFdGvK+JXK225xF23AXRXp/snhSuSFeLj
|
|
||||||
E5cpyJJ7AgMBAAECggEAQOv527X2e/sDr0XSpHZQuT/r9UBpBlnFIlFH+fBF5k0X
|
|
||||||
GWv0ae/O6U1dzs0kmX57xG0n0ry6+vTXeleTYiH8cTOd66EzN9AAOO+hG29IGZf9
|
|
||||||
HAEZkkO/FARc/mjzdtFnEYsjIHWM3ZWdwQx3Q28JKu6w51rQiN51g3NqOCGdF/uF
|
|
||||||
rE5XPKsKndn+nLHvsNuApFgUYZEwdrozgUueEgRaPTUCNhzotcA9eWoBdA24XNhk
|
|
||||||
x8Cm/bZWabXm7gBO75zl3Cu2F21ay+EuwyOZTsx6lZi6YX9/zo1mkO81Zi3tQk50
|
|
||||||
NMEI0feLNwsdxTbmOcVJadjOgd+QVghlFyr5HGBWMQKBgQD3AH3rhnAo6tOyNkGN
|
|
||||||
+IzIU1MhUS452O7IavykUYO9sM24BVChpRtlI9Dpev4yE/q3BAO3+oWT3cJrN7/3
|
|
||||||
iyo1dzAkpGvI65XWfElXFM4nLjEiZzx4W9fiPN91Oucpr0ED6+BZXTtz4gVm0TP/
|
|
||||||
TUc2xvTB6EKvIyWmKOYEi0snxQKBgQDPSOjbz9jWOrC9XY7PmtLB6QJDDz7XSGVK
|
|
||||||
wzD+gDAPpAwhk58BEokdOhBx2Lwl8zMJi0CRHgH2vNvkRyhvUQ4UFzisrqann/Tw
|
|
||||||
klp5sw3iWC6ERC8z9zL7GfHs7sK3mOVeAdK6ffowPM3JrZ2vPusVBdr0MN3oZwki
|
|
||||||
CtNXqbY1PwKBgGheQNbAW6wubX0kB9chavtKmhm937Z5v4vYCSC1gOEqUAKt3EAx
|
|
||||||
L74wwBmn6rjmUE382EVpCgBM99WuHONQXmlxD1qsTw763LlgkuzE0cckcYaD8L06
|
|
||||||
saHa7uDuHrcyYlpx1L5t8q0ol/e19i6uTKUMtGcq6OJwC3yGU4sgAIWxAoGBAMVq
|
|
||||||
qiQXm2vFL+jafxYoXUvDMJ1PmskMsTP4HOR2j8+FrOwZnVk3HxGP6HOVOPRn4JbZ
|
|
||||||
YiAT1Uj6a+7I+rCyINdvmlGUcTK6fFzW9oZryvBkjcD483/pkktmVWwTpa2YV/Ml
|
|
||||||
h16IdsyUTGYlDUYHhXtbPUJOfDpIT4F1j/0wrFGfAoGAO82BcUsehEUQE0xvQLIn
|
|
||||||
7QaFtUI5z19WW730jVuEobiYlh9Ka4DPbKMvka8MwyOxEwhk39gZQavmfG6+wZm+
|
|
||||||
kjERU23LhHziJGWS2Um4yIhC7myKbWaLzjHEq72dszLpQku4BzE5fT60fxI7cURD
|
|
||||||
WGm/Z3Q2weS3ZGIoMj1RNPI=
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
Certificate:
|
|
||||||
Data:
|
|
||||||
Version: 3 (0x2)
|
|
||||||
Serial Number:
|
|
||||||
82:ed:bf:41:c8:80:91:9d
|
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
|
||||||
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
|
||||||
Validity
|
|
||||||
Not Before: Jan 19 19:09:06 2018 GMT
|
|
||||||
Not After : Nov 28 19:09:06 2027 GMT
|
|
||||||
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=fakehostname
|
|
||||||
Subject Public Key Info:
|
|
||||||
Public Key Algorithm: rsaEncryption
|
|
||||||
Public-Key: (2048 bit)
|
|
||||||
Modulus:
|
|
||||||
00:c7:ff:be:a1:64:06:47:e1:c4:95:0a:65:59:6b:
|
|
||||||
91:c4:a8:a0:a3:08:aa:dc:3f:00:44:0a:cf:41:4b:
|
|
||||||
ed:e2:6f:03:78:c7:d3:67:14:d3:fe:b4:27:85:1a:
|
|
||||||
02:57:97:b5:86:16:87:97:82:0d:e8:2b:ed:69:16:
|
|
||||||
c3:96:a6:c4:47:b8:5d:c1:76:a9:02:9d:28:52:c9:
|
|
||||||
d9:93:f1:b2:da:18:7c:0a:78:bd:1c:3f:12:4f:e5:
|
|
||||||
3f:ee:5b:b7:b3:3c:a5:b6:55:65:c6:33:09:b0:45:
|
|
||||||
a4:49:f5:d8:f6:54:25:2e:db:4b:c3:65:64:86:16:
|
|
||||||
bf:73:8e:78:e8:25:cc:c1:b4:7d:d1:b1:55:20:a4:
|
|
||||||
ae:de:b8:41:ee:43:9a:48:33:d4:12:39:a0:a8:fb:
|
|
||||||
91:4f:47:bb:3b:d6:75:3b:62:a6:c5:5a:d7:7e:36:
|
|
||||||
10:bc:3a:0d:46:e3:de:c1:df:50:d0:94:77:22:17:
|
|
||||||
a0:51:9b:af:dc:34:60:26:1d:a0:04:ac:a5:06:04:
|
|
||||||
57:64:1a:d1:4f:1c:19:f8:be:4b:68:12:0f:5f:c3:
|
|
||||||
12:40:64:bb:c6:a6:84:d9:5a:b0:78:1d:1b:11:c1:
|
|
||||||
54:e6:15:d1:af:2b:e2:57:2b:6d:b9:c4:5d:b7:01:
|
|
||||||
74:57:a7:fb:27:85:2b:92:15:e2:e3:13:97:29:c8:
|
|
||||||
92:7b
|
|
||||||
Exponent: 65537 (0x10001)
|
|
||||||
X509v3 extensions:
|
|
||||||
X509v3 Subject Alternative Name:
|
|
||||||
DNS:fakehostname
|
|
||||||
X509v3 Key Usage: critical
|
|
||||||
Digital Signature, Key Encipherment
|
|
||||||
X509v3 Extended Key Usage:
|
|
||||||
TLS Web Server Authentication, TLS Web Client Authentication
|
|
||||||
X509v3 Basic Constraints: critical
|
|
||||||
CA:FALSE
|
|
||||||
X509v3 Subject Key Identifier:
|
|
||||||
F8:76:79:CB:11:85:F0:46:E5:95:E6:7E:69:CB:12:5E:4E:AA:EC:4D
|
|
||||||
X509v3 Authority Key Identifier:
|
|
||||||
keyid:9A:CF:CF:6E:EB:71:3D:DB:3C:F1:AE:88:6B:56:72:03:CB:08:A7:48
|
|
||||||
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
|
|
||||||
serial:82:ED:BF:41:C8:80:91:9B
|
|
||||||
|
|
||||||
Authority Information Access:
|
|
||||||
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
|
|
||||||
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
|
|
||||||
|
|
||||||
X509v3 CRL Distribution Points:
|
|
||||||
|
|
||||||
Full Name:
|
|
||||||
URI:http://testca.pythontest.net/testca/revocation.crl
|
|
||||||
|
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
|
||||||
6d:50:8d:fb:ee:4e:93:8b:eb:47:56:ba:38:cc:80:e1:9d:c7:
|
|
||||||
e1:9e:1f:9c:22:0c:d2:08:9b:ed:bf:31:d9:00:ee:af:8c:56:
|
|
||||||
78:92:d1:7c:ba:4e:81:7f:82:1f:f4:68:99:86:91:c6:cb:57:
|
|
||||||
d3:b9:41:12:fa:75:53:fd:22:32:21:50:af:6b:4c:b1:34:36:
|
|
||||||
d1:a8:25:0a:d0:f0:f8:81:7d:69:58:6e:af:e3:d2:c4:32:87:
|
|
||||||
79:d7:cd:ad:0c:56:f3:15:27:10:0c:f9:57:59:53:00:ed:af:
|
|
||||||
5d:4d:07:86:7a:e5:f3:97:88:bc:86:b4:f1:17:46:33:55:28:
|
|
||||||
66:7b:70:d3:a5:12:b9:4f:c7:ed:e6:13:20:2d:f0:9e:ec:17:
|
|
||||||
64:cf:fd:13:14:1b:76:ba:64:ac:c5:51:b6:cd:13:0a:93:b1:
|
|
||||||
fd:43:09:a0:0b:44:6c:77:45:43:0b:e5:ed:70:b2:76:dc:08:
|
|
||||||
4a:5b:73:5f:c1:fc:7f:63:70:f8:b9:ca:3c:98:06:5f:fd:98:
|
|
||||||
d1:e4:e6:61:5f:09:8f:6c:18:86:98:9c:cb:3f:73:7b:3f:38:
|
|
||||||
f5:a7:09:20:ee:a5:63:1c:ff:8b:a6:d1:8c:e8:f4:84:3d:99:
|
|
||||||
38:0f:cc:e0:52:03:f9:18:05:23:76:39:de:52:ce:8e:fb:a6:
|
|
||||||
6e:f5:4f:c3
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIE9zCCA9+gAwIBAgIJAILtv0HIgJGdMA0GCSqGSIb3DQEBBQUAME0xCzAJBgNV
|
|
||||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
|
||||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODAxMTkxOTA5MDZaFw0yNzExMjgx
|
|
||||||
OTA5MDZaMGIxCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
|
|
||||||
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xFTATBgNVBAMMDGZh
|
|
||||||
a2Vob3N0bmFtZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMf/vqFk
|
|
||||||
BkfhxJUKZVlrkcSooKMIqtw/AEQKz0FL7eJvA3jH02cU0/60J4UaAleXtYYWh5eC
|
|
||||||
Degr7WkWw5amxEe4XcF2qQKdKFLJ2ZPxstoYfAp4vRw/Ek/lP+5bt7M8pbZVZcYz
|
|
||||||
CbBFpEn12PZUJS7bS8NlZIYWv3OOeOglzMG0fdGxVSCkrt64Qe5Dmkgz1BI5oKj7
|
|
||||||
kU9HuzvWdTtipsVa1342ELw6DUbj3sHfUNCUdyIXoFGbr9w0YCYdoASspQYEV2Qa
|
|
||||||
0U8cGfi+S2gSD1/DEkBku8amhNlasHgdGxHBVOYV0a8r4lcrbbnEXbcBdFen+yeF
|
|
||||||
K5IV4uMTlynIknsCAwEAAaOCAcMwggG/MBcGA1UdEQQQMA6CDGZha2Vob3N0bmFt
|
|
||||||
ZTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC
|
|
||||||
MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPh2ecsRhfBG5ZXmfmnLEl5OquxNMH0G
|
|
||||||
A1UdIwR2MHSAFJrPz27rcT3bPPGuiGtWcgPLCKdIoVGkTzBNMQswCQYDVQQGEwJY
|
|
||||||
WTEmMCQGA1UECgwdUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24gQ0ExFjAUBgNV
|
|
||||||
BAMMDW91ci1jYS1zZXJ2ZXKCCQCC7b9ByICRmzCBgwYIKwYBBQUHAQEEdzB1MDwG
|
|
||||||
CCsGAQUFBzAChjBodHRwOi8vdGVzdGNhLnB5dGhvbnRlc3QubmV0L3Rlc3RjYS9w
|
|
||||||
eWNhY2VydC5jZXIwNQYIKwYBBQUHMAGGKWh0dHA6Ly90ZXN0Y2EucHl0aG9udGVz
|
|
||||||
dC5uZXQvdGVzdGNhL29jc3AvMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly90ZXN0
|
|
||||||
Y2EucHl0aG9udGVzdC5uZXQvdGVzdGNhL3Jldm9jYXRpb24uY3JsMA0GCSqGSIb3
|
|
||||||
DQEBBQUAA4IBAQBtUI377k6Ti+tHVro4zIDhncfhnh+cIgzSCJvtvzHZAO6vjFZ4
|
|
||||||
ktF8uk6Bf4If9GiZhpHGy1fTuUES+nVT/SIyIVCva0yxNDbRqCUK0PD4gX1pWG6v
|
|
||||||
49LEMod5182tDFbzFScQDPlXWVMA7a9dTQeGeuXzl4i8hrTxF0YzVShme3DTpRK5
|
|
||||||
T8ft5hMgLfCe7Bdkz/0TFBt2umSsxVG2zRMKk7H9QwmgC0Rsd0VDC+XtcLJ23AhK
|
|
||||||
W3Nfwfx/Y3D4uco8mAZf/ZjR5OZhXwmPbBiGmJzLP3N7Pzj1pwkg7qVjHP+LptGM
|
|
||||||
6PSEPZk4D8zgUgP5GAUjdjneUs6O+6Zu9U/D
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDe3QWmhZX07HZbntz4
|
|
||||||
CFqAOaoYMdYwD7Z3WPNIc2zR7p4D6BMOa7NAWjLV5A7CUw6hZANiAAQ5IVKzLLz4
|
|
||||||
LCfcpy6fMOp+jk5KwywsU3upPtjA6E3UetxPcfnnv+gghRyDAYLN2OVqZgLMEmUo
|
|
||||||
F1j1SM1QrbhHIuNcVxI9gPPMdumcNFSz/hqxrBRtA/8Z2gywczdNLjc=
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
Certificate:
|
|
||||||
Data:
|
|
||||||
Version: 3 (0x2)
|
|
||||||
Serial Number:
|
|
||||||
82:ed:bf:41:c8:80:91:9e
|
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
|
||||||
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
|
|
||||||
Validity
|
|
||||||
Not Before: Jan 19 19:09:06 2018 GMT
|
|
||||||
Not After : Nov 28 19:09:06 2027 GMT
|
|
||||||
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=localhost-ecc
|
|
||||||
Subject Public Key Info:
|
|
||||||
Public Key Algorithm: id-ecPublicKey
|
|
||||||
Public-Key: (384 bit)
|
|
||||||
pub:
|
|
||||||
04:39:21:52:b3:2c:bc:f8:2c:27:dc:a7:2e:9f:30:
|
|
||||||
ea:7e:8e:4e:4a:c3:2c:2c:53:7b:a9:3e:d8:c0:e8:
|
|
||||||
4d:d4:7a:dc:4f:71:f9:e7:bf:e8:20:85:1c:83:01:
|
|
||||||
82:cd:d8:e5:6a:66:02:cc:12:65:28:17:58:f5:48:
|
|
||||||
cd:50:ad:b8:47:22:e3:5c:57:12:3d:80:f3:cc:76:
|
|
||||||
e9:9c:34:54:b3:fe:1a:b1:ac:14:6d:03:ff:19:da:
|
|
||||||
0c:b0:73:37:4d:2e:37
|
|
||||||
ASN1 OID: secp384r1
|
|
||||||
NIST CURVE: P-384
|
|
||||||
X509v3 extensions:
|
|
||||||
X509v3 Subject Alternative Name:
|
|
||||||
DNS:localhost-ecc
|
|
||||||
X509v3 Key Usage: critical
|
|
||||||
Digital Signature, Key Encipherment
|
|
||||||
X509v3 Extended Key Usage:
|
|
||||||
TLS Web Server Authentication, TLS Web Client Authentication
|
|
||||||
X509v3 Basic Constraints: critical
|
|
||||||
CA:FALSE
|
|
||||||
X509v3 Subject Key Identifier:
|
|
||||||
33:23:0E:15:04:83:2E:3D:BF:DA:81:6D:10:38:80:C3:C2:B0:A4:74
|
|
||||||
X509v3 Authority Key Identifier:
|
|
||||||
keyid:9A:CF:CF:6E:EB:71:3D:DB:3C:F1:AE:88:6B:56:72:03:CB:08:A7:48
|
|
||||||
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
|
|
||||||
serial:82:ED:BF:41:C8:80:91:9B
|
|
||||||
|
|
||||||
Authority Information Access:
|
|
||||||
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
|
|
||||||
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
|
|
||||||
|
|
||||||
X509v3 CRL Distribution Points:
|
|
||||||
|
|
||||||
Full Name:
|
|
||||||
URI:http://testca.pythontest.net/testca/revocation.crl
|
|
||||||
|
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
|
||||||
3b:6f:97:af:7e:5f:e0:14:34:ed:57:7e:de:ce:c4:85:1e:aa:
|
|
||||||
84:52:94:7c:e5:ce:e9:9c:88:8b:ad:b5:4d:16:ac:af:81:ea:
|
|
||||||
b8:a2:e2:50:2e:cb:e9:11:bd:1b:a6:3f:0c:a2:d7:7b:67:72:
|
|
||||||
b3:43:16:ad:c6:87:ac:6e:ac:47:78:ef:2f:8c:86:e8:9b:d1:
|
|
||||||
43:8c:c1:7a:91:30:e9:14:d6:9f:41:8b:9b:0b:24:9b:78:86:
|
|
||||||
11:8a:fc:2b:cd:c9:13:ee:90:4f:14:33:51:a3:c4:9e:d6:06:
|
|
||||||
48:f5:41:12:af:f0:f2:71:40:78:f5:96:c2:5d:cf:e1:38:ff:
|
|
||||||
bf:10:eb:74:2f:c2:23:21:3e:27:f5:f1:f2:af:2c:62:82:31:
|
|
||||||
00:c8:96:1b:c3:7e:8d:71:89:e7:40:b5:67:1a:33:fb:c0:8b:
|
|
||||||
96:0c:36:78:25:27:82:d8:27:27:52:0f:f7:69:cd:ff:2b:92:
|
|
||||||
10:d3:d2:0a:db:65:ed:af:90:eb:db:76:f3:8a:7a:13:9e:c6:
|
|
||||||
33:57:15:42:06:13:d6:54:49:fa:84:a7:0e:1d:14:72:ca:19:
|
|
||||||
8e:2b:aa:a4:02:54:3c:f6:1c:23:81:7a:59:54:b0:92:65:72:
|
|
||||||
c8:e5:ba:9f:03:4e:30:f2:4d:45:85:e3:35:a8:b1:68:58:b9:
|
|
||||||
3b:20:a3:eb
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIESzCCAzOgAwIBAgIJAILtv0HIgJGeMA0GCSqGSIb3DQEBBQUAME0xCzAJBgNV
|
|
||||||
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
|
|
||||||
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODAxMTkxOTA5MDZaFw0yNzExMjgx
|
|
||||||
OTA5MDZaMGMxCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
|
|
||||||
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xFjAUBgNVBAMMDWxv
|
|
||||||
Y2FsaG9zdC1lY2MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQ5IVKzLLz4LCfcpy6f
|
|
||||||
MOp+jk5KwywsU3upPtjA6E3UetxPcfnnv+gghRyDAYLN2OVqZgLMEmUoF1j1SM1Q
|
|
||||||
rbhHIuNcVxI9gPPMdumcNFSz/hqxrBRtA/8Z2gywczdNLjejggHEMIIBwDAYBgNV
|
|
||||||
HREEETAPgg1sb2NhbGhvc3QtZWNjMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAU
|
|
||||||
BggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUMyMO
|
|
||||||
FQSDLj2/2oFtEDiAw8KwpHQwfQYDVR0jBHYwdIAUms/PbutxPds88a6Ia1ZyA8sI
|
|
||||||
p0ihUaRPME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUg
|
|
||||||
Rm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcoIJAILtv0HIgJGb
|
|
||||||
MIGDBggrBgEFBQcBAQR3MHUwPAYIKwYBBQUHMAKGMGh0dHA6Ly90ZXN0Y2EucHl0
|
|
||||||
aG9udGVzdC5uZXQvdGVzdGNhL3B5Y2FjZXJ0LmNlcjA1BggrBgEFBQcwAYYpaHR0
|
|
||||||
cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0Y2Evb2NzcC8wQwYDVR0fBDww
|
|
||||||
OjA4oDagNIYyaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0Y2EvcmV2
|
|
||||||
b2NhdGlvbi5jcmwwDQYJKoZIhvcNAQEFBQADggEBADtvl69+X+AUNO1Xft7OxIUe
|
|
||||||
qoRSlHzlzumciIuttU0WrK+B6rii4lAuy+kRvRumPwyi13tncrNDFq3Gh6xurEd4
|
|
||||||
7y+Mhuib0UOMwXqRMOkU1p9Bi5sLJJt4hhGK/CvNyRPukE8UM1GjxJ7WBkj1QRKv
|
|
||||||
8PJxQHj1lsJdz+E4/78Q63QvwiMhPif18fKvLGKCMQDIlhvDfo1xiedAtWcaM/vA
|
|
||||||
i5YMNnglJ4LYJydSD/dpzf8rkhDT0grbZe2vkOvbdvOKehOexjNXFUIGE9ZUSfqE
|
|
||||||
pw4dFHLKGY4rqqQCVDz2HCOBellUsJJlcsjlup8DTjDyTUWF4zWosWhYuTsgo+s=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -41,6 +41,8 @@ class ExceptionTests(unittest.TestCase):
|
|||||||
self.assertEqual(buf1, buf2)
|
self.assertEqual(buf1, buf2)
|
||||||
self.assertEqual(exc.__name__, excname)
|
self.assertEqual(exc.__name__, excname)
|
||||||
|
|
||||||
|
# TODO: RUSTPYTHON
|
||||||
|
@unittest.expectedFailure
|
||||||
def testRaising(self):
|
def testRaising(self):
|
||||||
self.raise_catch(AttributeError, "AttributeError")
|
self.raise_catch(AttributeError, "AttributeError")
|
||||||
self.assertRaises(AttributeError, getattr, sys, "undefined_attribute")
|
self.assertRaises(AttributeError, getattr, sys, "undefined_attribute")
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -599,101 +599,102 @@ class MathTests(unittest.TestCase):
|
|||||||
self.assertTrue(math.isnan(math.frexp(NAN)[0]))
|
self.assertTrue(math.isnan(math.frexp(NAN)[0]))
|
||||||
|
|
||||||
|
|
||||||
@requires_IEEE_754
|
# TODO: RUSTPYTHON
|
||||||
@unittest.skipIf(HAVE_DOUBLE_ROUNDING,
|
# @requires_IEEE_754
|
||||||
"fsum is not exact on machines with double rounding")
|
# @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
|
||||||
def testFsum(self):
|
# "fsum is not exact on machines with double rounding")
|
||||||
# math.fsum relies on exact rounding for correct operation.
|
# def testFsum(self):
|
||||||
# There's a known problem with IA32 floating-point that causes
|
# # math.fsum relies on exact rounding for correct operation.
|
||||||
# inexact rounding in some situations, and will cause the
|
# # There's a known problem with IA32 floating-point that causes
|
||||||
# math.fsum tests below to fail; see issue #2937. On non IEEE
|
# # inexact rounding in some situations, and will cause the
|
||||||
# 754 platforms, and on IEEE 754 platforms that exhibit the
|
# # math.fsum tests below to fail; see issue #2937. On non IEEE
|
||||||
# problem described in issue #2937, we simply skip the whole
|
# # 754 platforms, and on IEEE 754 platforms that exhibit the
|
||||||
# test.
|
# # problem described in issue #2937, we simply skip the whole
|
||||||
|
# # test.
|
||||||
|
|
||||||
# Python version of math.fsum, for comparison. Uses a
|
# # Python version of math.fsum, for comparison. Uses a
|
||||||
# different algorithm based on frexp, ldexp and integer
|
# # different algorithm based on frexp, ldexp and integer
|
||||||
# arithmetic.
|
# # arithmetic.
|
||||||
from sys import float_info
|
# from sys import float_info
|
||||||
mant_dig = float_info.mant_dig
|
# mant_dig = float_info.mant_dig
|
||||||
etiny = float_info.min_exp - mant_dig
|
# etiny = float_info.min_exp - mant_dig
|
||||||
|
|
||||||
def msum(iterable):
|
# def msum(iterable):
|
||||||
"""Full precision summation. Compute sum(iterable) without any
|
# """Full precision summation. Compute sum(iterable) without any
|
||||||
intermediate accumulation of error. Based on the 'lsum' function
|
# intermediate accumulation of error. Based on the 'lsum' function
|
||||||
at http://code.activestate.com/recipes/393090/
|
# at http://code.activestate.com/recipes/393090/
|
||||||
"""
|
# """
|
||||||
tmant, texp = 0, 0
|
# tmant, texp = 0, 0
|
||||||
for x in iterable:
|
# for x in iterable:
|
||||||
mant, exp = math.frexp(x)
|
# mant, exp = math.frexp(x)
|
||||||
mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
|
# mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
|
||||||
if texp > exp:
|
# if texp > exp:
|
||||||
tmant <<= texp-exp
|
# tmant <<= texp-exp
|
||||||
texp = exp
|
# texp = exp
|
||||||
else:
|
# else:
|
||||||
mant <<= exp-texp
|
# mant <<= exp-texp
|
||||||
tmant += mant
|
# tmant += mant
|
||||||
# Round tmant * 2**texp to a float. The original recipe
|
# # Round tmant * 2**texp to a float. The original recipe
|
||||||
# used float(str(tmant)) * 2.0**texp for this, but that's
|
# # used float(str(tmant)) * 2.0**texp for this, but that's
|
||||||
# a little unsafe because str -> float conversion can't be
|
# # a little unsafe because str -> float conversion can't be
|
||||||
# relied upon to do correct rounding on all platforms.
|
# # relied upon to do correct rounding on all platforms.
|
||||||
tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
|
# tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
|
||||||
if tail > 0:
|
# if tail > 0:
|
||||||
h = 1 << (tail-1)
|
# h = 1 << (tail-1)
|
||||||
tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
|
# tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
|
||||||
texp += tail
|
# texp += tail
|
||||||
return math.ldexp(tmant, texp)
|
# return math.ldexp(tmant, texp)
|
||||||
|
|
||||||
test_values = [
|
# test_values = [
|
||||||
([], 0.0),
|
# ([], 0.0),
|
||||||
([0.0], 0.0),
|
# ([0.0], 0.0),
|
||||||
([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
|
# ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
|
||||||
([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
|
# ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
|
||||||
([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
|
# ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
|
||||||
([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
|
# ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
|
||||||
([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
|
# ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
|
||||||
([1./n for n in range(1, 1001)],
|
# ([1./n for n in range(1, 1001)],
|
||||||
float.fromhex('0x1.df11f45f4e61ap+2')),
|
# float.fromhex('0x1.df11f45f4e61ap+2')),
|
||||||
([(-1.)**n/n for n in range(1, 1001)],
|
# ([(-1.)**n/n for n in range(1, 1001)],
|
||||||
float.fromhex('-0x1.62a2af1bd3624p-1')),
|
# float.fromhex('-0x1.62a2af1bd3624p-1')),
|
||||||
([1e16, 1., 1e-16], 10000000000000002.0),
|
# ([1e16, 1., 1e-16], 10000000000000002.0),
|
||||||
([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
|
# ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
|
||||||
# exercise code for resizing partials array
|
# # exercise code for resizing partials array
|
||||||
([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
|
# ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
|
||||||
[-2.**1022],
|
# [-2.**1022],
|
||||||
float.fromhex('0x1.5555555555555p+970')),
|
# float.fromhex('0x1.5555555555555p+970')),
|
||||||
]
|
# ]
|
||||||
|
|
||||||
# Telescoping sum, with exact differences (due to Sterbenz)
|
# # Telescoping sum, with exact differences (due to Sterbenz)
|
||||||
terms = [1.7**i for i in range(1001)]
|
# terms = [1.7**i for i in range(1001)]
|
||||||
test_values.append((
|
# test_values.append((
|
||||||
[terms[i+1] - terms[i] for i in range(1000)] + [-terms[1000]],
|
# [terms[i+1] - terms[i] for i in range(1000)] + [-terms[1000]],
|
||||||
-terms[0]
|
# -terms[0]
|
||||||
))
|
# ))
|
||||||
|
|
||||||
for i, (vals, expected) in enumerate(test_values):
|
# for i, (vals, expected) in enumerate(test_values):
|
||||||
try:
|
# try:
|
||||||
actual = math.fsum(vals)
|
# actual = math.fsum(vals)
|
||||||
except OverflowError:
|
# except OverflowError:
|
||||||
self.fail("test %d failed: got OverflowError, expected %r "
|
# self.fail("test %d failed: got OverflowError, expected %r "
|
||||||
"for math.fsum(%.100r)" % (i, expected, vals))
|
# "for math.fsum(%.100r)" % (i, expected, vals))
|
||||||
except ValueError:
|
# except ValueError:
|
||||||
self.fail("test %d failed: got ValueError, expected %r "
|
# self.fail("test %d failed: got ValueError, expected %r "
|
||||||
"for math.fsum(%.100r)" % (i, expected, vals))
|
# "for math.fsum(%.100r)" % (i, expected, vals))
|
||||||
self.assertEqual(actual, expected)
|
# self.assertEqual(actual, expected)
|
||||||
|
|
||||||
from random import random, gauss, shuffle
|
# from random import random, gauss, shuffle
|
||||||
for j in range(1000):
|
# for j in range(1000):
|
||||||
vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
|
# vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
|
||||||
s = 0
|
# s = 0
|
||||||
for i in range(200):
|
# for i in range(200):
|
||||||
v = gauss(0, random()) ** 7 - s
|
# v = gauss(0, random()) ** 7 - s
|
||||||
s += v
|
# s += v
|
||||||
vals.append(v)
|
# vals.append(v)
|
||||||
shuffle(vals)
|
# shuffle(vals)
|
||||||
|
|
||||||
s = msum(vals)
|
# s = msum(vals)
|
||||||
self.assertEqual(msum(vals), math.fsum(vals))
|
# self.assertEqual(msum(vals), math.fsum(vals))
|
||||||
|
|
||||||
|
|
||||||
# Python 3.9
|
# Python 3.9
|
||||||
@@ -1557,12 +1558,13 @@ class MathTests(unittest.TestCase):
|
|||||||
# def test_nan_constant(self):
|
# def test_nan_constant(self):
|
||||||
# self.assertTrue(math.isnan(math.nan))
|
# self.assertTrue(math.isnan(math.nan))
|
||||||
|
|
||||||
@requires_IEEE_754
|
# TODO: RUSTPYTHON
|
||||||
def test_inf_constant(self):
|
# @requires_IEEE_754
|
||||||
self.assertTrue(math.isinf(math.inf))
|
# def test_inf_constant(self):
|
||||||
self.assertGreater(math.inf, 0.0)
|
# self.assertTrue(math.isinf(math.inf))
|
||||||
self.assertEqual(math.inf, float("inf"))
|
# self.assertGreater(math.inf, 0.0)
|
||||||
self.assertEqual(-math.inf, float("-inf"))
|
# self.assertEqual(math.inf, float("inf"))
|
||||||
|
# self.assertEqual(-math.inf, float("-inf"))
|
||||||
|
|
||||||
# RED_FLAG 16-Oct-2000 Tim
|
# RED_FLAG 16-Oct-2000 Tim
|
||||||
# While 2.0 is more consistent about exceptions than previous releases, it
|
# While 2.0 is more consistent about exceptions than previous releases, it
|
||||||
|
|||||||
@@ -384,6 +384,8 @@ class AbstractMemoryTests:
|
|||||||
mm.release()
|
mm.release()
|
||||||
m.tolist()
|
m.tolist()
|
||||||
|
|
||||||
|
# TODO: RUSTPYTHON
|
||||||
|
@unittest.expectedFailure
|
||||||
def test_issue22668(self):
|
def test_issue22668(self):
|
||||||
a = array.array('H', [256, 256, 256, 256])
|
a = array.array('H', [256, 256, 256, 256])
|
||||||
x = memoryview(a)
|
x = memoryview(a)
|
||||||
|
|||||||
@@ -723,6 +723,8 @@ class UnpackIteratorTest(unittest.TestCase):
|
|||||||
self.assertRaises(StopIteration, next, it)
|
self.assertRaises(StopIteration, next, it)
|
||||||
self.assertRaises(StopIteration, next, it)
|
self.assertRaises(StopIteration, next, it)
|
||||||
|
|
||||||
|
# TODO: RUSTPYTHON
|
||||||
|
@unittest.expectedFailure
|
||||||
def test_half_float(self):
|
def test_half_float(self):
|
||||||
# Little-endian examples from:
|
# Little-endian examples from:
|
||||||
# http://en.wikipedia.org/wiki/Half_precision_floating-point_format
|
# http://en.wikipedia.org/wiki/Half_precision_floating-point_format
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ authors = ["RustPython Team"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num-bigint = { version = "0.3", default-features = false }
|
num-bigint = "0.3"
|
||||||
|
|||||||
251
ast/src/ast.rs
251
ast/src/ast.rs
@@ -5,21 +5,20 @@
|
|||||||
//! location of the node.
|
//! location of the node.
|
||||||
|
|
||||||
pub use crate::location::Location;
|
pub use crate::location::Location;
|
||||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Top<U = ()> {
|
pub enum Top {
|
||||||
Program(Program<U>),
|
Program(Program),
|
||||||
Statement(Vec<Statement<U>>),
|
Statement(Vec<Statement>),
|
||||||
Expression(Expression<U>),
|
Expression(Expression),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
/// A full python program, it's a sequence of statements.
|
/// A full python program, it's a sequence of statements.
|
||||||
pub struct Program<U = ()> {
|
pub struct Program {
|
||||||
pub statements: Suite<U>,
|
pub statements: Suite,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@@ -29,18 +28,17 @@ pub struct ImportSymbol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Located<T, U = ()> {
|
pub struct Located<T> {
|
||||||
pub location: Location,
|
pub location: Location,
|
||||||
pub node: T,
|
pub node: T,
|
||||||
pub custom: U,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Statement<U = ()> = Located<StatementType<U>, U>;
|
pub type Statement = Located<StatementType>;
|
||||||
pub type Suite<U = ()> = Vec<Statement<U>>;
|
pub type Suite = Vec<Statement>;
|
||||||
|
|
||||||
/// Abstract syntax tree nodes for python statements.
|
/// Abstract syntax tree nodes for python statements.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum StatementType<U = ()> {
|
pub enum StatementType {
|
||||||
/// A [`break`](https://docs.python.org/3/reference/simple_stmts.html#the-break-statement) statement.
|
/// A [`break`](https://docs.python.org/3/reference/simple_stmts.html#the-break-statement) statement.
|
||||||
Break,
|
Break,
|
||||||
|
|
||||||
@@ -49,7 +47,7 @@ pub enum StatementType<U = ()> {
|
|||||||
|
|
||||||
/// A [`return`](https://docs.python.org/3/reference/simple_stmts.html#the-return-statement) statement.
|
/// A [`return`](https://docs.python.org/3/reference/simple_stmts.html#the-return-statement) statement.
|
||||||
/// This is used to return from a function.
|
/// This is used to return from a function.
|
||||||
Return { value: Option<Expression<U>> },
|
Return { value: Option<Expression> },
|
||||||
|
|
||||||
/// An [`import`](https://docs.python.org/3/reference/simple_stmts.html#the-import-statement) statement.
|
/// An [`import`](https://docs.python.org/3/reference/simple_stmts.html#the-import-statement) statement.
|
||||||
Import { names: Vec<ImportSymbol> },
|
Import { names: Vec<ImportSymbol> },
|
||||||
@@ -66,35 +64,35 @@ pub enum StatementType<U = ()> {
|
|||||||
|
|
||||||
/// An [`assert`](https://docs.python.org/3/reference/simple_stmts.html#the-assert-statement) statement.
|
/// An [`assert`](https://docs.python.org/3/reference/simple_stmts.html#the-assert-statement) statement.
|
||||||
Assert {
|
Assert {
|
||||||
test: Expression<U>,
|
test: Expression,
|
||||||
msg: Option<Expression<U>>,
|
msg: Option<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A `del` statement, to delete some variables.
|
/// A `del` statement, to delete some variables.
|
||||||
Delete { targets: Vec<Expression<U>> },
|
Delete { targets: Vec<Expression> },
|
||||||
|
|
||||||
/// Variable assignment. Note that we can assign to multiple targets.
|
/// Variable assignment. Note that we can assign to multiple targets.
|
||||||
Assign {
|
Assign {
|
||||||
targets: Vec<Expression<U>>,
|
targets: Vec<Expression>,
|
||||||
value: Expression<U>,
|
value: Expression,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Augmented assignment.
|
/// Augmented assignment.
|
||||||
AugAssign {
|
AugAssign {
|
||||||
target: Box<Expression<U>>,
|
target: Box<Expression>,
|
||||||
op: Operator,
|
op: Operator,
|
||||||
value: Box<Expression<U>>,
|
value: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A type annotated assignment.
|
/// A type annotated assignment.
|
||||||
AnnAssign {
|
AnnAssign {
|
||||||
target: Box<Expression<U>>,
|
target: Box<Expression>,
|
||||||
annotation: Box<Expression<U>>,
|
annotation: Box<Expression>,
|
||||||
value: Option<Expression<U>>,
|
value: Option<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// An expression used as a statement.
|
/// An expression used as a statement.
|
||||||
Expression { expression: Expression<U> },
|
Expression { expression: Expression },
|
||||||
|
|
||||||
/// The [`global`](https://docs.python.org/3/reference/simple_stmts.html#the-global-statement) statement,
|
/// The [`global`](https://docs.python.org/3/reference/simple_stmts.html#the-global-statement) statement,
|
||||||
/// to declare names as global variables.
|
/// to declare names as global variables.
|
||||||
@@ -106,56 +104,56 @@ pub enum StatementType<U = ()> {
|
|||||||
|
|
||||||
/// An [`if`](https://docs.python.org/3/reference/compound_stmts.html#the-if-statement) statement.
|
/// An [`if`](https://docs.python.org/3/reference/compound_stmts.html#the-if-statement) statement.
|
||||||
If {
|
If {
|
||||||
test: Expression<U>,
|
test: Expression,
|
||||||
body: Suite<U>,
|
body: Suite,
|
||||||
orelse: Option<Suite<U>>,
|
orelse: Option<Suite>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A [`while`](https://docs.python.org/3/reference/compound_stmts.html#the-while-statement) statement.
|
/// A [`while`](https://docs.python.org/3/reference/compound_stmts.html#the-while-statement) statement.
|
||||||
While {
|
While {
|
||||||
test: Expression<U>,
|
test: Expression,
|
||||||
body: Suite<U>,
|
body: Suite,
|
||||||
orelse: Option<Suite<U>>,
|
orelse: Option<Suite>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The [`with`](https://docs.python.org/3/reference/compound_stmts.html#the-with-statement) statement.
|
/// The [`with`](https://docs.python.org/3/reference/compound_stmts.html#the-with-statement) statement.
|
||||||
With {
|
With {
|
||||||
is_async: bool,
|
is_async: bool,
|
||||||
items: Vec<WithItem<U>>,
|
items: Vec<WithItem>,
|
||||||
body: Suite<U>,
|
body: Suite,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A [`for`](https://docs.python.org/3/reference/compound_stmts.html#the-for-statement) statement.
|
/// A [`for`](https://docs.python.org/3/reference/compound_stmts.html#the-for-statement) statement.
|
||||||
/// Contains the body of the loop, and the `else` clause.
|
/// Contains the body of the loop, and the `else` clause.
|
||||||
For {
|
For {
|
||||||
is_async: bool,
|
is_async: bool,
|
||||||
target: Box<Expression<U>>,
|
target: Box<Expression>,
|
||||||
iter: Box<Expression<U>>,
|
iter: Box<Expression>,
|
||||||
body: Suite<U>,
|
body: Suite,
|
||||||
orelse: Option<Suite<U>>,
|
orelse: Option<Suite>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A `raise` statement.
|
/// A `raise` statement.
|
||||||
Raise {
|
Raise {
|
||||||
exception: Option<Expression<U>>,
|
exception: Option<Expression>,
|
||||||
cause: Option<Expression<U>>,
|
cause: Option<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A [`try`](https://docs.python.org/3/reference/compound_stmts.html#the-try-statement) statement.
|
/// A [`try`](https://docs.python.org/3/reference/compound_stmts.html#the-try-statement) statement.
|
||||||
Try {
|
Try {
|
||||||
body: Suite<U>,
|
body: Suite,
|
||||||
handlers: Vec<ExceptHandler<U>>,
|
handlers: Vec<ExceptHandler>,
|
||||||
orelse: Option<Suite<U>>,
|
orelse: Option<Suite>,
|
||||||
finalbody: Option<Suite<U>>,
|
finalbody: Option<Suite>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A [class definition](https://docs.python.org/3/reference/compound_stmts.html#class-definitions).
|
/// A [class definition](https://docs.python.org/3/reference/compound_stmts.html#class-definitions).
|
||||||
ClassDef {
|
ClassDef {
|
||||||
name: String,
|
name: String,
|
||||||
body: Suite<U>,
|
body: Suite,
|
||||||
bases: Vec<Expression<U>>,
|
bases: Vec<Expression>,
|
||||||
keywords: Vec<Keyword<U>>,
|
keywords: Vec<Keyword>,
|
||||||
decorator_list: Vec<Expression<U>>,
|
decorator_list: Vec<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A [function definition](https://docs.python.org/3/reference/compound_stmts.html#function-definitions).
|
/// A [function definition](https://docs.python.org/3/reference/compound_stmts.html#function-definitions).
|
||||||
@@ -164,82 +162,82 @@ pub enum StatementType<U = ()> {
|
|||||||
FunctionDef {
|
FunctionDef {
|
||||||
is_async: bool,
|
is_async: bool,
|
||||||
name: String,
|
name: String,
|
||||||
args: Box<Parameters<U>>,
|
args: Box<Parameters>,
|
||||||
body: Suite<U>,
|
body: Suite,
|
||||||
decorator_list: Vec<Expression<U>>,
|
decorator_list: Vec<Expression>,
|
||||||
returns: Option<Expression<U>>,
|
returns: Option<Expression>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct WithItem<U = ()> {
|
pub struct WithItem {
|
||||||
pub context_expr: Expression<U>,
|
pub context_expr: Expression,
|
||||||
pub optional_vars: Option<Expression<U>>,
|
pub optional_vars: Option<Expression>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An expression at a given location in the sourcecode.
|
/// An expression at a given location in the sourcecode.
|
||||||
pub type Expression<U = ()> = Located<ExpressionType<U>, U>;
|
pub type Expression = Located<ExpressionType>;
|
||||||
|
|
||||||
/// A certain type of expression.
|
/// A certain type of expression.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum ExpressionType<U = ()> {
|
pub enum ExpressionType {
|
||||||
BoolOp {
|
BoolOp {
|
||||||
op: BooleanOperator,
|
op: BooleanOperator,
|
||||||
values: Vec<Expression<U>>,
|
values: Vec<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A binary operation on two operands.
|
/// A binary operation on two operands.
|
||||||
Binop {
|
Binop {
|
||||||
a: Box<Expression<U>>,
|
a: Box<Expression>,
|
||||||
op: Operator,
|
op: Operator,
|
||||||
b: Box<Expression<U>>,
|
b: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Subscript operation.
|
/// Subscript operation.
|
||||||
Subscript {
|
Subscript {
|
||||||
a: Box<Expression<U>>,
|
a: Box<Expression>,
|
||||||
b: Box<Expression<U>>,
|
b: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// An unary operation.
|
/// An unary operation.
|
||||||
Unop {
|
Unop {
|
||||||
op: UnaryOperator,
|
op: UnaryOperator,
|
||||||
a: Box<Expression<U>>,
|
a: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// An await expression.
|
/// An await expression.
|
||||||
Await {
|
Await {
|
||||||
value: Box<Expression<U>>,
|
value: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A yield expression.
|
/// A yield expression.
|
||||||
Yield {
|
Yield {
|
||||||
value: Option<Box<Expression<U>>>,
|
value: Option<Box<Expression>>,
|
||||||
},
|
},
|
||||||
|
|
||||||
// A yield from expression.
|
// A yield from expression.
|
||||||
YieldFrom {
|
YieldFrom {
|
||||||
value: Box<Expression<U>>,
|
value: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A chained comparison. Note that in python you can use
|
/// A chained comparison. Note that in python you can use
|
||||||
/// `1 < a < 10` for example.
|
/// `1 < a < 10` for example.
|
||||||
Compare {
|
Compare {
|
||||||
vals: Vec<Expression<U>>,
|
vals: Vec<Expression>,
|
||||||
ops: Vec<Comparison>,
|
ops: Vec<Comparison>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Attribute access in the form of `value.name`.
|
/// Attribute access in the form of `value.name`.
|
||||||
Attribute {
|
Attribute {
|
||||||
value: Box<Expression<U>>,
|
value: Box<Expression>,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A call expression.
|
/// A call expression.
|
||||||
Call {
|
Call {
|
||||||
function: Box<Expression<U>>,
|
function: Box<Expression>,
|
||||||
args: Vec<Expression<U>>,
|
args: Vec<Expression>,
|
||||||
keywords: Vec<Keyword<U>>,
|
keywords: Vec<Keyword>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A numeric literal.
|
/// A numeric literal.
|
||||||
@@ -249,43 +247,43 @@ pub enum ExpressionType<U = ()> {
|
|||||||
|
|
||||||
/// A `list` literal value.
|
/// A `list` literal value.
|
||||||
List {
|
List {
|
||||||
elements: Vec<Expression<U>>,
|
elements: Vec<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A `tuple` literal value.
|
/// A `tuple` literal value.
|
||||||
Tuple {
|
Tuple {
|
||||||
elements: Vec<Expression<U>>,
|
elements: Vec<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A `dict` literal value.
|
/// A `dict` literal value.
|
||||||
/// For example: `{2: 'two', 3: 'three'}`
|
/// For example: `{2: 'two', 3: 'three'}`
|
||||||
Dict {
|
Dict {
|
||||||
elements: Vec<(Option<Expression<U>>, Expression<U>)>,
|
elements: Vec<(Option<Expression>, Expression)>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A `set` literal.
|
/// A `set` literal.
|
||||||
Set {
|
Set {
|
||||||
elements: Vec<Expression<U>>,
|
elements: Vec<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Comprehension {
|
Comprehension {
|
||||||
kind: Box<ComprehensionKind<U>>,
|
kind: Box<ComprehensionKind>,
|
||||||
generators: Vec<Comprehension<U>>,
|
generators: Vec<Comprehension>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A starred expression.
|
/// A starred expression.
|
||||||
Starred {
|
Starred {
|
||||||
value: Box<Expression<U>>,
|
value: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A slice expression.
|
/// A slice expression.
|
||||||
Slice {
|
Slice {
|
||||||
elements: Vec<Expression<U>>,
|
elements: Vec<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A string literal.
|
/// A string literal.
|
||||||
String {
|
String {
|
||||||
value: StringGroup<U>,
|
value: StringGroup,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A bytes literal.
|
/// A bytes literal.
|
||||||
@@ -300,21 +298,21 @@ pub enum ExpressionType<U = ()> {
|
|||||||
|
|
||||||
/// A `lambda` function expression.
|
/// A `lambda` function expression.
|
||||||
Lambda {
|
Lambda {
|
||||||
args: Box<Parameters<U>>,
|
args: Box<Parameters>,
|
||||||
body: Box<Expression<U>>,
|
body: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// An if-expression.
|
/// An if-expression.
|
||||||
IfExpression {
|
IfExpression {
|
||||||
test: Box<Expression<U>>,
|
test: Box<Expression>,
|
||||||
body: Box<Expression<U>>,
|
body: Box<Expression>,
|
||||||
orelse: Box<Expression<U>>,
|
orelse: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
// A named expression
|
// A named expression
|
||||||
NamedExpression {
|
NamedExpression {
|
||||||
left: Box<Expression<U>>,
|
left: Box<Expression>,
|
||||||
right: Box<Expression<U>>,
|
right: Box<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The literal 'True'.
|
/// The literal 'True'.
|
||||||
@@ -330,7 +328,7 @@ pub enum ExpressionType<U = ()> {
|
|||||||
Ellipsis,
|
Ellipsis,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U> Expression<U> {
|
impl Expression {
|
||||||
/// Returns a short name for the node suitable for use in error messages.
|
/// Returns a short name for the node suitable for use in error messages.
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
use self::ExpressionType::*;
|
use self::ExpressionType::*;
|
||||||
@@ -382,70 +380,61 @@ impl<U> Expression<U> {
|
|||||||
/// In cpython this is called arguments, but we choose parameters to
|
/// In cpython this is called arguments, but we choose parameters to
|
||||||
/// distinguish between function parameters and actual call arguments.
|
/// distinguish between function parameters and actual call arguments.
|
||||||
#[derive(Debug, PartialEq, Default)]
|
#[derive(Debug, PartialEq, Default)]
|
||||||
pub struct Parameters<U = ()> {
|
pub struct Parameters {
|
||||||
pub posonlyargs_count: usize,
|
pub posonlyargs_count: usize,
|
||||||
pub args: Vec<Parameter<U>>,
|
pub args: Vec<Parameter>,
|
||||||
pub kwonlyargs: Vec<Parameter<U>>,
|
pub kwonlyargs: Vec<Parameter>,
|
||||||
pub vararg: Varargs<U>, // Optionally we handle optionally named '*args' or '*'
|
pub vararg: Varargs, // Optionally we handle optionally named '*args' or '*'
|
||||||
pub kwarg: Varargs<U>,
|
pub kwarg: Varargs,
|
||||||
pub defaults: Vec<Expression<U>>,
|
pub defaults: Vec<Expression>,
|
||||||
pub kw_defaults: Vec<Option<Expression<U>>>,
|
pub kw_defaults: Vec<Option<Expression>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A single formal parameter to a function.
|
/// A single formal parameter to a function.
|
||||||
#[derive(Debug, PartialEq, Default)]
|
#[derive(Debug, PartialEq, Default)]
|
||||||
pub struct Parameter<U = ()> {
|
pub struct Parameter {
|
||||||
pub location: Location,
|
pub location: Location,
|
||||||
pub arg: String,
|
pub arg: String,
|
||||||
pub annotation: Option<Box<Expression<U>>>,
|
pub annotation: Option<Box<Expression>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum ComprehensionKind<U = ()> {
|
pub enum ComprehensionKind {
|
||||||
GeneratorExpression {
|
GeneratorExpression { element: Expression },
|
||||||
element: Expression<U>,
|
List { element: Expression },
|
||||||
},
|
Set { element: Expression },
|
||||||
List {
|
Dict { key: Expression, value: Expression },
|
||||||
element: Expression<U>,
|
|
||||||
},
|
|
||||||
Set {
|
|
||||||
element: Expression<U>,
|
|
||||||
},
|
|
||||||
Dict {
|
|
||||||
key: Expression<U>,
|
|
||||||
value: Expression<U>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A list/set/dict/generator compression.
|
/// A list/set/dict/generator compression.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Comprehension<U = ()> {
|
pub struct Comprehension {
|
||||||
pub location: Location,
|
pub location: Location,
|
||||||
pub target: Expression<U>,
|
pub target: Expression,
|
||||||
pub iter: Expression<U>,
|
pub iter: Expression,
|
||||||
pub ifs: Vec<Expression<U>>,
|
pub ifs: Vec<Expression>,
|
||||||
pub is_async: bool,
|
pub is_async: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct ArgumentList<U = ()> {
|
pub struct ArgumentList {
|
||||||
pub args: Vec<Expression<U>>,
|
pub args: Vec<Expression>,
|
||||||
pub keywords: Vec<Keyword<U>>,
|
pub keywords: Vec<Keyword>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Keyword<U = ()> {
|
pub struct Keyword {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub value: Expression<U>,
|
pub value: Expression,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct ExceptHandler<U = ()> {
|
pub struct ExceptHandler {
|
||||||
pub location: Location,
|
pub location: Location,
|
||||||
pub typ: Option<Expression<U>>,
|
pub typ: Option<Expression>,
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub body: Suite<U>,
|
pub body: Suite,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An operator for a binary operation (an operation with two operands).
|
/// An operator for a binary operation (an operation with two operands).
|
||||||
@@ -517,35 +506,35 @@ pub enum ConversionFlag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum StringGroup<U = ()> {
|
pub enum StringGroup {
|
||||||
Constant {
|
Constant {
|
||||||
value: String,
|
value: String,
|
||||||
},
|
},
|
||||||
FormattedValue {
|
FormattedValue {
|
||||||
value: Box<Expression<U>>,
|
value: Box<Expression>,
|
||||||
conversion: Option<ConversionFlag>,
|
conversion: Option<ConversionFlag>,
|
||||||
spec: Option<Box<StringGroup<U>>>,
|
spec: Option<Box<StringGroup>>,
|
||||||
},
|
},
|
||||||
Joined {
|
Joined {
|
||||||
values: Vec<StringGroup<U>>,
|
values: Vec<StringGroup>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Varargs<U = ()> {
|
pub enum Varargs {
|
||||||
None,
|
None,
|
||||||
Unnamed,
|
Unnamed,
|
||||||
Named(Parameter<U>),
|
Named(Parameter),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U> Default for Varargs<U> {
|
impl Default for Varargs {
|
||||||
fn default() -> Varargs<U> {
|
fn default() -> Varargs {
|
||||||
Varargs::None
|
Varargs::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U> From<Option<Option<Parameter<U>>>> for Varargs<U> {
|
impl From<Option<Option<Parameter>>> for Varargs {
|
||||||
fn from(opt: Option<Option<Parameter<U>>>) -> Varargs<U> {
|
fn from(opt: Option<Option<Parameter>>) -> Varargs {
|
||||||
match opt {
|
match opt {
|
||||||
Some(inner_opt) => match inner_opt {
|
Some(inner_opt) => match inner_opt {
|
||||||
Some(param) => Varargs::Named(param),
|
Some(param) => Varargs::Named(param),
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
#![no_std]
|
|
||||||
|
|
||||||
extern crate alloc;
|
|
||||||
|
|
||||||
mod ast;
|
mod ast;
|
||||||
mod location;
|
mod location;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Datatypes to support source location information.
|
//! Datatypes to support source location information.
|
||||||
|
|
||||||
use core::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
/// A location somewhere in the sourcecode.
|
/// A location somewhere in the sourcecode.
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||||
|
|||||||
@@ -7,16 +7,13 @@ edition = "2018"
|
|||||||
repository = "https://github.com/RustPython/RustPython"
|
repository = "https://github.com/RustPython/RustPython"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[features]
|
|
||||||
std = ["bstr/std", "itertools/use_std", "lz4_flex/std"]
|
|
||||||
default = ["std"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bincode = "1.1"
|
bincode = "1.1"
|
||||||
bitflags = "1.1"
|
bitflags = "1.1"
|
||||||
lz4_flex = { version = "0.7", default-features = false, features = ["safe-decode", "safe-encode"] }
|
lz-fear = "0.1"
|
||||||
num-bigint = { version = "0.3", default-features = false, features = ["serde"] }
|
num-bigint = { version = "0.3", features = ["serde"] }
|
||||||
num-complex = { version = "0.3", default-features = false, features = ["serde"] }
|
num-complex = { version = "0.3", features = ["serde"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
itertools = { version = "0.9", default-features = false }
|
itertools = "0.9"
|
||||||
bstr = { version = "0.2", default-features = false }
|
bstr = "0.2"
|
||||||
|
|||||||
948
bytecode/src/bytecode.rs
Normal file
948
bytecode/src/bytecode.rs
Normal file
@@ -0,0 +1,948 @@
|
|||||||
|
//! Implement python as a virtual machine with bytecodes. This module
|
||||||
|
//! implements bytecode structure.
|
||||||
|
|
||||||
|
use bitflags::bitflags;
|
||||||
|
use bstr::ByteSlice;
|
||||||
|
use itertools::Itertools;
|
||||||
|
use num_bigint::BigInt;
|
||||||
|
use num_complex::Complex64;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
/// Sourcecode location.
|
||||||
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Location {
|
||||||
|
row: usize,
|
||||||
|
column: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Location {
|
||||||
|
pub fn new(row: usize, column: usize) -> Self {
|
||||||
|
Location { row, column }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn row(&self) -> usize {
|
||||||
|
self.row
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn column(&self) -> usize {
|
||||||
|
self.column
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Constant: Sized {
|
||||||
|
type Name: AsRef<str>;
|
||||||
|
fn borrow_constant(&self) -> BorrowedConstant<Self>;
|
||||||
|
fn into_data(self) -> ConstantData {
|
||||||
|
self.borrow_constant().into_data()
|
||||||
|
}
|
||||||
|
fn map_constant<Bag: ConstantBag>(self, bag: &Bag) -> Bag::Constant {
|
||||||
|
bag.make_constant(self.into_data())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Constant for ConstantData {
|
||||||
|
type Name = String;
|
||||||
|
fn borrow_constant(&self) -> BorrowedConstant<Self> {
|
||||||
|
use BorrowedConstant::*;
|
||||||
|
match self {
|
||||||
|
ConstantData::Integer { value } => Integer { value },
|
||||||
|
ConstantData::Float { value } => Float { value: *value },
|
||||||
|
ConstantData::Complex { value } => Complex { value: *value },
|
||||||
|
ConstantData::Boolean { value } => Boolean { value: *value },
|
||||||
|
ConstantData::Str { value } => Str { value },
|
||||||
|
ConstantData::Bytes { value } => Bytes { value },
|
||||||
|
ConstantData::Code { code } => Code { code },
|
||||||
|
ConstantData::Tuple { elements } => Tuple {
|
||||||
|
elements: Box::new(elements.iter().map(|e| e.borrow_constant())),
|
||||||
|
},
|
||||||
|
ConstantData::None => None,
|
||||||
|
ConstantData::Ellipsis => Ellipsis,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn into_data(self) -> ConstantData {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ConstantBag: Sized {
|
||||||
|
type Constant: Constant;
|
||||||
|
fn make_constant(&self, constant: ConstantData) -> Self::Constant;
|
||||||
|
fn make_constant_borrowed<C: Constant>(&self, constant: BorrowedConstant<C>) -> Self::Constant {
|
||||||
|
self.make_constant(constant.into_data())
|
||||||
|
}
|
||||||
|
fn make_name(&self, name: String) -> <Self::Constant as Constant>::Name;
|
||||||
|
fn make_name_ref(&self, name: &str) -> <Self::Constant as Constant>::Name {
|
||||||
|
self.make_name(name.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct BasicBag;
|
||||||
|
impl ConstantBag for BasicBag {
|
||||||
|
type Constant = ConstantData;
|
||||||
|
fn make_constant(&self, constant: ConstantData) -> Self::Constant {
|
||||||
|
constant
|
||||||
|
}
|
||||||
|
fn make_name(&self, name: String) -> <Self::Constant as Constant>::Name {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Primary container of a single code object. Each python function has
|
||||||
|
/// a codeobject. Also a module has a codeobject.
|
||||||
|
#[derive(Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct CodeObject<C: Constant = ConstantData> {
|
||||||
|
pub instructions: Box<[Instruction]>,
|
||||||
|
pub locations: Box<[Location]>,
|
||||||
|
pub flags: CodeFlags,
|
||||||
|
pub posonlyarg_count: usize, // Number of positional-only arguments
|
||||||
|
pub arg_count: usize,
|
||||||
|
pub kwonlyarg_count: usize,
|
||||||
|
pub source_path: String,
|
||||||
|
pub first_line_number: usize,
|
||||||
|
pub obj_name: String, // Name of the object that created this code object
|
||||||
|
pub cell2arg: Option<Box<[isize]>>,
|
||||||
|
pub constants: Box<[C]>,
|
||||||
|
#[serde(bound(
|
||||||
|
deserialize = "C::Name: serde::Deserialize<'de>",
|
||||||
|
serialize = "C::Name: serde::Serialize"
|
||||||
|
))]
|
||||||
|
pub names: Box<[C::Name]>,
|
||||||
|
pub varnames: Box<[C::Name]>,
|
||||||
|
pub cellvars: Box<[C::Name]>,
|
||||||
|
pub freevars: Box<[C::Name]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct CodeFlags: u16 {
|
||||||
|
const HAS_DEFAULTS = 0x01;
|
||||||
|
const HAS_KW_ONLY_DEFAULTS = 0x02;
|
||||||
|
const HAS_ANNOTATIONS = 0x04;
|
||||||
|
const NEW_LOCALS = 0x08;
|
||||||
|
const IS_GENERATOR = 0x10;
|
||||||
|
const IS_COROUTINE = 0x20;
|
||||||
|
const HAS_VARARGS = 0x40;
|
||||||
|
const HAS_VARKEYWORDS = 0x80;
|
||||||
|
const IS_OPTIMIZED = 0x0100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CodeFlags {
|
||||||
|
pub const NAME_MAPPING: &'static [(&'static str, CodeFlags)] = &[
|
||||||
|
("GENERATOR", CodeFlags::IS_GENERATOR),
|
||||||
|
("COROUTINE", CodeFlags::IS_COROUTINE),
|
||||||
|
(
|
||||||
|
"ASYNC_GENERATOR",
|
||||||
|
Self::from_bits_truncate(Self::IS_GENERATOR.bits | Self::IS_COROUTINE.bits),
|
||||||
|
),
|
||||||
|
("VARARGS", CodeFlags::HAS_VARARGS),
|
||||||
|
("VARKEYWORDS", CodeFlags::HAS_VARKEYWORDS),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug, Deserialize, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
// XXX: if you add a new instruction that stores a Label, make sure to add it in
|
||||||
|
// compile::CodeInfo::finalize_code and CodeObject::label_targets
|
||||||
|
pub struct Label(pub usize);
|
||||||
|
impl fmt::Display for Label {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
self.0.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transforms a value prior to formatting it.
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum ConversionFlag {
|
||||||
|
/// Converts by calling `str(<value>)`.
|
||||||
|
Str,
|
||||||
|
/// Converts by calling `ascii(<value>)`.
|
||||||
|
Ascii,
|
||||||
|
/// Converts by calling `repr(<value>)`.
|
||||||
|
Repr,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type NameIdx = usize;
|
||||||
|
|
||||||
|
/// A Single bytecode instruction.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum Instruction {
|
||||||
|
Import {
|
||||||
|
name_idx: Option<NameIdx>,
|
||||||
|
symbols_idx: Vec<NameIdx>,
|
||||||
|
level: usize,
|
||||||
|
},
|
||||||
|
ImportStar,
|
||||||
|
ImportFrom {
|
||||||
|
idx: NameIdx,
|
||||||
|
},
|
||||||
|
LoadFast(NameIdx),
|
||||||
|
LoadNameAny(NameIdx),
|
||||||
|
LoadGlobal(NameIdx),
|
||||||
|
LoadDeref(NameIdx),
|
||||||
|
LoadClassDeref(NameIdx),
|
||||||
|
StoreFast(NameIdx),
|
||||||
|
StoreLocal(NameIdx),
|
||||||
|
StoreGlobal(NameIdx),
|
||||||
|
StoreDeref(NameIdx),
|
||||||
|
DeleteFast(NameIdx),
|
||||||
|
DeleteLocal(NameIdx),
|
||||||
|
DeleteGlobal(NameIdx),
|
||||||
|
DeleteDeref(NameIdx),
|
||||||
|
LoadClosure(NameIdx),
|
||||||
|
Subscript,
|
||||||
|
StoreSubscript,
|
||||||
|
DeleteSubscript,
|
||||||
|
StoreAttr {
|
||||||
|
idx: NameIdx,
|
||||||
|
},
|
||||||
|
DeleteAttr {
|
||||||
|
idx: NameIdx,
|
||||||
|
},
|
||||||
|
LoadConst {
|
||||||
|
/// index into constants vec
|
||||||
|
idx: usize,
|
||||||
|
},
|
||||||
|
UnaryOperation {
|
||||||
|
op: UnaryOperator,
|
||||||
|
},
|
||||||
|
BinaryOperation {
|
||||||
|
op: BinaryOperator,
|
||||||
|
inplace: bool,
|
||||||
|
},
|
||||||
|
LoadAttr {
|
||||||
|
idx: NameIdx,
|
||||||
|
},
|
||||||
|
CompareOperation {
|
||||||
|
op: ComparisonOperator,
|
||||||
|
},
|
||||||
|
Pop,
|
||||||
|
Rotate {
|
||||||
|
amount: usize,
|
||||||
|
},
|
||||||
|
Duplicate,
|
||||||
|
GetIter,
|
||||||
|
Continue,
|
||||||
|
Break,
|
||||||
|
Jump {
|
||||||
|
target: Label,
|
||||||
|
},
|
||||||
|
/// Pop the top of the stack, and jump if this value is true.
|
||||||
|
JumpIfTrue {
|
||||||
|
target: Label,
|
||||||
|
},
|
||||||
|
/// Pop the top of the stack, and jump if this value is false.
|
||||||
|
JumpIfFalse {
|
||||||
|
target: Label,
|
||||||
|
},
|
||||||
|
/// Peek at the top of the stack, and jump if this value is true.
|
||||||
|
/// Otherwise, pop top of stack.
|
||||||
|
JumpIfTrueOrPop {
|
||||||
|
target: Label,
|
||||||
|
},
|
||||||
|
/// Peek at the top of the stack, and jump if this value is false.
|
||||||
|
/// Otherwise, pop top of stack.
|
||||||
|
JumpIfFalseOrPop {
|
||||||
|
target: Label,
|
||||||
|
},
|
||||||
|
MakeFunction,
|
||||||
|
CallFunction {
|
||||||
|
typ: CallType,
|
||||||
|
},
|
||||||
|
ForIter {
|
||||||
|
target: Label,
|
||||||
|
},
|
||||||
|
ReturnValue,
|
||||||
|
YieldValue,
|
||||||
|
YieldFrom,
|
||||||
|
SetupAnnotation,
|
||||||
|
SetupLoop {
|
||||||
|
start: Label,
|
||||||
|
end: Label,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Setup a finally handler, which will be called whenever one of this events occurs:
|
||||||
|
/// - the block is popped
|
||||||
|
/// - the function returns
|
||||||
|
/// - an exception is returned
|
||||||
|
SetupFinally {
|
||||||
|
handler: Label,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Enter a finally block, without returning, excepting, just because we are there.
|
||||||
|
EnterFinally,
|
||||||
|
|
||||||
|
/// Marker bytecode for the end of a finally sequence.
|
||||||
|
/// When this bytecode is executed, the eval loop does one of those things:
|
||||||
|
/// - Continue at a certain bytecode position
|
||||||
|
/// - Propagate the exception
|
||||||
|
/// - Return from a function
|
||||||
|
/// - Do nothing at all, just continue
|
||||||
|
EndFinally,
|
||||||
|
|
||||||
|
SetupExcept {
|
||||||
|
handler: Label,
|
||||||
|
},
|
||||||
|
SetupWith {
|
||||||
|
end: Label,
|
||||||
|
},
|
||||||
|
WithCleanupStart,
|
||||||
|
WithCleanupFinish,
|
||||||
|
PopBlock,
|
||||||
|
Raise {
|
||||||
|
argc: usize,
|
||||||
|
},
|
||||||
|
BuildString {
|
||||||
|
size: usize,
|
||||||
|
},
|
||||||
|
BuildTuple {
|
||||||
|
size: usize,
|
||||||
|
unpack: bool,
|
||||||
|
},
|
||||||
|
BuildList {
|
||||||
|
size: usize,
|
||||||
|
unpack: bool,
|
||||||
|
},
|
||||||
|
BuildSet {
|
||||||
|
size: usize,
|
||||||
|
unpack: bool,
|
||||||
|
},
|
||||||
|
BuildMap {
|
||||||
|
size: usize,
|
||||||
|
unpack: bool,
|
||||||
|
for_call: bool,
|
||||||
|
},
|
||||||
|
BuildSlice {
|
||||||
|
size: usize,
|
||||||
|
},
|
||||||
|
ListAppend {
|
||||||
|
i: usize,
|
||||||
|
},
|
||||||
|
SetAdd {
|
||||||
|
i: usize,
|
||||||
|
},
|
||||||
|
MapAdd {
|
||||||
|
i: usize,
|
||||||
|
},
|
||||||
|
|
||||||
|
PrintExpr,
|
||||||
|
LoadBuildClass,
|
||||||
|
UnpackSequence {
|
||||||
|
size: usize,
|
||||||
|
},
|
||||||
|
UnpackEx {
|
||||||
|
before: usize,
|
||||||
|
after: usize,
|
||||||
|
},
|
||||||
|
FormatValue {
|
||||||
|
conversion: Option<ConversionFlag>,
|
||||||
|
},
|
||||||
|
PopException,
|
||||||
|
Reverse {
|
||||||
|
amount: usize,
|
||||||
|
},
|
||||||
|
GetAwaitable,
|
||||||
|
BeforeAsyncWith,
|
||||||
|
SetupAsyncWith {
|
||||||
|
end: Label,
|
||||||
|
},
|
||||||
|
GetAIter,
|
||||||
|
GetANext,
|
||||||
|
|
||||||
|
/// Reverse order evaluation in MapAdd
|
||||||
|
/// required to support named expressions of Python 3.8 in dict comprehension
|
||||||
|
/// today (including Py3.9) only required in dict comprehension.
|
||||||
|
MapAddRev {
|
||||||
|
i: usize,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
use self::Instruction::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum CallType {
|
||||||
|
Positional(usize),
|
||||||
|
Keyword(usize),
|
||||||
|
Ex(bool),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum ConstantData {
|
||||||
|
Integer { value: BigInt },
|
||||||
|
Float { value: f64 },
|
||||||
|
Complex { value: Complex64 },
|
||||||
|
Boolean { value: bool },
|
||||||
|
Str { value: String },
|
||||||
|
Bytes { value: Vec<u8> },
|
||||||
|
Code { code: Box<CodeObject> },
|
||||||
|
Tuple { elements: Vec<ConstantData> },
|
||||||
|
None,
|
||||||
|
Ellipsis,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum BorrowedConstant<'a, C: Constant> {
|
||||||
|
Integer { value: &'a BigInt },
|
||||||
|
Float { value: f64 },
|
||||||
|
Complex { value: Complex64 },
|
||||||
|
Boolean { value: bool },
|
||||||
|
Str { value: &'a str },
|
||||||
|
Bytes { value: &'a [u8] },
|
||||||
|
Code { code: &'a CodeObject<C> },
|
||||||
|
Tuple { elements: BorrowedTupleIter<'a, C> },
|
||||||
|
None,
|
||||||
|
Ellipsis,
|
||||||
|
}
|
||||||
|
type BorrowedTupleIter<'a, C> = Box<dyn Iterator<Item = BorrowedConstant<'a, C>> + 'a>;
|
||||||
|
impl<C: Constant> BorrowedConstant<'_, C> {
|
||||||
|
// takes `self` because we need to consume the iterator
|
||||||
|
pub fn fmt_display(self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
BorrowedConstant::Integer { value } => write!(f, "{}", value),
|
||||||
|
BorrowedConstant::Float { value } => write!(f, "{}", value),
|
||||||
|
BorrowedConstant::Complex { value } => write!(f, "{}", value),
|
||||||
|
BorrowedConstant::Boolean { value } => {
|
||||||
|
write!(f, "{}", if value { "True" } else { "False" })
|
||||||
|
}
|
||||||
|
BorrowedConstant::Str { value } => write!(f, "{:?}", value),
|
||||||
|
BorrowedConstant::Bytes { value } => write!(f, "b{:?}", value.as_bstr()),
|
||||||
|
BorrowedConstant::Code { code } => write!(f, "{:?}", code),
|
||||||
|
BorrowedConstant::Tuple { elements } => {
|
||||||
|
write!(f, "(")?;
|
||||||
|
let mut first = true;
|
||||||
|
for c in elements {
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
|
} else {
|
||||||
|
write!(f, ", ")?;
|
||||||
|
}
|
||||||
|
c.fmt_display(f)?;
|
||||||
|
}
|
||||||
|
write!(f, ")")
|
||||||
|
}
|
||||||
|
BorrowedConstant::None => write!(f, "None"),
|
||||||
|
BorrowedConstant::Ellipsis => write!(f, "..."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn into_data(self) -> ConstantData {
|
||||||
|
use ConstantData::*;
|
||||||
|
match self {
|
||||||
|
BorrowedConstant::Integer { value } => Integer {
|
||||||
|
value: value.clone(),
|
||||||
|
},
|
||||||
|
BorrowedConstant::Float { value } => Float { value },
|
||||||
|
BorrowedConstant::Complex { value } => Complex { value },
|
||||||
|
BorrowedConstant::Boolean { value } => Boolean { value },
|
||||||
|
BorrowedConstant::Str { value } => Str {
|
||||||
|
value: value.to_owned(),
|
||||||
|
},
|
||||||
|
BorrowedConstant::Bytes { value } => Bytes {
|
||||||
|
value: value.to_owned(),
|
||||||
|
},
|
||||||
|
BorrowedConstant::Code { code } => Code {
|
||||||
|
code: Box::new(code.map_clone_bag(&BasicBag)),
|
||||||
|
},
|
||||||
|
BorrowedConstant::Tuple { elements } => Tuple {
|
||||||
|
elements: elements.map(BorrowedConstant::into_data).collect(),
|
||||||
|
},
|
||||||
|
BorrowedConstant::None => None,
|
||||||
|
BorrowedConstant::Ellipsis => Ellipsis,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum ComparisonOperator {
|
||||||
|
Greater,
|
||||||
|
GreaterOrEqual,
|
||||||
|
Less,
|
||||||
|
LessOrEqual,
|
||||||
|
Equal,
|
||||||
|
NotEqual,
|
||||||
|
In,
|
||||||
|
NotIn,
|
||||||
|
Is,
|
||||||
|
IsNot,
|
||||||
|
ExceptionMatch,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum BinaryOperator {
|
||||||
|
Power,
|
||||||
|
Multiply,
|
||||||
|
MatrixMultiply,
|
||||||
|
Divide,
|
||||||
|
FloorDivide,
|
||||||
|
Modulo,
|
||||||
|
Add,
|
||||||
|
Subtract,
|
||||||
|
Lshift,
|
||||||
|
Rshift,
|
||||||
|
And,
|
||||||
|
Xor,
|
||||||
|
Or,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum UnaryOperator {
|
||||||
|
Not,
|
||||||
|
Invert,
|
||||||
|
Minus,
|
||||||
|
Plus,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Maintain a stack of blocks on the VM.
|
||||||
|
pub enum BlockType {
|
||||||
|
Loop,
|
||||||
|
Except,
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub struct Arguments<'a, N: AsRef<str>> {
|
||||||
|
pub posonlyargs: &'a [N],
|
||||||
|
pub args: &'a [N],
|
||||||
|
pub vararg: Option<&'a N>,
|
||||||
|
pub kwonlyargs: &'a [N],
|
||||||
|
pub varkwarg: Option<&'a N>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: AsRef<str>> fmt::Debug for Arguments<'_, N> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
macro_rules! fmt_slice {
|
||||||
|
($x:expr) => {
|
||||||
|
format_args!("[{}]", $x.iter().map(AsRef::as_ref).format(", "))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
f.debug_struct("Arguments")
|
||||||
|
.field("posonlyargs", &fmt_slice!(self.posonlyargs))
|
||||||
|
.field("args", &fmt_slice!(self.posonlyargs))
|
||||||
|
.field("vararg", &self.vararg.map(N::as_ref))
|
||||||
|
.field("kwonlyargs", &fmt_slice!(self.kwonlyargs))
|
||||||
|
.field("varkwarg", &self.varkwarg.map(N::as_ref))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Constant> CodeObject<C> {
|
||||||
|
pub fn new(
|
||||||
|
flags: CodeFlags,
|
||||||
|
posonlyarg_count: usize,
|
||||||
|
arg_count: usize,
|
||||||
|
kwonlyarg_count: usize,
|
||||||
|
source_path: String,
|
||||||
|
first_line_number: usize,
|
||||||
|
obj_name: String,
|
||||||
|
) -> Self {
|
||||||
|
CodeObject {
|
||||||
|
instructions: Box::new([]),
|
||||||
|
locations: Box::new([]),
|
||||||
|
flags,
|
||||||
|
posonlyarg_count,
|
||||||
|
arg_count,
|
||||||
|
kwonlyarg_count,
|
||||||
|
source_path,
|
||||||
|
first_line_number,
|
||||||
|
obj_name,
|
||||||
|
cell2arg: None,
|
||||||
|
constants: Box::new([]),
|
||||||
|
names: Box::new([]),
|
||||||
|
varnames: Box::new([]),
|
||||||
|
cellvars: Box::new([]),
|
||||||
|
freevars: Box::new([]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// like inspect.getargs
|
||||||
|
pub fn arg_names(&self) -> Arguments<C::Name> {
|
||||||
|
let nargs = self.arg_count;
|
||||||
|
let nkwargs = self.kwonlyarg_count;
|
||||||
|
let mut varargspos = nargs + nkwargs;
|
||||||
|
let posonlyargs = &self.varnames[..self.posonlyarg_count];
|
||||||
|
let args = &self.varnames[..nargs];
|
||||||
|
let kwonlyargs = &self.varnames[nargs..varargspos];
|
||||||
|
|
||||||
|
let vararg = if self.flags.contains(CodeFlags::HAS_VARARGS) {
|
||||||
|
let vararg = &self.varnames[varargspos];
|
||||||
|
varargspos += 1;
|
||||||
|
Some(vararg)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let varkwarg = if self.flags.contains(CodeFlags::HAS_VARKEYWORDS) {
|
||||||
|
Some(&self.varnames[varargspos])
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
Arguments {
|
||||||
|
posonlyargs,
|
||||||
|
args,
|
||||||
|
vararg,
|
||||||
|
kwonlyargs,
|
||||||
|
varkwarg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn label_targets(&self) -> BTreeSet<Label> {
|
||||||
|
let mut label_targets = BTreeSet::new();
|
||||||
|
for instruction in &*self.instructions {
|
||||||
|
match instruction {
|
||||||
|
Jump { target: l }
|
||||||
|
| JumpIfTrue { target: l }
|
||||||
|
| JumpIfFalse { target: l }
|
||||||
|
| JumpIfTrueOrPop { target: l }
|
||||||
|
| JumpIfFalseOrPop { target: l }
|
||||||
|
| ForIter { target: l }
|
||||||
|
| SetupFinally { handler: l }
|
||||||
|
| SetupExcept { handler: l }
|
||||||
|
| SetupWith { end: l }
|
||||||
|
| SetupAsyncWith { end: l } => {
|
||||||
|
label_targets.insert(*l);
|
||||||
|
}
|
||||||
|
SetupLoop { start, end } => {
|
||||||
|
label_targets.insert(*start);
|
||||||
|
label_targets.insert(*end);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
Import { .. } | ImportStar | ImportFrom { .. } | LoadFast(_) | LoadNameAny(_)
|
||||||
|
| LoadGlobal(_) | LoadDeref(_) | LoadClassDeref(_) | StoreFast(_) | StoreLocal(_)
|
||||||
|
| StoreGlobal(_) | StoreDeref(_) | DeleteFast(_) | DeleteLocal(_) | DeleteGlobal(_)
|
||||||
|
| DeleteDeref(_) | LoadClosure(_) | Subscript | StoreSubscript | DeleteSubscript
|
||||||
|
| StoreAttr { .. } | DeleteAttr { .. } | LoadConst { .. } | UnaryOperation { .. }
|
||||||
|
| BinaryOperation { .. } | LoadAttr { .. } | CompareOperation { .. } | Pop
|
||||||
|
| Rotate { .. } | Duplicate | GetIter | Continue | Break | MakeFunction
|
||||||
|
| CallFunction { .. } | ReturnValue | YieldValue | YieldFrom | SetupAnnotation
|
||||||
|
| EnterFinally | EndFinally | WithCleanupStart | WithCleanupFinish | PopBlock
|
||||||
|
| Raise { .. } | BuildString { .. } | BuildTuple { .. } | BuildList { .. }
|
||||||
|
| BuildSet { .. } | BuildMap { .. } | BuildSlice { .. } | ListAppend { .. }
|
||||||
|
| SetAdd { .. } | MapAdd { .. } | PrintExpr | LoadBuildClass | UnpackSequence { .. }
|
||||||
|
| UnpackEx { .. } | FormatValue { .. } | PopException | Reverse { .. }
|
||||||
|
| GetAwaitable | BeforeAsyncWith | GetAIter | GetANext | MapAddRev { .. } => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label_targets
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_inner(
|
||||||
|
&self,
|
||||||
|
f: &mut fmt::Formatter,
|
||||||
|
expand_codeobjects: bool,
|
||||||
|
level: usize,
|
||||||
|
) -> fmt::Result {
|
||||||
|
let label_targets = self.label_targets();
|
||||||
|
|
||||||
|
for (offset, instruction) in self.instructions.iter().enumerate() {
|
||||||
|
let arrow = if label_targets.contains(&Label(offset)) {
|
||||||
|
">>"
|
||||||
|
} else {
|
||||||
|
" "
|
||||||
|
};
|
||||||
|
for _ in 0..level {
|
||||||
|
write!(f, " ")?;
|
||||||
|
}
|
||||||
|
write!(f, "{} {:5} ", arrow, offset)?;
|
||||||
|
instruction.fmt_dis(
|
||||||
|
f,
|
||||||
|
&self.constants,
|
||||||
|
&self.names,
|
||||||
|
&self.varnames,
|
||||||
|
&self.cellvars,
|
||||||
|
&self.freevars,
|
||||||
|
expand_codeobjects,
|
||||||
|
level,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn display_expand_codeobjects<'a>(&'a self) -> impl fmt::Display + 'a {
|
||||||
|
struct Display<'a, C: Constant>(&'a CodeObject<C>);
|
||||||
|
impl<C: Constant> fmt::Display for Display<'_, C> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
self.0.display_inner(f, true, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Display(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map_bag<Bag: ConstantBag>(self, bag: &Bag) -> CodeObject<Bag::Constant> {
|
||||||
|
let map_names = |names: Box<[C::Name]>| {
|
||||||
|
names
|
||||||
|
.into_vec()
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| bag.make_name_ref(x.as_ref()))
|
||||||
|
.collect::<Box<[_]>>()
|
||||||
|
};
|
||||||
|
CodeObject {
|
||||||
|
constants: self
|
||||||
|
.constants
|
||||||
|
.into_vec()
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| x.map_constant(bag))
|
||||||
|
.collect(),
|
||||||
|
names: map_names(self.names),
|
||||||
|
varnames: map_names(self.varnames),
|
||||||
|
cellvars: map_names(self.cellvars),
|
||||||
|
freevars: map_names(self.freevars),
|
||||||
|
|
||||||
|
instructions: self.instructions,
|
||||||
|
locations: self.locations,
|
||||||
|
flags: self.flags,
|
||||||
|
posonlyarg_count: self.posonlyarg_count,
|
||||||
|
arg_count: self.arg_count,
|
||||||
|
kwonlyarg_count: self.kwonlyarg_count,
|
||||||
|
source_path: self.source_path,
|
||||||
|
first_line_number: self.first_line_number,
|
||||||
|
obj_name: self.obj_name,
|
||||||
|
cell2arg: self.cell2arg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map_clone_bag<Bag: ConstantBag>(&self, bag: &Bag) -> CodeObject<Bag::Constant> {
|
||||||
|
let map_names = |names: &[C::Name]| {
|
||||||
|
names
|
||||||
|
.iter()
|
||||||
|
.map(|x| bag.make_name_ref(x.as_ref()))
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
CodeObject {
|
||||||
|
constants: self
|
||||||
|
.constants
|
||||||
|
.iter()
|
||||||
|
.map(|x| bag.make_constant_borrowed(x.borrow_constant()))
|
||||||
|
.collect(),
|
||||||
|
names: map_names(&self.names),
|
||||||
|
varnames: map_names(&self.varnames),
|
||||||
|
cellvars: map_names(&self.cellvars),
|
||||||
|
freevars: map_names(&self.freevars),
|
||||||
|
|
||||||
|
instructions: self.instructions.clone(),
|
||||||
|
locations: self.locations.clone(),
|
||||||
|
flags: self.flags,
|
||||||
|
posonlyarg_count: self.posonlyarg_count,
|
||||||
|
arg_count: self.arg_count,
|
||||||
|
kwonlyarg_count: self.kwonlyarg_count,
|
||||||
|
source_path: self.source_path.clone(),
|
||||||
|
first_line_number: self.first_line_number,
|
||||||
|
obj_name: self.obj_name.clone(),
|
||||||
|
cell2arg: self.cell2arg.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CodeObject<ConstantData> {
|
||||||
|
/// Load a code object from bytes
|
||||||
|
pub fn from_bytes(data: &[u8]) -> Result<Self, Box<dyn std::error::Error>> {
|
||||||
|
let reader = lz_fear::framed::LZ4FrameReader::new(data)?;
|
||||||
|
Ok(bincode::deserialize_from(reader.into_read())?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Serialize this bytecode to bytes.
|
||||||
|
pub fn to_bytes(&self) -> Vec<u8> {
|
||||||
|
let data = bincode::serialize(&self).expect("CodeObject is not serializable");
|
||||||
|
let mut out = Vec::new();
|
||||||
|
lz_fear::framed::CompressionSettings::default()
|
||||||
|
.compress_with_size_unchecked(data.as_slice(), &mut out, data.len() as u64)
|
||||||
|
.unwrap();
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Constant> fmt::Display for CodeObject<C> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
self.display_inner(f, false, 1)?;
|
||||||
|
for constant in &*self.constants {
|
||||||
|
if let BorrowedConstant::Code { code } = constant.borrow_constant() {
|
||||||
|
write!(f, "\nDisassembly of {:?}\n", code)?;
|
||||||
|
code.fmt(f)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Instruction {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
fn fmt_dis<C: Constant>(
|
||||||
|
&self,
|
||||||
|
f: &mut fmt::Formatter,
|
||||||
|
constants: &[C],
|
||||||
|
names: &[C::Name],
|
||||||
|
varnames: &[C::Name],
|
||||||
|
cellvars: &[C::Name],
|
||||||
|
freevars: &[C::Name],
|
||||||
|
expand_codeobjects: bool,
|
||||||
|
level: usize,
|
||||||
|
) -> fmt::Result {
|
||||||
|
macro_rules! w {
|
||||||
|
($variant:ident) => {
|
||||||
|
writeln!(f, stringify!($variant))
|
||||||
|
};
|
||||||
|
($variant:ident, $var:expr) => {
|
||||||
|
writeln!(f, "{:20} ({})", stringify!($variant), $var)
|
||||||
|
};
|
||||||
|
($variant:ident, $var1:expr, $var2:expr) => {
|
||||||
|
writeln!(f, "{:20} ({}, {})", stringify!($variant), $var1, $var2)
|
||||||
|
};
|
||||||
|
($variant:ident, $var1:expr, $var2:expr, $var3:expr) => {
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{:20} ({}, {}, {})",
|
||||||
|
stringify!($variant),
|
||||||
|
$var1,
|
||||||
|
$var2,
|
||||||
|
$var3
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let cellname = |i: usize| {
|
||||||
|
cellvars
|
||||||
|
.get(i)
|
||||||
|
.unwrap_or_else(|| &freevars[i - cellvars.len()])
|
||||||
|
.as_ref()
|
||||||
|
};
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Import {
|
||||||
|
name_idx,
|
||||||
|
symbols_idx,
|
||||||
|
level,
|
||||||
|
} => w!(
|
||||||
|
Import,
|
||||||
|
format!("{:?}", name_idx.map(|idx| names[idx].as_ref())),
|
||||||
|
format!(
|
||||||
|
"({:?})",
|
||||||
|
symbols_idx
|
||||||
|
.iter()
|
||||||
|
.map(|&idx| names[idx].as_ref())
|
||||||
|
.format(", ")
|
||||||
|
),
|
||||||
|
level
|
||||||
|
),
|
||||||
|
ImportStar => w!(ImportStar),
|
||||||
|
ImportFrom { idx } => w!(ImportFrom, names[*idx].as_ref()),
|
||||||
|
LoadFast(idx) => w!(LoadFast, *idx, varnames[*idx].as_ref()),
|
||||||
|
LoadNameAny(idx) => w!(LoadNameAny, *idx, names[*idx].as_ref()),
|
||||||
|
LoadGlobal(idx) => w!(LoadGlobal, *idx, names[*idx].as_ref()),
|
||||||
|
LoadDeref(idx) => w!(LoadDeref, *idx, cellname(*idx)),
|
||||||
|
LoadClassDeref(idx) => w!(LoadClassDeref, *idx, cellname(*idx)),
|
||||||
|
StoreFast(idx) => w!(StoreFast, *idx, varnames[*idx].as_ref()),
|
||||||
|
StoreLocal(idx) => w!(StoreLocal, *idx, names[*idx].as_ref()),
|
||||||
|
StoreGlobal(idx) => w!(StoreGlobal, *idx, names[*idx].as_ref()),
|
||||||
|
StoreDeref(idx) => w!(StoreDeref, *idx, cellname(*idx)),
|
||||||
|
DeleteFast(idx) => w!(DeleteFast, *idx, varnames[*idx].as_ref()),
|
||||||
|
DeleteLocal(idx) => w!(DeleteLocal, *idx, names[*idx].as_ref()),
|
||||||
|
DeleteGlobal(idx) => w!(DeleteGlobal, *idx, names[*idx].as_ref()),
|
||||||
|
DeleteDeref(idx) => w!(DeleteDeref, *idx, cellname(*idx)),
|
||||||
|
LoadClosure(i) => w!(LoadClosure, *i, cellname(*i)),
|
||||||
|
Subscript => w!(Subscript),
|
||||||
|
StoreSubscript => w!(StoreSubscript),
|
||||||
|
DeleteSubscript => w!(DeleteSubscript),
|
||||||
|
StoreAttr { idx } => w!(StoreAttr, names[*idx].as_ref()),
|
||||||
|
DeleteAttr { idx } => w!(DeleteAttr, names[*idx].as_ref()),
|
||||||
|
LoadConst { idx } => {
|
||||||
|
let value = &constants[*idx];
|
||||||
|
match value.borrow_constant() {
|
||||||
|
BorrowedConstant::Code { code } if expand_codeobjects => {
|
||||||
|
writeln!(f, "{:20} ({:?}):", "LoadConst", code)?;
|
||||||
|
code.display_inner(f, true, level + 1)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
c => {
|
||||||
|
write!(f, "{:20} (", "LoadConst")?;
|
||||||
|
c.fmt_display(f)?;
|
||||||
|
writeln!(f, ")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnaryOperation { op } => w!(UnaryOperation, format!("{:?}", op)),
|
||||||
|
BinaryOperation { op, inplace } => w!(BinaryOperation, format!("{:?}", op), inplace),
|
||||||
|
LoadAttr { idx } => w!(LoadAttr, names[*idx].as_ref()),
|
||||||
|
CompareOperation { op } => w!(CompareOperation, format!("{:?}", op)),
|
||||||
|
Pop => w!(Pop),
|
||||||
|
Rotate { amount } => w!(Rotate, amount),
|
||||||
|
Duplicate => w!(Duplicate),
|
||||||
|
GetIter => w!(GetIter),
|
||||||
|
Continue => w!(Continue),
|
||||||
|
Break => w!(Break),
|
||||||
|
Jump { target } => w!(Jump, target),
|
||||||
|
JumpIfTrue { target } => w!(JumpIfTrue, target),
|
||||||
|
JumpIfFalse { target } => w!(JumpIfFalse, target),
|
||||||
|
JumpIfTrueOrPop { target } => w!(JumpIfTrueOrPop, target),
|
||||||
|
JumpIfFalseOrPop { target } => w!(JumpIfFalseOrPop, target),
|
||||||
|
MakeFunction => w!(MakeFunction),
|
||||||
|
CallFunction { typ } => w!(CallFunction, format!("{:?}", typ)),
|
||||||
|
ForIter { target } => w!(ForIter, target),
|
||||||
|
ReturnValue => w!(ReturnValue),
|
||||||
|
YieldValue => w!(YieldValue),
|
||||||
|
YieldFrom => w!(YieldFrom),
|
||||||
|
SetupAnnotation => w!(SetupAnnotation),
|
||||||
|
SetupLoop { start, end } => w!(SetupLoop, start, end),
|
||||||
|
SetupExcept { handler } => w!(SetupExcept, handler),
|
||||||
|
SetupFinally { handler } => w!(SetupFinally, handler),
|
||||||
|
EnterFinally => w!(EnterFinally),
|
||||||
|
EndFinally => w!(EndFinally),
|
||||||
|
SetupWith { end } => w!(SetupWith, end),
|
||||||
|
WithCleanupStart => w!(WithCleanupStart),
|
||||||
|
WithCleanupFinish => w!(WithCleanupFinish),
|
||||||
|
BeforeAsyncWith => w!(BeforeAsyncWith),
|
||||||
|
SetupAsyncWith { end } => w!(SetupAsyncWith, end),
|
||||||
|
PopBlock => w!(PopBlock),
|
||||||
|
Raise { argc } => w!(Raise, argc),
|
||||||
|
BuildString { size } => w!(BuildString, size),
|
||||||
|
BuildTuple { size, unpack } => w!(BuildTuple, size, unpack),
|
||||||
|
BuildList { size, unpack } => w!(BuildList, size, unpack),
|
||||||
|
BuildSet { size, unpack } => w!(BuildSet, size, unpack),
|
||||||
|
BuildMap {
|
||||||
|
size,
|
||||||
|
unpack,
|
||||||
|
for_call,
|
||||||
|
} => w!(BuildMap, size, unpack, for_call),
|
||||||
|
BuildSlice { size } => w!(BuildSlice, size),
|
||||||
|
ListAppend { i } => w!(ListAppend, i),
|
||||||
|
SetAdd { i } => w!(SetAdd, i),
|
||||||
|
MapAddRev { i } => w!(MapAddRev, i),
|
||||||
|
PrintExpr => w!(PrintExpr),
|
||||||
|
LoadBuildClass => w!(LoadBuildClass),
|
||||||
|
UnpackSequence { size } => w!(UnpackSequence, size),
|
||||||
|
UnpackEx { before, after } => w!(UnpackEx, before, after),
|
||||||
|
FormatValue { .. } => w!(FormatValue), // TODO: write conversion
|
||||||
|
PopException => w!(PopException),
|
||||||
|
Reverse { amount } => w!(Reverse, amount),
|
||||||
|
GetAwaitable => w!(GetAwaitable),
|
||||||
|
GetAIter => w!(GetAIter),
|
||||||
|
GetANext => w!(GetANext),
|
||||||
|
MapAdd { i } => w!(MapAdd, i),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ConstantData {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
self.borrow_constant().fmt_display(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: Constant> fmt::Debug for CodeObject<C> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"<code object {} at ??? file {:?}, line {}>",
|
||||||
|
self.obj_name, self.source_path, self.first_line_number
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct FrozenModule<C: Constant = ConstantData> {
|
||||||
|
#[serde(bound(
|
||||||
|
deserialize = "C: serde::Deserialize<'de>, C::Name: serde::Deserialize<'de>",
|
||||||
|
serialize = "C: serde::Serialize, C::Name: serde::Serialize"
|
||||||
|
))]
|
||||||
|
pub code: CodeObject<C>,
|
||||||
|
pub package: bool,
|
||||||
|
}
|
||||||
1089
bytecode/src/lib.rs
1089
bytecode/src/lib.rs
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,6 @@ hexf-parse = "0.1.0"
|
|||||||
cfg-if = "0.1"
|
cfg-if = "0.1"
|
||||||
once_cell = "1.4.1"
|
once_cell = "1.4.1"
|
||||||
siphasher = "0.3"
|
siphasher = "0.3"
|
||||||
rand = "0.8"
|
rand = "0.7.3"
|
||||||
derive_more = "0.99.9"
|
derive_more = "0.99.9"
|
||||||
volatile = "0.3"
|
volatile = "0.3"
|
||||||
|
|||||||
@@ -1,714 +0,0 @@
|
|||||||
//! An unresizable vector backed by a `Box<[T]>`
|
|
||||||
|
|
||||||
use std::borrow::{Borrow, BorrowMut};
|
|
||||||
use std::mem::{self, MaybeUninit};
|
|
||||||
use std::ops::{Bound, Deref, DerefMut, RangeBounds};
|
|
||||||
use std::{alloc, cmp, fmt, ptr, slice};
|
|
||||||
|
|
||||||
pub struct BoxVec<T> {
|
|
||||||
xs: Box<[MaybeUninit<T>]>,
|
|
||||||
len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Drop for BoxVec<T> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.clear();
|
|
||||||
|
|
||||||
// MaybeUninit inhibits array's drop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! panic_oob {
|
|
||||||
($method_name:expr, $index:expr, $len:expr) => {
|
|
||||||
panic!(
|
|
||||||
concat!(
|
|
||||||
"BoxVec::",
|
|
||||||
$method_name,
|
|
||||||
": index {} is out of bounds in vector of length {}"
|
|
||||||
),
|
|
||||||
$index, $len
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn capacity_overflow() -> ! {
|
|
||||||
panic!("capacity overflow")
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> BoxVec<T> {
|
|
||||||
pub fn new(n: usize) -> BoxVec<T> {
|
|
||||||
unsafe {
|
|
||||||
let layout = match alloc::Layout::array::<T>(n) {
|
|
||||||
Ok(l) => l,
|
|
||||||
Err(_) => capacity_overflow(),
|
|
||||||
};
|
|
||||||
let ptr = if mem::size_of::<T>() == 0 {
|
|
||||||
ptr::NonNull::<MaybeUninit<T>>::dangling().as_ptr()
|
|
||||||
} else {
|
|
||||||
let ptr = alloc::alloc(layout);
|
|
||||||
if ptr.is_null() {
|
|
||||||
alloc::handle_alloc_error(layout)
|
|
||||||
}
|
|
||||||
ptr as *mut MaybeUninit<T>
|
|
||||||
};
|
|
||||||
let ptr = ptr::slice_from_raw_parts_mut(ptr, n);
|
|
||||||
let xs = Box::from_raw(ptr);
|
|
||||||
BoxVec { xs, len: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.len
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.len() == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn capacity(&self) -> usize {
|
|
||||||
self.xs.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_full(&self) -> bool {
|
|
||||||
self.len() == self.capacity()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remaining_capacity(&self) -> usize {
|
|
||||||
self.capacity() - self.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push(&mut self, element: T) {
|
|
||||||
self.try_push(element).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn try_push(&mut self, element: T) -> Result<(), CapacityError<T>> {
|
|
||||||
if self.len() < self.capacity() {
|
|
||||||
unsafe {
|
|
||||||
self.push_unchecked(element);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(CapacityError::new(element))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # Safety
|
|
||||||
/// Must ensure that self.len() < self.capacity()
|
|
||||||
pub unsafe fn push_unchecked(&mut self, element: T) {
|
|
||||||
let len = self.len();
|
|
||||||
debug_assert!(len < self.capacity());
|
|
||||||
ptr::write(self.get_unchecked_ptr(len), element);
|
|
||||||
self.set_len(len + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get pointer to where element at `index` would be
|
|
||||||
unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut T {
|
|
||||||
self.xs.as_mut_ptr().add(index).cast()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert(&mut self, index: usize, element: T) {
|
|
||||||
self.try_insert(index, element).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn try_insert(&mut self, index: usize, element: T) -> Result<(), CapacityError<T>> {
|
|
||||||
if index > self.len() {
|
|
||||||
panic_oob!("try_insert", index, self.len())
|
|
||||||
}
|
|
||||||
if self.len() == self.capacity() {
|
|
||||||
return Err(CapacityError::new(element));
|
|
||||||
}
|
|
||||||
let len = self.len();
|
|
||||||
|
|
||||||
// follows is just like Vec<T>
|
|
||||||
unsafe {
|
|
||||||
// infallible
|
|
||||||
// The spot to put the new value
|
|
||||||
{
|
|
||||||
let p: *mut _ = self.get_unchecked_ptr(index);
|
|
||||||
// Shift everything over to make space. (Duplicating the
|
|
||||||
// `index`th element into two consecutive places.)
|
|
||||||
ptr::copy(p, p.offset(1), len - index);
|
|
||||||
// Write it in, overwriting the first copy of the `index`th
|
|
||||||
// element.
|
|
||||||
ptr::write(p, element);
|
|
||||||
}
|
|
||||||
self.set_len(len + 1);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pop(&mut self) -> Option<T> {
|
|
||||||
if self.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
let new_len = self.len() - 1;
|
|
||||||
self.set_len(new_len);
|
|
||||||
Some(ptr::read(self.get_unchecked_ptr(new_len)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn swap_remove(&mut self, index: usize) -> T {
|
|
||||||
self.swap_pop(index)
|
|
||||||
.unwrap_or_else(|| panic_oob!("swap_remove", index, self.len()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn swap_pop(&mut self, index: usize) -> Option<T> {
|
|
||||||
let len = self.len();
|
|
||||||
if index >= len {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
self.swap(index, len - 1);
|
|
||||||
self.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove(&mut self, index: usize) -> T {
|
|
||||||
self.pop_at(index)
|
|
||||||
.unwrap_or_else(|| panic_oob!("remove", index, self.len()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pop_at(&mut self, index: usize) -> Option<T> {
|
|
||||||
if index >= self.len() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
self.drain(index..index + 1).next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn truncate(&mut self, new_len: usize) {
|
|
||||||
unsafe {
|
|
||||||
if new_len < self.len() {
|
|
||||||
let tail: *mut [_] = &mut self[new_len..];
|
|
||||||
self.len = new_len;
|
|
||||||
ptr::drop_in_place(tail);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove all elements in the vector.
|
|
||||||
pub fn clear(&mut self) {
|
|
||||||
self.truncate(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retains only the elements specified by the predicate.
|
|
||||||
///
|
|
||||||
/// In other words, remove all elements `e` such that `f(&mut e)` returns false.
|
|
||||||
/// This method operates in place and preserves the order of the retained
|
|
||||||
/// elements.
|
|
||||||
pub fn retain<F>(&mut self, mut f: F)
|
|
||||||
where
|
|
||||||
F: FnMut(&mut T) -> bool,
|
|
||||||
{
|
|
||||||
let len = self.len();
|
|
||||||
let mut del = 0;
|
|
||||||
{
|
|
||||||
let v = &mut **self;
|
|
||||||
|
|
||||||
for i in 0..len {
|
|
||||||
if !f(&mut v[i]) {
|
|
||||||
del += 1;
|
|
||||||
} else if del > 0 {
|
|
||||||
v.swap(i - del, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if del > 0 {
|
|
||||||
self.drain(len - del..);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the vector’s length without dropping or moving out elements
|
|
||||||
///
|
|
||||||
/// This method is `unsafe` because it changes the notion of the
|
|
||||||
/// number of “valid” elements in the vector. Use with care.
|
|
||||||
///
|
|
||||||
/// This method uses *debug assertions* to check that `length` is
|
|
||||||
/// not greater than the capacity.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
/// Must ensure that length <= self.capacity()
|
|
||||||
pub unsafe fn set_len(&mut self, length: usize) {
|
|
||||||
debug_assert!(length <= self.capacity());
|
|
||||||
self.len = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copy and appends all elements in a slice to the `BoxVec`.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// This method will return an error if the capacity left (see
|
|
||||||
/// [`remaining_capacity`]) is smaller then the length of the provided
|
|
||||||
/// slice.
|
|
||||||
///
|
|
||||||
/// [`remaining_capacity`]: #method.remaining_capacity
|
|
||||||
pub fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError>
|
|
||||||
where
|
|
||||||
T: Copy,
|
|
||||||
{
|
|
||||||
if self.remaining_capacity() < other.len() {
|
|
||||||
return Err(CapacityError::new(()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let self_len = self.len();
|
|
||||||
let other_len = other.len();
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let dst = self.as_mut_ptr().add(self_len);
|
|
||||||
ptr::copy_nonoverlapping(other.as_ptr(), dst, other_len);
|
|
||||||
self.set_len(self_len + other_len);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a draining iterator that removes the specified range in the vector
|
|
||||||
/// and yields the removed items from start to end. The element range is
|
|
||||||
/// removed even if the iterator is not consumed until the end.
|
|
||||||
///
|
|
||||||
/// Note: It is unspecified how many elements are removed from the vector,
|
|
||||||
/// if the `Drain` value is leaked.
|
|
||||||
///
|
|
||||||
/// **Panics** if the starting point is greater than the end point or if
|
|
||||||
/// the end point is greater than the length of the vector.
|
|
||||||
pub fn drain<R>(&mut self, range: R) -> Drain<T>
|
|
||||||
where
|
|
||||||
R: RangeBounds<usize>,
|
|
||||||
{
|
|
||||||
// Memory safety
|
|
||||||
//
|
|
||||||
// When the Drain is first created, it shortens the length of
|
|
||||||
// the source vector to make sure no uninitialized or moved-from elements
|
|
||||||
// are accessible at all if the Drain's destructor never gets to run.
|
|
||||||
//
|
|
||||||
// Drain will ptr::read out the values to remove.
|
|
||||||
// When finished, remaining tail of the vec is copied back to cover
|
|
||||||
// the hole, and the vector length is restored to the new length.
|
|
||||||
//
|
|
||||||
let len = self.len();
|
|
||||||
let start = match range.start_bound() {
|
|
||||||
Bound::Unbounded => 0,
|
|
||||||
Bound::Included(&i) => i,
|
|
||||||
Bound::Excluded(&i) => i.saturating_add(1),
|
|
||||||
};
|
|
||||||
let end = match range.end_bound() {
|
|
||||||
Bound::Excluded(&j) => j,
|
|
||||||
Bound::Included(&j) => j.saturating_add(1),
|
|
||||||
Bound::Unbounded => len,
|
|
||||||
};
|
|
||||||
self.drain_range(start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn drain_range(&mut self, start: usize, end: usize) -> Drain<T> {
|
|
||||||
let len = self.len();
|
|
||||||
|
|
||||||
// bounds check happens here (before length is changed!)
|
|
||||||
let range_slice: *const _ = &self[start..end];
|
|
||||||
|
|
||||||
// Calling `set_len` creates a fresh and thus unique mutable references, making all
|
|
||||||
// older aliases we created invalid. So we cannot call that function.
|
|
||||||
self.len = start;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
Drain {
|
|
||||||
tail_start: end,
|
|
||||||
tail_len: len - end,
|
|
||||||
iter: (*range_slice).iter(),
|
|
||||||
vec: ptr::NonNull::from(self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a slice containing all elements of the vector.
|
|
||||||
pub fn as_slice(&self) -> &[T] {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a mutable slice containing all elements of the vector.
|
|
||||||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a raw pointer to the vector's buffer.
|
|
||||||
#[inline]
|
|
||||||
pub fn as_ptr(&self) -> *const T {
|
|
||||||
self.xs.as_ptr().cast()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a raw mutable pointer to the vector's buffer.
|
|
||||||
#[inline]
|
|
||||||
pub fn as_mut_ptr(&mut self) -> *mut T {
|
|
||||||
self.xs.as_mut_ptr().cast()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Deref for BoxVec<T> {
|
|
||||||
type Target = [T];
|
|
||||||
#[inline]
|
|
||||||
fn deref(&self) -> &[T] {
|
|
||||||
unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> DerefMut for BoxVec<T> {
|
|
||||||
#[inline]
|
|
||||||
fn deref_mut(&mut self) -> &mut [T] {
|
|
||||||
let len = self.len();
|
|
||||||
unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), len) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate the `BoxVec` with references to each element.
|
|
||||||
impl<'a, T> IntoIterator for &'a BoxVec<T> {
|
|
||||||
type Item = &'a T;
|
|
||||||
type IntoIter = slice::Iter<'a, T>;
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
|
||||||
self.iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate the `BoxVec` with mutable references to each element.
|
|
||||||
impl<'a, T> IntoIterator for &'a mut BoxVec<T> {
|
|
||||||
type Item = &'a mut T;
|
|
||||||
type IntoIter = slice::IterMut<'a, T>;
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
|
||||||
self.iter_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate the `BoxVec` with each element by value.
|
|
||||||
///
|
|
||||||
/// The vector is consumed by this operation.
|
|
||||||
impl<T> IntoIterator for BoxVec<T> {
|
|
||||||
type Item = T;
|
|
||||||
type IntoIter = IntoIter<T>;
|
|
||||||
fn into_iter(self) -> IntoIter<T> {
|
|
||||||
IntoIter { index: 0, v: self }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// By-value iterator for `BoxVec`.
|
|
||||||
pub struct IntoIter<T> {
|
|
||||||
index: usize,
|
|
||||||
v: BoxVec<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Iterator for IntoIter<T> {
|
|
||||||
type Item = T;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<T> {
|
|
||||||
if self.index == self.v.len {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
let index = self.index;
|
|
||||||
self.index += 1;
|
|
||||||
Some(ptr::read(self.v.get_unchecked_ptr(index)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
let len = self.v.len() - self.index;
|
|
||||||
(len, Some(len))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> DoubleEndedIterator for IntoIter<T> {
|
|
||||||
fn next_back(&mut self) -> Option<T> {
|
|
||||||
if self.index == self.v.len {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
let new_len = self.v.len() - 1;
|
|
||||||
self.v.set_len(new_len);
|
|
||||||
Some(ptr::read(self.v.get_unchecked_ptr(new_len)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ExactSizeIterator for IntoIter<T> {}
|
|
||||||
|
|
||||||
impl<T> Drop for IntoIter<T> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
// panic safety: Set length to 0 before dropping elements.
|
|
||||||
let index = self.index;
|
|
||||||
let len = self.v.len();
|
|
||||||
unsafe {
|
|
||||||
self.v.set_len(0);
|
|
||||||
let elements = slice::from_raw_parts_mut(self.v.get_unchecked_ptr(index), len - index);
|
|
||||||
ptr::drop_in_place(elements);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> fmt::Debug for IntoIter<T>
|
|
||||||
where
|
|
||||||
T: fmt::Debug,
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
f.debug_list().entries(&self.v[self.index..]).finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A draining iterator for `BoxVec`.
|
|
||||||
pub struct Drain<'a, T> {
|
|
||||||
/// Index of tail to preserve
|
|
||||||
tail_start: usize,
|
|
||||||
/// Length of tail
|
|
||||||
tail_len: usize,
|
|
||||||
/// Current remaining range to remove
|
|
||||||
iter: slice::Iter<'a, T>,
|
|
||||||
vec: ptr::NonNull<BoxVec<T>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {}
|
|
||||||
unsafe impl<'a, T: Send> Send for Drain<'a, T> {}
|
|
||||||
|
|
||||||
impl<T> Iterator for Drain<'_, T> {
|
|
||||||
type Item = T;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
self.iter
|
|
||||||
.next()
|
|
||||||
.map(|elt| unsafe { ptr::read(elt as *const _) })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
self.iter.size_hint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> DoubleEndedIterator for Drain<'_, T> {
|
|
||||||
fn next_back(&mut self) -> Option<Self::Item> {
|
|
||||||
self.iter
|
|
||||||
.next_back()
|
|
||||||
.map(|elt| unsafe { ptr::read(elt as *const _) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ExactSizeIterator for Drain<'_, T> {}
|
|
||||||
|
|
||||||
impl<'a, T> Drain<'a, T> {
|
|
||||||
pub fn as_slice(&self) -> &'a [T] {
|
|
||||||
self.iter.as_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Drop for Drain<'_, T> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
// len is currently 0 so panicking while dropping will not cause a double drop.
|
|
||||||
|
|
||||||
// exhaust self first
|
|
||||||
while let Some(_) = self.next() {}
|
|
||||||
|
|
||||||
if self.tail_len > 0 {
|
|
||||||
unsafe {
|
|
||||||
let source_vec = self.vec.as_mut();
|
|
||||||
// memmove back untouched tail, update to new length
|
|
||||||
let start = source_vec.len();
|
|
||||||
let tail = self.tail_start;
|
|
||||||
let src = source_vec.as_ptr().add(tail);
|
|
||||||
let dst = source_vec.as_mut_ptr().add(start);
|
|
||||||
ptr::copy(src, dst, self.tail_len);
|
|
||||||
source_vec.set_len(start + self.tail_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ScopeExitGuard<T, Data, F>
|
|
||||||
where
|
|
||||||
F: FnMut(&Data, &mut T),
|
|
||||||
{
|
|
||||||
value: T,
|
|
||||||
data: Data,
|
|
||||||
f: F,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, Data, F> Drop for ScopeExitGuard<T, Data, F>
|
|
||||||
where
|
|
||||||
F: FnMut(&Data, &mut T),
|
|
||||||
{
|
|
||||||
fn drop(&mut self) {
|
|
||||||
(self.f)(&self.data, &mut self.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extend the `BoxVec` with an iterator.
|
|
||||||
///
|
|
||||||
/// Does not extract more items than there is space for. No error
|
|
||||||
/// occurs if there are more iterator elements.
|
|
||||||
impl<T> Extend<T> for BoxVec<T> {
|
|
||||||
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
|
|
||||||
let take = self.capacity() - self.len();
|
|
||||||
unsafe {
|
|
||||||
let len = self.len();
|
|
||||||
let mut ptr = raw_ptr_add(self.as_mut_ptr(), len);
|
|
||||||
let end_ptr = raw_ptr_add(ptr, take);
|
|
||||||
// Keep the length in a separate variable, write it back on scope
|
|
||||||
// exit. To help the compiler with alias analysis and stuff.
|
|
||||||
// We update the length to handle panic in the iteration of the
|
|
||||||
// user's iterator, without dropping any elements on the floor.
|
|
||||||
let mut guard = ScopeExitGuard {
|
|
||||||
value: &mut self.len,
|
|
||||||
data: len,
|
|
||||||
f: move |&len, self_len| {
|
|
||||||
**self_len = len;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let mut iter = iter.into_iter();
|
|
||||||
loop {
|
|
||||||
if ptr == end_ptr {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if let Some(elt) = iter.next() {
|
|
||||||
raw_ptr_write(ptr, elt);
|
|
||||||
ptr = raw_ptr_add(ptr, 1);
|
|
||||||
guard.data += 1;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Rawptr add but uses arithmetic distance for ZST
|
|
||||||
unsafe fn raw_ptr_add<T>(ptr: *mut T, offset: usize) -> *mut T {
|
|
||||||
if mem::size_of::<T>() == 0 {
|
|
||||||
// Special case for ZST
|
|
||||||
(ptr as usize).wrapping_add(offset) as _
|
|
||||||
} else {
|
|
||||||
ptr.add(offset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn raw_ptr_write<T>(ptr: *mut T, value: T) {
|
|
||||||
if mem::size_of::<T>() == 0 {
|
|
||||||
/* nothing */
|
|
||||||
} else {
|
|
||||||
ptr::write(ptr, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Clone for BoxVec<T>
|
|
||||||
where
|
|
||||||
T: Clone,
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
let mut new = BoxVec::new(self.capacity());
|
|
||||||
new.extend(self.iter().cloned());
|
|
||||||
new
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clone_from(&mut self, rhs: &Self) {
|
|
||||||
// recursive case for the common prefix
|
|
||||||
let prefix = cmp::min(self.len(), rhs.len());
|
|
||||||
self[..prefix].clone_from_slice(&rhs[..prefix]);
|
|
||||||
|
|
||||||
if prefix < self.len() {
|
|
||||||
// rhs was shorter
|
|
||||||
for _ in 0..self.len() - prefix {
|
|
||||||
self.pop();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let rhs_elems = rhs[self.len()..].iter().cloned();
|
|
||||||
self.extend(rhs_elems);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PartialEq for BoxVec<T>
|
|
||||||
where
|
|
||||||
T: PartialEq,
|
|
||||||
{
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
**self == **other
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PartialEq<[T]> for BoxVec<T>
|
|
||||||
where
|
|
||||||
T: PartialEq,
|
|
||||||
{
|
|
||||||
fn eq(&self, other: &[T]) -> bool {
|
|
||||||
**self == *other
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Eq for BoxVec<T> where T: Eq {}
|
|
||||||
|
|
||||||
impl<T> Borrow<[T]> for BoxVec<T> {
|
|
||||||
fn borrow(&self) -> &[T] {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> BorrowMut<[T]> for BoxVec<T> {
|
|
||||||
fn borrow_mut(&mut self) -> &mut [T] {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> AsRef<[T]> for BoxVec<T> {
|
|
||||||
fn as_ref(&self) -> &[T] {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> AsMut<[T]> for BoxVec<T> {
|
|
||||||
fn as_mut(&mut self) -> &mut [T] {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> fmt::Debug for BoxVec<T>
|
|
||||||
where
|
|
||||||
T: fmt::Debug,
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
(**self).fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Error value indicating insufficient capacity
|
|
||||||
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
|
|
||||||
pub struct CapacityError<T = ()> {
|
|
||||||
element: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> CapacityError<T> {
|
|
||||||
/// Create a new `CapacityError` from `element`.
|
|
||||||
pub fn new(element: T) -> CapacityError<T> {
|
|
||||||
CapacityError { element }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extract the overflowing element
|
|
||||||
pub fn element(self) -> T {
|
|
||||||
self.element
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert into a `CapacityError` that does not carry an element.
|
|
||||||
pub fn simplify(self) -> CapacityError {
|
|
||||||
CapacityError { element: () }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const CAPERROR: &str = "insufficient capacity";
|
|
||||||
|
|
||||||
impl<T> std::error::Error for CapacityError<T> {}
|
|
||||||
|
|
||||||
impl<T> fmt::Display for CapacityError<T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{}", CAPERROR)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> fmt::Debug for CapacityError<T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "capacity error: {}", CAPERROR)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -252,7 +252,7 @@ pub fn to_hex(value: f64) -> String {
|
|||||||
const BITS: i16 = 52;
|
const BITS: i16 = 52;
|
||||||
const FRACT_MASK: u64 = 0xf_ffff_ffff_ffff;
|
const FRACT_MASK: u64 = 0xf_ffff_ffff_ffff;
|
||||||
format!(
|
format!(
|
||||||
"{}{:#x}.{:013x}p{:+}",
|
"{}0x{:x}.{:013x}p{:+}",
|
||||||
sign_fmt,
|
sign_fmt,
|
||||||
mantissa >> BITS,
|
mantissa >> BITS,
|
||||||
mantissa & FRACT_MASK,
|
mantissa & FRACT_MASK,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
//! A crate to hold types and functions common to all rustpython components.
|
//! A crate to hold types and functions common to all rustpython components.
|
||||||
|
|
||||||
pub mod borrow;
|
pub mod borrow;
|
||||||
pub mod boxvec;
|
|
||||||
pub mod cmp;
|
pub mod cmp;
|
||||||
pub mod float_ops;
|
pub mod float_ops;
|
||||||
pub mod hash;
|
pub mod hash;
|
||||||
|
|||||||
@@ -7,20 +7,14 @@ repository = "https://github.com/RustPython/RustPython"
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[features]
|
|
||||||
std = ["rustpython-bytecode/std", "itertools/use_std"]
|
|
||||||
default = ["std"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
indexmap = "1.0"
|
indexmap = "1.0"
|
||||||
itertools = { version = "0.9", default-features = false }
|
itertools = "0.9"
|
||||||
rustpython-bytecode = { path = "../bytecode", version = "0.1.1", default-features = false }
|
rustpython-bytecode = { path = "../bytecode", version = "0.1.1" }
|
||||||
rustpython-ast = { path = "../ast" }
|
rustpython-ast = { path = "../ast" }
|
||||||
num-complex = { version = "0.3", features = ["serde"] }
|
num-complex = { version = "0.3", features = ["serde"] }
|
||||||
num-traits = "0.2"
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
ahash = "0.6"
|
arrayvec = "0.5"
|
||||||
scopeguard = "1.1"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rustpython-parser = { path = "../parser" }
|
rustpython-parser = { path = "../parser" }
|
||||||
|
|||||||
@@ -5,10 +5,6 @@ description = "A usability wrapper around rustpython-parser and rustpython-compi
|
|||||||
authors = ["RustPython Team"]
|
authors = ["RustPython Team"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[features]
|
|
||||||
std = ["rustpython-compiler-core/std", "rustpython-bytecode/std", "rustpython-parser/std"]
|
|
||||||
default = ["std"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
rustpython-compiler-core = { path = ".." }
|
rustpython-compiler-core = { path = ".." }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use rustpython_bytecode::CodeObject;
|
use rustpython_bytecode::bytecode::CodeObject;
|
||||||
use rustpython_compiler_core::{compile, symboltable};
|
use rustpython_compiler_core::{compile, symboltable};
|
||||||
use rustpython_parser::{ast::Location, parser};
|
use rustpython_parser::{ast::Location, parser};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,7 @@
|
|||||||
use rustpython_ast::Location;
|
use rustpython_ast::Location;
|
||||||
|
|
||||||
use alloc::string::String;
|
|
||||||
use core::fmt;
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CompileError {
|
pub struct CompileError {
|
||||||
@@ -39,7 +37,6 @@ pub enum CompileErrorType {
|
|||||||
InvalidFuturePlacement,
|
InvalidFuturePlacement,
|
||||||
InvalidFutureFeature(String),
|
InvalidFutureFeature(String),
|
||||||
FunctionImportStar,
|
FunctionImportStar,
|
||||||
TooManyStarUnpack,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CompileErrorType {
|
impl fmt::Display for CompileErrorType {
|
||||||
@@ -73,14 +70,10 @@ impl fmt::Display for CompileErrorType {
|
|||||||
CompileErrorType::FunctionImportStar => {
|
CompileErrorType::FunctionImportStar => {
|
||||||
write!(f, "import * only allowed at module level")
|
write!(f, "import * only allowed at module level")
|
||||||
}
|
}
|
||||||
CompileErrorType::TooManyStarUnpack => {
|
|
||||||
write!(f, "too many expressions in star-unpacking assignment")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl Error for CompileErrorType {}
|
impl Error for CompileErrorType {}
|
||||||
|
|
||||||
impl fmt::Display for CompileError {
|
impl fmt::Display for CompileError {
|
||||||
@@ -89,5 +82,8 @@ impl fmt::Display for CompileError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
impl Error for CompileError {
|
||||||
impl Error for CompileError {}
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,224 +0,0 @@
|
|||||||
use crate::IndexSet;
|
|
||||||
use rustpython_bytecode::{CodeFlags, CodeObject, ConstantData, Instruction, Label, Location};
|
|
||||||
|
|
||||||
pub type BlockIdx = Label;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct InstructionInfo {
|
|
||||||
/// If the instruction has a Label argument, it's actually a BlockIdx, not a code offset
|
|
||||||
pub instr: Instruction,
|
|
||||||
pub location: Location,
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: look into using petgraph for handling blocks and stuff? it's heavier than this, but it
|
|
||||||
// might enable more analysis/optimizations
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Block {
|
|
||||||
pub instructions: Vec<InstructionInfo>,
|
|
||||||
pub next: BlockIdx,
|
|
||||||
}
|
|
||||||
impl Default for Block {
|
|
||||||
fn default() -> Self {
|
|
||||||
Block {
|
|
||||||
instructions: Vec::new(),
|
|
||||||
next: Label(u32::MAX),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CodeInfo {
|
|
||||||
pub flags: CodeFlags,
|
|
||||||
pub posonlyarg_count: usize, // Number of positional-only arguments
|
|
||||||
pub arg_count: usize,
|
|
||||||
pub kwonlyarg_count: usize,
|
|
||||||
pub source_path: String,
|
|
||||||
pub first_line_number: usize,
|
|
||||||
pub obj_name: String, // Name of the object that created this code object
|
|
||||||
|
|
||||||
pub blocks: Vec<Block>,
|
|
||||||
pub current_block: BlockIdx,
|
|
||||||
pub constants: Vec<ConstantData>,
|
|
||||||
pub name_cache: IndexSet<String>,
|
|
||||||
pub varname_cache: IndexSet<String>,
|
|
||||||
pub cellvar_cache: IndexSet<String>,
|
|
||||||
pub freevar_cache: IndexSet<String>,
|
|
||||||
}
|
|
||||||
impl CodeInfo {
|
|
||||||
pub fn finalize_code(mut self, optimize: u8) -> CodeObject {
|
|
||||||
let max_stacksize = self.max_stacksize();
|
|
||||||
let cell2arg = self.cell2arg();
|
|
||||||
|
|
||||||
if optimize > 0 {
|
|
||||||
self.dce();
|
|
||||||
}
|
|
||||||
|
|
||||||
let CodeInfo {
|
|
||||||
flags,
|
|
||||||
posonlyarg_count,
|
|
||||||
arg_count,
|
|
||||||
kwonlyarg_count,
|
|
||||||
source_path,
|
|
||||||
first_line_number,
|
|
||||||
obj_name,
|
|
||||||
|
|
||||||
blocks,
|
|
||||||
current_block: _,
|
|
||||||
constants,
|
|
||||||
name_cache,
|
|
||||||
varname_cache,
|
|
||||||
cellvar_cache,
|
|
||||||
freevar_cache,
|
|
||||||
} = self;
|
|
||||||
|
|
||||||
let mut num_instructions = 0;
|
|
||||||
let mut block_to_offset = vec![Label(0); blocks.len()];
|
|
||||||
|
|
||||||
for (idx, block) in iter_blocks(&blocks) {
|
|
||||||
block_to_offset[idx.0 as usize] = Label(num_instructions as u32);
|
|
||||||
num_instructions += block.instructions.len();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut instructions = Vec::with_capacity(num_instructions);
|
|
||||||
let mut locations = Vec::with_capacity(num_instructions);
|
|
||||||
|
|
||||||
for (_, block) in iter_blocks(&blocks) {
|
|
||||||
for info in &block.instructions {
|
|
||||||
let mut instr = info.instr.clone();
|
|
||||||
if let Some(l) = instr.label_arg_mut() {
|
|
||||||
*l = block_to_offset[l.0 as usize];
|
|
||||||
}
|
|
||||||
instructions.push(instr);
|
|
||||||
locations.push(info.location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeObject {
|
|
||||||
flags,
|
|
||||||
posonlyarg_count,
|
|
||||||
arg_count,
|
|
||||||
kwonlyarg_count,
|
|
||||||
source_path,
|
|
||||||
first_line_number,
|
|
||||||
obj_name,
|
|
||||||
|
|
||||||
max_stacksize,
|
|
||||||
instructions: instructions.into_boxed_slice(),
|
|
||||||
locations: locations.into_boxed_slice(),
|
|
||||||
constants: constants.into(),
|
|
||||||
names: name_cache.into_iter().collect(),
|
|
||||||
varnames: varname_cache.into_iter().collect(),
|
|
||||||
cellvars: cellvar_cache.into_iter().collect(),
|
|
||||||
freevars: freevar_cache.into_iter().collect(),
|
|
||||||
cell2arg,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cell2arg(&self) -> Option<Box<[isize]>> {
|
|
||||||
if self.cellvar_cache.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let total_args = self.arg_count
|
|
||||||
+ self.kwonlyarg_count
|
|
||||||
+ self.flags.contains(CodeFlags::HAS_VARARGS) as usize
|
|
||||||
+ self.flags.contains(CodeFlags::HAS_VARKEYWORDS) as usize;
|
|
||||||
|
|
||||||
let mut found_cellarg = false;
|
|
||||||
let cell2arg = self
|
|
||||||
.cellvar_cache
|
|
||||||
.iter()
|
|
||||||
.map(|var| {
|
|
||||||
self.varname_cache
|
|
||||||
.get_index_of(var)
|
|
||||||
// check that it's actually an arg
|
|
||||||
.filter(|i| *i < total_args)
|
|
||||||
.map_or(-1, |i| {
|
|
||||||
found_cellarg = true;
|
|
||||||
i as isize
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect::<Box<[_]>>();
|
|
||||||
|
|
||||||
if found_cellarg {
|
|
||||||
Some(cell2arg)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dce(&mut self) {
|
|
||||||
for block in &mut self.blocks {
|
|
||||||
let mut last_instr = None;
|
|
||||||
for (i, ins) in block.instructions.iter().enumerate() {
|
|
||||||
if ins.instr.unconditional_branch() {
|
|
||||||
last_instr = Some(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(i) = last_instr {
|
|
||||||
block.instructions.truncate(i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn max_stacksize(&self) -> u32 {
|
|
||||||
let mut maxdepth = 0u32;
|
|
||||||
let mut stack = Vec::with_capacity(self.blocks.len());
|
|
||||||
let mut startdepths = vec![u32::MAX; self.blocks.len()];
|
|
||||||
startdepths[0] = 0;
|
|
||||||
stack.push(Label(0));
|
|
||||||
'process_blocks: while let Some(block) = stack.pop() {
|
|
||||||
let mut depth = startdepths[block.0 as usize];
|
|
||||||
let block = &self.blocks[block.0 as usize];
|
|
||||||
for i in &block.instructions {
|
|
||||||
let instr = &i.instr;
|
|
||||||
let effect = instr.stack_effect(false);
|
|
||||||
let new_depth = add_ui(depth, effect);
|
|
||||||
if new_depth > maxdepth {
|
|
||||||
maxdepth = new_depth
|
|
||||||
}
|
|
||||||
// we don't want to worry about Continue or Break, they use unwinding to jump to
|
|
||||||
// their targets and as such the stack size is taken care of in frame.rs by setting
|
|
||||||
// it back to the level it was at when SetupLoop was run
|
|
||||||
let jump_label = instr.label_arg().filter(
|
|
||||||
|_| !matches!(instr, Instruction::Continue { .. } | Instruction::Break { .. }),
|
|
||||||
);
|
|
||||||
if let Some(&target_block) = jump_label {
|
|
||||||
let effect = instr.stack_effect(true);
|
|
||||||
let target_depth = add_ui(depth, effect);
|
|
||||||
if target_depth > maxdepth {
|
|
||||||
maxdepth = target_depth
|
|
||||||
}
|
|
||||||
stackdepth_push(&mut stack, &mut startdepths, target_block, target_depth);
|
|
||||||
}
|
|
||||||
depth = new_depth;
|
|
||||||
if instr.unconditional_branch() {
|
|
||||||
continue 'process_blocks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stackdepth_push(&mut stack, &mut startdepths, block.next, depth);
|
|
||||||
}
|
|
||||||
maxdepth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stackdepth_push(stack: &mut Vec<Label>, startdepths: &mut [u32], target: Label, depth: u32) {
|
|
||||||
let block_depth = &mut startdepths[target.0 as usize];
|
|
||||||
if *block_depth == u32::MAX || depth > *block_depth {
|
|
||||||
*block_depth = depth;
|
|
||||||
stack.push(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_ui(a: u32, b: i32) -> u32 {
|
|
||||||
if b < 0 {
|
|
||||||
a - b.abs() as u32
|
|
||||||
} else {
|
|
||||||
a + b as u32
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn iter_blocks(blocks: &[Block]) -> impl Iterator<Item = (BlockIdx, &Block)> + '_ {
|
|
||||||
let get_idx = move |i: BlockIdx| blocks.get(i.0 as usize).map(|b| (i, b));
|
|
||||||
std::iter::successors(get_idx(Label(0)), move |(_, b)| get_idx(b.next)) // if b.next is u32::MAX that's the end
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,12 @@
|
|||||||
//! Compile a Python AST or source code into bytecode consumable by RustPython.
|
//! Compile a Python AST or source code into bytecode consumable by RustPython or
|
||||||
|
//! (eventually) CPython.
|
||||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustPython/RustPython/master/logo.png")]
|
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustPython/RustPython/master/logo.png")]
|
||||||
#![doc(html_root_url = "https://docs.rs/rustpython-compiler/")]
|
#![doc(html_root_url = "https://docs.rs/rustpython-compiler/")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
|
||||||
|
|
||||||
extern crate alloc;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
type IndexMap<K, V> = indexmap::IndexMap<K, V, ahash::RandomState>;
|
|
||||||
type IndexSet<T> = indexmap::IndexSet<T, ahash::RandomState>;
|
|
||||||
|
|
||||||
pub mod compile;
|
pub mod compile;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod ir;
|
|
||||||
pub mod mode;
|
pub mod mode;
|
||||||
pub mod symboltable;
|
pub mod symboltable;
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
use core::fmt;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
Exec,
|
Exec,
|
||||||
@@ -7,7 +5,7 @@ pub enum Mode {
|
|||||||
Single,
|
Single,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::str::FromStr for Mode {
|
impl std::str::FromStr for Mode {
|
||||||
type Err = ModeParseError;
|
type Err = ModeParseError;
|
||||||
fn from_str(s: &str) -> Result<Self, ModeParseError> {
|
fn from_str(s: &str) -> Result<Self, ModeParseError> {
|
||||||
match s {
|
match s {
|
||||||
@@ -24,8 +22,8 @@ pub struct ModeParseError {
|
|||||||
_priv: (),
|
_priv: (),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ModeParseError {
|
impl std::fmt::Display for ModeParseError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
write!(f, r#"mode should be "exec", "eval", or "single""#)
|
write!(f, r#"mode should be "exec", "eval", or "single""#)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,9 @@ Inspirational file: https://github.com/python/cpython/blob/master/Python/symtabl
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::error::{CompileError, CompileErrorType};
|
use crate::error::{CompileError, CompileErrorType};
|
||||||
use crate::IndexMap;
|
use indexmap::map::IndexMap;
|
||||||
use alloc::{borrow::ToOwned, format, string::String, vec, vec::Vec};
|
|
||||||
use core::fmt;
|
|
||||||
use rustpython_ast::{self as ast, Location};
|
use rustpython_ast::{self as ast, Location};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
pub fn make_symbol_table(program: &ast::Program) -> Result<SymbolTable, SymbolTableError> {
|
pub fn make_symbol_table(program: &ast::Program) -> Result<SymbolTable, SymbolTableError> {
|
||||||
let mut builder = SymbolTableBuilder::default();
|
let mut builder = SymbolTableBuilder::default();
|
||||||
@@ -59,7 +58,7 @@ impl SymbolTable {
|
|||||||
typ,
|
typ,
|
||||||
line_number,
|
line_number,
|
||||||
is_nested,
|
is_nested,
|
||||||
symbols: IndexMap::default(),
|
symbols: IndexMap::new(),
|
||||||
sub_tables: vec![],
|
sub_tables: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,8 +187,8 @@ impl SymbolTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for SymbolTable {
|
impl std::fmt::Debug for SymbolTable {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"SymbolTable({:?} symbols, {:?} sub scopes)",
|
"SymbolTable({:?} symbols, {:?} sub scopes)",
|
||||||
@@ -210,9 +209,8 @@ fn analyze_symbol_table(symbol_table: &mut SymbolTable) -> SymbolTableResult {
|
|||||||
type SymbolMap = IndexMap<String, Symbol>;
|
type SymbolMap = IndexMap<String, Symbol>;
|
||||||
|
|
||||||
mod stack {
|
mod stack {
|
||||||
use alloc::vec::Vec;
|
use std::panic;
|
||||||
use core::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
pub struct StackStack<T> {
|
pub struct StackStack<T> {
|
||||||
v: Vec<NonNull<T>>,
|
v: Vec<NonNull<T>>,
|
||||||
}
|
}
|
||||||
@@ -229,10 +227,9 @@ mod stack {
|
|||||||
F: FnOnce(&mut Self) -> R,
|
F: FnOnce(&mut Self) -> R,
|
||||||
{
|
{
|
||||||
self.v.push(x.into());
|
self.v.push(x.into());
|
||||||
let mut this = scopeguard::guard(self, |this| {
|
let res = panic::catch_unwind(panic::AssertUnwindSafe(|| f(self)));
|
||||||
this.v.pop();
|
self.v.pop();
|
||||||
});
|
res.unwrap_or_else(|x| panic::resume_unwind(x))
|
||||||
f(&mut this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> impl Iterator<Item = &T> + DoubleEndedIterator + '_ {
|
pub fn iter(&self) -> impl Iterator<Item = &T> + DoubleEndedIterator + '_ {
|
||||||
@@ -276,7 +273,7 @@ struct SymbolTableAnalyzer {
|
|||||||
|
|
||||||
impl SymbolTableAnalyzer {
|
impl SymbolTableAnalyzer {
|
||||||
fn analyze_symbol_table(&mut self, symbol_table: &mut SymbolTable) -> SymbolTableResult {
|
fn analyze_symbol_table(&mut self, symbol_table: &mut SymbolTable) -> SymbolTableResult {
|
||||||
let symbols = core::mem::take(&mut symbol_table.symbols);
|
let symbols = std::mem::take(&mut symbol_table.symbols);
|
||||||
let sub_tables = &mut *symbol_table.sub_tables;
|
let sub_tables = &mut *symbol_table.sub_tables;
|
||||||
|
|
||||||
let mut info = (symbols, symbol_table.typ);
|
let mut info = (symbols, symbol_table.typ);
|
||||||
@@ -472,7 +469,7 @@ impl SymbolTableAnalyzer {
|
|||||||
SymbolTableType::Class => {
|
SymbolTableType::Class => {
|
||||||
// named expressions are forbidden in comprehensions on class scope
|
// named expressions are forbidden in comprehensions on class scope
|
||||||
return Err(SymbolTableError {
|
return Err(SymbolTableError {
|
||||||
error: "assignment expression within a comprehension cannot be used in a class body".to_owned(),
|
error: "assignment expression within a comprehension cannot be used in a class body".to_string(),
|
||||||
// TODO: accurate location info, somehow
|
// TODO: accurate location info, somehow
|
||||||
location: Location::default(),
|
location: Location::default(),
|
||||||
});
|
});
|
||||||
@@ -1002,7 +999,7 @@ impl SymbolTableBuilder {
|
|||||||
// comprehension iterator definitions
|
// comprehension iterator definitions
|
||||||
if let ExpressionContext::IterDefinitionExp = context {
|
if let ExpressionContext::IterDefinitionExp = context {
|
||||||
return Err(SymbolTableError {
|
return Err(SymbolTableError {
|
||||||
error: "assignment expression cannot be used in a comprehension iterable expression".to_owned(),
|
error: "assignment expression cannot be used in a comprehension iterable expression".to_string(),
|
||||||
// TODO: accurate location info, somehow
|
// TODO: accurate location info, somehow
|
||||||
location: Location::default(),
|
location: Location::default(),
|
||||||
});
|
});
|
||||||
@@ -1221,7 +1218,7 @@ impl SymbolTableBuilder {
|
|||||||
return Err(SymbolTableError {
|
return Err(SymbolTableError {
|
||||||
error:
|
error:
|
||||||
"assignment expression cannot be used in a comprehension iterable expression"
|
"assignment expression cannot be used in a comprehension iterable expression"
|
||||||
.to_owned(),
|
.to_string(),
|
||||||
location,
|
location,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use crate::{extract_spans, Diagnostic};
|
|||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use proc_macro2::{Span, TokenStream as TokenStream2};
|
use proc_macro2::{Span, TokenStream as TokenStream2};
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use rustpython_bytecode::{CodeObject, FrozenModule};
|
use rustpython_bytecode::bytecode::{CodeObject, FrozenModule};
|
||||||
use rustpython_compiler as compile;
|
use rustpython_compiler as compile;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
@@ -242,7 +242,7 @@ impl PyCompileInput {
|
|||||||
});
|
});
|
||||||
} else if ident == "crate_name" {
|
} else if ident == "crate_name" {
|
||||||
let name = match &name_value.lit {
|
let name = match &name_value.lit {
|
||||||
Lit::Str(s) => s.parse()?,
|
Lit::Str(s) => syn::Ident::new(&s.value(), s.span()),
|
||||||
_ => bail_span!(name_value.lit, "source must be a string"),
|
_ => bail_span!(name_value.lit, "source must be a string"),
|
||||||
};
|
};
|
||||||
crate_name = Some(name);
|
crate_name = Some(name);
|
||||||
@@ -261,7 +261,7 @@ impl PyCompileInput {
|
|||||||
source,
|
source,
|
||||||
mode: mode.unwrap_or(compile::Mode::Exec),
|
mode: mode.unwrap_or(compile::Mode::Exec),
|
||||||
module_name: module_name.unwrap_or_else(|| "frozen".to_owned()),
|
module_name: module_name.unwrap_or_else(|| "frozen".to_owned()),
|
||||||
crate_name: crate_name.unwrap_or_else(|| syn::parse_quote!(::rustpython_vm::bytecode)),
|
crate_name: crate_name.unwrap_or_else(|| syn::parse_quote!(rustpython_vm)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,7 +302,7 @@ struct PyCompileArgs {
|
|||||||
source: CompilationSource,
|
source: CompilationSource,
|
||||||
mode: compile::Mode,
|
mode: compile::Mode,
|
||||||
module_name: String,
|
module_name: String,
|
||||||
crate_name: syn::Path,
|
crate_name: syn::Ident,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn impl_py_compile(input: TokenStream2) -> Result<TokenStream2, Diagnostic> {
|
pub fn impl_py_compile(input: TokenStream2) -> Result<TokenStream2, Diagnostic> {
|
||||||
@@ -316,7 +316,7 @@ pub fn impl_py_compile(input: TokenStream2) -> Result<TokenStream2, Diagnostic>
|
|||||||
let bytes = LitByteStr::new(&bytes, Span::call_site());
|
let bytes = LitByteStr::new(&bytes, Span::call_site());
|
||||||
|
|
||||||
let output = quote! {
|
let output = quote! {
|
||||||
#crate_name::CodeObject::from_bytes(#bytes)
|
::#crate_name::bytecode::CodeObject::from_bytes(#bytes)
|
||||||
.expect("Deserializing CodeObject failed")
|
.expect("Deserializing CodeObject failed")
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -339,8 +339,8 @@ pub fn impl_py_freeze(input: TokenStream2) -> Result<TokenStream2, Diagnostic> {
|
|||||||
let bytes = code.to_bytes();
|
let bytes = code.to_bytes();
|
||||||
let bytes = LitByteStr::new(&bytes, Span::call_site());
|
let bytes = LitByteStr::new(&bytes, Span::call_site());
|
||||||
quote! {
|
quote! {
|
||||||
m.insert(#module_name.into(), #crate_name::FrozenModule {
|
m.insert(#module_name.into(), ::#crate_name::bytecode::FrozenModule {
|
||||||
code: #crate_name::CodeObject::from_bytes(
|
code: ::#crate_name::bytecode::CodeObject::from_bytes(
|
||||||
#bytes
|
#bytes
|
||||||
).expect("Deserializing CodeObject failed"),
|
).expect("Deserializing CodeObject failed"),
|
||||||
package: #package,
|
package: #package,
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ where
|
|||||||
quote! {
|
quote! {
|
||||||
class.set_str_attr(
|
class.set_str_attr(
|
||||||
#py_name,
|
#py_name,
|
||||||
ctx.make_funcdef(#py_name, Self::#ident)
|
ctx.new_function_named(Self::#ident, #py_name.to_owned())
|
||||||
#doc
|
#doc
|
||||||
.#build_func(ctx),
|
.#build_func(ctx),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ impl ModuleItem for FunctionItem {
|
|||||||
);
|
);
|
||||||
let module = args.module_name();
|
let module = args.module_name();
|
||||||
let new_func = quote_spanned!(ident.span()=>
|
let new_func = quote_spanned!(ident.span()=>
|
||||||
vm.ctx.make_funcdef(#py_name, #ident)
|
vm.ctx.new_function_named(#ident, #py_name.to_owned())
|
||||||
#doc
|
#doc
|
||||||
.into_function()
|
.into_function()
|
||||||
.with_module(vm.ctx.new_str(#module.to_owned()))
|
.with_module(vm.ctx.new_str(#module.to_owned()))
|
||||||
|
|||||||
@@ -41,9 +41,7 @@ fn run(vm: &vm::VirtualMachine) -> vm::pyobject::PyResult<()> {
|
|||||||
let scope: vm::scope::Scope = vm.new_scope_with_builtins();
|
let scope: vm::scope::Scope = vm.new_scope_with_builtins();
|
||||||
|
|
||||||
// typing `quit()` is too long, let's make `on(False)` work instead.
|
// typing `quit()` is too long, let's make `on(False)` work instead.
|
||||||
scope
|
scope.globals.set_item("on", vm.ctx.new_function(on), vm)?;
|
||||||
.globals
|
|
||||||
.set_item("on", vm.ctx.new_function("on", on), vm)?;
|
|
||||||
|
|
||||||
// let's include a fibonacci function, but let's be lazy and write it in Python
|
// let's include a fibonacci function, but let's be lazy and write it in Python
|
||||||
add_python_function!(
|
add_python_function!(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
from testutils import assert_raises
|
from testutils import assert_raises
|
||||||
import pickle
|
import pickle
|
||||||
import sys
|
|
||||||
|
|
||||||
# new
|
# new
|
||||||
assert bytearray([1, 2, 3])
|
assert bytearray([1, 2, 3])
|
||||||
@@ -754,8 +753,4 @@ b = pickle.loads(pickle.dumps(a, 4))
|
|||||||
assert type(a) == type(b)
|
assert type(a) == type(b)
|
||||||
assert a.x == b.x
|
assert a.x == b.x
|
||||||
assert a.y == b.y
|
assert a.y == b.y
|
||||||
assert a == b
|
assert a == b
|
||||||
|
|
||||||
a = bytearray()
|
|
||||||
for i in range(-1, 2, 1):
|
|
||||||
assert_raises(IndexError, lambda: a[-sys.maxsize - i], _msg='bytearray index out of range')
|
|
||||||
@@ -10,9 +10,9 @@ edition = "2018"
|
|||||||
autotests = false
|
autotests = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cranelift = "0.69.0"
|
cranelift = "0.68.0"
|
||||||
cranelift-module = "0.69.0"
|
cranelift-module = "0.68.0"
|
||||||
cranelift-jit = "0.69.0"
|
cranelift-simplejit = "0.68.0"
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
libffi = "1.0"
|
libffi = "1.0"
|
||||||
rustpython-bytecode = { path = "../bytecode", version = "0.1.2" }
|
rustpython-bytecode = { path = "../bytecode", version = "0.1.2" }
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use cranelift::prelude::*;
|
use cranelift::prelude::*;
|
||||||
use num_traits::cast::ToPrimitive;
|
use num_traits::cast::ToPrimitive;
|
||||||
use rustpython_bytecode::{
|
use rustpython_bytecode::bytecode::{
|
||||||
self as bytecode, BinaryOperator, BorrowedConstant, CodeObject, ComparisonOperator,
|
self, BinaryOperator, BorrowedConstant, CodeObject, ComparisonOperator, Instruction, Label,
|
||||||
Instruction, Label, UnaryOperator,
|
UnaryOperator,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
|
|||||||
let params = compiler.builder.func.dfg.block_params(entry_block).to_vec();
|
let params = compiler.builder.func.dfg.block_params(entry_block).to_vec();
|
||||||
for (i, (ty, val)) in arg_types.iter().zip(params).enumerate() {
|
for (i, (ty, val)) in arg_types.iter().zip(params).enumerate() {
|
||||||
compiler
|
compiler
|
||||||
.store_variable(i as u32, JitValue::new(val, ty.clone()))
|
.store_variable(i, JitValue::new(val, ty.clone()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
compiler
|
compiler
|
||||||
@@ -66,8 +66,8 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
|
|||||||
val: JitValue,
|
val: JitValue,
|
||||||
) -> Result<(), JitCompileError> {
|
) -> Result<(), JitCompileError> {
|
||||||
let builder = &mut self.builder;
|
let builder = &mut self.builder;
|
||||||
let local = self.variables[idx as usize].get_or_insert_with(|| {
|
let local = self.variables[idx].get_or_insert_with(|| {
|
||||||
let var = Variable::new(idx as usize);
|
let var = Variable::new(idx);
|
||||||
let local = Local {
|
let local = Local {
|
||||||
var,
|
var,
|
||||||
ty: val.ty.clone(),
|
ty: val.ty.clone(),
|
||||||
@@ -119,7 +119,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
|
|||||||
let label_targets = bytecode.label_targets();
|
let label_targets = bytecode.label_targets();
|
||||||
|
|
||||||
for (offset, instruction) in bytecode.instructions.iter().enumerate() {
|
for (offset, instruction) in bytecode.instructions.iter().enumerate() {
|
||||||
let label = Label(offset as u32);
|
let label = Label(offset);
|
||||||
if label_targets.contains(&label) {
|
if label_targets.contains(&label) {
|
||||||
let block = self.get_or_create_block(label);
|
let block = self.get_or_create_block(label);
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Instruction::LoadFast(idx) => {
|
Instruction::LoadFast(idx) => {
|
||||||
let local = self.variables[*idx as usize]
|
let local = self.variables[*idx]
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(JitCompileError::BadBytecode)?;
|
.ok_or(JitCompileError::BadBytecode)?;
|
||||||
self.stack.push(JitValue {
|
self.stack.push(JitValue {
|
||||||
@@ -232,9 +232,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
|
|||||||
let val = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
|
let val = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
|
||||||
self.store_variable(*idx, val)
|
self.store_variable(*idx, val)
|
||||||
}
|
}
|
||||||
Instruction::LoadConst { idx } => {
|
Instruction::LoadConst { idx } => self.load_const(constants[*idx].borrow_constant()),
|
||||||
self.load_const(constants[*idx as usize].borrow_constant())
|
|
||||||
}
|
|
||||||
Instruction::ReturnValue => {
|
Instruction::ReturnValue => {
|
||||||
let val = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
|
let val = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
|
||||||
if let Some(ref ty) = self.sig.ret {
|
if let Some(ref ty) = self.sig.ret {
|
||||||
@@ -322,7 +320,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
|
|||||||
_ => Err(JitCompileError::NotSupported),
|
_ => Err(JitCompileError::NotSupported),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instruction::BinaryOperation { op } | Instruction::BinaryOperationInplace { op } => {
|
Instruction::BinaryOperation { op, .. } => {
|
||||||
// the rhs is popped off first
|
// the rhs is popped off first
|
||||||
let b = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
|
let b = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
|
||||||
let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
|
let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use cranelift::prelude::*;
|
use cranelift::prelude::*;
|
||||||
use cranelift_jit::{JITBuilder, JITModule};
|
|
||||||
use cranelift_module::{FuncId, Linkage, Module, ModuleError};
|
use cranelift_module::{FuncId, Linkage, Module, ModuleError};
|
||||||
|
use cranelift_simplejit::{SimpleJITBuilder, SimpleJITModule, SimpleJITProduct};
|
||||||
|
|
||||||
use rustpython_bytecode as bytecode;
|
use rustpython_bytecode::bytecode;
|
||||||
|
|
||||||
mod instructions;
|
mod instructions;
|
||||||
|
|
||||||
@@ -32,13 +32,13 @@ pub enum JitArgumentError {
|
|||||||
struct Jit {
|
struct Jit {
|
||||||
builder_context: FunctionBuilderContext,
|
builder_context: FunctionBuilderContext,
|
||||||
ctx: codegen::Context,
|
ctx: codegen::Context,
|
||||||
module: JITModule,
|
module: SimpleJITModule,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Jit {
|
impl Jit {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let builder = JITBuilder::new(cranelift_module::default_libcall_names());
|
let builder = SimpleJITBuilder::new(cranelift_module::default_libcall_names());
|
||||||
let module = JITModule::new(builder);
|
let module = SimpleJITModule::new(builder);
|
||||||
Self {
|
Self {
|
||||||
builder_context: FunctionBuilderContext::new(),
|
builder_context: FunctionBuilderContext::new(),
|
||||||
ctx: module.make_context(),
|
ctx: module.make_context(),
|
||||||
@@ -77,7 +77,7 @@ impl Jit {
|
|||||||
builder.finalize();
|
builder.finalize();
|
||||||
|
|
||||||
let id = self.module.declare_function(
|
let id = self.module.declare_function(
|
||||||
&format!("jit_{}", bytecode.obj_name.as_ref()),
|
&format!("jit_{}", bytecode.obj_name),
|
||||||
Linkage::Export,
|
Linkage::Export,
|
||||||
&self.ctx.func.signature,
|
&self.ctx.func.signature,
|
||||||
)?;
|
)?;
|
||||||
@@ -105,14 +105,14 @@ pub fn compile<C: bytecode::Constant>(
|
|||||||
Ok(CompiledCode {
|
Ok(CompiledCode {
|
||||||
sig,
|
sig,
|
||||||
code,
|
code,
|
||||||
module: jit.module,
|
memory: jit.module.finish(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CompiledCode {
|
pub struct CompiledCode {
|
||||||
sig: JitSig,
|
sig: JitSig,
|
||||||
code: *const u8,
|
code: *const u8,
|
||||||
module: JITModule,
|
memory: SimpleJITProduct,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompiledCode {
|
impl CompiledCode {
|
||||||
@@ -287,7 +287,7 @@ unsafe impl Sync for CompiledCode {}
|
|||||||
impl Drop for CompiledCode {
|
impl Drop for CompiledCode {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// SAFETY: The only pointer that this memory will also be dropped now
|
// SAFETY: The only pointer that this memory will also be dropped now
|
||||||
unsafe { self.module.free_memory() }
|
unsafe { self.memory.free_memory() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use rustpython_bytecode::{CodeObject, ConstantData, Instruction};
|
use rustpython_bytecode::bytecode::{CodeObject, ConstantData, Instruction};
|
||||||
use rustpython_jit::{CompiledCode, JitType};
|
use rustpython_jit::{CompiledCode, JitType};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -78,15 +78,13 @@ impl StackMachine {
|
|||||||
names: &[String],
|
names: &[String],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match instruction {
|
match instruction {
|
||||||
Instruction::LoadConst { idx } => {
|
Instruction::LoadConst { idx } => self.stack.push(constants[idx].clone().into()),
|
||||||
self.stack.push(constants[idx as usize].clone().into())
|
Instruction::LoadNameAny(idx) => {
|
||||||
|
self.stack.push(StackValue::String(names[idx].clone()))
|
||||||
}
|
}
|
||||||
Instruction::LoadNameAny(idx) => self
|
|
||||||
.stack
|
|
||||||
.push(StackValue::String(names[idx as usize].clone())),
|
|
||||||
Instruction::StoreLocal(idx) => {
|
Instruction::StoreLocal(idx) => {
|
||||||
self.locals
|
self.locals
|
||||||
.insert(names[idx as usize].clone(), self.stack.pop().unwrap());
|
.insert(names[idx].clone(), self.stack.pop().unwrap());
|
||||||
}
|
}
|
||||||
Instruction::StoreAttr { .. } => {
|
Instruction::StoreAttr { .. } => {
|
||||||
// Do nothing except throw away the stack values
|
// Do nothing except throw away the stack values
|
||||||
@@ -106,7 +104,7 @@ impl StackMachine {
|
|||||||
}
|
}
|
||||||
self.stack.push(StackValue::Map(map));
|
self.stack.push(StackValue::Map(map));
|
||||||
}
|
}
|
||||||
Instruction::MakeFunction(_flags) => {
|
Instruction::MakeFunction => {
|
||||||
let name = if let Some(StackValue::String(name)) = self.stack.pop() {
|
let name = if let Some(StackValue::String(name)) = self.stack.pop() {
|
||||||
name
|
name
|
||||||
} else {
|
} else {
|
||||||
@@ -136,7 +134,7 @@ impl StackMachine {
|
|||||||
let mut values = Vec::new();
|
let mut values = Vec::new();
|
||||||
|
|
||||||
// Pop all values from stack:
|
// Pop all values from stack:
|
||||||
values.extend(self.stack.drain(self.stack.len() - amount as usize..));
|
values.extend(self.stack.drain(self.stack.len() - amount..));
|
||||||
|
|
||||||
// Push top of stack back first:
|
// Push top of stack back first:
|
||||||
self.stack.push(values.pop().unwrap());
|
self.stack.push(values.pop().unwrap());
|
||||||
|
|||||||
@@ -8,22 +8,15 @@ repository = "https://github.com/RustPython/RustPython"
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[features]
|
|
||||||
std = []
|
|
||||||
default = ["std", "lalrpop-util/std", "num-bigint/std"]
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
lalrpop = "0.19.4"
|
lalrpop = "0.19"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustpython-ast = { path = "../ast" }
|
rustpython-ast = { path = "../ast" }
|
||||||
lalrpop-util = { version = "0.19.4", default-features = false }
|
lalrpop-util = "0.19.1"
|
||||||
log = "0.4.1"
|
log = "0.4.1"
|
||||||
num-bigint = { version = "0.3", default-features = false }
|
num-bigint = "0.3"
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = "0.2"
|
||||||
unic-emoji-char = "0.9"
|
unic-emoji-char = "0.9"
|
||||||
unic-ucd-ident = "0.9"
|
unic-ucd-ident = "0.9"
|
||||||
unicode_names2 = "0.4"
|
unicode_names2 = "0.4"
|
||||||
phf = { version = "0.8", features = ["macros"] }
|
|
||||||
ahash = "0.6"
|
|
||||||
hashbrown = "0.9"
|
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ use lalrpop_util::ParseError as LalrpopError;
|
|||||||
use crate::ast::Location;
|
use crate::ast::Location;
|
||||||
use crate::token::Tok;
|
use crate::token::Tok;
|
||||||
|
|
||||||
use alloc::{boxed::Box, string::String};
|
|
||||||
use core::fmt;
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
/// Represents an error during lexical scanning.
|
/// Represents an error during lexical scanning.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@@ -24,7 +22,6 @@ pub enum LexicalErrorType {
|
|||||||
NestingError,
|
NestingError,
|
||||||
IndentationError,
|
IndentationError,
|
||||||
TabError,
|
TabError,
|
||||||
TabsAfterSpaces,
|
|
||||||
DefaultArgumentError,
|
DefaultArgumentError,
|
||||||
PositionalArgumentError,
|
PositionalArgumentError,
|
||||||
DuplicateKeywordArgumentError,
|
DuplicateKeywordArgumentError,
|
||||||
@@ -48,9 +45,6 @@ impl fmt::Display for LexicalErrorType {
|
|||||||
LexicalErrorType::TabError => {
|
LexicalErrorType::TabError => {
|
||||||
write!(f, "inconsistent use of tabs and spaces in indentation")
|
write!(f, "inconsistent use of tabs and spaces in indentation")
|
||||||
}
|
}
|
||||||
LexicalErrorType::TabsAfterSpaces => {
|
|
||||||
write!(f, "Tabs not allowed as part of indentation after spaces")
|
|
||||||
}
|
|
||||||
LexicalErrorType::DefaultArgumentError => {
|
LexicalErrorType::DefaultArgumentError => {
|
||||||
write!(f, "non-default argument follows default argument")
|
write!(f, "non-default argument follows default argument")
|
||||||
}
|
}
|
||||||
@@ -72,16 +66,6 @@ impl fmt::Display for LexicalErrorType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl Error for LexicalErrorType {
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
||||||
match self {
|
|
||||||
LexicalErrorType::FStringError(e) => Some(e),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: consolidate these with ParseError
|
// TODO: consolidate these with ParseError
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct FStringError {
|
pub struct FStringError {
|
||||||
@@ -131,16 +115,6 @@ impl From<FStringError> for LalrpopError<Location, Tok, LexicalError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl Error for FStringErrorType {
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
||||||
match self {
|
|
||||||
FStringErrorType::InvalidExpression(e) => Some(e.as_ref()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents an error during parsing
|
/// Represents an error during parsing
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct ParseError {
|
pub struct ParseError {
|
||||||
@@ -226,45 +200,32 @@ impl fmt::Display for ParseErrorType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
impl Error for ParseErrorType {}
|
||||||
impl Error for ParseErrorType {
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
||||||
match self {
|
|
||||||
ParseErrorType::Lexical(e) => Some(e),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ParseErrorType {
|
impl ParseErrorType {
|
||||||
pub fn is_indentation_error(&self) -> bool {
|
pub fn is_indentation_error(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
ParseErrorType::Lexical(LexicalErrorType::IndentationError) => true,
|
ParseErrorType::Lexical(LexicalErrorType::IndentationError) => true,
|
||||||
ParseErrorType::UnrecognizedToken(token, expected) => {
|
ParseErrorType::UnrecognizedToken(token, expected) => {
|
||||||
*token == Tok::Indent || expected.as_ref().map_or(false, |s| s == "Indent")
|
*token == Tok::Indent || expected.clone() == Some("Indent".to_owned())
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn is_tab_error(&self) -> bool {
|
pub fn is_tab_error(&self) -> bool {
|
||||||
matches!(
|
matches!(self, ParseErrorType::Lexical(LexicalErrorType::TabError))
|
||||||
self,
|
|
||||||
ParseErrorType::Lexical(LexicalErrorType::TabError)
|
|
||||||
| ParseErrorType::Lexical(LexicalErrorType::TabsAfterSpaces)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::ops::Deref for ParseError {
|
impl std::ops::Deref for ParseError {
|
||||||
type Target = ParseErrorType;
|
type Target = ParseErrorType;
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.error
|
&self.error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl Error for ParseError {
|
impl Error for ParseError {
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
self.error.source()
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use alloc::{borrow::ToOwned, boxed::Box, format, string::String, vec, vec::Vec};
|
use std::iter;
|
||||||
use core::{iter, mem, str};
|
use std::mem;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
use crate::ast::{ConversionFlag, Expression, Location, StringGroup};
|
use crate::ast::{ConversionFlag, Expression, Location, StringGroup};
|
||||||
use crate::error::{FStringError, FStringErrorType, ParseError};
|
use crate::error::{FStringError, FStringErrorType, ParseError};
|
||||||
@@ -80,7 +81,7 @@ impl<'a> FStringParser<'a> {
|
|||||||
// match a python 3.8 self documenting expression
|
// match a python 3.8 self documenting expression
|
||||||
// format '{' PYTHON_EXPRESSION '=' FORMAT_SPECIFIER? '}'
|
// format '{' PYTHON_EXPRESSION '=' FORMAT_SPECIFIER? '}'
|
||||||
'=' if self.chars.peek() != Some(&'=') && delims.is_empty() => {
|
'=' if self.chars.peek() != Some(&'=') && delims.is_empty() => {
|
||||||
pred_expression_text = expression.to_owned(); // safe expression before = to print it
|
pred_expression_text = expression.to_string(); // safe expression before = to print it
|
||||||
}
|
}
|
||||||
|
|
||||||
':' if delims.is_empty() => {
|
':' if delims.is_empty() => {
|
||||||
@@ -282,7 +283,6 @@ mod tests {
|
|||||||
fn mk_ident(name: &str, row: usize, col: usize) -> ast::Expression {
|
fn mk_ident(name: &str, row: usize, col: usize) -> ast::Expression {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location: ast::Location::new(row, col),
|
location: ast::Location::new(row, col),
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Identifier {
|
node: ast::ExpressionType::Identifier {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use alloc::{string::String, vec, vec::Vec};
|
use std::collections::HashSet;
|
||||||
use hashbrown::HashSet;
|
|
||||||
|
|
||||||
use crate::ast;
|
use crate::ast;
|
||||||
use crate::error::{LexicalError, LexicalErrorType};
|
use crate::error::{LexicalError, LexicalErrorType};
|
||||||
@@ -46,8 +45,7 @@ pub fn parse_args(func_args: Vec<FunctionArgument>) -> Result<ast::ArgumentList,
|
|||||||
let mut args = vec![];
|
let mut args = vec![];
|
||||||
let mut keywords = vec![];
|
let mut keywords = vec![];
|
||||||
|
|
||||||
let mut keyword_names =
|
let mut keyword_names = HashSet::with_capacity(func_args.len());
|
||||||
HashSet::with_capacity_and_hasher(func_args.len(), ahash::RandomState::default());
|
|
||||||
for (name, value) in func_args {
|
for (name, value) in func_args {
|
||||||
match name {
|
match name {
|
||||||
Some(n) => {
|
Some(n) => {
|
||||||
|
|||||||
@@ -5,19 +5,13 @@
|
|||||||
pub use super::token::Tok;
|
pub use super::token::Tok;
|
||||||
use crate::ast::Location;
|
use crate::ast::Location;
|
||||||
use crate::error::{LexicalError, LexicalErrorType};
|
use crate::error::{LexicalError, LexicalErrorType};
|
||||||
use alloc::{
|
|
||||||
borrow::ToOwned,
|
|
||||||
format,
|
|
||||||
string::{String, ToString},
|
|
||||||
vec,
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use core::char;
|
|
||||||
use core::cmp::Ordering;
|
|
||||||
use core::str::FromStr;
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use num_traits::identities::Zero;
|
use num_traits::identities::Zero;
|
||||||
use num_traits::Num;
|
use num_traits::Num;
|
||||||
|
use std::char;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::str::FromStr;
|
||||||
use unic_emoji_char::is_emoji_presentation;
|
use unic_emoji_char::is_emoji_presentation;
|
||||||
use unic_ucd_ident::{is_xid_continue, is_xid_start};
|
use unic_ucd_ident::{is_xid_continue, is_xid_start};
|
||||||
|
|
||||||
@@ -72,53 +66,57 @@ pub struct Lexer<T: Iterator<Item = char>> {
|
|||||||
chr1: Option<char>,
|
chr1: Option<char>,
|
||||||
chr2: Option<char>,
|
chr2: Option<char>,
|
||||||
location: Location,
|
location: Location,
|
||||||
|
keywords: HashMap<String, Tok>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static KEYWORDS: phf::Map<&'static str, Tok> = phf::phf_map! {
|
pub fn get_keywords() -> HashMap<String, Tok> {
|
||||||
// Alphabetical keywords:
|
let mut keywords: HashMap<String, Tok> = HashMap::new();
|
||||||
"..." => Tok::Ellipsis,
|
|
||||||
"False" => Tok::False,
|
|
||||||
"None" => Tok::None,
|
|
||||||
"True" => Tok::True,
|
|
||||||
|
|
||||||
"and" => Tok::And,
|
// Alphabetical keywords:
|
||||||
"as" => Tok::As,
|
keywords.insert(String::from("..."), Tok::Ellipsis);
|
||||||
"assert" => Tok::Assert,
|
keywords.insert(String::from("False"), Tok::False);
|
||||||
"async" => Tok::Async,
|
keywords.insert(String::from("None"), Tok::None);
|
||||||
"await" => Tok::Await,
|
keywords.insert(String::from("True"), Tok::True);
|
||||||
"break" => Tok::Break,
|
|
||||||
"class" => Tok::Class,
|
keywords.insert(String::from("and"), Tok::And);
|
||||||
"continue" => Tok::Continue,
|
keywords.insert(String::from("as"), Tok::As);
|
||||||
"def" => Tok::Def,
|
keywords.insert(String::from("assert"), Tok::Assert);
|
||||||
"del" => Tok::Del,
|
keywords.insert(String::from("async"), Tok::Async);
|
||||||
"elif" => Tok::Elif,
|
keywords.insert(String::from("await"), Tok::Await);
|
||||||
"else" => Tok::Else,
|
keywords.insert(String::from("break"), Tok::Break);
|
||||||
"except" => Tok::Except,
|
keywords.insert(String::from("class"), Tok::Class);
|
||||||
"finally" => Tok::Finally,
|
keywords.insert(String::from("continue"), Tok::Continue);
|
||||||
"for" => Tok::For,
|
keywords.insert(String::from("def"), Tok::Def);
|
||||||
"from" => Tok::From,
|
keywords.insert(String::from("del"), Tok::Del);
|
||||||
"global" => Tok::Global,
|
keywords.insert(String::from("elif"), Tok::Elif);
|
||||||
"if" => Tok::If,
|
keywords.insert(String::from("else"), Tok::Else);
|
||||||
"import" => Tok::Import,
|
keywords.insert(String::from("except"), Tok::Except);
|
||||||
"in" => Tok::In,
|
keywords.insert(String::from("finally"), Tok::Finally);
|
||||||
"is" => Tok::Is,
|
keywords.insert(String::from("for"), Tok::For);
|
||||||
"lambda" => Tok::Lambda,
|
keywords.insert(String::from("from"), Tok::From);
|
||||||
"nonlocal" => Tok::Nonlocal,
|
keywords.insert(String::from("global"), Tok::Global);
|
||||||
"not" => Tok::Not,
|
keywords.insert(String::from("if"), Tok::If);
|
||||||
"or" => Tok::Or,
|
keywords.insert(String::from("import"), Tok::Import);
|
||||||
"pass" => Tok::Pass,
|
keywords.insert(String::from("in"), Tok::In);
|
||||||
"raise" => Tok::Raise,
|
keywords.insert(String::from("is"), Tok::Is);
|
||||||
"return" => Tok::Return,
|
keywords.insert(String::from("lambda"), Tok::Lambda);
|
||||||
"try" => Tok::Try,
|
keywords.insert(String::from("nonlocal"), Tok::Nonlocal);
|
||||||
"while" => Tok::While,
|
keywords.insert(String::from("not"), Tok::Not);
|
||||||
"with" => Tok::With,
|
keywords.insert(String::from("or"), Tok::Or);
|
||||||
"yield" => Tok::Yield,
|
keywords.insert(String::from("pass"), Tok::Pass);
|
||||||
};
|
keywords.insert(String::from("raise"), Tok::Raise);
|
||||||
|
keywords.insert(String::from("return"), Tok::Return);
|
||||||
|
keywords.insert(String::from("try"), Tok::Try);
|
||||||
|
keywords.insert(String::from("while"), Tok::While);
|
||||||
|
keywords.insert(String::from("with"), Tok::With);
|
||||||
|
keywords.insert(String::from("yield"), Tok::Yield);
|
||||||
|
keywords
|
||||||
|
}
|
||||||
|
|
||||||
pub type Spanned = (Location, Tok, Location);
|
pub type Spanned = (Location, Tok, Location);
|
||||||
pub type LexResult = Result<Spanned, LexicalError>;
|
pub type LexResult = Result<Spanned, LexicalError>;
|
||||||
|
|
||||||
pub fn make_tokenizer(source: &str) -> impl Iterator<Item = LexResult> + '_ {
|
pub fn make_tokenizer<'a>(source: &'a str) -> impl Iterator<Item = LexResult> + 'a {
|
||||||
let nlh = NewlineHandler::new(source.chars());
|
let nlh = NewlineHandler::new(source.chars());
|
||||||
Lexer::new(nlh)
|
Lexer::new(nlh)
|
||||||
}
|
}
|
||||||
@@ -195,6 +193,7 @@ where
|
|||||||
location: Location::new(0, 0),
|
location: Location::new(0, 0),
|
||||||
chr1: None,
|
chr1: None,
|
||||||
chr2: None,
|
chr2: None,
|
||||||
|
keywords: get_keywords(),
|
||||||
};
|
};
|
||||||
lxr.next_char();
|
lxr.next_char();
|
||||||
lxr.next_char();
|
lxr.next_char();
|
||||||
@@ -246,8 +245,8 @@ where
|
|||||||
}
|
}
|
||||||
let end_pos = self.get_pos();
|
let end_pos = self.get_pos();
|
||||||
|
|
||||||
if let Some(tok) = KEYWORDS.get(name.as_str()) {
|
if self.keywords.contains_key(&name) {
|
||||||
Ok((start_pos, tok.clone(), end_pos))
|
Ok((start_pos, self.keywords[&name].clone(), end_pos))
|
||||||
} else {
|
} else {
|
||||||
Ok((start_pos, Tok::Name { name }, end_pos))
|
Ok((start_pos, Tok::Name { name }, end_pos))
|
||||||
}
|
}
|
||||||
@@ -443,8 +442,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
match p {
|
match p {
|
||||||
0xD800..=0xDFFF => Ok(char::REPLACEMENT_CHARACTER),
|
0xD800..=0xDFFF => Ok(std::char::REPLACEMENT_CHARACTER),
|
||||||
_ => char::from_u32(p).ok_or(unicode_error),
|
_ => std::char::from_u32(p).ok_or(unicode_error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,7 +678,9 @@ where
|
|||||||
// This is technically stricter than python3 but spaces before
|
// This is technically stricter than python3 but spaces before
|
||||||
// tabs is even more insane than mixing spaces and tabs.
|
// tabs is even more insane than mixing spaces and tabs.
|
||||||
return Err(LexicalError {
|
return Err(LexicalError {
|
||||||
error: LexicalErrorType::TabsAfterSpaces,
|
error: LexicalErrorType::OtherError(
|
||||||
|
"Tabs not allowed as part of indentation after spaces".to_owned(),
|
||||||
|
),
|
||||||
location: self.get_pos(),
|
location: self.get_pos(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,6 @@
|
|||||||
|
|
||||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustPython/RustPython/master/logo.png")]
|
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustPython/RustPython/master/logo.png")]
|
||||||
#![doc(html_root_url = "https://docs.rs/rustpython-parser/")]
|
#![doc(html_root_url = "https://docs.rs/rustpython-parser/")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
|
||||||
|
|
||||||
extern crate alloc;
|
|
||||||
|
|
||||||
// hack to get around lalrpop hardcoding ::std::* paths
|
|
||||||
#[cfg(not(feature = "std"))]
|
|
||||||
extern crate self as std;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
use core::fmt;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
Program,
|
Program,
|
||||||
Statement,
|
Statement,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::str::FromStr for Mode {
|
impl std::str::FromStr for Mode {
|
||||||
type Err = ModeParseError;
|
type Err = ModeParseError;
|
||||||
fn from_str(s: &str) -> Result<Self, ModeParseError> {
|
fn from_str(s: &str) -> Result<Self, ModeParseError> {
|
||||||
match s {
|
match s {
|
||||||
@@ -22,8 +20,8 @@ pub struct ModeParseError {
|
|||||||
_priv: (),
|
_priv: (),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ModeParseError {
|
impl std::fmt::Display for ModeParseError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
write!(f, r#"mode should be "exec", "eval", or "single""#)
|
write!(f, r#"mode should be "exec", "eval", or "single""#)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,7 @@
|
|||||||
//! parse a whole program, a single statement, or a single
|
//! parse a whole program, a single statement, or a single
|
||||||
//! expression.
|
//! expression.
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use std::iter;
|
||||||
use core::iter;
|
|
||||||
|
|
||||||
use crate::ast;
|
use crate::ast;
|
||||||
use crate::error::ParseError;
|
use crate::error::ParseError;
|
||||||
@@ -61,11 +60,9 @@ pub fn parse_statement(source: &str) -> Result<Vec<ast::Statement>, ParseError>
|
|||||||
///
|
///
|
||||||
/// assert_eq!(ast::Expression {
|
/// assert_eq!(ast::Expression {
|
||||||
/// location: ast::Location::new(1, 3),
|
/// location: ast::Location::new(1, 3),
|
||||||
/// custom: (),
|
|
||||||
/// node: ast::ExpressionType::Binop {
|
/// node: ast::ExpressionType::Binop {
|
||||||
/// a: Box::new(ast::Expression {
|
/// a: Box::new(ast::Expression {
|
||||||
/// location: ast::Location::new(1, 1),
|
/// location: ast::Location::new(1, 1),
|
||||||
/// custom: (),
|
|
||||||
/// node: ast::ExpressionType::Number {
|
/// node: ast::ExpressionType::Number {
|
||||||
/// value: ast::Number::Integer { value: BigInt::from(1) }
|
/// value: ast::Number::Integer { value: BigInt::from(1) }
|
||||||
/// }
|
/// }
|
||||||
@@ -73,7 +70,6 @@ pub fn parse_statement(source: &str) -> Result<Vec<ast::Statement>, ParseError>
|
|||||||
/// op: ast::Operator::Add,
|
/// op: ast::Operator::Add,
|
||||||
/// b: Box::new(ast::Expression {
|
/// b: Box::new(ast::Expression {
|
||||||
/// location: ast::Location::new(1, 5),
|
/// location: ast::Location::new(1, 5),
|
||||||
/// custom: (),
|
|
||||||
/// node: ast::ExpressionType::Number {
|
/// node: ast::ExpressionType::Number {
|
||||||
/// value: ast::Number::Integer { value: BigInt::from(2) }
|
/// value: ast::Number::Integer { value: BigInt::from(2) }
|
||||||
/// }
|
/// }
|
||||||
@@ -107,13 +103,11 @@ mod tests {
|
|||||||
use super::parse_expression;
|
use super::parse_expression;
|
||||||
use super::parse_program;
|
use super::parse_program;
|
||||||
use super::parse_statement;
|
use super::parse_statement;
|
||||||
use alloc::borrow::ToOwned;
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
fn mk_ident(name: &str, row: usize, col: usize) -> ast::Expression {
|
fn mk_ident(name: &str, row: usize, col: usize) -> ast::Expression {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location: ast::Location::new(row, col),
|
location: ast::Location::new(row, col),
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Identifier {
|
node: ast::ExpressionType::Identifier {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
},
|
},
|
||||||
@@ -123,7 +117,6 @@ mod tests {
|
|||||||
fn make_int(value: i32, row: usize, col: usize) -> ast::Expression {
|
fn make_int(value: i32, row: usize, col: usize) -> ast::Expression {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location: ast::Location::new(row, col),
|
location: ast::Location::new(row, col),
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Number {
|
node: ast::ExpressionType::Number {
|
||||||
value: ast::Number::Integer {
|
value: ast::Number::Integer {
|
||||||
value: BigInt::from(value),
|
value: BigInt::from(value),
|
||||||
@@ -135,10 +128,9 @@ mod tests {
|
|||||||
fn make_string(value: &str, row: usize, col: usize) -> ast::Expression {
|
fn make_string(value: &str, row: usize, col: usize) -> ast::Expression {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location: ast::Location::new(row, col),
|
location: ast::Location::new(row, col),
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::String {
|
node: ast::ExpressionType::String {
|
||||||
value: ast::StringGroup::Constant {
|
value: ast::StringGroup::Constant {
|
||||||
value: value.to_owned(),
|
value: String::from(value),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -147,7 +139,6 @@ mod tests {
|
|||||||
fn as_statement(expr: ast::Expression) -> ast::Statement {
|
fn as_statement(expr: ast::Expression) -> ast::Statement {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
location: expr.location,
|
location: expr.location,
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::Expression { expression: expr },
|
node: ast::StatementType::Expression { expression: expr },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,17 +151,15 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_print_hello() {
|
fn test_parse_print_hello() {
|
||||||
let source = "print('Hello world')";
|
let source = String::from("print('Hello world')");
|
||||||
let parse_ast = parse_program(source).unwrap();
|
let parse_ast = parse_program(&source).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ast,
|
parse_ast,
|
||||||
ast::Program {
|
ast::Program {
|
||||||
statements: vec![ast::Statement {
|
statements: vec![ast::Statement {
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::Expression {
|
node: ast::StatementType::Expression {
|
||||||
expression: ast::Expression {
|
expression: ast::Expression {
|
||||||
custom: (),
|
|
||||||
location: ast::Location::new(1, 6),
|
location: ast::Location::new(1, 6),
|
||||||
node: ast::ExpressionType::Call {
|
node: ast::ExpressionType::Call {
|
||||||
function: Box::new(mk_ident("print", 1, 1)),
|
function: Box::new(mk_ident("print", 1, 1)),
|
||||||
@@ -186,18 +175,16 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_print_2() {
|
fn test_parse_print_2() {
|
||||||
let source = "print('Hello world', 2)";
|
let source = String::from("print('Hello world', 2)");
|
||||||
let parse_ast = parse_program(source).unwrap();
|
let parse_ast = parse_program(&source).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ast,
|
parse_ast,
|
||||||
ast::Program {
|
ast::Program {
|
||||||
statements: vec![ast::Statement {
|
statements: vec![ast::Statement {
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::Expression {
|
node: ast::StatementType::Expression {
|
||||||
expression: ast::Expression {
|
expression: ast::Expression {
|
||||||
location: ast::Location::new(1, 6),
|
location: ast::Location::new(1, 6),
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Call {
|
node: ast::ExpressionType::Call {
|
||||||
function: Box::new(mk_ident("print", 1, 1)),
|
function: Box::new(mk_ident("print", 1, 1)),
|
||||||
args: vec![make_string("Hello world", 1, 8), make_int(2, 1, 22),],
|
args: vec![make_string("Hello world", 1, 8), make_int(2, 1, 22),],
|
||||||
@@ -212,18 +199,16 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_kwargs() {
|
fn test_parse_kwargs() {
|
||||||
let source = "my_func('positional', keyword=2)";
|
let source = String::from("my_func('positional', keyword=2)");
|
||||||
let parse_ast = parse_program(source).unwrap();
|
let parse_ast = parse_program(&source).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ast,
|
parse_ast,
|
||||||
ast::Program {
|
ast::Program {
|
||||||
statements: vec![ast::Statement {
|
statements: vec![ast::Statement {
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::Expression {
|
node: ast::StatementType::Expression {
|
||||||
expression: ast::Expression {
|
expression: ast::Expression {
|
||||||
location: ast::Location::new(1, 8),
|
location: ast::Location::new(1, 8),
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Call {
|
node: ast::ExpressionType::Call {
|
||||||
function: Box::new(mk_ident("my_func", 1, 1)),
|
function: Box::new(mk_ident("my_func", 1, 1)),
|
||||||
args: vec![make_string("positional", 1, 10)],
|
args: vec![make_string("positional", 1, 10)],
|
||||||
@@ -241,19 +226,17 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_if_elif_else() {
|
fn test_parse_if_elif_else() {
|
||||||
let source = "if 1: 10\nelif 2: 20\nelse: 30";
|
let source = String::from("if 1: 10\nelif 2: 20\nelse: 30");
|
||||||
let parse_ast = parse_statement(source).unwrap();
|
let parse_ast = parse_statement(&source).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ast,
|
parse_ast,
|
||||||
vec![ast::Statement {
|
vec![ast::Statement {
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::If {
|
node: ast::StatementType::If {
|
||||||
test: make_int(1, 1, 4),
|
test: make_int(1, 1, 4),
|
||||||
body: vec![as_statement(make_int(10, 1, 7))],
|
body: vec![as_statement(make_int(10, 1, 7))],
|
||||||
orelse: Some(vec![ast::Statement {
|
orelse: Some(vec![ast::Statement {
|
||||||
location: ast::Location::new(2, 1),
|
location: ast::Location::new(2, 1),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::If {
|
node: ast::StatementType::If {
|
||||||
test: make_int(2, 2, 6),
|
test: make_int(2, 2, 6),
|
||||||
body: vec![as_statement(make_int(20, 2, 9))],
|
body: vec![as_statement(make_int(20, 2, 9))],
|
||||||
@@ -267,25 +250,24 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_lambda() {
|
fn test_parse_lambda() {
|
||||||
let source = "lambda x, y: x * y"; // lambda(x, y): x * y");
|
let source = String::from("lambda x, y: x * y"); // lambda(x, y): x * y");
|
||||||
let parse_ast = parse_statement(source);
|
let parse_ast = parse_statement(&source);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ast,
|
parse_ast,
|
||||||
Ok(vec![as_statement(ast::Expression {
|
Ok(vec![as_statement(ast::Expression {
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Lambda {
|
node: ast::ExpressionType::Lambda {
|
||||||
args: Box::new(ast::Parameters {
|
args: Box::new(ast::Parameters {
|
||||||
posonlyargs_count: 0,
|
posonlyargs_count: 0,
|
||||||
args: vec![
|
args: vec![
|
||||||
ast::Parameter {
|
ast::Parameter {
|
||||||
location: ast::Location::new(1, 8),
|
location: ast::Location::new(1, 8),
|
||||||
arg: "x".to_owned(),
|
arg: String::from("x"),
|
||||||
annotation: None,
|
annotation: None,
|
||||||
},
|
},
|
||||||
ast::Parameter {
|
ast::Parameter {
|
||||||
location: ast::Location::new(1, 11),
|
location: ast::Location::new(1, 11),
|
||||||
arg: "y".to_owned(),
|
arg: String::from("y"),
|
||||||
annotation: None,
|
annotation: None,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -297,7 +279,6 @@ mod tests {
|
|||||||
}),
|
}),
|
||||||
body: Box::new(ast::Expression {
|
body: Box::new(ast::Expression {
|
||||||
location: ast::Location::new(1, 16),
|
location: ast::Location::new(1, 16),
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Binop {
|
node: ast::ExpressionType::Binop {
|
||||||
a: Box::new(mk_ident("x", 1, 14)),
|
a: Box::new(mk_ident("x", 1, 14)),
|
||||||
op: ast::Operator::Mult,
|
op: ast::Operator::Mult,
|
||||||
@@ -311,16 +292,14 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_tuples() {
|
fn test_parse_tuples() {
|
||||||
let source = "a, b = 4, 5";
|
let source = String::from("a, b = 4, 5");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_statement(source),
|
parse_statement(&source),
|
||||||
Ok(vec![ast::Statement {
|
Ok(vec![ast::Statement {
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::Assign {
|
node: ast::StatementType::Assign {
|
||||||
targets: vec![ast::Expression {
|
targets: vec![ast::Expression {
|
||||||
custom: (),
|
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
node: ast::ExpressionType::Tuple {
|
node: ast::ExpressionType::Tuple {
|
||||||
elements: vec![mk_ident("a", 1, 1), mk_ident("b", 1, 4),]
|
elements: vec![mk_ident("a", 1, 1), mk_ident("b", 1, 4),]
|
||||||
@@ -328,7 +307,6 @@ mod tests {
|
|||||||
}],
|
}],
|
||||||
value: ast::Expression {
|
value: ast::Expression {
|
||||||
location: ast::Location::new(1, 8),
|
location: ast::Location::new(1, 8),
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Tuple {
|
node: ast::ExpressionType::Tuple {
|
||||||
elements: vec![make_int(4, 1, 8), make_int(5, 1, 11),]
|
elements: vec![make_int(4, 1, 8), make_int(5, 1, 11),]
|
||||||
}
|
}
|
||||||
@@ -340,33 +318,28 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_class() {
|
fn test_parse_class() {
|
||||||
let source = "\
|
let source = String::from(
|
||||||
class Foo(A, B):
|
"class Foo(A, B):\n def __init__(self):\n pass\n def method_with_default(self, arg='default'):\n pass",
|
||||||
def __init__(self):
|
);
|
||||||
pass
|
|
||||||
def method_with_default(self, arg='default'):
|
|
||||||
pass";
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_statement(source),
|
parse_statement(&source),
|
||||||
Ok(vec![ast::Statement {
|
Ok(vec![ast::Statement {
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::ClassDef {
|
node: ast::StatementType::ClassDef {
|
||||||
name: "Foo".to_owned(),
|
name: String::from("Foo"),
|
||||||
bases: vec![mk_ident("A", 1, 11), mk_ident("B", 1, 14)],
|
bases: vec![mk_ident("A", 1, 11), mk_ident("B", 1, 14)],
|
||||||
keywords: vec![],
|
keywords: vec![],
|
||||||
body: vec![
|
body: vec![
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
location: ast::Location::new(2, 2),
|
location: ast::Location::new(2, 2),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::FunctionDef {
|
node: ast::StatementType::FunctionDef {
|
||||||
is_async: false,
|
is_async: false,
|
||||||
name: "__init__".to_owned(),
|
name: String::from("__init__"),
|
||||||
args: Box::new(ast::Parameters {
|
args: Box::new(ast::Parameters {
|
||||||
posonlyargs_count: 0,
|
posonlyargs_count: 0,
|
||||||
args: vec![ast::Parameter {
|
args: vec![ast::Parameter {
|
||||||
location: ast::Location::new(2, 15),
|
location: ast::Location::new(2, 15),
|
||||||
arg: "self".to_owned(),
|
arg: String::from("self"),
|
||||||
annotation: None,
|
annotation: None,
|
||||||
}],
|
}],
|
||||||
kwonlyargs: vec![],
|
kwonlyargs: vec![],
|
||||||
@@ -377,7 +350,6 @@ class Foo(A, B):
|
|||||||
}),
|
}),
|
||||||
body: vec![ast::Statement {
|
body: vec![ast::Statement {
|
||||||
location: ast::Location::new(3, 3),
|
location: ast::Location::new(3, 3),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::Pass,
|
node: ast::StatementType::Pass,
|
||||||
}],
|
}],
|
||||||
decorator_list: vec![],
|
decorator_list: vec![],
|
||||||
@@ -386,21 +358,20 @@ class Foo(A, B):
|
|||||||
},
|
},
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
location: ast::Location::new(4, 2),
|
location: ast::Location::new(4, 2),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::FunctionDef {
|
node: ast::StatementType::FunctionDef {
|
||||||
is_async: false,
|
is_async: false,
|
||||||
name: "method_with_default".to_owned(),
|
name: String::from("method_with_default"),
|
||||||
args: Box::new(ast::Parameters {
|
args: Box::new(ast::Parameters {
|
||||||
posonlyargs_count: 0,
|
posonlyargs_count: 0,
|
||||||
args: vec![
|
args: vec![
|
||||||
ast::Parameter {
|
ast::Parameter {
|
||||||
location: ast::Location::new(4, 26),
|
location: ast::Location::new(4, 26),
|
||||||
arg: "self".to_owned(),
|
arg: String::from("self"),
|
||||||
annotation: None,
|
annotation: None,
|
||||||
},
|
},
|
||||||
ast::Parameter {
|
ast::Parameter {
|
||||||
location: ast::Location::new(4, 32),
|
location: ast::Location::new(4, 32),
|
||||||
arg: "arg".to_owned(),
|
arg: String::from("arg"),
|
||||||
annotation: None,
|
annotation: None,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -412,7 +383,6 @@ class Foo(A, B):
|
|||||||
}),
|
}),
|
||||||
body: vec![ast::Statement {
|
body: vec![ast::Statement {
|
||||||
location: ast::Location::new(5, 3),
|
location: ast::Location::new(5, 3),
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::Pass,
|
node: ast::StatementType::Pass,
|
||||||
}],
|
}],
|
||||||
decorator_list: vec![],
|
decorator_list: vec![],
|
||||||
@@ -428,13 +398,12 @@ class Foo(A, B):
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_dict_comprehension() {
|
fn test_parse_dict_comprehension() {
|
||||||
let source = "{x1: x2 for y in z}";
|
let source = String::from("{x1: x2 for y in z}");
|
||||||
let parse_ast = parse_expression(source).unwrap();
|
let parse_ast = parse_expression(&source).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ast,
|
parse_ast,
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Comprehension {
|
node: ast::ExpressionType::Comprehension {
|
||||||
kind: Box::new(ast::ComprehensionKind::Dict {
|
kind: Box::new(ast::ComprehensionKind::Dict {
|
||||||
key: mk_ident("x1", 1, 2),
|
key: mk_ident("x1", 1, 2),
|
||||||
@@ -454,12 +423,11 @@ class Foo(A, B):
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_list_comprehension() {
|
fn test_parse_list_comprehension() {
|
||||||
let source = "[x for y in z]";
|
let source = String::from("[x for y in z]");
|
||||||
let parse_ast = parse_expression(source).unwrap();
|
let parse_ast = parse_expression(&source).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ast,
|
parse_ast,
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
custom: (),
|
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
node: ast::ExpressionType::Comprehension {
|
node: ast::ExpressionType::Comprehension {
|
||||||
kind: Box::new(ast::ComprehensionKind::List {
|
kind: Box::new(ast::ComprehensionKind::List {
|
||||||
@@ -479,12 +447,11 @@ class Foo(A, B):
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_double_list_comprehension() {
|
fn test_parse_double_list_comprehension() {
|
||||||
let source = "[x for y, y2 in z for a in b if a < 5 if a > 10]";
|
let source = String::from("[x for y, y2 in z for a in b if a < 5 if a > 10]");
|
||||||
let parse_ast = parse_expression(source).unwrap();
|
let parse_ast = parse_expression(&source).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_ast,
|
parse_ast,
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
custom: (),
|
|
||||||
location: ast::Location::new(1, 1),
|
location: ast::Location::new(1, 1),
|
||||||
node: ast::ExpressionType::Comprehension {
|
node: ast::ExpressionType::Comprehension {
|
||||||
kind: Box::new(ast::ComprehensionKind::List {
|
kind: Box::new(ast::ComprehensionKind::List {
|
||||||
@@ -494,7 +461,6 @@ class Foo(A, B):
|
|||||||
ast::Comprehension {
|
ast::Comprehension {
|
||||||
location: ast::Location::new(1, 4),
|
location: ast::Location::new(1, 4),
|
||||||
target: ast::Expression {
|
target: ast::Expression {
|
||||||
custom: (),
|
|
||||||
location: ast::Location::new(1, 8),
|
location: ast::Location::new(1, 8),
|
||||||
node: ast::ExpressionType::Tuple {
|
node: ast::ExpressionType::Tuple {
|
||||||
elements: vec![mk_ident("y", 1, 8), mk_ident("y2", 1, 11),],
|
elements: vec![mk_ident("y", 1, 8), mk_ident("y2", 1, 11),],
|
||||||
@@ -510,7 +476,6 @@ class Foo(A, B):
|
|||||||
iter: mk_ident("b", 1, 28),
|
iter: mk_ident("b", 1, 28),
|
||||||
ifs: vec![
|
ifs: vec![
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
custom: (),
|
|
||||||
location: ast::Location::new(1, 35),
|
location: ast::Location::new(1, 35),
|
||||||
node: ast::ExpressionType::Compare {
|
node: ast::ExpressionType::Compare {
|
||||||
vals: vec![mk_ident("a", 1, 33), make_int(5, 1, 37),],
|
vals: vec![mk_ident("a", 1, 33), make_int(5, 1, 37),],
|
||||||
@@ -518,7 +483,6 @@ class Foo(A, B):
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
custom: (),
|
|
||||||
location: ast::Location::new(1, 44),
|
location: ast::Location::new(1, 44),
|
||||||
node: ast::ExpressionType::Compare {
|
node: ast::ExpressionType::Compare {
|
||||||
vals: vec![mk_ident("a", 1, 42), make_int(10, 1, 46),],
|
vals: vec![mk_ident("a", 1, 42), make_int(10, 1, 46),],
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
// See also: file:///usr/share/doc/python/html/reference/compound_stmts.html#function-definitions
|
// See also: file:///usr/share/doc/python/html/reference/compound_stmts.html#function-definitions
|
||||||
// See also: https://greentreesnakes.readthedocs.io/en/latest/nodes.html#keyword
|
// See also: https://greentreesnakes.readthedocs.io/en/latest/nodes.html#keyword
|
||||||
|
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
use crate::ast;
|
use crate::ast;
|
||||||
use crate::fstring::parse_located_fstring;
|
use crate::fstring::parse_located_fstring;
|
||||||
use crate::function::{parse_args, parse_params};
|
use crate::function::{parse_args, parse_params};
|
||||||
use crate::error::LexicalError;
|
use crate::error::LexicalError;
|
||||||
use crate::lexer;
|
use crate::lexer;
|
||||||
use alloc::{boxed::Box, string::{String, ToString}, vec, vec::Vec};
|
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ pub Top: ast::Top = {
|
|||||||
|
|
||||||
Program: ast::Program = {
|
Program: ast::Program = {
|
||||||
<lines:FileLine*> => ast::Program {
|
<lines:FileLine*> => ast::Program {
|
||||||
statements: lines.into_iter().flatten().collect(),
|
statements: Vec::from_iter(lines.into_iter().flatten())
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -68,7 +69,6 @@ PassStatement: ast::Statement = {
|
|||||||
<location:@L> "pass" => {
|
<location:@L> "pass" => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::Pass,
|
node: ast::StatementType::Pass,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -78,7 +78,6 @@ DelStatement: ast::Statement = {
|
|||||||
<location:@L> "del" <targets:ExpressionList2> => {
|
<location:@L> "del" <targets:ExpressionList2> => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::StatementType::Delete { targets },
|
node: ast::StatementType::Delete { targets },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -89,7 +88,6 @@ ExpressionStatement: ast::Statement = {
|
|||||||
// Just an expression, no assignment:
|
// Just an expression, no assignment:
|
||||||
if suffix.is_empty() {
|
if suffix.is_empty() {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Expression { expression }
|
node: ast::StatementType::Expression { expression }
|
||||||
}
|
}
|
||||||
@@ -104,7 +102,6 @@ ExpressionStatement: ast::Statement = {
|
|||||||
let value = values.into_iter().next().unwrap();
|
let value = values.into_iter().next().unwrap();
|
||||||
|
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Assign { targets, value },
|
node: ast::StatementType::Assign { targets, value },
|
||||||
}
|
}
|
||||||
@@ -112,7 +109,6 @@ ExpressionStatement: ast::Statement = {
|
|||||||
},
|
},
|
||||||
<location:@L> <target:TestOrStarExprList> <op:AugAssign> <rhs:TestListOrYieldExpr> => {
|
<location:@L> <target:TestOrStarExprList> <op:AugAssign> <rhs:TestListOrYieldExpr> => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::AugAssign {
|
node: ast::StatementType::AugAssign {
|
||||||
target: Box::new(target),
|
target: Box::new(target),
|
||||||
@@ -123,7 +119,6 @@ ExpressionStatement: ast::Statement = {
|
|||||||
},
|
},
|
||||||
<location:@L> <target:Test> ":" <annotation:Test> <rhs:AssignSuffix?> => {
|
<location:@L> <target:Test> ":" <annotation:Test> <rhs:AssignSuffix?> => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::AnnAssign {
|
node: ast::StatementType::AnnAssign {
|
||||||
target: Box::new(target),
|
target: Box::new(target),
|
||||||
@@ -150,7 +145,6 @@ TestOrStarExprList: ast::Expression = {
|
|||||||
} else {
|
} else {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Tuple { elements }
|
node: ast::ExpressionType::Tuple { elements }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +158,6 @@ TestOrStarNamedExprList: ast::Expression = {
|
|||||||
} else {
|
} else {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Tuple { elements }
|
node: ast::ExpressionType::Tuple { elements }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,28 +193,24 @@ AugAssign: ast::Operator = {
|
|||||||
FlowStatement: ast::Statement = {
|
FlowStatement: ast::Statement = {
|
||||||
<location:@L> "break" => {
|
<location:@L> "break" => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Break,
|
node: ast::StatementType::Break,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> "continue" => {
|
<location:@L> "continue" => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Continue,
|
node: ast::StatementType::Continue,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> "return" <value:TestList?> => {
|
<location:@L> "return" <value:TestList?> => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Return { value },
|
node: ast::StatementType::Return { value },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> <expression:YieldExpr> => {
|
<location:@L> <expression:YieldExpr> => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Expression { expression },
|
node: ast::StatementType::Expression { expression },
|
||||||
}
|
}
|
||||||
@@ -232,14 +221,12 @@ FlowStatement: ast::Statement = {
|
|||||||
RaiseStatement: ast::Statement = {
|
RaiseStatement: ast::Statement = {
|
||||||
<location:@L> "raise" => {
|
<location:@L> "raise" => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Raise { exception: None, cause: None },
|
node: ast::StatementType::Raise { exception: None, cause: None },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> "raise" <t:Test> <c:("from" Test)?> => {
|
<location:@L> "raise" <t:Test> <c:("from" Test)?> => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Raise { exception: Some(t), cause: c.map(|x| x.1) },
|
node: ast::StatementType::Raise { exception: Some(t), cause: c.map(|x| x.1) },
|
||||||
}
|
}
|
||||||
@@ -249,7 +236,6 @@ RaiseStatement: ast::Statement = {
|
|||||||
ImportStatement: ast::Statement = {
|
ImportStatement: ast::Statement = {
|
||||||
<location:@L> "import" <names: OneOrMore<ImportAsAlias<DottedName>>> => {
|
<location:@L> "import" <names: OneOrMore<ImportAsAlias<DottedName>>> => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Import { names },
|
node: ast::StatementType::Import { names },
|
||||||
}
|
}
|
||||||
@@ -257,7 +243,6 @@ ImportStatement: ast::Statement = {
|
|||||||
<location:@L> "from" <source:ImportFromLocation> "import" <names: ImportAsNames> => {
|
<location:@L> "from" <source:ImportFromLocation> "import" <names: ImportAsNames> => {
|
||||||
let (level, module) = source;
|
let (level, module) = source;
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::ImportFrom {
|
node: ast::StatementType::ImportFrom {
|
||||||
level,
|
level,
|
||||||
@@ -313,7 +298,6 @@ DottedName: String = {
|
|||||||
GlobalStatement: ast::Statement = {
|
GlobalStatement: ast::Statement = {
|
||||||
<location:@L> "global" <names:OneOrMore<Identifier>> => {
|
<location:@L> "global" <names:OneOrMore<Identifier>> => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Global { names }
|
node: ast::StatementType::Global { names }
|
||||||
}
|
}
|
||||||
@@ -323,7 +307,6 @@ GlobalStatement: ast::Statement = {
|
|||||||
NonlocalStatement: ast::Statement = {
|
NonlocalStatement: ast::Statement = {
|
||||||
<location:@L> "nonlocal" <names:OneOrMore<Identifier>> => {
|
<location:@L> "nonlocal" <names:OneOrMore<Identifier>> => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Nonlocal { names }
|
node: ast::StatementType::Nonlocal { names }
|
||||||
}
|
}
|
||||||
@@ -333,7 +316,6 @@ NonlocalStatement: ast::Statement = {
|
|||||||
AssertStatement: ast::Statement = {
|
AssertStatement: ast::Statement = {
|
||||||
<location:@L> "assert" <test:Test> <msg: ("," Test)?> => {
|
<location:@L> "assert" <test:Test> <msg: ("," Test)?> => {
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Assert {
|
node: ast::StatementType::Assert {
|
||||||
test, msg: msg.map(|e| e.1)
|
test, msg: msg.map(|e| e.1)
|
||||||
@@ -360,7 +342,6 @@ IfStatement: ast::Statement = {
|
|||||||
// handle elif:
|
// handle elif:
|
||||||
for i in s2.into_iter().rev() {
|
for i in s2.into_iter().rev() {
|
||||||
let x = ast::Statement {
|
let x = ast::Statement {
|
||||||
custom: (),
|
|
||||||
location: i.0,
|
location: i.0,
|
||||||
node: ast::StatementType::If { test: i.2, body: i.4, orelse: last },
|
node: ast::StatementType::If { test: i.2, body: i.4, orelse: last },
|
||||||
};
|
};
|
||||||
@@ -368,7 +349,6 @@ IfStatement: ast::Statement = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::If { test, body, orelse: last }
|
node: ast::StatementType::If { test, body, orelse: last }
|
||||||
}
|
}
|
||||||
@@ -379,7 +359,6 @@ WhileStatement: ast::Statement = {
|
|||||||
<location:@L> "while" <test:NamedExpressionTest> ":" <body:Suite> <s2:("else" ":" Suite)?> => {
|
<location:@L> "while" <test:NamedExpressionTest> ":" <body:Suite> <s2:("else" ":" Suite)?> => {
|
||||||
let orelse = s2.map(|s| s.2);
|
let orelse = s2.map(|s| s.2);
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::While {
|
node: ast::StatementType::While {
|
||||||
test,
|
test,
|
||||||
@@ -395,7 +374,6 @@ ForStatement: ast::Statement = {
|
|||||||
let is_async = is_async.is_some();
|
let is_async = is_async.is_some();
|
||||||
let orelse = s2.map(|s| s.2);
|
let orelse = s2.map(|s| s.2);
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::For {
|
node: ast::StatementType::For {
|
||||||
is_async,
|
is_async,
|
||||||
@@ -413,7 +391,6 @@ TryStatement: ast::Statement = {
|
|||||||
let orelse = else_suite.map(|s| s.2);
|
let orelse = else_suite.map(|s| s.2);
|
||||||
let finalbody = finally.map(|s| s.2);
|
let finalbody = finally.map(|s| s.2);
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Try {
|
node: ast::StatementType::Try {
|
||||||
body,
|
body,
|
||||||
@@ -428,7 +405,6 @@ TryStatement: ast::Statement = {
|
|||||||
let orelse = None;
|
let orelse = None;
|
||||||
let finalbody = Some(finally.2);
|
let finalbody = Some(finally.2);
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::Try {
|
node: ast::StatementType::Try {
|
||||||
body,
|
body,
|
||||||
@@ -463,7 +439,6 @@ WithStatement: ast::Statement = {
|
|||||||
<location:@L> <is_async:"async"?> "with" <items:OneOrMore<WithItem>> ":" <body:Suite> => {
|
<location:@L> <is_async:"async"?> "with" <items:OneOrMore<WithItem>> ":" <body:Suite> => {
|
||||||
let is_async = is_async.is_some();
|
let is_async = is_async.is_some();
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::With { is_async, items, body },
|
node: ast::StatementType::With { is_async, items, body },
|
||||||
}
|
}
|
||||||
@@ -481,7 +456,6 @@ FuncDef: ast::Statement = {
|
|||||||
<decorator_list:Decorator*> <location:@L> <is_async:"async"?> "def" <name:Identifier> <args:Parameters> <r:("->" Test)?> ":" <body:Suite> => {
|
<decorator_list:Decorator*> <location:@L> <is_async:"async"?> "def" <name:Identifier> <args:Parameters> <r:("->" Test)?> ":" <body:Suite> => {
|
||||||
let is_async = is_async.is_some();
|
let is_async = is_async.is_some();
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::FunctionDef {
|
node: ast::StatementType::FunctionDef {
|
||||||
is_async,
|
is_async,
|
||||||
@@ -623,7 +597,6 @@ ClassDef: ast::Statement = {
|
|||||||
None => (vec![], vec![]),
|
None => (vec![], vec![]),
|
||||||
};
|
};
|
||||||
ast::Statement {
|
ast::Statement {
|
||||||
custom: (),
|
|
||||||
location,
|
location,
|
||||||
node: ast::StatementType::ClassDef {
|
node: ast::StatementType::ClassDef {
|
||||||
name,
|
name,
|
||||||
@@ -639,13 +612,11 @@ ClassDef: ast::Statement = {
|
|||||||
Path: ast::Expression = {
|
Path: ast::Expression = {
|
||||||
<location:@L> <n:Identifier> => ast::Expression {
|
<location:@L> <n:Identifier> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Identifier { name: n }
|
node: ast::ExpressionType::Identifier { name: n }
|
||||||
},
|
},
|
||||||
<p:Path> <location:@L> "." <n:name> => {
|
<p:Path> <location:@L> "." <n:name> => {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Attribute {
|
node: ast::ExpressionType::Attribute {
|
||||||
value: Box::new(p),
|
value: Box::new(p),
|
||||||
name: n,
|
name: n,
|
||||||
@@ -664,12 +635,10 @@ Decorator: ast::Expression = {
|
|||||||
YieldExpr: ast::Expression = {
|
YieldExpr: ast::Expression = {
|
||||||
<location:@L> "yield" <value:TestList?> => ast::Expression {
|
<location:@L> "yield" <value:TestList?> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Yield { value: value.map(Box::new) }
|
node: ast::ExpressionType::Yield { value: value.map(Box::new) }
|
||||||
},
|
},
|
||||||
<location:@L> "yield" "from" <e:Test> => ast::Expression {
|
<location:@L> "yield" "from" <e:Test> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::YieldFrom { value: Box::new(e) }
|
node: ast::ExpressionType::YieldFrom { value: Box::new(e) }
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -679,7 +648,6 @@ Test: ast::Expression = {
|
|||||||
if let Some(c) = condition {
|
if let Some(c) = condition {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location: c.0,
|
location: c.0,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::IfExpression {
|
node: ast::ExpressionType::IfExpression {
|
||||||
test: Box::new(c.2),
|
test: Box::new(c.2),
|
||||||
body: Box::new(expr),
|
body: Box::new(expr),
|
||||||
@@ -698,12 +666,10 @@ NamedExpressionTest: ast::Expression = {
|
|||||||
if let Some(l) = left {
|
if let Some(l) = left {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location: location,
|
location: location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::NamedExpression {
|
node: ast::ExpressionType::NamedExpression {
|
||||||
left: Box::new(
|
left: Box::new(
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location: location,
|
location: location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Identifier { name: l.0, },
|
node: ast::ExpressionType::Identifier { name: l.0, },
|
||||||
}),
|
}),
|
||||||
right: Box::new(right),
|
right: Box::new(right),
|
||||||
@@ -719,7 +685,6 @@ LambdaDef: ast::Expression = {
|
|||||||
<location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test> =>
|
<location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test> =>
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Lambda {
|
node: ast::ExpressionType::Lambda {
|
||||||
args: Box::new(p.unwrap_or_default()),
|
args: Box::new(p.unwrap_or_default()),
|
||||||
body: Box::new(body)
|
body: Box::new(body)
|
||||||
@@ -736,7 +701,6 @@ OrTest: ast::Expression = {
|
|||||||
values.extend(e2.into_iter().map(|e| e.1));
|
values.extend(e2.into_iter().map(|e| e.1));
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::BoolOp { op: ast::BooleanOperator::Or, values }
|
node: ast::ExpressionType::BoolOp { op: ast::BooleanOperator::Or, values }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -752,7 +716,6 @@ AndTest: ast::Expression = {
|
|||||||
values.extend(e2.into_iter().map(|e| e.1));
|
values.extend(e2.into_iter().map(|e| e.1));
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::BoolOp { op: ast::BooleanOperator::And, values }
|
node: ast::ExpressionType::BoolOp { op: ast::BooleanOperator::And, values }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -762,7 +725,6 @@ AndTest: ast::Expression = {
|
|||||||
NotTest: ast::Expression = {
|
NotTest: ast::Expression = {
|
||||||
<location:@L> "not" <e:NotTest> => ast::Expression {
|
<location:@L> "not" <e:NotTest> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Unop { a: Box::new(e), op: ast::UnaryOperator::Not }
|
node: ast::ExpressionType::Unop { a: Box::new(e), op: ast::UnaryOperator::Not }
|
||||||
},
|
},
|
||||||
Comparison,
|
Comparison,
|
||||||
@@ -778,7 +740,6 @@ Comparison: ast::Expression = {
|
|||||||
}
|
}
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Compare { vals, ops }
|
node: ast::ExpressionType::Compare { vals, ops }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -801,7 +762,6 @@ CompOp: ast::Comparison = {
|
|||||||
Expression: ast::Expression = {
|
Expression: ast::Expression = {
|
||||||
<e1:Expression> <location:@L> "|" <e2:XorExpression> => ast::Expression {
|
<e1:Expression> <location:@L> "|" <e2:XorExpression> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Binop { a: Box::new(e1), op: ast::Operator::BitOr, b: Box::new(e2) }
|
node: ast::ExpressionType::Binop { a: Box::new(e1), op: ast::Operator::BitOr, b: Box::new(e2) }
|
||||||
},
|
},
|
||||||
XorExpression,
|
XorExpression,
|
||||||
@@ -810,7 +770,6 @@ Expression: ast::Expression = {
|
|||||||
XorExpression: ast::Expression = {
|
XorExpression: ast::Expression = {
|
||||||
<e1:XorExpression> <location:@L> "^" <e2:AndExpression> => ast::Expression {
|
<e1:XorExpression> <location:@L> "^" <e2:AndExpression> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Binop { a: Box::new(e1), op: ast::Operator::BitXor, b: Box::new(e2) }
|
node: ast::ExpressionType::Binop { a: Box::new(e1), op: ast::Operator::BitXor, b: Box::new(e2) }
|
||||||
},
|
},
|
||||||
AndExpression,
|
AndExpression,
|
||||||
@@ -819,7 +778,6 @@ XorExpression: ast::Expression = {
|
|||||||
AndExpression: ast::Expression = {
|
AndExpression: ast::Expression = {
|
||||||
<e1:AndExpression> <location:@L> "&" <e2:ShiftExpression> => ast::Expression {
|
<e1:AndExpression> <location:@L> "&" <e2:ShiftExpression> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Binop { a: Box::new(e1), op: ast::Operator::BitAnd, b: Box::new(e2) }
|
node: ast::ExpressionType::Binop { a: Box::new(e1), op: ast::Operator::BitAnd, b: Box::new(e2) }
|
||||||
},
|
},
|
||||||
ShiftExpression,
|
ShiftExpression,
|
||||||
@@ -828,7 +786,6 @@ AndExpression: ast::Expression = {
|
|||||||
ShiftExpression: ast::Expression = {
|
ShiftExpression: ast::Expression = {
|
||||||
<e1:ShiftExpression> <location:@L> <op:ShiftOp> <e2:ArithmaticExpression> => ast::Expression {
|
<e1:ShiftExpression> <location:@L> <op:ShiftOp> <e2:ArithmaticExpression> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Binop { a: Box::new(e1), op, b: Box::new(e2) }
|
node: ast::ExpressionType::Binop { a: Box::new(e1), op, b: Box::new(e2) }
|
||||||
},
|
},
|
||||||
ArithmaticExpression,
|
ArithmaticExpression,
|
||||||
@@ -842,7 +799,6 @@ ShiftOp: ast::Operator = {
|
|||||||
ArithmaticExpression: ast::Expression = {
|
ArithmaticExpression: ast::Expression = {
|
||||||
<a:ArithmaticExpression> <location:@L> <op:AddOp> <b:Term> => ast::Expression {
|
<a:ArithmaticExpression> <location:@L> <op:AddOp> <b:Term> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Binop { a: Box::new(a), op, b: Box::new(b) }
|
node: ast::ExpressionType::Binop { a: Box::new(a), op, b: Box::new(b) }
|
||||||
},
|
},
|
||||||
Term,
|
Term,
|
||||||
@@ -856,7 +812,6 @@ AddOp: ast::Operator = {
|
|||||||
Term: ast::Expression = {
|
Term: ast::Expression = {
|
||||||
<a:Term> <location:@L> <op:MulOp> <b:Factor> => ast::Expression {
|
<a:Term> <location:@L> <op:MulOp> <b:Factor> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Binop { a: Box::new(a), op, b: Box::new(b) }
|
node: ast::ExpressionType::Binop { a: Box::new(a), op, b: Box::new(b) }
|
||||||
},
|
},
|
||||||
Factor,
|
Factor,
|
||||||
@@ -873,7 +828,6 @@ MulOp: ast::Operator = {
|
|||||||
Factor: ast::Expression = {
|
Factor: ast::Expression = {
|
||||||
<location:@L> <op:UnOp> <e:Factor> => ast::Expression {
|
<location:@L> <op:UnOp> <e:Factor> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Unop { a: Box::new(e), op }
|
node: ast::ExpressionType::Unop { a: Box::new(e), op }
|
||||||
},
|
},
|
||||||
Power,
|
Power,
|
||||||
@@ -891,7 +845,6 @@ Power: ast::Expression = {
|
|||||||
None => e,
|
None => e,
|
||||||
Some((location, _, b)) => ast::Expression {
|
Some((location, _, b)) => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Binop { a: Box::new(e), op: ast::Operator::Pow, b: Box::new(b) }
|
node: ast::ExpressionType::Binop { a: Box::new(e), op: ast::Operator::Pow, b: Box::new(b) }
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -903,7 +856,6 @@ AtomExpr: ast::Expression = {
|
|||||||
if is_await.is_some() {
|
if is_await.is_some() {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Await { value: Box::new(atom) }
|
node: ast::ExpressionType::Await { value: Box::new(atom) }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -917,18 +869,15 @@ AtomExpr2: ast::Expression = {
|
|||||||
<f:AtomExpr2> <location:@L> "(" <a:ArgumentList> ")" => {
|
<f:AtomExpr2> <location:@L> "(" <a:ArgumentList> ")" => {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Call { function: Box::new(f), args: a.args, keywords: a.keywords }
|
node: ast::ExpressionType::Call { function: Box::new(f), args: a.args, keywords: a.keywords }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<e:AtomExpr2> <location:@L> "[" <s:SubscriptList> "]" => ast::Expression {
|
<e:AtomExpr2> <location:@L> "[" <s:SubscriptList> "]" => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Subscript { a: Box::new(e), b: Box::new(s) }
|
node: ast::ExpressionType::Subscript { a: Box::new(e), b: Box::new(s) }
|
||||||
},
|
},
|
||||||
<e:AtomExpr2> <location:@L> "." <name:Identifier> => ast::Expression {
|
<e:AtomExpr2> <location:@L> "." <name:Identifier> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Attribute { value: Box::new(e), name }
|
node: ast::ExpressionType::Attribute { value: Box::new(e), name }
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -945,7 +894,6 @@ SubscriptList: ast::Expression = {
|
|||||||
|
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Tuple { elements: dims },
|
node: ast::ExpressionType::Tuple { elements: dims },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -955,54 +903,47 @@ SubscriptList: ast::Expression = {
|
|||||||
Subscript: ast::Expression = {
|
Subscript: ast::Expression = {
|
||||||
Test,
|
Test,
|
||||||
<e1:Test?> <location:@L> ":" <e2:Test?> <e3:SliceOp?> => {
|
<e1:Test?> <location:@L> ":" <e2:Test?> <e3:SliceOp?> => {
|
||||||
let s1 = e1.unwrap_or(ast::Expression { location, custom: (), node: ast::ExpressionType::None });
|
let s1 = e1.unwrap_or(ast::Expression { location, node: ast::ExpressionType::None });
|
||||||
let s2 = e2.unwrap_or(ast::Expression { location, custom: (), node: ast::ExpressionType::None });
|
let s2 = e2.unwrap_or(ast::Expression { location, node: ast::ExpressionType::None });
|
||||||
let s3 = e3.unwrap_or(ast::Expression { location, custom: (), node: ast::ExpressionType::None });
|
let s3 = e3.unwrap_or(ast::Expression { location, node: ast::ExpressionType::None });
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Slice { elements: vec![s1, s2, s3] }
|
node: ast::ExpressionType::Slice { elements: vec![s1, s2, s3] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SliceOp: ast::Expression = {
|
SliceOp: ast::Expression = {
|
||||||
<location:@L> ":" <e:Test?> => e.unwrap_or(ast::Expression {location, custom: (), node: ast::ExpressionType::None})
|
<location:@L> ":" <e:Test?> => e.unwrap_or(ast::Expression {location, node: ast::ExpressionType::None})
|
||||||
}
|
}
|
||||||
|
|
||||||
Atom: ast::Expression = {
|
Atom: ast::Expression = {
|
||||||
<location:@L> <value:StringGroup> => ast::Expression {
|
<location:@L> <value:StringGroup> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::String { value }
|
node: ast::ExpressionType::String { value }
|
||||||
},
|
},
|
||||||
<location:@L> <value:Bytes> => ast::Expression {
|
<location:@L> <value:Bytes> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Bytes { value }
|
node: ast::ExpressionType::Bytes { value }
|
||||||
},
|
},
|
||||||
<location:@L> <value:Number> => ast::Expression {
|
<location:@L> <value:Number> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Number { value }
|
node: ast::ExpressionType::Number { value }
|
||||||
},
|
},
|
||||||
<location:@L> <name:Identifier> => ast::Expression {
|
<location:@L> <name:Identifier> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Identifier { name }
|
node: ast::ExpressionType::Identifier { name }
|
||||||
},
|
},
|
||||||
<location:@L> "[" <e:ListLiteralValues?> "]" => {
|
<location:@L> "[" <e:ListLiteralValues?> "]" => {
|
||||||
let elements = e.unwrap_or_default();
|
let elements = e.unwrap_or_default();
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::List { elements }
|
node: ast::ExpressionType::List { elements }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> "[" <element:TestOrStarNamedExpr> <generators:CompFor> "]" => {
|
<location:@L> "[" <element:TestOrStarNamedExpr> <generators:CompFor> "]" => {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Comprehension {
|
node: ast::ExpressionType::Comprehension {
|
||||||
kind: Box::new(ast::ComprehensionKind::List { element }),
|
kind: Box::new(ast::ComprehensionKind::List { element }),
|
||||||
generators,
|
generators,
|
||||||
@@ -1012,7 +953,6 @@ Atom: ast::Expression = {
|
|||||||
<location:@L> "(" <elements:TestOrStarNamedExprList?> ")" => {
|
<location:@L> "(" <elements:TestOrStarNamedExprList?> ")" => {
|
||||||
elements.unwrap_or(ast::Expression {
|
elements.unwrap_or(ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Tuple { elements: Vec::new() }
|
node: ast::ExpressionType::Tuple { elements: Vec::new() }
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -1020,7 +960,6 @@ Atom: ast::Expression = {
|
|||||||
<location:@L> "(" <element:Test> <generators:CompFor> ")" => {
|
<location:@L> "(" <element:Test> <generators:CompFor> ")" => {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Comprehension {
|
node: ast::ExpressionType::Comprehension {
|
||||||
kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element }),
|
kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element }),
|
||||||
generators,
|
generators,
|
||||||
@@ -1029,13 +968,11 @@ Atom: ast::Expression = {
|
|||||||
},
|
},
|
||||||
<location:@L> "{" <e:DictLiteralValues?> "}" => ast::Expression {
|
<location:@L> "{" <e:DictLiteralValues?> "}" => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Dict { elements: e.unwrap_or_default() }
|
node: ast::ExpressionType::Dict { elements: e.unwrap_or_default() }
|
||||||
},
|
},
|
||||||
<location:@L> "{" <e1:DictEntry> <generators:CompFor> "}" => {
|
<location:@L> "{" <e1:DictEntry> <generators:CompFor> "}" => {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Comprehension {
|
node: ast::ExpressionType::Comprehension {
|
||||||
kind: Box::new(ast::ComprehensionKind::Dict { key: e1.0, value: e1.1 }),
|
kind: Box::new(ast::ComprehensionKind::Dict { key: e1.0, value: e1.1 }),
|
||||||
generators,
|
generators,
|
||||||
@@ -1044,23 +981,21 @@ Atom: ast::Expression = {
|
|||||||
},
|
},
|
||||||
<location:@L> "{" <elements:SetLiteralValues> "}" => ast::Expression {
|
<location:@L> "{" <elements:SetLiteralValues> "}" => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Set { elements }
|
node: ast::ExpressionType::Set { elements }
|
||||||
},
|
},
|
||||||
<location:@L> "{" <element:Test> <generators:CompFor> "}" => {
|
<location:@L> "{" <element:Test> <generators:CompFor> "}" => {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Comprehension {
|
node: ast::ExpressionType::Comprehension {
|
||||||
kind: Box::new(ast::ComprehensionKind::Set { element }),
|
kind: Box::new(ast::ComprehensionKind::Set { element }),
|
||||||
generators,
|
generators,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> "True" => ast::Expression { location, custom: (), node: ast::ExpressionType::True },
|
<location:@L> "True" => ast::Expression { location, node: ast::ExpressionType::True },
|
||||||
<location:@L> "False" => ast::Expression { location, custom: (), node: ast::ExpressionType::False },
|
<location:@L> "False" => ast::Expression { location, node: ast::ExpressionType::False },
|
||||||
<location:@L> "None" => ast::Expression { location, custom: (), node: ast::ExpressionType::None },
|
<location:@L> "None" => ast::Expression { location, node: ast::ExpressionType::None },
|
||||||
<location:@L> "..." => ast::Expression { location, custom: (), node: ast::ExpressionType::Ellipsis },
|
<location:@L> "..." => ast::Expression { location, node: ast::ExpressionType::Ellipsis },
|
||||||
};
|
};
|
||||||
|
|
||||||
ListLiteralValues: Vec<ast::Expression> = {
|
ListLiteralValues: Vec<ast::Expression> = {
|
||||||
@@ -1096,7 +1031,6 @@ ExpressionList: ast::Expression = {
|
|||||||
} else {
|
} else {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Tuple { elements },
|
node: ast::ExpressionType::Tuple { elements },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1118,7 +1052,6 @@ TestList: ast::Expression = {
|
|||||||
} else {
|
} else {
|
||||||
ast::Expression {
|
ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Tuple { elements },
|
node: ast::ExpressionType::Tuple { elements },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1129,7 +1062,6 @@ TestList: ast::Expression = {
|
|||||||
StarExpr: ast::Expression = {
|
StarExpr: ast::Expression = {
|
||||||
<location:@L> "*" <e:Expression> => ast::Expression {
|
<location:@L> "*" <e:Expression> => ast::Expression {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Starred { value: Box::new(e) },
|
node: ast::ExpressionType::Starred { value: Box::new(e) },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1159,7 +1091,6 @@ FunctionArgument: (Option<Option<String>>, ast::Expression) = {
|
|||||||
let expr = match c {
|
let expr = match c {
|
||||||
Some(c) => ast::Expression {
|
Some(c) => ast::Expression {
|
||||||
location: e.location,
|
location: e.location,
|
||||||
custom: (),
|
|
||||||
node: ast::ExpressionType::Comprehension {
|
node: ast::ExpressionType::Comprehension {
|
||||||
kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element: e }),
|
kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element: e }),
|
||||||
generators: c,
|
generators: c,
|
||||||
@@ -1170,7 +1101,7 @@ FunctionArgument: (Option<Option<String>>, ast::Expression) = {
|
|||||||
(None, expr)
|
(None, expr)
|
||||||
},
|
},
|
||||||
<i:Identifier> "=" <e:Test> => (Some(Some(i)), e),
|
<i:Identifier> "=" <e:Test> => (Some(Some(i)), e),
|
||||||
<location:@L> "*" <e:Test> => (None, ast::Expression { location, custom: (), node: ast::ExpressionType::Starred { value: Box::new(e) } }),
|
<location:@L> "*" <e:Test> => (None, ast::Expression { location, node: ast::ExpressionType::Starred { value: Box::new(e) } }),
|
||||||
"**" <e:Test> => (Some(None), e),
|
"**" <e:Test> => (Some(None), e),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
//! Different token definitions.
|
//! Different token definitions.
|
||||||
//! Loosely based on token.h from CPython source:
|
//! Loosely based on token.h from CPython source:
|
||||||
use alloc::{string::String, vec::Vec};
|
|
||||||
use core::fmt::{self, Write};
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
use std::fmt::{self, Write};
|
||||||
|
|
||||||
/// Python source code can be tokenized in a sequence of these tokens.
|
/// Python source code can be tokenized in a sequence of these tokens.
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
@@ -125,11 +124,13 @@ impl fmt::Display for Tok {
|
|||||||
write!(f, "b\"")?;
|
write!(f, "b\"")?;
|
||||||
for i in value {
|
for i in value {
|
||||||
match i {
|
match i {
|
||||||
|
0..=8 => write!(f, "\\x0{}", i)?,
|
||||||
9 => f.write_str("\\t")?,
|
9 => f.write_str("\\t")?,
|
||||||
10 => f.write_str("\\n")?,
|
10 => f.write_str("\\n")?,
|
||||||
|
11 => write!(f, "\\x0{:x}", i)?,
|
||||||
13 => f.write_str("\\r")?,
|
13 => f.write_str("\\r")?,
|
||||||
32..=126 => f.write_char(*i as char)?,
|
32..=126 => f.write_char(*i as char)?,
|
||||||
_ => write!(f, "\\x{:02x}", i)?,
|
_ => write!(f, "\\x{:x}", i)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f.write_str("\"")
|
f.write_str("\"")
|
||||||
|
|||||||
25
src/lib.rs
25
src/lib.rs
@@ -297,18 +297,15 @@ fn parse_arguments<'a>(app: App<'a, '_>) -> ArgMatches<'a> {
|
|||||||
/// Create settings by examining command line arguments and environment
|
/// Create settings by examining command line arguments and environment
|
||||||
/// variables.
|
/// variables.
|
||||||
fn create_settings(matches: &ArgMatches) -> PySettings {
|
fn create_settings(matches: &ArgMatches) -> PySettings {
|
||||||
let mut settings = PySettings {
|
let mut settings = PySettings::default();
|
||||||
isolated: matches.is_present("isolate"),
|
settings.isolated = matches.is_present("isolate");
|
||||||
ignore_environment: matches.is_present("ignore-environment"),
|
settings.ignore_environment = matches.is_present("ignore-environment");
|
||||||
interactive: !matches.is_present("c")
|
|
||||||
&& !matches.is_present("m")
|
|
||||||
&& (!matches.is_present("script") || matches.is_present("inspect")),
|
|
||||||
bytes_warning: matches.occurrences_of("bytes-warning"),
|
|
||||||
no_site: matches.is_present("no-site"),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let ignore_environment = settings.ignore_environment || settings.isolated;
|
let ignore_environment = settings.ignore_environment || settings.isolated;
|
||||||
|
|
||||||
|
settings.interactive = !matches.is_present("c")
|
||||||
|
&& !matches.is_present("m")
|
||||||
|
&& (!matches.is_present("script") || matches.is_present("inspect"));
|
||||||
|
|
||||||
// add the current directory to sys.path
|
// add the current directory to sys.path
|
||||||
settings.path_list.push("".to_owned());
|
settings.path_list.push("".to_owned());
|
||||||
|
|
||||||
@@ -355,6 +352,10 @@ fn create_settings(matches: &ArgMatches) -> PySettings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
settings.bytes_warning = matches.occurrences_of("bytes-warning");
|
||||||
|
|
||||||
|
settings.no_site = matches.is_present("no-site");
|
||||||
|
|
||||||
if matches.is_present("no-user-site")
|
if matches.is_present("no-user-site")
|
||||||
|| matches.is_present("isolate")
|
|| matches.is_present("isolate")
|
||||||
|| (!ignore_environment && env::var_os("PYTHONNOUSERSITE").is_some())
|
|| (!ignore_environment && env::var_os("PYTHONNOUSERSITE").is_some())
|
||||||
@@ -509,7 +510,7 @@ fn run_rustpython(vm: &VirtualMachine, matches: &ArgMatches) -> PyResult<()> {
|
|||||||
vm.get_attribute(vm.sys_module.clone(), "modules")?
|
vm.get_attribute(vm.sys_module.clone(), "modules")?
|
||||||
.set_item("__main__", main_module, vm)?;
|
.set_item("__main__", main_module, vm)?;
|
||||||
|
|
||||||
let site_result = vm.import("site", None, 0);
|
let site_result = vm.import("site", &[], 0);
|
||||||
|
|
||||||
if site_result.is_err() {
|
if site_result.is_err() {
|
||||||
warn!(
|
warn!(
|
||||||
@@ -558,7 +559,7 @@ fn run_command(vm: &VirtualMachine, scope: Scope, source: String) -> PyResult<()
|
|||||||
|
|
||||||
fn run_module(vm: &VirtualMachine, module: &str) -> PyResult<()> {
|
fn run_module(vm: &VirtualMachine, module: &str) -> PyResult<()> {
|
||||||
debug!("Running module {}", module);
|
debug!("Running module {}", module);
|
||||||
let runpy = vm.import("runpy", None, 0)?;
|
let runpy = vm.import("runpy", &[], 0)?;
|
||||||
let run_module_as_main = vm.get_attribute(runpy, "_run_module_as_main")?;
|
let run_module_as_main = vm.get_attribute(runpy, "_run_module_as_main")?;
|
||||||
vm.invoke(&run_module_as_main, (module,))?;
|
vm.invoke(&run_module_as_main, (module,))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -9,14 +9,13 @@ edition = "2018"
|
|||||||
include = ["src/**/*.rs", "Cargo.toml", "build.rs", "Lib/**/*.py"]
|
include = ["src/**/*.rs", "Cargo.toml", "build.rs", "Lib/**/*.py"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["compile-parse", "threading", "std"]
|
default = ["compile-parse", "threading"]
|
||||||
vm-tracing-logging = []
|
vm-tracing-logging = []
|
||||||
flame-it = ["flame", "flamer"]
|
flame-it = ["flame", "flamer"]
|
||||||
freeze-stdlib = ["rustpython-pylib"]
|
freeze-stdlib = ["rustpython-pylib"]
|
||||||
jit = ["rustpython-jit"]
|
jit = ["rustpython-jit"]
|
||||||
threading = ["rustpython-common/threading"]
|
threading = ["rustpython-common/threading"]
|
||||||
compile-parse = ["rustpython-parser", "rustpython-compiler"]
|
compile-parse = ["rustpython-parser", "rustpython-compiler"]
|
||||||
std = ["rustpython-compiler/std"] # enables compiler-core/std, parser/std, etc
|
|
||||||
|
|
||||||
ssl = ["openssl", "openssl-sys", "openssl-probe"]
|
ssl = ["openssl", "openssl-sys", "openssl-probe"]
|
||||||
|
|
||||||
@@ -35,10 +34,10 @@ num-traits = "0.2.8"
|
|||||||
num-integer = "0.1.41"
|
num-integer = "0.1.41"
|
||||||
num-rational = "0.3"
|
num-rational = "0.3"
|
||||||
num-iter = "0.1.39"
|
num-iter = "0.1.39"
|
||||||
rand = "0.8"
|
rand = { version = "0.7", features = ["wasm-bindgen"] }
|
||||||
rand_core = "0.6"
|
rand_core = "0.5"
|
||||||
getrandom = { version = "0.2", features = ["js"] }
|
getrandom = { version = "0.1", features = ["wasm-bindgen"] }
|
||||||
mt19937 = "2.0"
|
mt19937 = "1.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
rustpython-derive = { path = "../derive", version = "0.1.2" }
|
rustpython-derive = { path = "../derive", version = "0.1.2" }
|
||||||
rustpython-parser = { path = "../parser", optional = true, version = "0.1.2" }
|
rustpython-parser = { path = "../parser", optional = true, version = "0.1.2" }
|
||||||
@@ -48,9 +47,10 @@ rustpython-jit = { path = "../jit", optional = true, version = "0.1.2" }
|
|||||||
rustpython-pylib = { path = "pylib-crate", optional = true, version = "0.1.0" }
|
rustpython-pylib = { path = "pylib-crate", optional = true, version = "0.1.0" }
|
||||||
serde = { version = "1.0.66", features = ["derive"] }
|
serde = { version = "1.0.66", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
byteorder = "1.2.6"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
rustc_version_runtime = "0.1.*"
|
rustc_version_runtime = "0.1.*"
|
||||||
puruspe = "0.1"
|
statrs = "0.12.0"
|
||||||
caseless = "0.2.1"
|
caseless = "0.2.1"
|
||||||
chrono = { version = "0.4", features = ["wasmbind"] }
|
chrono = { version = "0.4", features = ["wasmbind"] }
|
||||||
lexical-core = "0.7"
|
lexical-core = "0.7"
|
||||||
@@ -58,11 +58,12 @@ itertools = "0.9"
|
|||||||
hex = "0.4.0"
|
hex = "0.4.0"
|
||||||
hexf-parse = "0.1.0"
|
hexf-parse = "0.1.0"
|
||||||
indexmap = "1.0.2"
|
indexmap = "1.0.2"
|
||||||
ahash = "0.6"
|
|
||||||
crc = "^1.0.0"
|
crc = "^1.0.0"
|
||||||
|
maplit = "1.0"
|
||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
nix = "0.18"
|
nix = "0.18"
|
||||||
|
arr_macro = "0.1.2"
|
||||||
csv = "1.1.1"
|
csv = "1.1.1"
|
||||||
paste = "0.1"
|
paste = "0.1"
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
@@ -79,7 +80,6 @@ timsort = "0.1"
|
|||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
atty = "0.2"
|
atty = "0.2"
|
||||||
static_assertions = "1.1"
|
static_assertions = "1.1"
|
||||||
half = "1.6"
|
|
||||||
|
|
||||||
## unicode stuff
|
## unicode stuff
|
||||||
unicode_names2 = "0.4"
|
unicode_names2 = "0.4"
|
||||||
@@ -107,7 +107,7 @@ uname = "0.1.1"
|
|||||||
crc32fast = "1.2.0"
|
crc32fast = "1.2.0"
|
||||||
adler32 = "1.0.3"
|
adler32 = "1.0.3"
|
||||||
gethostname = "0.2.0"
|
gethostname = "0.2.0"
|
||||||
socket2 = "0.3.19"
|
socket2 = "0.3"
|
||||||
rustyline = "6.0"
|
rustyline = "6.0"
|
||||||
openssl = { version = "0.10", features = ["vendored"], optional = true }
|
openssl = { version = "0.10", features = ["vendored"], optional = true }
|
||||||
openssl-sys = { version = "0.9", optional = true }
|
openssl-sys = { version = "0.9", optional = true }
|
||||||
|
|||||||
@@ -2,11 +2,16 @@
|
|||||||
//! common way to use this crate is to just add the `"freeze-stdlib"` feature to `rustpython-vm`,
|
//! common way to use this crate is to just add the `"freeze-stdlib"` feature to `rustpython-vm`,
|
||||||
//! in order to automatically include the python part of the standard library into the binary.
|
//! in order to automatically include the python part of the standard library into the binary.
|
||||||
|
|
||||||
|
extern crate self as rustpython_pylib;
|
||||||
|
|
||||||
pub const LIB_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/Lib");
|
pub const LIB_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/Lib");
|
||||||
|
|
||||||
#[cfg(feature = "compiled-bytecode")]
|
#[cfg(feature = "compiled-bytecode")]
|
||||||
use {rustpython_bytecode::FrozenModule, std::collections::HashMap};
|
use {
|
||||||
|
rustpython_bytecode::bytecode::{self, FrozenModule},
|
||||||
|
std::collections::HashMap,
|
||||||
|
};
|
||||||
#[cfg(feature = "compiled-bytecode")]
|
#[cfg(feature = "compiled-bytecode")]
|
||||||
pub fn frozen_stdlib() -> HashMap<String, FrozenModule> {
|
pub fn frozen_stdlib() -> HashMap<String, FrozenModule> {
|
||||||
rustpython_derive::py_freeze!(dir = "Lib", crate_name = "rustpython_bytecode")
|
rustpython_derive::py_freeze!(dir = "Lib", crate_name = "rustpython_pylib")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,15 +9,26 @@ use num_traits::{cast::ToPrimitive, sign::Signed};
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
#[derive(FromArgs)]
|
||||||
pub struct SplitArgs<'s, T: TryFromObject + AnyStrWrapper<'s>> {
|
pub struct SplitArgs<'a, T, S, E>
|
||||||
|
where
|
||||||
|
T: TryFromObject + AnyStrWrapper<S>,
|
||||||
|
S: ?Sized + AnyStr<'a, E>,
|
||||||
|
E: Copy,
|
||||||
|
{
|
||||||
#[pyarg(any, default)]
|
#[pyarg(any, default)]
|
||||||
sep: Option<T>,
|
sep: Option<T>,
|
||||||
#[pyarg(any, default = "-1")]
|
#[pyarg(any, default = "-1")]
|
||||||
maxsplit: isize,
|
maxsplit: isize,
|
||||||
_phantom: std::marker::PhantomData<&'s ()>,
|
_phantom1: std::marker::PhantomData<&'a S>,
|
||||||
|
_phantom2: std::marker::PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s, T: TryFromObject + AnyStrWrapper<'s>> SplitArgs<'s, T> {
|
impl<'a, T, S, E> SplitArgs<'a, T, S, E>
|
||||||
|
where
|
||||||
|
T: TryFromObject + AnyStrWrapper<S>,
|
||||||
|
S: ?Sized + AnyStr<'a, E>,
|
||||||
|
E: Copy,
|
||||||
|
{
|
||||||
pub fn get_value(self, vm: &VirtualMachine) -> PyResult<(Option<T>, isize)> {
|
pub fn get_value(self, vm: &VirtualMachine) -> PyResult<(Option<T>, isize)> {
|
||||||
let sep = if let Some(s) = self.sep {
|
let sep = if let Some(s) = self.sep {
|
||||||
let sep = s.as_ref();
|
let sep = s.as_ref();
|
||||||
@@ -113,9 +124,11 @@ impl StringRange for std::ops::Range<usize> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AnyStrWrapper<'s> {
|
pub trait AnyStrWrapper<S>
|
||||||
type Str: ?Sized + AnyStr<'s>;
|
where
|
||||||
fn as_ref(&self) -> &Self::Str;
|
S: ?Sized,
|
||||||
|
{
|
||||||
|
fn as_ref(&self) -> &S;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AnyStrContainer<S>
|
pub trait AnyStrContainer<S>
|
||||||
@@ -127,23 +140,28 @@ where
|
|||||||
fn push_str(&mut self, s: &S);
|
fn push_str(&mut self, s: &S);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: GATs for `'s` once stabilized
|
pub trait AnyStr<'s, E>
|
||||||
pub trait AnyStr<'s>: 's {
|
where
|
||||||
type Char: Copy;
|
E: Copy,
|
||||||
type Container: AnyStrContainer<Self> + Extend<Self::Char>;
|
Self: 's,
|
||||||
type CharIter: Iterator<Item = char> + 's;
|
Self::Container: AnyStrContainer<Self> + std::iter::Extend<E>,
|
||||||
type ElementIter: Iterator<Item = Self::Char> + 's;
|
Self::CharIter: 's + std::iter::Iterator<Item = char>,
|
||||||
|
Self::ElementIter: 's + std::iter::Iterator<Item = E>,
|
||||||
|
{
|
||||||
|
type Container;
|
||||||
|
type CharIter;
|
||||||
|
type ElementIter;
|
||||||
|
|
||||||
fn element_bytes_len(c: Self::Char) -> usize;
|
fn element_bytes_len(c: E) -> usize;
|
||||||
|
|
||||||
fn to_container(&self) -> Self::Container;
|
fn to_container(&self) -> Self::Container;
|
||||||
fn as_bytes(&self) -> &[u8];
|
fn as_bytes(&self) -> &[u8];
|
||||||
fn as_utf8_str(&self) -> Result<&str, std::str::Utf8Error>;
|
fn as_utf8_str(&self) -> Result<&str, std::str::Utf8Error>;
|
||||||
fn chars(&'s self) -> Self::CharIter;
|
fn chars(&'s self) -> Self::CharIter;
|
||||||
fn elements(&'s self) -> Self::ElementIter;
|
fn elements(&'s self) -> Self::ElementIter;
|
||||||
fn get_bytes(&self, range: std::ops::Range<usize>) -> &Self;
|
fn get_bytes<'a>(&'a self, range: std::ops::Range<usize>) -> &'a Self;
|
||||||
// FIXME: get_chars is expensive for str
|
// FIXME: get_chars is expensive for str
|
||||||
fn get_chars(&self, range: std::ops::Range<usize>) -> &Self;
|
fn get_chars<'a>(&'a self, range: std::ops::Range<usize>) -> &'a Self;
|
||||||
fn bytes_len(&self) -> usize;
|
fn bytes_len(&self) -> usize;
|
||||||
// fn chars_len(&self) -> usize; // cannot access to cache here
|
// fn chars_len(&self) -> usize; // cannot access to cache here
|
||||||
fn is_empty(&self) -> bool;
|
fn is_empty(&self) -> bool;
|
||||||
@@ -157,14 +175,14 @@ pub trait AnyStr<'s>: 's {
|
|||||||
|
|
||||||
fn py_split<T, SP, SN, SW, R>(
|
fn py_split<T, SP, SN, SW, R>(
|
||||||
&self,
|
&self,
|
||||||
args: SplitArgs<'s, T>,
|
args: SplitArgs<'s, T, Self, E>,
|
||||||
vm: &VirtualMachine,
|
vm: &VirtualMachine,
|
||||||
split: SP,
|
split: SP,
|
||||||
splitn: SN,
|
splitn: SN,
|
||||||
splitw: SW,
|
splitw: SW,
|
||||||
) -> PyResult<Vec<R>>
|
) -> PyResult<Vec<R>>
|
||||||
where
|
where
|
||||||
T: TryFromObject + AnyStrWrapper<'s, Str = Self>,
|
T: TryFromObject + AnyStrWrapper<Self>,
|
||||||
SP: Fn(&Self, &Self, &VirtualMachine) -> Vec<R>,
|
SP: Fn(&Self, &Self, &VirtualMachine) -> Vec<R>,
|
||||||
SN: Fn(&Self, &Self, usize, &VirtualMachine) -> Vec<R>,
|
SN: Fn(&Self, &Self, usize, &VirtualMachine) -> Vec<R>,
|
||||||
SW: Fn(&Self, isize, &VirtualMachine) -> Vec<R>,
|
SW: Fn(&Self, isize, &VirtualMachine) -> Vec<R>,
|
||||||
@@ -231,7 +249,7 @@ pub trait AnyStr<'s>: 's {
|
|||||||
func_default: FD,
|
func_default: FD,
|
||||||
) -> &'a Self
|
) -> &'a Self
|
||||||
where
|
where
|
||||||
S: AnyStrWrapper<'s, Str = Self>,
|
S: AnyStrWrapper<Self>,
|
||||||
FC: Fn(&'a Self, &Self) -> &'a Self,
|
FC: Fn(&'a Self, &Self) -> &'a Self,
|
||||||
FD: Fn(&'a Self) -> &'a Self,
|
FD: Fn(&'a Self) -> &'a Self,
|
||||||
{
|
{
|
||||||
@@ -268,7 +286,7 @@ pub trait AnyStr<'s>: 's {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn py_pad(&self, left: usize, right: usize, fillchar: Self::Char) -> Self::Container {
|
fn py_pad(&self, left: usize, right: usize, fillchar: E) -> Self::Container {
|
||||||
let mut u = Self::Container::with_capacity(
|
let mut u = Self::Container::with_capacity(
|
||||||
(left + right) * Self::element_bytes_len(fillchar) + self.bytes_len(),
|
(left + right) * Self::element_bytes_len(fillchar) + self.bytes_len(),
|
||||||
);
|
);
|
||||||
@@ -278,23 +296,23 @@ pub trait AnyStr<'s>: 's {
|
|||||||
u
|
u
|
||||||
}
|
}
|
||||||
|
|
||||||
fn py_center(&self, width: usize, fillchar: Self::Char, len: usize) -> Self::Container {
|
fn py_center(&self, width: usize, fillchar: E, len: usize) -> Self::Container {
|
||||||
let marg = width - len;
|
let marg = width - len;
|
||||||
let left = marg / 2 + (marg & width & 1);
|
let left = marg / 2 + (marg & width & 1);
|
||||||
self.py_pad(left, marg - left, fillchar)
|
self.py_pad(left, marg - left, fillchar)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn py_ljust(&self, width: usize, fillchar: Self::Char, len: usize) -> Self::Container {
|
fn py_ljust(&self, width: usize, fillchar: E, len: usize) -> Self::Container {
|
||||||
self.py_pad(0, width - len, fillchar)
|
self.py_pad(0, width - len, fillchar)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn py_rjust(&self, width: usize, fillchar: Self::Char, len: usize) -> Self::Container {
|
fn py_rjust(&self, width: usize, fillchar: E, len: usize) -> Self::Container {
|
||||||
self.py_pad(width - len, 0, fillchar)
|
self.py_pad(width - len, 0, fillchar)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn py_join<'a>(
|
fn py_join<'a>(
|
||||||
&self,
|
&self,
|
||||||
mut iter: PyIterator<'a, impl AnyStrWrapper<'s, Str = Self> + TryFromObject>,
|
mut iter: PyIterator<'a, impl AnyStrWrapper<Self> + TryFromObject>,
|
||||||
) -> PyResult<Self::Container> {
|
) -> PyResult<Self::Container> {
|
||||||
let mut joined = if let Some(elem) = iter.next() {
|
let mut joined = if let Some(elem) = iter.next() {
|
||||||
elem?.as_ref().to_container()
|
elem?.as_ref().to_container()
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use super::code::PyCodeRef;
|
use super::code::PyCodeRef;
|
||||||
use super::pystr::PyStrRef;
|
|
||||||
use super::pytype::PyTypeRef;
|
use super::pytype::PyTypeRef;
|
||||||
use crate::coroutine::{Coro, Variant};
|
use crate::coroutine::{Coro, Variant};
|
||||||
use crate::exceptions::PyBaseExceptionRef;
|
use crate::exceptions::PyBaseExceptionRef;
|
||||||
use crate::frame::FrameRef;
|
use crate::frame::FrameRef;
|
||||||
use crate::function::OptionalArg;
|
use crate::function::OptionalArg;
|
||||||
use crate::pyobject::{
|
use crate::pyobject::{
|
||||||
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||||
};
|
};
|
||||||
use crate::slots::PyIter;
|
use crate::slots::PyIter;
|
||||||
use crate::vm::VirtualMachine;
|
use crate::vm::VirtualMachine;
|
||||||
@@ -33,27 +32,17 @@ impl PyAsyncGen {
|
|||||||
&self.inner
|
&self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(frame: FrameRef, name: PyStrRef) -> Self {
|
pub fn new(frame: FrameRef, vm: &VirtualMachine) -> PyRef<Self> {
|
||||||
PyAsyncGen {
|
PyAsyncGen {
|
||||||
inner: Coro::new(frame, Variant::AsyncGen, name),
|
inner: Coro::new(frame, Variant::AsyncGen),
|
||||||
running_async: AtomicCell::new(false),
|
running_async: AtomicCell::new(false),
|
||||||
}
|
}
|
||||||
|
.into_ref(vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: fix function names situation
|
||||||
#[pyproperty(magic)]
|
#[pyproperty(magic)]
|
||||||
fn name(&self) -> PyStrRef {
|
fn name(&self) {}
|
||||||
self.inner.name()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pyproperty(magic, setter)]
|
|
||||||
fn set_name(&self, name: PyStrRef) {
|
|
||||||
self.inner.set_name(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethod(magic)]
|
|
||||||
fn repr(zelf: PyRef<Self>) -> String {
|
|
||||||
zelf.inner.repr(zelf.get_id())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethod(name = "__aiter__")]
|
#[pymethod(name = "__aiter__")]
|
||||||
fn aiter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
fn aiter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ use crate::vm::VirtualMachine;
|
|||||||
|
|
||||||
pub struct PyNativeFuncDef {
|
pub struct PyNativeFuncDef {
|
||||||
pub func: PyNativeFunc,
|
pub func: PyNativeFunc,
|
||||||
pub name: PyStrRef,
|
pub name: Option<PyStrRef>,
|
||||||
pub doc: Option<PyStrRef>,
|
pub doc: Option<PyStrRef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PyNativeFuncDef {
|
impl From<PyNativeFunc> for PyNativeFuncDef {
|
||||||
pub fn new(func: PyNativeFunc, name: PyStrRef) -> Self {
|
fn from(func: PyNativeFunc) -> Self {
|
||||||
Self {
|
Self {
|
||||||
func,
|
func,
|
||||||
name,
|
name: None,
|
||||||
doc: None,
|
doc: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,10 +70,19 @@ impl PyValue for PyBuiltinFunction {
|
|||||||
|
|
||||||
impl fmt::Debug for PyBuiltinFunction {
|
impl fmt::Debug for PyBuiltinFunction {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "builtin function {}", self.value.name.borrow_value())
|
let name = match &self.value.name {
|
||||||
|
Some(s) => s.borrow_value(),
|
||||||
|
None => "<unknown name>",
|
||||||
|
};
|
||||||
|
write!(f, "builtin function {}", name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<PyNativeFunc> for PyBuiltinFunction {
|
||||||
|
fn from(value: PyNativeFunc) -> Self {
|
||||||
|
PyNativeFuncDef::from(value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
impl From<PyNativeFuncDef> for PyBuiltinFunction {
|
impl From<PyNativeFuncDef> for PyBuiltinFunction {
|
||||||
fn from(value: PyNativeFuncDef) -> Self {
|
fn from(value: PyNativeFuncDef) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -115,7 +124,7 @@ impl PyBuiltinFunction {
|
|||||||
vm.unwrap_or_none(self.module.clone())
|
vm.unwrap_or_none(self.module.clone())
|
||||||
}
|
}
|
||||||
#[pyproperty(magic)]
|
#[pyproperty(magic)]
|
||||||
fn name(&self) -> PyStrRef {
|
fn name(&self) -> Option<PyStrRef> {
|
||||||
self.value.name.clone()
|
self.value.name.clone()
|
||||||
}
|
}
|
||||||
#[pyproperty(magic)]
|
#[pyproperty(magic)]
|
||||||
@@ -175,7 +184,7 @@ impl Callable for PyBuiltinMethod {
|
|||||||
#[pyimpl(with(SlotDescriptor, Callable))]
|
#[pyimpl(with(SlotDescriptor, Callable))]
|
||||||
impl PyBuiltinMethod {
|
impl PyBuiltinMethod {
|
||||||
#[pyproperty(magic)]
|
#[pyproperty(magic)]
|
||||||
fn name(&self) -> PyStrRef {
|
fn name(&self) -> Option<PyStrRef> {
|
||||||
self.value.name.clone()
|
self.value.name.clone()
|
||||||
}
|
}
|
||||||
#[pyproperty(magic)]
|
#[pyproperty(magic)]
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ pub(crate) fn init(context: &PyContext) {
|
|||||||
PyByteArray::extend_class(context, &context.types.bytearray_type);
|
PyByteArray::extend_class(context, &context.types.bytearray_type);
|
||||||
let bytearray_type = &context.types.bytearray_type;
|
let bytearray_type = &context.types.bytearray_type;
|
||||||
extend_class!(context, bytearray_type, {
|
extend_class!(context, bytearray_type, {
|
||||||
"maketrans" => context.new_method("maketrans", PyBytesInner::maketrans),
|
"maketrans" => context.new_method(PyBytesInner::maketrans),
|
||||||
});
|
});
|
||||||
|
|
||||||
PyByteArrayIterator::extend_class(context, &context.types.bytearray_iterator_type);
|
PyByteArrayIterator::extend_class(context, &context.types.bytearray_iterator_type);
|
||||||
@@ -545,11 +545,11 @@ impl PyByteArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(name = "splitlines")]
|
#[pymethod(name = "splitlines")]
|
||||||
fn splitlines(&self, options: anystr::SplitLinesArgs, vm: &VirtualMachine) -> PyObjectRef {
|
fn splitlines(&self, options: anystr::SplitLinesArgs, vm: &VirtualMachine) -> PyResult {
|
||||||
let lines = self
|
let lines = self
|
||||||
.borrow_value()
|
.borrow_value()
|
||||||
.splitlines(options, |x| vm.ctx.new_bytearray(x.to_vec()));
|
.splitlines(options, |x| vm.ctx.new_bytearray(x.to_vec()));
|
||||||
vm.ctx.new_list(lines)
|
Ok(vm.ctx.new_list(lines))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(name = "zfill")]
|
#[pymethod(name = "zfill")]
|
||||||
@@ -607,8 +607,9 @@ impl PyByteArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(name = "reverse")]
|
#[pymethod(name = "reverse")]
|
||||||
fn reverse(&self) {
|
fn reverse(&self) -> PyResult<()> {
|
||||||
self.borrow_value_mut().elements.reverse();
|
self.borrow_value_mut().elements.reverse();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod]
|
#[pymethod]
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ pub(crate) fn init(context: &PyContext) {
|
|||||||
PyBytes::extend_class(context, &context.types.bytes_type);
|
PyBytes::extend_class(context, &context.types.bytes_type);
|
||||||
let bytes_type = &context.types.bytes_type;
|
let bytes_type = &context.types.bytes_type;
|
||||||
extend_class!(context, bytes_type, {
|
extend_class!(context, bytes_type, {
|
||||||
"maketrans" => context.new_method("maketrans", PyBytesInner::maketrans),
|
"maketrans" => context.new_method(PyBytesInner::maketrans),
|
||||||
});
|
});
|
||||||
PyBytesIterator::extend_class(context, &context.types.bytes_iterator_type);
|
PyBytesIterator::extend_class(context, &context.types.bytes_iterator_type);
|
||||||
}
|
}
|
||||||
@@ -118,8 +118,8 @@ impl PyBytes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(name = "__sizeof__")]
|
#[pymethod(name = "__sizeof__")]
|
||||||
fn sizeof(&self) -> usize {
|
fn sizeof(&self) -> PyResult<usize> {
|
||||||
size_of::<Self>() + self.inner.elements.len() * size_of::<u8>()
|
Ok(size_of::<Self>() + self.inner.elements.len() * size_of::<u8>())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(name = "__add__")]
|
#[pymethod(name = "__add__")]
|
||||||
@@ -387,11 +387,11 @@ impl PyBytes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(name = "splitlines")]
|
#[pymethod(name = "splitlines")]
|
||||||
fn splitlines(&self, options: anystr::SplitLinesArgs, vm: &VirtualMachine) -> PyObjectRef {
|
fn splitlines(&self, options: anystr::SplitLinesArgs, vm: &VirtualMachine) -> PyResult {
|
||||||
let lines = self
|
let lines = self
|
||||||
.inner
|
.inner
|
||||||
.splitlines(options, |x| vm.ctx.new_bytes(x.to_vec()));
|
.splitlines(options, |x| vm.ctx.new_bytes(x.to_vec()));
|
||||||
vm.ctx.new_list(lines)
|
Ok(vm.ctx.new_list(lines))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(name = "zfill")]
|
#[pymethod(name = "zfill")]
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ impl PyCodeRef {
|
|||||||
fn repr(self) -> String {
|
fn repr(self) -> String {
|
||||||
let code = &self.code;
|
let code = &self.code;
|
||||||
format!(
|
format!(
|
||||||
"<code object {} at {:#x} file {:?}, line {}>",
|
"<code object {} at 0x{:x} file {:?}, line {}>",
|
||||||
code.obj_name,
|
code.obj_name,
|
||||||
self.get_id(),
|
self.get_id(),
|
||||||
code.source_path,
|
code.source_path,
|
||||||
@@ -225,7 +225,7 @@ impl PyCodeRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pyproperty]
|
#[pyproperty]
|
||||||
fn co_filename(self) -> PyStrRef {
|
fn co_filename(self) -> String {
|
||||||
self.code.source_path.clone()
|
self.code.source_path.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ impl PyCodeRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pyproperty]
|
#[pyproperty]
|
||||||
fn co_name(self) -> PyStrRef {
|
fn co_name(self) -> String {
|
||||||
self.code.obj_name.clone()
|
self.code.obj_name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,12 +267,6 @@ impl PyCodeRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for PyCode {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
(**self).fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(ctx: &PyContext) {
|
pub fn init(ctx: &PyContext) {
|
||||||
PyCodeRef::extend_class(ctx, &ctx.types.code_type);
|
PyCodeRef::extend_class(ctx, &ctx.types.code_type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ fn try_complex(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<(Compl
|
|||||||
if let Some(complex) = obj.payload_if_subclass::<PyComplex>(vm) {
|
if let Some(complex) = obj.payload_if_subclass::<PyComplex>(vm) {
|
||||||
return Ok(Some((complex.value, true)));
|
return Ok(Some((complex.value, true)));
|
||||||
}
|
}
|
||||||
if let Some(float) = float::try_float_opt(obj, vm)? {
|
if let Some(float) = float::try_float(obj, vm)? {
|
||||||
return Ok(Some((Complex64::new(float, 0.0), false)));
|
return Ok(Some((Complex64::new(float, 0.0), false)));
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use super::pytype::PyTypeRef;
|
|||||||
use crate::coroutine::{Coro, Variant};
|
use crate::coroutine::{Coro, Variant};
|
||||||
use crate::frame::FrameRef;
|
use crate::frame::FrameRef;
|
||||||
use crate::function::OptionalArg;
|
use crate::function::OptionalArg;
|
||||||
use crate::pyobject::{IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||||
use crate::slots::PyIter;
|
use crate::slots::PyIter;
|
||||||
use crate::vm::VirtualMachine;
|
use crate::vm::VirtualMachine;
|
||||||
|
|
||||||
@@ -28,25 +28,17 @@ impl PyCoroutine {
|
|||||||
&self.inner
|
&self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(frame: FrameRef, name: PyStrRef) -> Self {
|
pub fn new(frame: FrameRef, vm: &VirtualMachine) -> PyRef<Self> {
|
||||||
PyCoroutine {
|
PyCoroutine {
|
||||||
inner: Coro::new(frame, Variant::Coroutine, name),
|
inner: Coro::new(frame, Variant::Coroutine),
|
||||||
}
|
}
|
||||||
|
.into_ref(vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: fix function names situation
|
||||||
#[pyproperty(magic)]
|
#[pyproperty(magic)]
|
||||||
fn name(&self) -> PyStrRef {
|
fn name(&self, vm: &VirtualMachine) -> PyObjectRef {
|
||||||
self.inner.name()
|
vm.ctx.none()
|
||||||
}
|
|
||||||
|
|
||||||
#[pyproperty(magic, setter)]
|
|
||||||
fn set_name(&self, name: PyStrRef) {
|
|
||||||
self.inner.set_name(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethod(magic)]
|
|
||||||
fn repr(zelf: PyRef<Self>) -> String {
|
|
||||||
zelf.inner.repr(zelf.get_id())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod]
|
#[pymethod]
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ impl PyDictRef {
|
|||||||
|
|
||||||
/// Take a python dictionary and convert it to attributes.
|
/// Take a python dictionary and convert it to attributes.
|
||||||
pub fn to_attributes(self) -> PyAttributes {
|
pub fn to_attributes(self) -> PyAttributes {
|
||||||
let mut attrs = PyAttributes::default();
|
let mut attrs = PyAttributes::new();
|
||||||
for (key, value) in self {
|
for (key, value) in self {
|
||||||
let key = pystr::clone_value(&key);
|
let key = pystr::clone_value(&key);
|
||||||
attrs.insert(key, value);
|
attrs.insert(key, value);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ impl From<f64> for PyFloat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_float_opt(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<f64>> {
|
pub(crate) fn try_float(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<f64>> {
|
||||||
if let Some(float) = obj.payload_if_exact::<PyFloat>(vm) {
|
if let Some(float) = obj.payload_if_exact::<PyFloat>(vm) {
|
||||||
return Ok(Some(float.value));
|
return Ok(Some(float.value));
|
||||||
}
|
}
|
||||||
@@ -76,11 +76,6 @@ pub fn try_float_opt(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_float(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<f64> {
|
|
||||||
try_float_opt(obj, vm)?
|
|
||||||
.ok_or_else(|| vm.new_type_error(format!("must be real number, not {}", obj.class().name)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn to_op_float(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<f64>> {
|
pub(crate) fn to_op_float(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<f64>> {
|
||||||
let v = if let Some(float) = obj.payload_if_subclass::<PyFloat>(vm) {
|
let v = if let Some(float) = obj.payload_if_subclass::<PyFloat>(vm) {
|
||||||
Some(float.value)
|
Some(float.value)
|
||||||
@@ -181,7 +176,7 @@ impl PyFloat {
|
|||||||
val
|
val
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(f) = try_float_opt(&val, vm)? {
|
if let Some(f) = try_float(&val, vm)? {
|
||||||
f
|
f
|
||||||
} else if let Some(s) = val.payload_if_subclass::<PyStr>(vm) {
|
} else if let Some(s) = val.payload_if_subclass::<PyStr>(vm) {
|
||||||
float_ops::parse_str(s.borrow_value().trim()).ok_or_else(|| {
|
float_ops::parse_str(s.borrow_value().trim()).ok_or_else(|| {
|
||||||
@@ -560,7 +555,7 @@ impl Hashable for PyFloat {
|
|||||||
pub type PyFloatRef = PyRef<PyFloat>;
|
pub type PyFloatRef = PyRef<PyFloat>;
|
||||||
|
|
||||||
// Retrieve inner float value:
|
// Retrieve inner float value:
|
||||||
pub(crate) fn get_value(obj: &PyObjectRef) -> f64 {
|
pub fn get_value(obj: &PyObjectRef) -> f64 {
|
||||||
obj.payload::<PyFloat>().unwrap().value
|
obj.payload::<PyFloat>().unwrap().value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,7 +581,9 @@ impl IntoPyFloat {
|
|||||||
|
|
||||||
impl TryFromObject for IntoPyFloat {
|
impl TryFromObject for IntoPyFloat {
|
||||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||||
let value = try_float(&obj, vm)?;
|
let value = try_float(&obj, vm)?.ok_or_else(|| {
|
||||||
|
vm.new_type_error(format!("must be real number, not {}", obj.class().name))
|
||||||
|
})?;
|
||||||
Ok(IntoPyFloat { value })
|
Ok(IntoPyFloat { value })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ impl FrameRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pyproperty]
|
#[pyproperty]
|
||||||
fn f_lasti(self) -> u32 {
|
fn f_lasti(self) -> usize {
|
||||||
self.lasti()
|
self.lasti()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ pub struct PyFunction {
|
|||||||
closure: Option<PyTupleTyped<PyCellRef>>,
|
closure: Option<PyTupleTyped<PyCellRef>>,
|
||||||
defaults: Option<PyTupleRef>,
|
defaults: Option<PyTupleRef>,
|
||||||
kw_only_defaults: Option<PyDictRef>,
|
kw_only_defaults: Option<PyDictRef>,
|
||||||
name: PyMutex<PyStrRef>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PyFunction {
|
impl PyFunction {
|
||||||
@@ -51,7 +50,6 @@ impl PyFunction {
|
|||||||
defaults: Option<PyTupleRef>,
|
defaults: Option<PyTupleRef>,
|
||||||
kw_only_defaults: Option<PyDictRef>,
|
kw_only_defaults: Option<PyDictRef>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let name = PyMutex::new(code.obj_name.clone());
|
|
||||||
PyFunction {
|
PyFunction {
|
||||||
code,
|
code,
|
||||||
#[cfg(feature = "jit")]
|
#[cfg(feature = "jit")]
|
||||||
@@ -60,7 +58,6 @@ impl PyFunction {
|
|||||||
closure,
|
closure,
|
||||||
defaults,
|
defaults,
|
||||||
kw_only_defaults,
|
kw_only_defaults,
|
||||||
name,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,9 +281,9 @@ impl PyFunction {
|
|||||||
let is_gen = code.flags.contains(bytecode::CodeFlags::IS_GENERATOR);
|
let is_gen = code.flags.contains(bytecode::CodeFlags::IS_GENERATOR);
|
||||||
let is_coro = code.flags.contains(bytecode::CodeFlags::IS_COROUTINE);
|
let is_coro = code.flags.contains(bytecode::CodeFlags::IS_COROUTINE);
|
||||||
match (is_gen, is_coro) {
|
match (is_gen, is_coro) {
|
||||||
(true, false) => Ok(PyGenerator::new(frame, self.name()).into_object(vm)),
|
(true, false) => Ok(PyGenerator::new(frame, vm).into_object()),
|
||||||
(false, true) => Ok(PyCoroutine::new(frame, self.name()).into_object(vm)),
|
(false, true) => Ok(PyCoroutine::new(frame, vm).into_object()),
|
||||||
(true, true) => Ok(PyAsyncGen::new(frame, self.name()).into_object(vm)),
|
(true, true) => Ok(PyAsyncGen::new(frame, vm).into_object()),
|
||||||
(false, false) => vm.run_frame_full(frame),
|
(false, false) => vm.run_frame_full(frame),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -324,21 +321,6 @@ impl PyFunction {
|
|||||||
self.globals.clone()
|
self.globals.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyproperty(magic)]
|
|
||||||
fn name(&self) -> PyStrRef {
|
|
||||||
self.name.lock().clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pyproperty(magic, setter)]
|
|
||||||
fn set_name(&self, name: PyStrRef) {
|
|
||||||
*self.name.lock() = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethod(magic)]
|
|
||||||
fn repr(zelf: PyRef<Self>) -> String {
|
|
||||||
format!("<function {} at {:#x}>", zelf.name.lock(), zelf.get_id())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "jit")]
|
#[cfg(feature = "jit")]
|
||||||
#[pymethod(magic)]
|
#[pymethod(magic)]
|
||||||
fn jit(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<()> {
|
fn jit(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<()> {
|
||||||
|
|||||||
@@ -3,12 +3,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::code::PyCodeRef;
|
use super::code::PyCodeRef;
|
||||||
use super::pystr::PyStrRef;
|
|
||||||
use super::pytype::PyTypeRef;
|
use super::pytype::PyTypeRef;
|
||||||
use crate::coroutine::{Coro, Variant};
|
use crate::coroutine::{Coro, Variant};
|
||||||
use crate::frame::FrameRef;
|
use crate::frame::FrameRef;
|
||||||
use crate::function::OptionalArg;
|
use crate::function::OptionalArg;
|
||||||
use crate::pyobject::{IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||||
use crate::slots::PyIter;
|
use crate::slots::PyIter;
|
||||||
use crate::vm::VirtualMachine;
|
use crate::vm::VirtualMachine;
|
||||||
|
|
||||||
@@ -30,25 +29,17 @@ impl PyGenerator {
|
|||||||
&self.inner
|
&self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(frame: FrameRef, name: PyStrRef) -> Self {
|
pub fn new(frame: FrameRef, vm: &VirtualMachine) -> PyRef<Self> {
|
||||||
PyGenerator {
|
PyGenerator {
|
||||||
inner: Coro::new(frame, Variant::Gen, name),
|
inner: Coro::new(frame, Variant::Gen),
|
||||||
}
|
}
|
||||||
|
.into_ref(vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: fix function names situation
|
||||||
#[pyproperty(magic)]
|
#[pyproperty(magic)]
|
||||||
fn name(&self) -> PyStrRef {
|
fn name(&self, vm: &VirtualMachine) -> PyObjectRef {
|
||||||
self.inner.name()
|
vm.ctx.none()
|
||||||
}
|
|
||||||
|
|
||||||
#[pyproperty(magic, setter)]
|
|
||||||
fn set_name(&self, name: PyStrRef) {
|
|
||||||
self.inner.set_name(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethod(magic)]
|
|
||||||
fn repr(zelf: PyRef<Self>) -> String {
|
|
||||||
zelf.inner.repr(zelf.get_id())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod]
|
#[pymethod]
|
||||||
|
|||||||
@@ -570,8 +570,11 @@ impl PyInt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(name = "as_integer_ratio")]
|
#[pymethod(name = "as_integer_ratio")]
|
||||||
fn as_integer_ratio(&self, vm: &VirtualMachine) -> (PyObjectRef, BigInt) {
|
fn as_integer_ratio(&self, vm: &VirtualMachine) -> PyResult {
|
||||||
(vm.ctx.new_bigint(&self.value), BigInt::one())
|
Ok(vm.ctx.new_tuple(vec![
|
||||||
|
vm.ctx.new_bigint(&self.value),
|
||||||
|
vm.ctx.new_bigint(&BigInt::one()),
|
||||||
|
]))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod]
|
#[pymethod]
|
||||||
@@ -885,7 +888,7 @@ fn detect_base(c: &u8) -> Option<u32> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve inner int value:
|
// Retrieve inner int value:
|
||||||
pub(crate) fn get_value(obj: &PyObjectRef) -> &BigInt {
|
pub fn get_value(obj: &PyObjectRef) -> &BigInt {
|
||||||
&obj.payload::<PyInt>().unwrap().value
|
&obj.payload::<PyInt>().unwrap().value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -908,7 +911,7 @@ pub(crate) fn try_int(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<BigInt
|
|||||||
vm.to_repr(obj)?,
|
vm.to_repr(obj)?,
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// test for strings and bytes
|
// test for strings and bytes
|
||||||
if let Some(s) = obj.downcast_ref::<PyStr>() {
|
if let Some(s) = obj.downcast_ref::<PyStr>() {
|
||||||
|
|||||||
@@ -117,13 +117,13 @@ impl PyList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(name = "__iadd__")]
|
#[pymethod(name = "__iadd__")]
|
||||||
fn iadd(zelf: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
fn iadd(zelf: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||||
if let Ok(new_elements) = vm.extract_elements(&other) {
|
if let Ok(new_elements) = vm.extract_elements(&other) {
|
||||||
let mut e = new_elements;
|
let mut e = new_elements;
|
||||||
zelf.borrow_value_mut().append(&mut e);
|
zelf.borrow_value_mut().append(&mut e);
|
||||||
zelf.into_object()
|
Ok(zelf.into_object())
|
||||||
} else {
|
} else {
|
||||||
vm.ctx.not_implemented()
|
Ok(vm.ctx.not_implemented())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,11 +103,11 @@ mod decl {
|
|||||||
#[derive(FromArgs)]
|
#[derive(FromArgs)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
struct CompileArgs {
|
struct CompileArgs {
|
||||||
#[pyarg(any)]
|
#[pyarg(positional)]
|
||||||
source: Either<PyStrRef, PyBytesRef>,
|
source: Either<PyStrRef, PyBytesRef>,
|
||||||
#[pyarg(any)]
|
#[pyarg(positional)]
|
||||||
filename: PyStrRef,
|
filename: PyStrRef,
|
||||||
#[pyarg(any)]
|
#[pyarg(positional)]
|
||||||
mode: PyStrRef,
|
mode: PyStrRef,
|
||||||
#[pyarg(any, optional)]
|
#[pyarg(any, optional)]
|
||||||
flags: OptionalArg<PyIntRef>,
|
flags: OptionalArg<PyIntRef>,
|
||||||
@@ -320,8 +320,8 @@ mod decl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
fn globals(vm: &VirtualMachine) -> PyDictRef {
|
fn globals(vm: &VirtualMachine) -> PyResult<PyDictRef> {
|
||||||
vm.current_globals().clone()
|
Ok(vm.current_globals().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
@@ -341,9 +341,15 @@ mod decl {
|
|||||||
// builtin_help
|
// builtin_help
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
fn hex(number: PyIntRef) -> String {
|
fn hex(number: PyIntRef, vm: &VirtualMachine) -> PyResult {
|
||||||
let n = number.borrow_value();
|
let n = number.borrow_value();
|
||||||
format!("{:#x}", n)
|
let s = if n.is_negative() {
|
||||||
|
format!("-0x{:x}", -n)
|
||||||
|
} else {
|
||||||
|
format!("0x{:x}", n)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(vm.ctx.new_str(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ use crossbeam_utils::atomic::AtomicCell;
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use num_traits::{One, Signed, ToPrimitive, Zero};
|
use num_traits::{One, Signed, ToPrimitive, Zero};
|
||||||
use rustpython_common::borrow::BorrowValue;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BufferRef(Box<dyn Buffer>);
|
pub struct BufferRef(Box<dyn Buffer>);
|
||||||
@@ -500,7 +499,7 @@ impl PyMemoryView {
|
|||||||
.get_pos(i)
|
.get_pos(i)
|
||||||
.ok_or_else(|| vm.new_index_error("index out of range".to_owned()))?;
|
.ok_or_else(|| vm.new_index_error("index out of range".to_owned()))?;
|
||||||
let itemsize = zelf.options.itemsize;
|
let itemsize = zelf.options.itemsize;
|
||||||
let data = zelf.format_spec.pack(vec![value], vm)?;
|
let data = zelf.format_spec.pack(&[value], vm)?;
|
||||||
zelf.obj_bytes_mut()[i..i + itemsize].copy_from_slice(&data);
|
zelf.obj_bytes_mut()[i..i + itemsize].copy_from_slice(&data);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -655,7 +654,6 @@ impl PyMemoryView {
|
|||||||
fn toreadonly(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
|
fn toreadonly(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
|
||||||
zelf.try_not_released(vm)?;
|
zelf.try_not_released(vm)?;
|
||||||
let buffer = BufferRef(Box::new(zelf.clone()));
|
let buffer = BufferRef(Box::new(zelf.clone()));
|
||||||
zelf.exports.fetch_add(1);
|
|
||||||
Ok(PyMemoryView {
|
Ok(PyMemoryView {
|
||||||
obj: zelf.obj.clone(),
|
obj: zelf.obj.clone(),
|
||||||
buffer,
|
buffer,
|
||||||
@@ -675,9 +673,9 @@ impl PyMemoryView {
|
|||||||
#[pymethod(magic)]
|
#[pymethod(magic)]
|
||||||
fn repr(zelf: PyRef<Self>) -> String {
|
fn repr(zelf: PyRef<Self>) -> String {
|
||||||
if zelf.released.load() {
|
if zelf.released.load() {
|
||||||
format!("<released memory at {:#x}>", zelf.get_id())
|
format!("<released memory at 0x{:x}>", zelf.get_id())
|
||||||
} else {
|
} else {
|
||||||
format!("<memory at {:#x}>", zelf.get_id())
|
format!("<memory at 0x{:x}>", zelf.get_id())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -705,48 +703,6 @@ impl PyMemoryView {
|
|||||||
bytes_to_hex(bytes, sep, bytes_per_sep, vm)
|
bytes_to_hex(bytes, sep, bytes_per_sep, vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: support cast shape
|
|
||||||
#[pymethod]
|
|
||||||
fn cast(zelf: PyRef<Self>, format: PyStrRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
|
|
||||||
zelf.try_not_released(vm)?;
|
|
||||||
if !zelf.options.contiguous {
|
|
||||||
return Err(vm.new_type_error(
|
|
||||||
"memoryview: casts are restricted to C-contiguous views".to_owned(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let format_spec = Self::parse_format(format.borrow_value(), vm)?;
|
|
||||||
let itemsize = format_spec.size();
|
|
||||||
let bytelen = zelf.options.len * zelf.options.itemsize;
|
|
||||||
|
|
||||||
if bytelen % itemsize != 0 {
|
|
||||||
return Err(
|
|
||||||
vm.new_type_error("memoryview: length is not a multiple of itemsize".to_owned())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let buffer = BufferRef(Box::new(zelf.clone()));
|
|
||||||
zelf.exports.fetch_add(1);
|
|
||||||
|
|
||||||
Ok(PyMemoryView {
|
|
||||||
obj: zelf.obj.clone(),
|
|
||||||
buffer,
|
|
||||||
options: BufferOptions {
|
|
||||||
itemsize,
|
|
||||||
len: bytelen / itemsize,
|
|
||||||
format: format.to_string().into(),
|
|
||||||
..zelf.options.clone()
|
|
||||||
},
|
|
||||||
released: AtomicCell::new(false),
|
|
||||||
stop: zelf.stop + itemsize - zelf.options.itemsize,
|
|
||||||
exports: AtomicCell::new(0),
|
|
||||||
format_spec,
|
|
||||||
hash: OnceCell::new(),
|
|
||||||
..*zelf
|
|
||||||
}
|
|
||||||
.into_ref(vm))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eq(zelf: &PyRef<Self>, other: &PyObjectRef, vm: &VirtualMachine) -> PyResult<bool> {
|
fn eq(zelf: &PyRef<Self>, other: &PyObjectRef, vm: &VirtualMachine) -> PyResult<bool> {
|
||||||
if zelf.is(other) {
|
if zelf.is(other) {
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
|
|||||||
@@ -51,7 +51,12 @@ impl PyModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(magic)]
|
#[pymethod(magic)]
|
||||||
fn init(zelf: PyRef<Self>, name: PyStrRef, doc: OptionalOption<PyStrRef>, vm: &VirtualMachine) {
|
fn init(
|
||||||
|
zelf: PyRef<Self>,
|
||||||
|
name: PyStrRef,
|
||||||
|
doc: OptionalOption<PyStrRef>,
|
||||||
|
vm: &VirtualMachine,
|
||||||
|
) -> PyResult<()> {
|
||||||
debug_assert!(crate::pyobject::TypeProtocol::class(zelf.as_object())
|
debug_assert!(crate::pyobject::TypeProtocol::class(zelf.as_object())
|
||||||
.slots
|
.slots
|
||||||
.flags
|
.flags
|
||||||
@@ -62,6 +67,7 @@ impl PyModule {
|
|||||||
name.into_object(),
|
name.into_object(),
|
||||||
doc.flatten().into_pyobject(vm),
|
doc.flatten().into_pyobject(vm),
|
||||||
);
|
);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(zelf: PyRef<Self>, vm: &VirtualMachine) -> Option<String> {
|
fn name(zelf: PyRef<Self>, vm: &VirtualMachine) -> Option<String> {
|
||||||
@@ -76,7 +82,7 @@ impl PyModule {
|
|||||||
|
|
||||||
#[pymethod(magic)]
|
#[pymethod(magic)]
|
||||||
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
|
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
|
||||||
let importlib = vm.import("_frozen_importlib", None, 0)?;
|
let importlib = vm.import("_frozen_importlib", &[], 0)?;
|
||||||
let module_repr = vm.get_attribute(importlib, "_module_repr")?;
|
let module_repr = vm.get_attribute(importlib, "_module_repr")?;
|
||||||
vm.invoke(&module_repr, (zelf,))
|
vm.invoke(&module_repr, (zelf,))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,12 +168,12 @@ impl PyBaseObject {
|
|||||||
|
|
||||||
#[pymethod(magic)]
|
#[pymethod(magic)]
|
||||||
fn repr(zelf: PyObjectRef) -> String {
|
fn repr(zelf: PyObjectRef) -> String {
|
||||||
format!("<{} object at {:#x}>", zelf.class().name, zelf.get_id())
|
format!("<{} object at 0x{:x}>", zelf.class().name, zelf.get_id())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclassmethod(magic)]
|
#[pyclassmethod(magic)]
|
||||||
fn subclasshook(_args: FuncArgs, vm: &VirtualMachine) -> PyObjectRef {
|
fn subclasshook(_args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||||
vm.ctx.not_implemented()
|
Ok(vm.ctx.not_implemented())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclassmethod(magic)]
|
#[pyclassmethod(magic)]
|
||||||
@@ -314,11 +314,11 @@ pub fn init(context: &PyContext) {
|
|||||||
|
|
||||||
fn common_reduce(obj: PyObjectRef, proto: usize, vm: &VirtualMachine) -> PyResult {
|
fn common_reduce(obj: PyObjectRef, proto: usize, vm: &VirtualMachine) -> PyResult {
|
||||||
if proto >= 2 {
|
if proto >= 2 {
|
||||||
let reducelib = vm.import("__reducelib", None, 0)?;
|
let reducelib = vm.import("__reducelib", &[], 0)?;
|
||||||
let reduce_2 = vm.get_attribute(reducelib, "reduce_2")?;
|
let reduce_2 = vm.get_attribute(reducelib, "reduce_2")?;
|
||||||
vm.invoke(&reduce_2, (obj,))
|
vm.invoke(&reduce_2, (obj,))
|
||||||
} else {
|
} else {
|
||||||
let copyreg = vm.import("copyreg", None, 0)?;
|
let copyreg = vm.import("copyreg", &[], 0)?;
|
||||||
let reduce_ex = vm.get_attribute(copyreg, "_reduce_ex")?;
|
let reduce_ex = vm.get_attribute(copyreg, "_reduce_ex")?;
|
||||||
vm.invoke(&reduce_ex, (obj, proto))
|
vm.invoke(&reduce_ex, (obj, proto))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ pub(crate) fn init(context: &PyContext) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// Retrieve inner int value:
|
// Retrieve inner int value:
|
||||||
pub(crate) fn get_value(obj: &PyObjectRef) -> bool {
|
pub fn get_value(obj: &PyObjectRef) -> bool {
|
||||||
!obj.payload::<PyInt>().unwrap().borrow_value().is_zero()
|
!obj.payload::<PyInt>().unwrap().borrow_value().is_zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,14 +95,12 @@ impl fmt::Display for PyStr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TryIntoRef<PyStr> for String {
|
impl TryIntoRef<PyStr> for String {
|
||||||
#[inline]
|
|
||||||
fn try_into_ref(self, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>> {
|
fn try_into_ref(self, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>> {
|
||||||
Ok(PyStr::from(self).into_ref(vm))
|
Ok(PyStr::from(self).into_ref(vm))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryIntoRef<PyStr> for &str {
|
impl TryIntoRef<PyStr> for &str {
|
||||||
#[inline]
|
|
||||||
fn try_into_ref(self, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>> {
|
fn try_into_ref(self, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>> {
|
||||||
Ok(PyStr::from(self).into_ref(vm))
|
Ok(PyStr::from(self).into_ref(vm))
|
||||||
}
|
}
|
||||||
@@ -572,8 +570,8 @@ impl PyStr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod(name = "__rmod__")]
|
#[pymethod(name = "__rmod__")]
|
||||||
fn rmod(&self, _values: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
fn rmod(&self, _values: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||||
vm.ctx.not_implemented()
|
Ok(vm.ctx.not_implemented())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod]
|
#[pymethod]
|
||||||
@@ -876,7 +874,7 @@ impl PyStr {
|
|||||||
fillchar: OptionalArg<PyStrRef>,
|
fillchar: OptionalArg<PyStrRef>,
|
||||||
vm: &VirtualMachine,
|
vm: &VirtualMachine,
|
||||||
) -> PyResult<String> {
|
) -> PyResult<String> {
|
||||||
self._pad(width, fillchar, AnyStr::py_center, vm)
|
self._pad(width, fillchar, AnyStr::<char>::py_center, vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod]
|
#[pymethod]
|
||||||
@@ -886,7 +884,7 @@ impl PyStr {
|
|||||||
fillchar: OptionalArg<PyStrRef>,
|
fillchar: OptionalArg<PyStrRef>,
|
||||||
vm: &VirtualMachine,
|
vm: &VirtualMachine,
|
||||||
) -> PyResult<String> {
|
) -> PyResult<String> {
|
||||||
self._pad(width, fillchar, AnyStr::py_ljust, vm)
|
self._pad(width, fillchar, AnyStr::<char>::py_ljust, vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod]
|
#[pymethod]
|
||||||
@@ -896,7 +894,7 @@ impl PyStr {
|
|||||||
fillchar: OptionalArg<PyStrRef>,
|
fillchar: OptionalArg<PyStrRef>,
|
||||||
vm: &VirtualMachine,
|
vm: &VirtualMachine,
|
||||||
) -> PyResult<String> {
|
) -> PyResult<String> {
|
||||||
self._pad(width, fillchar, AnyStr::py_rjust, vm)
|
self._pad(width, fillchar, AnyStr::<char>::py_rjust, vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethod]
|
#[pymethod]
|
||||||
@@ -904,7 +902,7 @@ impl PyStr {
|
|||||||
let tab_stop = args.tabsize();
|
let tab_stop = args.tabsize();
|
||||||
let mut expanded_str = String::with_capacity(self.value.len());
|
let mut expanded_str = String::with_capacity(self.value.len());
|
||||||
let mut tab_size = tab_stop;
|
let mut tab_size = tab_stop;
|
||||||
let mut col_count = 0usize;
|
let mut col_count = 0 as usize;
|
||||||
for ch in self.value.chars() {
|
for ch in self.value.chars() {
|
||||||
match ch {
|
match ch {
|
||||||
'\t' => {
|
'\t' => {
|
||||||
@@ -1157,7 +1155,7 @@ impl TryFromObject for std::ffi::OsString {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type SplitArgs<'a> = anystr::SplitArgs<'a, PyStrRef>;
|
type SplitArgs<'a> = anystr::SplitArgs<'a, PyStrRef, str, char>;
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
#[derive(FromArgs)]
|
||||||
pub struct FindArgs {
|
pub struct FindArgs {
|
||||||
@@ -1183,11 +1181,11 @@ pub fn init(ctx: &PyContext) {
|
|||||||
PyStrReverseIterator::extend_class(ctx, &ctx.types.str_reverseiterator_type);
|
PyStrReverseIterator::extend_class(ctx, &ctx.types.str_reverseiterator_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clone_value(obj: &PyObjectRef) -> String {
|
pub fn clone_value(obj: &PyObjectRef) -> String {
|
||||||
String::from(obj.payload::<PyStr>().unwrap().borrow_value())
|
String::from(obj.payload::<PyStr>().unwrap().borrow_value())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn borrow_value(obj: &PyObjectRef) -> &str {
|
pub fn borrow_value(obj: &PyObjectRef) -> &str {
|
||||||
&obj.payload::<PyStr>().unwrap().value
|
&obj.payload::<PyStr>().unwrap().value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1338,8 +1336,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> AnyStrWrapper<'s> for PyStrRef {
|
impl AnyStrWrapper<str> for PyStrRef {
|
||||||
type Str = str;
|
|
||||||
fn as_ref(&self) -> &str {
|
fn as_ref(&self) -> &str {
|
||||||
&*self.value
|
&*self.value
|
||||||
}
|
}
|
||||||
@@ -1359,8 +1356,7 @@ impl AnyStrContainer<str> for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> AnyStr<'s> for str {
|
impl<'s> AnyStr<'s, char> for str {
|
||||||
type Char = char;
|
|
||||||
type Container = String;
|
type Container = String;
|
||||||
type CharIter = std::str::Chars<'s>;
|
type CharIter = std::str::Chars<'s>;
|
||||||
type ElementIter = std::str::Chars<'s>;
|
type ElementIter = std::str::Chars<'s>;
|
||||||
@@ -1389,11 +1385,11 @@ impl<'s> AnyStr<'s> for str {
|
|||||||
str::chars(self)
|
str::chars(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_bytes(&self, range: std::ops::Range<usize>) -> &Self {
|
fn get_bytes<'a>(&'a self, range: std::ops::Range<usize>) -> &'a Self {
|
||||||
&self[range]
|
&self[range]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_chars(&self, range: std::ops::Range<usize>) -> &Self {
|
fn get_chars<'a>(&'a self, range: std::ops::Range<usize>) -> &'a Self {
|
||||||
rustpython_common::str::get_chars(self, range)
|
rustpython_common::str::get_chars(self, range)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use crate::common::lock::{
|
|||||||
PyMappedRwLockReadGuard, PyRwLock, PyRwLockReadGuard, PyRwLockUpgradableReadGuard,
|
PyMappedRwLockReadGuard, PyRwLock, PyRwLockReadGuard, PyRwLockUpgradableReadGuard,
|
||||||
PyRwLockWriteGuard,
|
PyRwLockWriteGuard,
|
||||||
};
|
};
|
||||||
use std::collections::HashSet;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use super::classmethod::PyClassMethod;
|
use super::classmethod::PyClassMethod;
|
||||||
@@ -133,7 +133,7 @@ impl PyType {
|
|||||||
|
|
||||||
pub fn get_attributes(&self) -> PyAttributes {
|
pub fn get_attributes(&self) -> PyAttributes {
|
||||||
// Gather all members here:
|
// Gather all members here:
|
||||||
let mut attributes = PyAttributes::default();
|
let mut attributes = PyAttributes::new();
|
||||||
|
|
||||||
for bc in self.iter_mro().rev() {
|
for bc in self.iter_mro().rev() {
|
||||||
for (name, value) in bc.attributes.read().iter() {
|
for (name, value) in bc.attributes.read().iter() {
|
||||||
@@ -791,7 +791,7 @@ pub fn new(
|
|||||||
name: &str,
|
name: &str,
|
||||||
base: PyTypeRef,
|
base: PyTypeRef,
|
||||||
bases: Vec<PyTypeRef>,
|
bases: Vec<PyTypeRef>,
|
||||||
attrs: PyAttributes,
|
attrs: HashMap<String, PyObjectRef>,
|
||||||
mut slots: PyTypeSlots,
|
mut slots: PyTypeSlots,
|
||||||
) -> Result<PyTypeRef, String> {
|
) -> Result<PyTypeRef, String> {
|
||||||
// Check for duplicates in bases.
|
// Check for duplicates in bases.
|
||||||
@@ -864,7 +864,7 @@ fn calculate_meta_class(
|
|||||||
Ok(winner)
|
Ok(winner)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn best_base(bases: &[PyTypeRef], vm: &VirtualMachine) -> PyResult<PyTypeRef> {
|
fn best_base<'a>(bases: &'a [PyTypeRef], vm: &VirtualMachine) -> PyResult<PyTypeRef> {
|
||||||
// let mut base = None;
|
// let mut base = None;
|
||||||
// let mut winner = None;
|
// let mut winner = None;
|
||||||
|
|
||||||
@@ -914,7 +914,8 @@ fn best_base(bases: &[PyTypeRef], vm: &VirtualMachine) -> PyResult<PyTypeRef> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::{linearise_mro, new};
|
||||||
|
use super::{HashMap, IdProtocol, PyContext, PyTypeRef};
|
||||||
|
|
||||||
fn map_ids(obj: Result<Vec<PyTypeRef>, String>) -> Result<Vec<usize>, String> {
|
fn map_ids(obj: Result<Vec<PyTypeRef>, String>) -> Result<Vec<usize>, String> {
|
||||||
Ok(obj?.into_iter().map(|x| x.get_id()).collect())
|
Ok(obj?.into_iter().map(|x| x.get_id()).collect())
|
||||||
@@ -931,7 +932,7 @@ mod tests {
|
|||||||
"A",
|
"A",
|
||||||
object.clone(),
|
object.clone(),
|
||||||
vec![object.clone()],
|
vec![object.clone()],
|
||||||
PyAttributes::default(),
|
HashMap::new(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -940,7 +941,7 @@ mod tests {
|
|||||||
"B",
|
"B",
|
||||||
object.clone(),
|
object.clone(),
|
||||||
vec![object.clone()],
|
vec![object.clone()],
|
||||||
PyAttributes::default(),
|
HashMap::new(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::builtins::pytype::PyTypeRef;
|
use crate::builtins::pytype::PyTypeRef;
|
||||||
use crate::frame::FrameRef;
|
use crate::frame::FrameRef;
|
||||||
use crate::pyobject::{BorrowValue, PyClassImpl, PyContext, PyRef, PyValue};
|
use crate::pyobject::{PyClassImpl, PyContext, PyRef, PyValue};
|
||||||
use crate::vm::VirtualMachine;
|
use crate::vm::VirtualMachine;
|
||||||
|
|
||||||
#[pyclass(module = false, name = "traceback")]
|
#[pyclass(module = false, name = "traceback")]
|
||||||
@@ -8,7 +8,7 @@ use crate::vm::VirtualMachine;
|
|||||||
pub struct PyTraceback {
|
pub struct PyTraceback {
|
||||||
pub next: Option<PyTracebackRef>, // TODO: Make mutable
|
pub next: Option<PyTracebackRef>, // TODO: Make mutable
|
||||||
pub frame: FrameRef,
|
pub frame: FrameRef,
|
||||||
pub lasti: u32,
|
pub lasti: usize,
|
||||||
pub lineno: usize,
|
pub lineno: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ impl PyValue for PyTraceback {
|
|||||||
|
|
||||||
#[pyimpl]
|
#[pyimpl]
|
||||||
impl PyTraceback {
|
impl PyTraceback {
|
||||||
pub fn new(next: Option<PyRef<Self>>, frame: FrameRef, lasti: u32, lineno: usize) -> Self {
|
pub fn new(next: Option<PyRef<Self>>, frame: FrameRef, lasti: usize, lineno: usize) -> Self {
|
||||||
PyTraceback {
|
PyTraceback {
|
||||||
next,
|
next,
|
||||||
frame,
|
frame,
|
||||||
@@ -37,7 +37,7 @@ impl PyTraceback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pyproperty(name = "tb_lasti")]
|
#[pyproperty(name = "tb_lasti")]
|
||||||
fn lasti(&self) -> u32 {
|
fn lasti(&self) -> usize {
|
||||||
self.lasti
|
self.lasti
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ impl PyTraceback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PyTracebackRef {
|
impl PyTracebackRef {
|
||||||
pub fn iter(&self) -> impl Iterator<Item = PyTracebackRef> {
|
pub fn iter<'a>(&'a self) -> impl Iterator<Item = PyTracebackRef> + 'a {
|
||||||
std::iter::successors(Some(self.clone()), |tb| tb.next.clone())
|
std::iter::successors(Some(self.clone()), |tb| tb.next.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,9 +67,9 @@ impl serde::Serialize for PyTraceback {
|
|||||||
use serde::ser::SerializeStruct;
|
use serde::ser::SerializeStruct;
|
||||||
|
|
||||||
let mut struc = s.serialize_struct("PyTraceback", 3)?;
|
let mut struc = s.serialize_struct("PyTraceback", 3)?;
|
||||||
struc.serialize_field("name", self.frame.code.obj_name.borrow_value())?;
|
struc.serialize_field("name", &self.frame.code.obj_name)?;
|
||||||
struc.serialize_field("lineno", &self.lineno)?;
|
struc.serialize_field("lineno", &self.lineno)?;
|
||||||
struc.serialize_field("filename", self.frame.code.source_path.borrow_value())?;
|
struc.serialize_field("filename", &self.frame.code.source_path)?;
|
||||||
struc.end()
|
struc.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -317,7 +317,6 @@ impl<T: TransmuteFromObject> TryFromObject for PyTupleTyped<T> {
|
|||||||
|
|
||||||
impl<'a, T: TransmuteFromObject + 'a> BorrowValue<'a> for PyTupleTyped<T> {
|
impl<'a, T: TransmuteFromObject + 'a> BorrowValue<'a> for PyTupleTyped<T> {
|
||||||
type Borrowed = &'a [T];
|
type Borrowed = &'a [T];
|
||||||
#[inline]
|
|
||||||
fn borrow_value(&'a self) -> Self::Borrowed {
|
fn borrow_value(&'a self) -> Self::Borrowed {
|
||||||
unsafe { &*(self.tuple.borrow_value() as *const [PyObjectRef] as *const [T]) }
|
unsafe { &*(self.tuple.borrow_value() as *const [PyObjectRef] as *const [T]) }
|
||||||
}
|
}
|
||||||
@@ -328,17 +327,3 @@ impl<T: TransmuteFromObject + fmt::Debug> fmt::Debug for PyTupleTyped<T> {
|
|||||||
self.borrow_value().fmt(f)
|
self.borrow_value().fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TransmuteFromObject> From<PyTupleTyped<T>> for PyTupleRef {
|
|
||||||
#[inline]
|
|
||||||
fn from(tup: PyTupleTyped<T>) -> Self {
|
|
||||||
tup.tuple
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: TransmuteFromObject> IntoPyObject for PyTupleTyped<T> {
|
|
||||||
#[inline]
|
|
||||||
fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {
|
|
||||||
self.tuple.into_object()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ impl ByteInnerTranslateOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ByteInnerSplitOptions<'a> = anystr::SplitArgs<'a, PyBytesInner>;
|
pub type ByteInnerSplitOptions<'a> = anystr::SplitArgs<'a, PyBytesInner, [u8], u8>;
|
||||||
|
|
||||||
#[allow(clippy::len_without_is_empty)]
|
#[allow(clippy::len_without_is_empty)]
|
||||||
impl PyBytesInner {
|
impl PyBytesInner {
|
||||||
@@ -468,7 +468,7 @@ impl PyBytesInner {
|
|||||||
options: ByteInnerPaddingOptions,
|
options: ByteInnerPaddingOptions,
|
||||||
vm: &VirtualMachine,
|
vm: &VirtualMachine,
|
||||||
) -> PyResult<Vec<u8>> {
|
) -> PyResult<Vec<u8>> {
|
||||||
self._pad(options, AnyStr::py_center, vm)
|
self._pad(options, AnyStr::<u8>::py_center, vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ljust(
|
pub fn ljust(
|
||||||
@@ -476,7 +476,7 @@ impl PyBytesInner {
|
|||||||
options: ByteInnerPaddingOptions,
|
options: ByteInnerPaddingOptions,
|
||||||
vm: &VirtualMachine,
|
vm: &VirtualMachine,
|
||||||
) -> PyResult<Vec<u8>> {
|
) -> PyResult<Vec<u8>> {
|
||||||
self._pad(options, AnyStr::py_ljust, vm)
|
self._pad(options, AnyStr::<u8>::py_ljust, vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rjust(
|
pub fn rjust(
|
||||||
@@ -484,7 +484,7 @@ impl PyBytesInner {
|
|||||||
options: ByteInnerPaddingOptions,
|
options: ByteInnerPaddingOptions,
|
||||||
vm: &VirtualMachine,
|
vm: &VirtualMachine,
|
||||||
) -> PyResult<Vec<u8>> {
|
) -> PyResult<Vec<u8>> {
|
||||||
self._pad(options, AnyStr::py_rjust, vm)
|
self._pad(options, AnyStr::<u8>::py_rjust, vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn count(&self, options: ByteInnerFindOptions, vm: &VirtualMachine) -> PyResult<usize> {
|
pub fn count(&self, options: ByteInnerFindOptions, vm: &VirtualMachine) -> PyResult<usize> {
|
||||||
@@ -938,8 +938,7 @@ pub trait ByteOr: ToPrimitive {
|
|||||||
|
|
||||||
impl ByteOr for BigInt {}
|
impl ByteOr for BigInt {}
|
||||||
|
|
||||||
impl<'s> AnyStrWrapper<'s> for PyBytesInner {
|
impl AnyStrWrapper<[u8]> for PyBytesInner {
|
||||||
type Str = [u8];
|
|
||||||
fn as_ref(&self) -> &[u8] {
|
fn as_ref(&self) -> &[u8] {
|
||||||
&self.elements
|
&self.elements
|
||||||
}
|
}
|
||||||
@@ -961,8 +960,7 @@ impl AnyStrContainer<[u8]> for Vec<u8> {
|
|||||||
|
|
||||||
const ASCII_WHITESPACES: [u8; 6] = [0x20, 0x09, 0x0a, 0x0c, 0x0d, 0x0b];
|
const ASCII_WHITESPACES: [u8; 6] = [0x20, 0x09, 0x0a, 0x0c, 0x0d, 0x0b];
|
||||||
|
|
||||||
impl<'s> AnyStr<'s> for [u8] {
|
impl<'s> AnyStr<'s, u8> for [u8] {
|
||||||
type Char = u8;
|
|
||||||
type Container = Vec<u8>;
|
type Container = Vec<u8>;
|
||||||
type CharIter = bstr::Chars<'s>;
|
type CharIter = bstr::Chars<'s>;
|
||||||
type ElementIter = std::iter::Copied<std::slice::Iter<'s, u8>>;
|
type ElementIter = std::iter::Copied<std::slice::Iter<'s, u8>>;
|
||||||
@@ -991,11 +989,11 @@ impl<'s> AnyStr<'s> for [u8] {
|
|||||||
self.iter().copied()
|
self.iter().copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_bytes(&self, range: std::ops::Range<usize>) -> &Self {
|
fn get_bytes<'a>(&'a self, range: std::ops::Range<usize>) -> &'a Self {
|
||||||
&self[range]
|
&self[range]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_chars(&self, range: std::ops::Range<usize>) -> &Self {
|
fn get_chars<'a>(&'a self, range: std::ops::Range<usize>) -> &'a Self {
|
||||||
&self[range]
|
&self[range]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use crate::builtins::{PyStrRef, PyTypeRef};
|
use crate::builtins::pytype::PyTypeRef;
|
||||||
use crate::exceptions::{self, PyBaseExceptionRef};
|
use crate::exceptions::{self, PyBaseExceptionRef};
|
||||||
use crate::frame::{ExecutionResult, FrameRef};
|
use crate::frame::{ExecutionResult, FrameRef};
|
||||||
use crate::pyobject::{PyObjectRef, PyResult, TypeProtocol};
|
use crate::pyobject::{PyObjectRef, PyResult, TypeProtocol};
|
||||||
use crate::vm::VirtualMachine;
|
use crate::vm::VirtualMachine;
|
||||||
|
|
||||||
use crate::common::lock::PyMutex;
|
use crate::common::lock::PyRwLock;
|
||||||
use crossbeam_utils::atomic::AtomicCell;
|
use crossbeam_utils::atomic::AtomicCell;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
@@ -37,20 +37,20 @@ pub struct Coro {
|
|||||||
frame: FrameRef,
|
frame: FrameRef,
|
||||||
pub closed: AtomicCell<bool>,
|
pub closed: AtomicCell<bool>,
|
||||||
running: AtomicCell<bool>,
|
running: AtomicCell<bool>,
|
||||||
exceptions: PyMutex<Vec<PyBaseExceptionRef>>,
|
exceptions: PyRwLock<Vec<PyBaseExceptionRef>>,
|
||||||
|
started: AtomicCell<bool>,
|
||||||
variant: Variant,
|
variant: Variant,
|
||||||
name: PyMutex<PyStrRef>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Coro {
|
impl Coro {
|
||||||
pub fn new(frame: FrameRef, variant: Variant, name: PyStrRef) -> Self {
|
pub fn new(frame: FrameRef, variant: Variant) -> Self {
|
||||||
Coro {
|
Coro {
|
||||||
frame,
|
frame,
|
||||||
closed: AtomicCell::new(false),
|
closed: AtomicCell::new(false),
|
||||||
running: AtomicCell::new(false),
|
running: AtomicCell::new(false),
|
||||||
exceptions: PyMutex::new(vec![]),
|
exceptions: PyRwLock::new(vec![]),
|
||||||
|
started: AtomicCell::new(false),
|
||||||
variant,
|
variant,
|
||||||
name: PyMutex::new(name),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,20 +65,21 @@ impl Coro {
|
|||||||
where
|
where
|
||||||
F: FnOnce(FrameRef) -> PyResult<ExecutionResult>,
|
F: FnOnce(FrameRef) -> PyResult<ExecutionResult>,
|
||||||
{
|
{
|
||||||
if self.running.compare_exchange(false, true).is_err() {
|
self.running.store(true);
|
||||||
return Err(vm.new_value_error(format!("{} already executing", self.variant.name())));
|
let curr_exception_stack_len = vm.exceptions.borrow().len();
|
||||||
}
|
vm.exceptions
|
||||||
let curr_exception_stack_len;
|
.borrow_mut()
|
||||||
{
|
.append(&mut self.exceptions.write());
|
||||||
let mut vm_excs = vm.exceptions.borrow_mut();
|
|
||||||
curr_exception_stack_len = vm_excs.len();
|
|
||||||
vm_excs.append(&mut self.exceptions.lock());
|
|
||||||
}
|
|
||||||
let result = vm.with_frame(self.frame.clone(), func);
|
let result = vm.with_frame(self.frame.clone(), func);
|
||||||
self.exceptions
|
std::mem::swap(
|
||||||
.lock()
|
&mut *self.exceptions.write(),
|
||||||
.extend(vm.exceptions.borrow_mut().drain(curr_exception_stack_len..));
|
&mut vm
|
||||||
|
.exceptions
|
||||||
|
.borrow_mut()
|
||||||
|
.split_off(curr_exception_stack_len),
|
||||||
|
);
|
||||||
self.running.store(false);
|
self.running.store(false);
|
||||||
|
self.started.store(true);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,16 +87,12 @@ impl Coro {
|
|||||||
if self.closed.load() {
|
if self.closed.load() {
|
||||||
return Err(vm.new_exception_empty(self.variant.stop_iteration(vm)));
|
return Err(vm.new_exception_empty(self.variant.stop_iteration(vm)));
|
||||||
}
|
}
|
||||||
let value = if self.frame.lasti() > 0 {
|
if !self.started.load() && !vm.is_none(&value) {
|
||||||
Some(value)
|
|
||||||
} else if !vm.is_none(&value) {
|
|
||||||
return Err(vm.new_type_error(format!(
|
return Err(vm.new_type_error(format!(
|
||||||
"can't send non-None value to a just-started {}",
|
"can't send non-None value to a just-started {}",
|
||||||
self.variant.name()
|
self.variant.name()
|
||||||
)));
|
)));
|
||||||
} else {
|
}
|
||||||
None
|
|
||||||
};
|
|
||||||
let result = self.run_with_context(vm, |f| f.resume(value, vm));
|
let result = self.run_with_context(vm, |f| f.resume(value, vm));
|
||||||
self.maybe_close(&result);
|
self.maybe_close(&result);
|
||||||
match result {
|
match result {
|
||||||
@@ -156,6 +153,9 @@ impl Coro {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn started(&self) -> bool {
|
||||||
|
self.started.load()
|
||||||
|
}
|
||||||
pub fn running(&self) -> bool {
|
pub fn running(&self) -> bool {
|
||||||
self.running.load()
|
self.running.load()
|
||||||
}
|
}
|
||||||
@@ -165,19 +165,8 @@ impl Coro {
|
|||||||
pub fn frame(&self) -> FrameRef {
|
pub fn frame(&self) -> FrameRef {
|
||||||
self.frame.clone()
|
self.frame.clone()
|
||||||
}
|
}
|
||||||
pub fn name(&self) -> PyStrRef {
|
pub fn name(&self) -> String {
|
||||||
self.name.lock().clone()
|
self.frame.code.obj_name.clone()
|
||||||
}
|
|
||||||
pub fn set_name(&self, name: PyStrRef) {
|
|
||||||
*self.name.lock() = name;
|
|
||||||
}
|
|
||||||
pub fn repr(&self, id: usize) -> String {
|
|
||||||
format!(
|
|
||||||
"<{} object {} at {:#x}>",
|
|
||||||
self.variant.name(),
|
|
||||||
self.name.lock(),
|
|
||||||
id
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -240,13 +240,13 @@ fn write_traceback_entry<W: Write>(
|
|||||||
output: &mut W,
|
output: &mut W,
|
||||||
tb_entry: &PyTracebackRef,
|
tb_entry: &PyTracebackRef,
|
||||||
) -> Result<(), W::Error> {
|
) -> Result<(), W::Error> {
|
||||||
let filename = tb_entry.frame.code.source_path.borrow_value();
|
let filename = tb_entry.frame.code.source_path.to_owned();
|
||||||
writeln!(
|
writeln!(
|
||||||
output,
|
output,
|
||||||
r##" File "{}", line {}, in {}"##,
|
r##" File "{}", line {}, in {}"##,
|
||||||
filename, tb_entry.lineno, tb_entry.frame.code.obj_name
|
filename, tb_entry.lineno, tb_entry.frame.code.obj_name
|
||||||
)?;
|
)?;
|
||||||
print_source_line(output, filename, tb_entry.lineno)?;
|
print_source_line(output, &filename, tb_entry.lineno)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -660,7 +660,7 @@ impl ExceptionZoo {
|
|||||||
});
|
});
|
||||||
|
|
||||||
extend_class!(ctx, &excs.import_error, {
|
extend_class!(ctx, &excs.import_error, {
|
||||||
"__init__" => ctx.new_method("__init__", import_error_init),
|
"__init__" => ctx.new_method(import_error_init),
|
||||||
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
|
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -669,7 +669,7 @@ impl ExceptionZoo {
|
|||||||
});
|
});
|
||||||
|
|
||||||
extend_class!(ctx, &excs.key_error, {
|
extend_class!(ctx, &excs.key_error, {
|
||||||
"__str__" => ctx.new_method("__str__", key_error_str),
|
"__str__" => ctx.new_method(key_error_str),
|
||||||
});
|
});
|
||||||
|
|
||||||
extend_class!(ctx, &excs.unicode_decode_error, {
|
extend_class!(ctx, &excs.unicode_decode_error, {
|
||||||
|
|||||||
561
vm/src/frame.rs
561
vm/src/frame.rs
File diff suppressed because it is too large
Load Diff
@@ -19,10 +19,8 @@ pub fn map_frozen<'a>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_module_inits(
|
pub fn get_module_inits(vm: &VirtualMachine) -> HashMap<String, code::FrozenModule> {
|
||||||
vm: &VirtualMachine,
|
let mut modules = HashMap::new();
|
||||||
) -> HashMap<String, code::FrozenModule, ahash::RandomState> {
|
|
||||||
let mut modules = HashMap::default();
|
|
||||||
|
|
||||||
macro_rules! ext_modules {
|
macro_rules! ext_modules {
|
||||||
($($t:tt)*) => {
|
($($t:tt)*) => {
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ use crate::pyobject::{
|
|||||||
};
|
};
|
||||||
use crate::vm::VirtualMachine;
|
use crate::vm::VirtualMachine;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use itertools::Itertools;
|
|
||||||
use result_like::impl_option_like;
|
use result_like::impl_option_like;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
|
|
||||||
@@ -98,24 +98,15 @@ impl FuncArgs {
|
|||||||
Self { args, kwargs }
|
Self { args, kwargs }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_kwargs_names<A, KW>(mut args: A, kwarg_names: KW) -> Self
|
pub fn with_kwargs_names(mut args: Vec<PyObjectRef>, kwarg_names: Vec<String>) -> Self {
|
||||||
where
|
|
||||||
A: ExactSizeIterator<Item = PyObjectRef>,
|
|
||||||
KW: ExactSizeIterator<Item = String>,
|
|
||||||
{
|
|
||||||
// last `kwarg_names.len()` elements of args in order of appearance in the call signature
|
// last `kwarg_names.len()` elements of args in order of appearance in the call signature
|
||||||
let total_argc = args.len();
|
let kwarg_values = args.drain((args.len() - kwarg_names.len())..);
|
||||||
let kwargc = kwarg_names.len();
|
|
||||||
let posargc = total_argc - kwargc;
|
|
||||||
|
|
||||||
let posargs = args.by_ref().take(posargc).collect();
|
let mut kwargs = IndexMap::new();
|
||||||
|
for (name, value) in kwarg_names.iter().zip(kwarg_values) {
|
||||||
let kwargs = kwarg_names.zip_eq(args).collect::<IndexMap<_, _>>();
|
kwargs.insert(name.clone(), value);
|
||||||
|
|
||||||
FuncArgs {
|
|
||||||
args: posargs,
|
|
||||||
kwargs,
|
|
||||||
}
|
}
|
||||||
|
FuncArgs { args, kwargs }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepend_arg(&mut self, item: PyObjectRef) {
|
pub fn prepend_arg(&mut self, item: PyObjectRef) {
|
||||||
@@ -177,7 +168,9 @@ impl FuncArgs {
|
|||||||
self.kwargs.swap_remove(name)
|
self.kwargs.swap_remove(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remaining_keywords(&mut self) -> impl Iterator<Item = (String, PyObjectRef)> + '_ {
|
pub fn remaining_keywords<'a>(
|
||||||
|
&'a mut self,
|
||||||
|
) -> impl Iterator<Item = (String, PyObjectRef)> + 'a {
|
||||||
self.kwargs.drain(..)
|
self.kwargs.drain(..)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,9 +317,9 @@ impl<T> KwArgs<T> {
|
|||||||
self.0.remove(name)
|
self.0.remove(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T> std::iter::FromIterator<(String, T)> for KwArgs<T> {
|
impl<T> From<HashMap<String, T>> for KwArgs<T> {
|
||||||
fn from_iter<I: IntoIterator<Item = (String, T)>>(iter: I) -> Self {
|
fn from(kwargs: HashMap<String, T>) -> Self {
|
||||||
KwArgs(iter.into_iter().collect())
|
KwArgs(kwargs.into_iter().collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T> Default for KwArgs<T> {
|
impl<T> Default for KwArgs<T> {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use crate::builtins::{code, list};
|
|||||||
#[cfg(feature = "rustpython-compiler")]
|
#[cfg(feature = "rustpython-compiler")]
|
||||||
use crate::compile;
|
use crate::compile;
|
||||||
use crate::exceptions::PyBaseExceptionRef;
|
use crate::exceptions::PyBaseExceptionRef;
|
||||||
use crate::pyobject::{BorrowValue, ItemProtocol, PyResult, PyValue, TryFromObject, TypeProtocol};
|
use crate::pyobject::{ItemProtocol, PyResult, PyValue, TryFromObject, TypeProtocol};
|
||||||
use crate::scope::Scope;
|
use crate::scope::Scope;
|
||||||
use crate::version::get_git_revision;
|
use crate::version::get_git_revision;
|
||||||
use crate::vm::{InitParameter, VirtualMachine};
|
use crate::vm::{InitParameter, VirtualMachine};
|
||||||
@@ -36,7 +36,7 @@ pub(crate) fn init_importlib(
|
|||||||
let install_external = vm.get_attribute(importlib, "_install_external_importers")?;
|
let install_external = vm.get_attribute(importlib, "_install_external_importers")?;
|
||||||
vm.invoke(&install_external, ())?;
|
vm.invoke(&install_external, ())?;
|
||||||
// Set pyc magic number to commit hash. Should be changed when bytecode will be more stable.
|
// Set pyc magic number to commit hash. Should be changed when bytecode will be more stable.
|
||||||
let importlib_external = vm.import("_frozen_importlib_external", None, 0)?;
|
let importlib_external = vm.import("_frozen_importlib_external", &[], 0)?;
|
||||||
let mut magic = get_git_revision().into_bytes();
|
let mut magic = get_git_revision().into_bytes();
|
||||||
magic.truncate(4);
|
magic.truncate(4);
|
||||||
if magic.len() != 4 {
|
if magic.len() != 4 {
|
||||||
@@ -44,7 +44,7 @@ pub(crate) fn init_importlib(
|
|||||||
}
|
}
|
||||||
vm.set_attr(&importlib_external, "MAGIC_NUMBER", vm.ctx.new_bytes(magic))?;
|
vm.set_attr(&importlib_external, "MAGIC_NUMBER", vm.ctx.new_bytes(magic))?;
|
||||||
let zipimport_res = (|| -> PyResult<()> {
|
let zipimport_res = (|| -> PyResult<()> {
|
||||||
let zipimport = vm.import("zipimport", None, 0)?;
|
let zipimport = vm.import("zipimport", &[], 0)?;
|
||||||
let zipimporter = vm.get_attribute(zipimport, "zipimporter")?;
|
let zipimporter = vm.get_attribute(zipimport, "zipimporter")?;
|
||||||
let path_hooks = vm.get_attribute(vm.sys_module.clone(), "path_hooks")?;
|
let path_hooks = vm.get_attribute(vm.sys_module.clone(), "path_hooks")?;
|
||||||
let path_hooks = list::PyListRef::try_from_object(vm, path_hooks)?;
|
let path_hooks = list::PyListRef::try_from_object(vm, path_hooks)?;
|
||||||
@@ -139,12 +139,12 @@ fn remove_importlib_frames_inner(
|
|||||||
return (None, false);
|
return (None, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
let file_name = traceback.frame.code.source_path.borrow_value();
|
let file_name = &traceback.frame.code.source_path;
|
||||||
|
|
||||||
let (inner_tb, mut now_in_importlib) =
|
let (inner_tb, mut now_in_importlib) =
|
||||||
remove_importlib_frames_inner(vm, traceback.next.clone(), always_trim);
|
remove_importlib_frames_inner(vm, traceback.next.clone(), always_trim);
|
||||||
if file_name == "_frozen_importlib" || file_name == "_frozen_importlib_external" {
|
if file_name == "_frozen_importlib" || file_name == "_frozen_importlib_external" {
|
||||||
if traceback.frame.code.obj_name.borrow_value() == "_call_with_frames_removed" {
|
if traceback.frame.code.obj_name == "_call_with_frames_removed" {
|
||||||
now_in_importlib = true;
|
now_in_importlib = true;
|
||||||
}
|
}
|
||||||
if always_trim || now_in_importlib {
|
if always_trim || now_in_importlib {
|
||||||
|
|||||||
@@ -12,7 +12,10 @@
|
|||||||
#![allow(clippy::module_inception)]
|
#![allow(clippy::module_inception)]
|
||||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustPython/RustPython/master/logo.png")]
|
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustPython/RustPython/master/logo.png")]
|
||||||
#![doc(html_root_url = "https://docs.rs/rustpython-vm/")]
|
#![doc(html_root_url = "https://docs.rs/rustpython-vm/")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(
|
||||||
|
target_os = "redox",
|
||||||
|
feature(matches_macro, proc_macro_hygiene, result_map_or)
|
||||||
|
)]
|
||||||
|
|
||||||
#[cfg(feature = "flame-it")]
|
#[cfg(feature = "flame-it")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@@ -22,6 +25,8 @@ extern crate flamer;
|
|||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate maplit;
|
||||||
// extern crate env_logger;
|
// extern crate env_logger;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@@ -72,7 +77,7 @@ mod vm;
|
|||||||
|
|
||||||
// pub use self::pyobject::Executor;
|
// pub use self::pyobject::Executor;
|
||||||
pub use self::vm::{InitParameter, Interpreter, PySettings, VirtualMachine};
|
pub use self::vm::{InitParameter, Interpreter, PySettings, VirtualMachine};
|
||||||
pub use rustpython_bytecode as bytecode;
|
pub use rustpython_bytecode::*;
|
||||||
pub use rustpython_common as common;
|
pub use rustpython_common as common;
|
||||||
#[cfg(feature = "rustpython-compiler")]
|
#[cfg(feature = "rustpython-compiler")]
|
||||||
pub use rustpython_compiler as compile;
|
pub use rustpython_compiler as compile;
|
||||||
|
|||||||
@@ -1,3 +1,16 @@
|
|||||||
|
#[macro_export]
|
||||||
|
macro_rules! no_kwargs {
|
||||||
|
( $vm: ident, $args:ident ) => {
|
||||||
|
// Zero-arg case
|
||||||
|
if $args.kwargs.len() != 0 {
|
||||||
|
return Err($vm.new_type_error(format!(
|
||||||
|
"Expected no keyword arguments (got: {})",
|
||||||
|
$args.kwargs.len()
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! py_module {
|
macro_rules! py_module {
|
||||||
( $vm:expr, $module_name:expr, { $($name:expr => $value:expr),* $(,)? }) => {{
|
( $vm:expr, $module_name:expr, { $($name:expr => $value:expr),* $(,)? }) => {{
|
||||||
@@ -228,9 +241,9 @@ macro_rules! named_function {
|
|||||||
#[allow(unused_variables)] // weird lint, something to do with paste probably
|
#[allow(unused_variables)] // weird lint, something to do with paste probably
|
||||||
let ctx: &$crate::pyobject::PyContext = &$ctx;
|
let ctx: &$crate::pyobject::PyContext = &$ctx;
|
||||||
$crate::__exports::paste::expr! {
|
$crate::__exports::paste::expr! {
|
||||||
ctx.make_funcdef(
|
ctx.new_function_named(
|
||||||
stringify!($module),
|
|
||||||
[<$module _ $func>],
|
[<$module _ $func>],
|
||||||
|
stringify!($module).to_owned(),
|
||||||
)
|
)
|
||||||
.into_function()
|
.into_function()
|
||||||
.with_module(ctx.new_str(stringify!($func).to_owned()))
|
.with_module(ctx.new_str(stringify!($func).to_owned()))
|
||||||
@@ -256,21 +269,3 @@ cfg_if::cfg_if! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A modified version of the hashmap! macro from the maplit crate
|
|
||||||
macro_rules! hashmap {
|
|
||||||
(@single $($x:tt)*) => (());
|
|
||||||
(@count $($rest:expr),*) => (<[()]>::len(&[$(hashmap!(@single $rest)),*]));
|
|
||||||
|
|
||||||
(hasher=$hasher:expr, $($key:expr => $value:expr,)+) => { hashmap!(hasher=$hasher, $($key => $value),+) };
|
|
||||||
(hasher=$hasher:expr, $($key:expr => $value:expr),*) => {
|
|
||||||
{
|
|
||||||
let _cap = hashmap!(@count $($key),*);
|
|
||||||
let mut _map = ::std::collections::HashMap::with_capacity_and_hasher(_cap, $hasher);
|
|
||||||
$(
|
|
||||||
let _ = _map.insert($key, $value);
|
|
||||||
)*
|
|
||||||
_map
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -30,25 +30,6 @@ impl Write for PyWriter<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_all(
|
|
||||||
mut buf: &[u8],
|
|
||||||
mut write: impl FnMut(&[u8]) -> io::Result<usize>,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
while !buf.is_empty() {
|
|
||||||
match write(buf) {
|
|
||||||
Ok(0) => {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::WriteZero,
|
|
||||||
"failed to write whole buffer",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
Ok(n) => buf = &buf[n..],
|
|
||||||
Err(e) => return Err(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn file_readline(obj: &PyObjectRef, size: Option<usize>, vm: &VirtualMachine) -> PyResult {
|
pub fn file_readline(obj: &PyObjectRef, size: Option<usize>, vm: &VirtualMachine) -> PyResult {
|
||||||
let args = size.map_or_else(Vec::new, |size| vec![vm.ctx.new_int(size)]);
|
let args = size.map_or_else(Vec::new, |size| vec![vm.ctx.new_int(size)]);
|
||||||
let ret = vm.call_method(obj, "readline", args)?;
|
let ret = vm.call_method(obj, "readline", args)?;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ pub type PyResult<T = PyObjectRef> = Result<T, PyBaseExceptionRef>; // A valid v
|
|||||||
/// For attributes we do not use a dict, but a hashmap. This is probably
|
/// For attributes we do not use a dict, but a hashmap. This is probably
|
||||||
/// faster, unordered, and only supports strings as keys.
|
/// faster, unordered, and only supports strings as keys.
|
||||||
/// TODO: class attributes should maintain insertion order (use IndexMap here)
|
/// TODO: class attributes should maintain insertion order (use IndexMap here)
|
||||||
pub type PyAttributes = HashMap<String, PyObjectRef, ahash::RandomState>;
|
pub type PyAttributes = HashMap<String, PyObjectRef>;
|
||||||
|
|
||||||
// TODO: remove this impl
|
// TODO: remove this impl
|
||||||
impl fmt::Display for PyObjectRef {
|
impl fmt::Display for PyObjectRef {
|
||||||
@@ -133,9 +133,8 @@ impl PyContext {
|
|||||||
|
|
||||||
let string_cache = Dict::default();
|
let string_cache = Dict::default();
|
||||||
|
|
||||||
let new_str = PyRef::new_ref(pystr::PyStr::from("__new__"), types.str_type.clone(), None);
|
|
||||||
let tp_new_wrapper = create_object(
|
let tp_new_wrapper = create_object(
|
||||||
PyNativeFuncDef::new(pytype::tp_new_wrapper.into_func(), new_str).into_function(),
|
PyNativeFuncDef::from(pytype::tp_new_wrapper.into_func()).into_function(),
|
||||||
&types.builtin_function_or_method_type,
|
&types.builtin_function_or_method_type,
|
||||||
)
|
)
|
||||||
.into_object();
|
.into_object();
|
||||||
@@ -274,44 +273,45 @@ impl PyContext {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_function<F, FKind>(&self, f: F) -> PyObjectRef
|
||||||
|
where
|
||||||
|
F: IntoPyNativeFunc<FKind>,
|
||||||
|
{
|
||||||
|
PyNativeFuncDef::from(f.into_func()).build_function(self)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn new_stringref(&self, s: String) -> pystr::PyStrRef {
|
pub(crate) fn new_stringref(&self, s: String) -> pystr::PyStrRef {
|
||||||
PyRef::new_ref(pystr::PyStr::from(s), self.types.str_type.clone(), None)
|
PyRef::new_ref(pystr::PyStr::from(s), self.types.str_type.clone(), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
pub fn new_function_named<F, FKind>(&self, f: F, name: String) -> PyNativeFuncDef
|
||||||
pub fn make_funcdef<F, FKind>(&self, name: impl Into<String>, f: F) -> PyNativeFuncDef
|
|
||||||
where
|
where
|
||||||
F: IntoPyNativeFunc<FKind>,
|
F: IntoPyNativeFunc<FKind>,
|
||||||
{
|
{
|
||||||
PyNativeFuncDef::new(f.into_func(), self.new_stringref(name.into()))
|
let mut f = PyNativeFuncDef::from(f.into_func());
|
||||||
|
f.name = Some(self.new_stringref(name));
|
||||||
|
f
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_function<F, FKind>(&self, name: impl Into<String>, f: F) -> PyObjectRef
|
pub fn new_method<F, FKind>(&self, f: F) -> PyObjectRef
|
||||||
where
|
where
|
||||||
F: IntoPyNativeFunc<FKind>,
|
F: IntoPyNativeFunc<FKind>,
|
||||||
{
|
{
|
||||||
self.make_funcdef(name, f).build_function(self)
|
PyNativeFuncDef::from(f.into_func()).build_method(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_method<F, FKind>(&self, name: impl Into<String>, f: F) -> PyObjectRef
|
pub fn new_classmethod<F, FKind>(&self, f: F) -> PyObjectRef
|
||||||
where
|
where
|
||||||
F: IntoPyNativeFunc<FKind>,
|
F: IntoPyNativeFunc<FKind>,
|
||||||
{
|
{
|
||||||
self.make_funcdef(name, f).build_method(self)
|
PyNativeFuncDef::from(f.into_func()).build_classmethod(self)
|
||||||
}
|
}
|
||||||
|
pub fn new_staticmethod<F, FKind>(&self, f: F) -> PyObjectRef
|
||||||
pub fn new_classmethod<F, FKind>(&self, name: impl Into<String>, f: F) -> PyObjectRef
|
|
||||||
where
|
|
||||||
F: IntoPyNativeFunc<FKind>,
|
|
||||||
{
|
|
||||||
self.make_funcdef(name, f).build_classmethod(self)
|
|
||||||
}
|
|
||||||
pub fn new_staticmethod<F, FKind>(&self, name: impl Into<String>, f: F) -> PyObjectRef
|
|
||||||
where
|
where
|
||||||
F: IntoPyNativeFunc<FKind>,
|
F: IntoPyNativeFunc<FKind>,
|
||||||
{
|
{
|
||||||
PyObject::new(
|
PyObject::new(
|
||||||
PyStaticMethod::from(self.new_method(name, f)),
|
PyStaticMethod::from(self.new_method(f)),
|
||||||
self.types.staticmethod_type.clone(),
|
self.types.staticmethod_type.clone(),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
@@ -763,7 +763,6 @@ pub trait TryIntoRef<T: PyObjectPayload> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PyObjectPayload> TryIntoRef<T> for PyRef<T> {
|
impl<T: PyObjectPayload> TryIntoRef<T> for PyRef<T> {
|
||||||
#[inline]
|
|
||||||
fn try_into_ref(self, _vm: &VirtualMachine) -> PyResult<PyRef<T>> {
|
fn try_into_ref(self, _vm: &VirtualMachine) -> PyResult<PyRef<T>> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
@@ -1104,11 +1103,9 @@ pub trait PyClassImpl: PyClassDef {
|
|||||||
fn extend_slots(slots: &mut PyTypeSlots);
|
fn extend_slots(slots: &mut PyTypeSlots);
|
||||||
|
|
||||||
fn make_slots() -> PyTypeSlots {
|
fn make_slots() -> PyTypeSlots {
|
||||||
let mut slots = PyTypeSlots {
|
let mut slots = PyTypeSlots::default();
|
||||||
flags: Self::TP_FLAGS,
|
slots.flags = Self::TP_FLAGS;
|
||||||
name: PyRwLock::new(Some(Self::TP_NAME.to_owned())),
|
slots.name = PyRwLock::new(Some(Self::TP_NAME.to_owned()));
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
Self::extend_slots(&mut slots);
|
Self::extend_slots(&mut slots);
|
||||||
slots
|
slots
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ impl Drop for PyObjectRef {
|
|||||||
Ok(v) => println!("{}", v.to_string()),
|
Ok(v) => println!("{}", v.to_string()),
|
||||||
Err(_) => println!("{}", del_method.class().name),
|
Err(_) => println!("{}", del_method.class().name),
|
||||||
}
|
}
|
||||||
let tb_module = vm.import("traceback", None, 0).unwrap();
|
let tb_module = vm.import("traceback", &[], 0).unwrap();
|
||||||
// TODO: set exc traceback
|
// TODO: set exc traceback
|
||||||
let print_stack = vm.get_attribute(tb_module, "print_stack").unwrap();
|
let print_stack = vm.get_attribute(tb_module, "print_stack").unwrap();
|
||||||
vm.invoke(&print_stack, ()).unwrap();
|
vm.invoke(&print_stack, ()).unwrap();
|
||||||
@@ -489,7 +489,7 @@ pub(crate) fn init_type_hierarchy() -> (PyTypeRef, PyTypeRef) {
|
|||||||
bases: vec![],
|
bases: vec![],
|
||||||
mro: vec![],
|
mro: vec![],
|
||||||
subclasses: PyRwLock::default(),
|
subclasses: PyRwLock::default(),
|
||||||
attributes: PyRwLock::new(PyAttributes::default()),
|
attributes: PyRwLock::new(PyAttributes::new()),
|
||||||
slots: PyType::make_slots(),
|
slots: PyType::make_slots(),
|
||||||
};
|
};
|
||||||
let object_payload = PyType {
|
let object_payload = PyType {
|
||||||
@@ -498,7 +498,7 @@ pub(crate) fn init_type_hierarchy() -> (PyTypeRef, PyTypeRef) {
|
|||||||
bases: vec![],
|
bases: vec![],
|
||||||
mro: vec![],
|
mro: vec![],
|
||||||
subclasses: PyRwLock::default(),
|
subclasses: PyRwLock::default(),
|
||||||
attributes: PyRwLock::new(PyAttributes::default()),
|
attributes: PyRwLock::new(PyAttributes::new()),
|
||||||
slots: object::PyBaseObject::make_slots(),
|
slots: object::PyBaseObject::make_slots(),
|
||||||
};
|
};
|
||||||
let type_type = PyRc::new(partially_init!(
|
let type_type = PyRc::new(partially_init!(
|
||||||
|
|||||||
@@ -391,7 +391,7 @@ impl TryFromObject for SequenceIndex {
|
|||||||
// Use PySliceableSequence::wrap_index for implementors
|
// Use PySliceableSequence::wrap_index for implementors
|
||||||
pub(crate) fn wrap_index(p: isize, len: usize) -> Option<usize> {
|
pub(crate) fn wrap_index(p: isize, len: usize) -> Option<usize> {
|
||||||
let neg = p.is_negative();
|
let neg = p.is_negative();
|
||||||
let p = p.wrapping_abs() as usize;
|
let p = p.abs().to_usize()?;
|
||||||
if neg {
|
if neg {
|
||||||
len.checked_sub(p)
|
len.checked_sub(p)
|
||||||
} else if p >= len {
|
} else if p >= len {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use crate::builtins::bytes::PyBytesRef;
|
use crate::builtins::bytes::PyBytesRef;
|
||||||
use crate::builtins::code::PyCode;
|
use crate::builtins::code::PyCode;
|
||||||
use crate::builtins::module::PyModuleRef;
|
use crate::builtins::module::PyModuleRef;
|
||||||
use crate::builtins::pystr::{self, PyStr, PyStrRef};
|
use crate::builtins::pystr;
|
||||||
|
use crate::builtins::pystr::PyStrRef;
|
||||||
use crate::import;
|
use crate::import;
|
||||||
use crate::pyobject::{BorrowValue, ItemProtocol, PyObjectRef, PyResult, PyValue};
|
use crate::pyobject::{BorrowValue, ItemProtocol, PyObjectRef, PyResult};
|
||||||
use crate::vm::VirtualMachine;
|
use crate::vm::VirtualMachine;
|
||||||
|
|
||||||
#[cfg(feature = "threading")]
|
#[cfg(feature = "threading")]
|
||||||
@@ -81,7 +82,7 @@ fn _imp_get_frozen_object(name: PyStrRef, vm: &VirtualMachine) -> PyResult<PyCod
|
|||||||
.get(name.borrow_value())
|
.get(name.borrow_value())
|
||||||
.map(|frozen| {
|
.map(|frozen| {
|
||||||
let mut frozen = frozen.code.clone();
|
let mut frozen = frozen.code.clone();
|
||||||
frozen.source_path = PyStr::from(format!("frozen {}", name)).into_ref(vm);
|
frozen.source_path = format!("frozen {}", name);
|
||||||
PyCode::new(frozen)
|
PyCode::new(frozen)
|
||||||
})
|
})
|
||||||
.ok_or_else(|| vm.new_import_error(format!("No such frozen object named {}", name), name))
|
.ok_or_else(|| vm.new_import_error(format!("No such frozen object named {}", name), name))
|
||||||
|
|||||||
@@ -984,7 +984,10 @@ mod decl {
|
|||||||
args: ProductArgs,
|
args: ProductArgs,
|
||||||
vm: &VirtualMachine,
|
vm: &VirtualMachine,
|
||||||
) -> PyResult<PyRef<Self>> {
|
) -> PyResult<PyRef<Self>> {
|
||||||
let repeat = args.repeat.unwrap_or(1);
|
let repeat = match args.repeat.into_option() {
|
||||||
|
Some(i) => i,
|
||||||
|
None => 1,
|
||||||
|
};
|
||||||
|
|
||||||
let mut pools = Vec::new();
|
let mut pools = Vec::new();
|
||||||
for arg in iterables.into_iter() {
|
for arg in iterables.into_iter() {
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ static ESCAPE_CHARS: [&str; 0x20] = [
|
|||||||
// And which one need to be escaped (1)
|
// And which one need to be escaped (1)
|
||||||
// The characters that need escaping are 0x00 to 0x1F, 0x22 ("), 0x5C (\), 0x7F (DEL)
|
// The characters that need escaping are 0x00 to 0x1F, 0x22 ("), 0x5C (\), 0x7F (DEL)
|
||||||
// Non-ASCII unicode characters can be safely included in a JSON string
|
// Non-ASCII unicode characters can be safely included in a JSON string
|
||||||
#[allow(clippy::unusual_byte_groupings)] // it's groups of 16, come on clippy
|
|
||||||
static NEEDS_ESCAPING_BITSET: [u64; 4] = [
|
static NEEDS_ESCAPING_BITSET: [u64; 4] = [
|
||||||
//fedcba9876543210_fedcba9876543210_fedcba9876543210_fedcba9876543210
|
//fedcba9876543210_fedcba9876543210_fedcba9876543210_fedcba9876543210
|
||||||
0b0000000000000000_0000000000000100_1111111111111111_1111111111111111, // 3_2_1_0
|
0b0000000000000000_0000000000000100_1111111111111111_1111111111111111, // 3_2_1_0
|
||||||
|
|||||||
@@ -6,18 +6,21 @@ mod decl {
|
|||||||
use rustpython_parser::lexer;
|
use rustpython_parser::lexer;
|
||||||
|
|
||||||
use crate::builtins::pystr::PyStrRef;
|
use crate::builtins::pystr::PyStrRef;
|
||||||
use crate::pyobject::{BorrowValue, PyObjectRef};
|
use crate::pyobject::{BorrowValue, PyObjectRef, PyResult};
|
||||||
use crate::vm::VirtualMachine;
|
use crate::vm::VirtualMachine;
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
fn iskeyword(s: PyStrRef) -> bool {
|
fn iskeyword(s: PyStrRef, vm: &VirtualMachine) -> PyResult {
|
||||||
lexer::KEYWORDS.contains_key(s.borrow_value())
|
let keywords = lexer::get_keywords();
|
||||||
|
let value = keywords.contains_key(s.borrow_value());
|
||||||
|
let value = vm.ctx.new_bool(value);
|
||||||
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyattr]
|
#[pyattr]
|
||||||
fn kwlist(vm: &VirtualMachine) -> PyObjectRef {
|
fn kwlist(vm: &VirtualMachine) -> PyObjectRef {
|
||||||
vm.ctx.new_list(
|
vm.ctx.new_list(
|
||||||
lexer::KEYWORDS
|
lexer::get_keywords()
|
||||||
.keys()
|
.keys()
|
||||||
.map(|k| vm.ctx.new_str(k.to_owned()))
|
.map(|k| vm.ctx.new_str(k.to_owned()))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|||||||
@@ -23,14 +23,8 @@ mod decl {
|
|||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
fn loads(code_bytes: PyBytesLike, vm: &VirtualMachine) -> PyResult<PyCode> {
|
fn loads(code_bytes: PyBytesLike, vm: &VirtualMachine) -> PyResult<PyCode> {
|
||||||
let code =
|
let code = bytecode::CodeObject::from_bytes(&*code_bytes.borrow_value())
|
||||||
bytecode::CodeObject::from_bytes(&*code_bytes.borrow_value()).map_err(|e| match e {
|
.map_err(|_| vm.new_value_error("Couldn't deserialize python bytecode".to_owned()))?;
|
||||||
bytecode::CodeDeserializeError::Eof => vm.new_exception_msg(
|
|
||||||
vm.ctx.exceptions.eof_error.clone(),
|
|
||||||
"end of file while deserializing bytecode".to_owned(),
|
|
||||||
),
|
|
||||||
_ => vm.new_value_error("Couldn't deserialize python bytecode".to_owned()),
|
|
||||||
})?;
|
|
||||||
Ok(PyCode {
|
Ok(PyCode {
|
||||||
code: vm.map_codeobj(code),
|
code: vm.map_codeobj(code),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,12 +5,13 @@
|
|||||||
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use num_traits::{One, Signed, Zero};
|
use num_traits::{One, Signed, Zero};
|
||||||
use puruspe::{erf, erfc, gamma, ln_gamma};
|
use statrs::function::erf::{erf, erfc};
|
||||||
|
use statrs::function::gamma::{gamma, ln_gamma};
|
||||||
|
|
||||||
use crate::builtins::float::{self, IntoPyFloat, PyFloatRef};
|
use crate::builtins::float::{self, IntoPyFloat, PyFloatRef};
|
||||||
use crate::builtins::int::{self, PyInt, PyIntRef};
|
use crate::builtins::int::{self, PyInt, PyIntRef};
|
||||||
use crate::function::{Args, OptionalArg};
|
use crate::function::{Args, OptionalArg};
|
||||||
use crate::pyobject::{BorrowValue, Either, PyIterable, PyObjectRef, PyResult, TypeProtocol};
|
use crate::pyobject::{BorrowValue, Either, PyObjectRef, PyResult, TypeProtocol};
|
||||||
use crate::vm::VirtualMachine;
|
use crate::vm::VirtualMachine;
|
||||||
use rustpython_common::float_ops;
|
use rustpython_common::float_ops;
|
||||||
|
|
||||||
@@ -371,104 +372,6 @@ fn math_lcm(args: Args<PyIntRef>) -> BigInt {
|
|||||||
math_perf_arb_len_int_op(args, |x, y| x.lcm(y.borrow_value()), BigInt::one())
|
math_perf_arb_len_int_op(args, |x, y| x.lcm(y.borrow_value()), BigInt::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn math_fsum(iter: PyIterable<IntoPyFloat>, vm: &VirtualMachine) -> PyResult<f64> {
|
|
||||||
let mut partials = vec![];
|
|
||||||
let mut special_sum = 0.0;
|
|
||||||
let mut inf_sum = 0.0;
|
|
||||||
|
|
||||||
for obj in iter.iter(vm)? {
|
|
||||||
let mut x = obj?.to_f64();
|
|
||||||
|
|
||||||
let xsave = x;
|
|
||||||
let mut j = 0;
|
|
||||||
// This inner loop applies `hi`/`lo` summation to each
|
|
||||||
// partial so that the list of partial sums remains exact.
|
|
||||||
for i in 0..partials.len() {
|
|
||||||
let mut y: f64 = partials[i];
|
|
||||||
if x.abs() < y.abs() {
|
|
||||||
std::mem::swap(&mut x, &mut y);
|
|
||||||
}
|
|
||||||
// Rounded `x+y` is stored in `hi` with round-off stored in
|
|
||||||
// `lo`. Together `hi+lo` are exactly equal to `x+y`.
|
|
||||||
let hi = x + y;
|
|
||||||
let lo = y - (hi - x);
|
|
||||||
if lo != 0.0 {
|
|
||||||
partials[j] = lo;
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
x = hi;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !x.is_finite() {
|
|
||||||
// a nonfinite x could arise either as
|
|
||||||
// a result of intermediate overflow, or
|
|
||||||
// as a result of a nan or inf in the
|
|
||||||
// summands
|
|
||||||
if xsave.is_finite() {
|
|
||||||
return Err(vm.new_overflow_error("intermediate overflow in fsum".to_owned()));
|
|
||||||
}
|
|
||||||
if xsave.is_infinite() {
|
|
||||||
inf_sum += xsave;
|
|
||||||
}
|
|
||||||
special_sum += xsave;
|
|
||||||
// reset partials
|
|
||||||
partials.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if j >= partials.len() {
|
|
||||||
partials.push(x);
|
|
||||||
} else {
|
|
||||||
partials[j] = x;
|
|
||||||
partials.truncate(j + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if special_sum != 0.0 {
|
|
||||||
return if inf_sum.is_nan() {
|
|
||||||
Err(vm.new_overflow_error("-inf + inf in fsum".to_owned()))
|
|
||||||
} else {
|
|
||||||
Ok(special_sum)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut n = partials.len();
|
|
||||||
if n > 0 {
|
|
||||||
n -= 1;
|
|
||||||
let mut hi = partials[n];
|
|
||||||
|
|
||||||
let mut lo = 0.0;
|
|
||||||
while n > 0 {
|
|
||||||
let x = hi;
|
|
||||||
|
|
||||||
n -= 1;
|
|
||||||
let y = partials[n];
|
|
||||||
|
|
||||||
hi = x + y;
|
|
||||||
lo = y - (hi - x);
|
|
||||||
if lo != 0.0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if n > 0 && ((lo < 0.0 && partials[n - 1] < 0.0) || (lo > 0.0 && partials[n - 1] > 0.0)) {
|
|
||||||
let y = lo + lo;
|
|
||||||
let x = hi + y;
|
|
||||||
|
|
||||||
// Make half-even rounding work across multiple partials.
|
|
||||||
// Needed so that sum([1e-16, 1, 1e16]) will round-up the last
|
|
||||||
// digit to two instead of down to zero (the 1e-16 makes the 1
|
|
||||||
// slightly closer to two). With a potential 1 ULP rounding
|
|
||||||
// error fixed-up, math.fsum() can guarantee commutativity.
|
|
||||||
#[allow(clippy::float_cmp)]
|
|
||||||
if y == x - hi {
|
|
||||||
hi = x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(hi)
|
|
||||||
} else {
|
|
||||||
Ok(0.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn math_factorial(value: PyIntRef, vm: &VirtualMachine) -> PyResult<BigInt> {
|
fn math_factorial(value: PyIntRef, vm: &VirtualMachine) -> PyResult<BigInt> {
|
||||||
let value = value.borrow_value();
|
let value = value.borrow_value();
|
||||||
if value.is_negative() {
|
if value.is_negative() {
|
||||||
@@ -613,7 +516,6 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
|||||||
"ldexp" => named_function!(ctx, math, ldexp),
|
"ldexp" => named_function!(ctx, math, ldexp),
|
||||||
"modf" => named_function!(ctx, math, modf),
|
"modf" => named_function!(ctx, math, modf),
|
||||||
"fmod" => named_function!(ctx, math, fmod),
|
"fmod" => named_function!(ctx, math, fmod),
|
||||||
"fsum" => named_function!(ctx, math, fsum),
|
|
||||||
"remainder" => named_function!(ctx, math, remainder),
|
"remainder" => named_function!(ctx, math, remainder),
|
||||||
|
|
||||||
// Rounding functions:
|
// Rounding functions:
|
||||||
|
|||||||
@@ -71,10 +71,9 @@ mod zlib;
|
|||||||
|
|
||||||
pub type StdlibInitFunc = Box<py_dyn_fn!(dyn Fn(&VirtualMachine) -> PyObjectRef)>;
|
pub type StdlibInitFunc = Box<py_dyn_fn!(dyn Fn(&VirtualMachine) -> PyObjectRef)>;
|
||||||
|
|
||||||
pub fn get_module_inits() -> HashMap<String, StdlibInitFunc, ahash::RandomState> {
|
pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut modules = hashmap! {
|
let mut modules = hashmap! {
|
||||||
hasher = ahash::RandomState::default(),
|
|
||||||
"array".to_owned() => Box::new(array::make_module) as StdlibInitFunc,
|
"array".to_owned() => Box::new(array::make_module) as StdlibInitFunc,
|
||||||
"atexit".to_owned() => Box::new(atexit::make_module),
|
"atexit".to_owned() => Box::new(atexit::make_module),
|
||||||
"binascii".to_owned() => Box::new(binascii::make_module),
|
"binascii".to_owned() => Box::new(binascii::make_module),
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user