Compare commits
No commits in common. "4306dcc6c0ddd1f0feb57970a3c65c1f05484c46" and "229cefe028665e759c75a5be8cf07602ebb79186" have entirely different histories.
4306dcc6c0
...
229cefe028
23 changed files with 167 additions and 499 deletions
131
Cargo.lock
generated
131
Cargo.lock
generated
|
@ -45,9 +45,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.65"
|
version = "0.3.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61"
|
checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"addr2line",
|
"addr2line",
|
||||||
"cc",
|
"cc",
|
||||||
|
@ -78,9 +78,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.1.18"
|
version = "3.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b"
|
checksum = "6aad2534fad53df1cc12519c5cda696dd3e20e6118a027e24054aea14a0bdcbe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
@ -95,9 +95,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "3.1.18"
|
version = "3.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c"
|
checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
|
@ -108,9 +108,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_lex"
|
name = "clap_lex"
|
||||||
version = "0.2.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 = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213"
|
checksum = "189ddd3b5d32a70b35e7686054371742a937b0d99128e76dde6340210e966669"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"os_str_bytes",
|
"os_str_bytes",
|
||||||
]
|
]
|
||||||
|
@ -159,9 +159,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
version = "0.13.4"
|
version = "0.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
|
checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"darling_macro",
|
"darling_macro",
|
||||||
|
@ -169,9 +169,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling_core"
|
name = "darling_core"
|
||||||
version = "0.13.4"
|
version = "0.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610"
|
checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fnv",
|
"fnv",
|
||||||
"ident_case",
|
"ident_case",
|
||||||
|
@ -183,9 +183,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling_macro"
|
name = "darling_macro"
|
||||||
version = "0.13.4"
|
version = "0.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
|
checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling_core",
|
"darling_core",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -206,9 +206,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "eyre"
|
name = "eyre"
|
||||||
version = "0.6.8"
|
version = "0.6.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb"
|
checksum = "9289ed2c0440a6536e65119725cf91fc2c6b5e513bfd2e36e1134d7cca6ca12f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indenter",
|
"indenter",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -244,18 +244,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gc"
|
name = "gc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
|
||||||
"gctrace-derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gctrace-derive"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
|
@ -323,15 +311,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.126"
|
version = "0.2.121"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.17"
|
version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
@ -353,51 +341,52 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "2.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.5.1"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082"
|
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.28.4"
|
version = "0.27.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
|
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.11.0"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b10983b38c53aebdf33f542c6275b0f58a238129d00c4ae0e6fb59738d783ca"
|
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_str_bytes"
|
name = "os_str_bytes"
|
||||||
version = "6.0.1"
|
version = "6.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "029d8d0b2f198229de29dca79676f2738ff952edf3fde542eb8bf94d8c21b435"
|
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "owo-colors"
|
name = "owo-colors"
|
||||||
version = "3.4.0"
|
version = "3.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "decf7381921fea4dcb2549c5667eda59b3ec297ab7e2b5fc33eac69d2e7da87b"
|
checksum = "5e72e30578e0d0993c8ae20823dd9cff2bc5517d2f586a8aef462a581e8a03eb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.9"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error"
|
name = "proc-macro-error"
|
||||||
|
@ -425,27 +414,27 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.40"
|
version = "1.0.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
|
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.20"
|
version = "1.0.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
checksum = "b4af2ec4714533fcdf07e886f17025ace8b997b9ce51204ee69b6da831c3da57"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.5.6"
|
version = "1.5.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
|
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
]
|
]
|
||||||
|
@ -461,9 +450,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.26"
|
version = "0.6.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
|
@ -494,13 +483,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.98"
|
version = "1.0.89"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"unicode-ident",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -529,9 +518,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.34"
|
version = "0.1.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
|
checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
@ -541,9 +530,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-attributes"
|
name = "tracing-attributes"
|
||||||
version = "0.1.21"
|
version = "0.1.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
|
checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -552,9 +541,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.26"
|
version = "0.1.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f"
|
checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"valuable",
|
"valuable",
|
||||||
|
@ -572,9 +561,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-log"
|
name = "tracing-log"
|
||||||
version = "0.1.3"
|
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 = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
|
@ -583,9 +572,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-subscriber"
|
name = "tracing-subscriber"
|
||||||
version = "0.3.11"
|
version = "0.3.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596"
|
checksum = "9e0ab7bdc962035a87fba73f3acca9b8a8d0034c2e6f60b84aeaaddddc155dce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -600,10 +589,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-xid"
|
||||||
version = "1.0.0"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "valuable"
|
name = "valuable"
|
||||||
|
|
|
@ -5,8 +5,7 @@ edition = "2021"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"gc",
|
"gc"
|
||||||
"gc/gctrace-derive"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
@ -3,5 +3,6 @@ name = "gc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gctrace-derive = { version = "0.1.0", path = "gctrace-derive" }
|
|
||||||
|
|
3
gc/fuzz/.gitignore
vendored
3
gc/fuzz/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
||||||
target
|
|
||||||
corpus
|
|
||||||
artifacts
|
|
93
gc/fuzz/Cargo.lock
generated
93
gc/fuzz/Cargo.lock
generated
|
@ -1,93 +0,0 @@
|
||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arbitrary"
|
|
||||||
version = "1.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a7924531f38b1970ff630f03eb20a2fde69db5c590c93b0f3482e95dcc5fd60"
|
|
||||||
dependencies = [
|
|
||||||
"derive_arbitrary",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cc"
|
|
||||||
version = "1.0.73"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derive_arbitrary"
|
|
||||||
version = "1.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c9a577516173adb681466d517d39bd468293bc2c2a16439375ef0f35bba45f3d"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gc"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gc-fuzz"
|
|
||||||
version = "0.0.0"
|
|
||||||
dependencies = [
|
|
||||||
"gc",
|
|
||||||
"libfuzzer-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libfuzzer-sys"
|
|
||||||
version = "0.4.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "336244aaeab6a12df46480dc585802aa743a72d66b11937844c61bbca84c991d"
|
|
||||||
dependencies = [
|
|
||||||
"arbitrary",
|
|
||||||
"cc",
|
|
||||||
"once_cell",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "once_cell"
|
|
||||||
version = "1.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.40"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.20"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.98"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
|
|
|
@ -1,25 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "gc-fuzz"
|
|
||||||
version = "0.0.0"
|
|
||||||
authors = ["Automatically generated"]
|
|
||||||
publish = false
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
[package.metadata]
|
|
||||||
cargo-fuzz = true
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
libfuzzer-sys = { version = "0.4", features = ["arbitrary-derive"] }
|
|
||||||
|
|
||||||
[dependencies.gc]
|
|
||||||
path = ".."
|
|
||||||
|
|
||||||
# Prevent this from interfering with workspaces
|
|
||||||
[workspace]
|
|
||||||
members = ["."]
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "fuzz_target_1"
|
|
||||||
path = "fuzz_targets/fuzz_target_1.rs"
|
|
||||||
test = false
|
|
||||||
doc = false
|
|
|
@ -1,33 +0,0 @@
|
||||||
#![no_main]
|
|
||||||
use libfuzzer_sys::fuzz_target;
|
|
||||||
use gc::{self, test_utils::GotDropped};
|
|
||||||
|
|
||||||
use libfuzzer_sys::arbitrary::Arbitrary;
|
|
||||||
|
|
||||||
#[derive(Arbitrary, Debug)]
|
|
||||||
enum AllocatorMethod {
|
|
||||||
Alloc,
|
|
||||||
Remove {
|
|
||||||
// Free the index^th allocation we've made.
|
|
||||||
index: usize
|
|
||||||
},
|
|
||||||
CollectGarbage
|
|
||||||
}
|
|
||||||
|
|
||||||
fuzz_target!(|ops: Vec<AllocatorMethod>| {
|
|
||||||
let allocator = gc::allocator::GCAllocator::new();
|
|
||||||
for op in ops {
|
|
||||||
match op {
|
|
||||||
AllocatorMethod::Alloc => {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
AllocatorMethod::Remove {index} => {
|
|
||||||
},
|
|
||||||
|
|
||||||
AllocatorMethod::CollectGarbage => {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,12 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "gctrace-derive"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
proc-macro = true
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
proc-macro2 = "1.0.40"
|
|
||||||
quote = "1.0.20"
|
|
||||||
syn = "1.0.98"
|
|
|
@ -1,75 +0,0 @@
|
||||||
use proc_macro::TokenStream;
|
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
|
||||||
use quote::{quote, quote_spanned};
|
|
||||||
use syn::spanned::Spanned;
|
|
||||||
use syn::{
|
|
||||||
parse_macro_input, parse_quote, Data, DeriveInput, Fields, GenericParam, Generics, Index,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add a bound `T: GcTrace` to every type parameter T.
|
|
||||||
fn add_trait_bounds(mut generics: Generics) -> Generics {
|
|
||||||
for param in &mut generics.params {
|
|
||||||
if let GenericParam::Type(ref mut type_param) = *param {
|
|
||||||
type_param.bounds.push(parse_quote!(gc::trace::GcTrace));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
generics
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate an expression to call trace on every gc field recursively.
|
|
||||||
fn gctrace_fields(data: &Data) -> TokenStream2 {
|
|
||||||
match *data {
|
|
||||||
Data::Struct(ref data) => match data.fields {
|
|
||||||
Fields::Named(ref fields) => {
|
|
||||||
let recurse = fields.named.iter().map(|f| {
|
|
||||||
let name = &f.ident;
|
|
||||||
quote_spanned! {f.span()=>
|
|
||||||
gc::trace::GCTrace::trace(&self.#name, tracer)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
quote! {
|
|
||||||
#(#recurse;)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Fields::Unnamed(ref fields) => {
|
|
||||||
let recurse = fields.unnamed.iter().enumerate().map(|(i, f)| {
|
|
||||||
let index = Index::from(i);
|
|
||||||
quote_spanned! {f.span()=>
|
|
||||||
gc::trace::GCTrace::trace(&self.#index, tracer)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
quote! {
|
|
||||||
#(#recurse;)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Fields::Unit => TokenStream2::default(),
|
|
||||||
},
|
|
||||||
Data::Enum(_) | Data::Union(_) => unimplemented!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro_derive(GCTrace)]
|
|
||||||
pub fn gctrace_derive(input: TokenStream) -> TokenStream {
|
|
||||||
// Parse the input tokens into a syntax tree
|
|
||||||
let input = parse_macro_input!(input as DeriveInput);
|
|
||||||
|
|
||||||
let name = input.ident;
|
|
||||||
|
|
||||||
let generics = add_trait_bounds(input.generics);
|
|
||||||
|
|
||||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
|
||||||
let trace_fields = gctrace_fields(&input.data);
|
|
||||||
|
|
||||||
// Build the output, possibly using quasi-quotation
|
|
||||||
//
|
|
||||||
let expanded = quote! {
|
|
||||||
unsafe impl #impl_generics gc::trace::GCTrace for #name #ty_generics #where_clause {
|
|
||||||
fn trace(&self, tracer: &mut gc::trace::GCTracer) {
|
|
||||||
#trace_fields
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Hand the output tokens back to the compiler
|
|
||||||
TokenStream::from(expanded)
|
|
||||||
}
|
|
|
@ -10,7 +10,7 @@ pub struct GCAllocator {
|
||||||
|
|
||||||
impl GCAllocator {
|
impl GCAllocator {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn alloc<T: trace::GCTrace>(&mut self, x: T) -> GcRef<T> {
|
pub fn alloc<T>(&mut self, x: T) -> GcRef<T> {
|
||||||
let alloc = Allocation::new(x);
|
let alloc = Allocation::new(x);
|
||||||
let ptr = alloc.ptr as *mut T;
|
let ptr = alloc.ptr as *mut T;
|
||||||
self.allocations.push(alloc);
|
self.allocations.push(alloc);
|
||||||
|
@ -41,7 +41,7 @@ impl GCAllocator {
|
||||||
pub unsafe fn gc_ref_root<T: trace::GCTrace>(&mut self, root: &GcRef<T>) {
|
pub unsafe fn gc_ref_root<T: trace::GCTrace>(&mut self, root: &GcRef<T>) {
|
||||||
// Mark
|
// Mark
|
||||||
let mut tracer = trace::GCTracer::with_capacity(self.allocations.len());
|
let mut tracer = trace::GCTracer::with_capacity(self.allocations.len());
|
||||||
tracer.mark_reachable_rec(root);
|
tracer.mark_reachable(root);
|
||||||
root.trace(&mut tracer);
|
root.trace(&mut tracer);
|
||||||
|
|
||||||
// And sweep
|
// And sweep
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
use std::{marker::PhantomData, ops::Deref, ptr::NonNull};
|
use std::{ops::Deref, ptr::NonNull};
|
||||||
|
|
||||||
use crate::trace::GCTrace;
|
pub struct GcRef<T>(pub(crate) NonNull<T>);
|
||||||
|
|
||||||
#[derive(Clone)]
|
impl<T> Deref for GcRef<T> {
|
||||||
pub struct GcRef<T: GCTrace>(pub(crate) NonNull<T>, PhantomData<T>);
|
|
||||||
|
|
||||||
impl<T: GCTrace> Deref for GcRef<T> {
|
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
|
@ -13,9 +10,9 @@ impl<T: GCTrace> Deref for GcRef<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: GCTrace> GcRef<T> {
|
impl<T> GcRef<T> {
|
||||||
pub(crate) unsafe fn new(ptr: NonNull<T>) -> Self {
|
pub(crate) unsafe fn new(ptr: NonNull<T>) -> Self {
|
||||||
Self(ptr, PhantomData)
|
Self(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
|
|
@ -1,35 +1,50 @@
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
#![feature(negative_impls)]
|
|
||||||
|
|
||||||
pub mod allocator;
|
pub mod allocator;
|
||||||
pub mod gc_ref;
|
pub mod gc_ref;
|
||||||
pub mod trace;
|
pub mod trace;
|
||||||
mod trace_impl;
|
|
||||||
|
|
||||||
// make the test_utils mod pub to use it in fuzzing
|
|
||||||
pub mod test_utils;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
mod tests {
|
||||||
use super::allocator::GCAllocator;
|
use super::allocator::GCAllocator;
|
||||||
use super::test_utils::GotDropped;
|
use super::gc_ref::GcRef;
|
||||||
|
use super::trace;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
struct GCRoot<'a>(GcRef<GotDropped<'a>>);
|
||||||
|
|
||||||
|
unsafe impl<'a> trace::GCTrace for GCRoot<'a> {
|
||||||
|
fn trace(&self, tracer: &mut trace::GCTracer) {
|
||||||
|
tracer.mark_reachable(&self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GotDropped<'a>(&'a AtomicBool);
|
||||||
|
impl<'a> Drop for GotDropped<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.0.store(true, Ordering::Release);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_works() {
|
fn it_works() {
|
||||||
let got_dropped = GotDropped::default();
|
let dropped = AtomicBool::from(false);
|
||||||
|
let got_dropped = GotDropped(&dropped);
|
||||||
|
|
||||||
let mut gc = GCAllocator::default();
|
let mut gc = GCAllocator::default();
|
||||||
gc.alloc(got_dropped.make_drop_checker());
|
gc.alloc(got_dropped);
|
||||||
|
|
||||||
unsafe { gc.gc(&()) };
|
unsafe { gc.gc(&()) };
|
||||||
assert!(got_dropped.was_dropped());
|
assert!(dropped.load(Ordering::Acquire));
|
||||||
|
|
||||||
let got_dropped = GotDropped::default();
|
let dropped = AtomicBool::from(false);
|
||||||
let drop_checker = gc.alloc(got_dropped.make_drop_checker());
|
let got_dropped = gc.alloc(GotDropped(&dropped));
|
||||||
|
let gc_root = gc.alloc(GCRoot(got_dropped));
|
||||||
|
|
||||||
unsafe { gc.gc(&(drop_checker,)) };
|
unsafe {
|
||||||
assert!(!got_dropped.was_dropped());
|
gc.gc_ref_root(&gc_root);
|
||||||
|
};
|
||||||
|
assert!(!dropped.load(Ordering::Acquire));
|
||||||
unsafe { gc.gc(&()) };
|
unsafe { gc.gc(&()) };
|
||||||
assert!(got_dropped.was_dropped());
|
assert!(dropped.load(Ordering::Acquire));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
|
|
||||||
use crate::trace::GCTrace;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct GotDropped(AtomicBool);
|
|
||||||
|
|
||||||
impl GotDropped {
|
|
||||||
pub fn make_drop_checker(&self) -> DropChecker {
|
|
||||||
DropChecker(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn was_dropped(&self) -> bool {
|
|
||||||
self.0.load(Ordering::SeqCst)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DropChecker<'a>(pub &'a GotDropped);
|
|
||||||
|
|
||||||
impl<'a> Drop for DropChecker<'a> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.0 .0.store(true, Ordering::SeqCst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<'a> GCTrace for DropChecker<'a> {
|
|
||||||
fn trace(&self, _tracer: &mut crate::trace::GCTracer) {}
|
|
||||||
}
|
|
|
@ -1,17 +1,15 @@
|
||||||
use std::{collections::HashSet, ops::Deref};
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use crate::gc_ref::GcRef;
|
use crate::gc_ref::GcRef;
|
||||||
|
|
||||||
pub struct GCTracer {
|
pub struct GCTracer {
|
||||||
accessible: HashSet<*const ()>,
|
accessible: HashSet<*const ()>,
|
||||||
explored: HashSet<*const ()>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GCTracer {
|
impl GCTracer {
|
||||||
pub(super) fn with_capacity(cap: usize) -> Self {
|
pub(super) fn with_capacity(cap: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
accessible: HashSet::with_capacity(cap),
|
accessible: HashSet::with_capacity(cap),
|
||||||
explored: HashSet::with_capacity(cap),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,28 +17,39 @@ impl GCTracer {
|
||||||
self.accessible.contains(&ptr)
|
self.accessible.contains(&ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark_reachable_rec<T: GCTrace>(&mut self, obj: &T) {
|
pub fn mark_reachable<T>(&mut self, obj: &GcRef<T>) {
|
||||||
let ptr = obj as *const T as *const ();
|
let ptr = obj.0.as_ptr() as *const ();
|
||||||
if !self.explored.contains(&ptr) {
|
self.accessible.insert(ptr);
|
||||||
self.explored.insert(ptr);
|
}
|
||||||
|
|
||||||
|
pub fn mark_reachable_rec<T: GCTrace>(&mut self, obj: &GcRef<T>) {
|
||||||
|
let ptr = obj.0.as_ptr() as *const ();
|
||||||
|
if !self.accessible.contains(&ptr) {
|
||||||
|
self.accessible.insert(ptr);
|
||||||
obj.trace(self);
|
obj.trace(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use gctrace_derive::GCTrace;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// Implementors of the trait *need* to ensure that every reachable reference gets marked as
|
/// Implementors of the trait *need* to ensure that every reachable reference gets marked as
|
||||||
/// reachable by callign trace on it
|
/// reachable with mark_reachable or mark_reachable_rec.
|
||||||
pub unsafe trait GCTrace {
|
pub unsafe trait GCTrace {
|
||||||
fn trace(&self, _tracer: &mut GCTracer) {}
|
fn trace(&self, tracer: &mut GCTracer);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: GCTrace> GCTrace for GcRef<T> {
|
unsafe impl<T> GCTrace for &[T]
|
||||||
|
where
|
||||||
|
T: GCTrace,
|
||||||
|
{
|
||||||
fn trace(&self, tracer: &mut GCTracer) {
|
fn trace(&self, tracer: &mut GCTracer) {
|
||||||
tracer.accessible.insert(self.0.as_ptr() as *const ());
|
for item in self.iter() {
|
||||||
tracer.mark_reachable_rec(self.deref());
|
item.trace(tracer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl GCTrace for () {
|
||||||
|
fn trace(&self, _tracer: &mut GCTracer) {}
|
||||||
|
}
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
use super::trace::{GCTrace, GCTracer};
|
|
||||||
use std::{cell::RefCell, collections::HashMap, ops::Deref};
|
|
||||||
unsafe impl GCTrace for () {}
|
|
||||||
unsafe impl GCTrace for i32 {}
|
|
||||||
unsafe impl GCTrace for u32 {}
|
|
||||||
unsafe impl GCTrace for i64 {}
|
|
||||||
unsafe impl GCTrace for u64 {}
|
|
||||||
unsafe impl GCTrace for f32 {}
|
|
||||||
unsafe impl GCTrace for f64 {}
|
|
||||||
unsafe impl GCTrace for isize {}
|
|
||||||
unsafe impl GCTrace for usize {}
|
|
||||||
unsafe impl GCTrace for String {}
|
|
||||||
|
|
||||||
unsafe impl<T: GCTrace> GCTrace for (T,) {
|
|
||||||
fn trace(&self, tracer: &mut GCTracer) {
|
|
||||||
tracer.mark_reachable_rec(&self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<T: GCTrace> GCTrace for RefCell<T> {
|
|
||||||
fn trace(&self, tracer: &mut GCTracer) {
|
|
||||||
let borrow = self.borrow();
|
|
||||||
tracer.mark_reachable_rec(borrow.deref())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<T: GCTrace> GCTrace for Option<T> {
|
|
||||||
fn trace(&self, tracer: &mut GCTracer) {
|
|
||||||
if let Some(ref v) = self {
|
|
||||||
tracer.mark_reachable_rec(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<K: GCTrace, V: GCTrace> GCTrace for HashMap<K, V> {
|
|
||||||
fn trace(&self, tracer: &mut GCTracer) {
|
|
||||||
for (k, v) in self.iter() {
|
|
||||||
tracer.mark_reachable_rec(k);
|
|
||||||
tracer.mark_reachable_rec(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -52,7 +52,6 @@ impl<T: Error> ErrorLocationWrapper<T> {
|
||||||
|
|
||||||
impl<T: std::error::Error> ErrorWithLocation for ErrorLocationWrapper<T> {
|
impl<T: std::error::Error> ErrorWithLocation for ErrorLocationWrapper<T> {
|
||||||
fn get_location(&self) -> Location {
|
fn get_location(&self) -> Location {
|
||||||
#[allow(clippy::needless_borrow)]
|
|
||||||
(&self.location).into()
|
(&self.location).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::Interpret;
|
use super::Interpret;
|
||||||
use super::{types::Primitive, RuntimeError};
|
use super::{types::Value, RuntimeError};
|
||||||
use crate::ast::expression::{
|
use crate::ast::expression::{
|
||||||
self,
|
self,
|
||||||
operator::{Operator, UnaryOperator},
|
operator::{Operator, UnaryOperator},
|
||||||
|
@ -7,19 +7,19 @@ use crate::ast::expression::{
|
||||||
use crate::interpreter::world::World;
|
use crate::interpreter::world::World;
|
||||||
|
|
||||||
impl Interpret for expression::ExpressionNode {
|
impl Interpret for expression::ExpressionNode {
|
||||||
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
|
||||||
expression::all_variants!(self, n => n.interpret(w))
|
expression::all_variants!(self, n => n.interpret(w))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for expression::Literal {
|
impl Interpret for expression::Literal {
|
||||||
fn interpret(&self, _: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, _: &mut World) -> Result<Value, RuntimeError> {
|
||||||
Ok(self.clone().into())
|
Ok(self.clone().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for expression::BinaryExpr {
|
impl Interpret for expression::BinaryExpr {
|
||||||
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
|
||||||
let left_val = self.left.interpret(w).expect("expected lval");
|
let left_val = self.left.interpret(w).expect("expected lval");
|
||||||
let right_val = self.right.interpret(w).expect("expected rval");
|
let right_val = self.right.interpret(w).expect("expected rval");
|
||||||
match self.operator {
|
match self.operator {
|
||||||
|
@ -36,13 +36,13 @@ impl Interpret for expression::BinaryExpr {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for expression::UnaryExpr {
|
impl Interpret for expression::UnaryExpr {
|
||||||
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
|
||||||
let val = self.right.interpret(w)?;
|
let val = self.right.interpret(w)?;
|
||||||
match self.operator {
|
match self.operator {
|
||||||
UnaryOperator::Bang => Ok(Primitive::Bool(!val.truthy())),
|
UnaryOperator::Bang => Ok(Value::Bool(!val.truthy())),
|
||||||
UnaryOperator::Minus => match val {
|
UnaryOperator::Minus => match val {
|
||||||
Primitive::Int(i) => Ok(Primitive::Int(-i)),
|
Value::Int(i) => Ok(Value::Int(-i)),
|
||||||
Primitive::Float(f) => Ok(Primitive::Float(-f)),
|
Value::Float(f) => Ok(Value::Float(-f)),
|
||||||
_ => Err(RuntimeError),
|
_ => Err(RuntimeError),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -50,25 +50,25 @@ impl Interpret for expression::UnaryExpr {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for expression::GroupingExpr {
|
impl Interpret for expression::GroupingExpr {
|
||||||
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
|
||||||
self.0.interpret(w)
|
self.0.interpret(w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for expression::VariableExpr {
|
impl Interpret for expression::VariableExpr {
|
||||||
fn interpret(&self, world: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, world: &mut World) -> Result<Value, RuntimeError> {
|
||||||
match world.get_var(&self.var_name) {
|
match world.get_var(&self.var_name) {
|
||||||
Some(v) => Ok(v),
|
Some(v) => Ok(v.clone()),
|
||||||
None => Err(RuntimeError),
|
None => Err(RuntimeError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for expression::BlockExpr {
|
impl Interpret for expression::BlockExpr {
|
||||||
fn interpret(&self, world: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, world: &mut World) -> Result<Value, RuntimeError> {
|
||||||
for stmnt in self.statements.iter() {
|
for stmnt in self.statements.iter() {
|
||||||
stmnt.interpret(world)?;
|
stmnt.interpret(world)?;
|
||||||
}
|
}
|
||||||
Ok(Primitive::Nil)
|
Ok(Value::Nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
mod expression_interpreter;
|
mod expression_interpreter;
|
||||||
mod statement_interpreter;
|
mod statement_interpreter;
|
||||||
pub use super::{error::RuntimeError, types};
|
pub use super::{error::RuntimeError, types};
|
||||||
use super::{types::Primitive, world::World};
|
use super::{types::Value, world::World};
|
||||||
|
|
||||||
pub trait Interpret {
|
pub trait Interpret {
|
||||||
fn interpret(&self, world: &mut World) -> Result<Primitive, RuntimeError>;
|
fn interpret(&self, world: &mut World) -> Result<Value, RuntimeError>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
use super::Interpret;
|
use super::Interpret;
|
||||||
use super::{types::Primitive, RuntimeError};
|
use super::{types::Value, RuntimeError};
|
||||||
use crate::ast::statement;
|
use crate::ast::statement;
|
||||||
use crate::interpreter::world::World;
|
use crate::interpreter::world::World;
|
||||||
|
|
||||||
impl Interpret for statement::Statement {
|
impl Interpret for statement::Statement {
|
||||||
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
|
||||||
statement::all_variants!(self, n => n.interpret(w))
|
statement::all_variants!(self, n => n.interpret(w))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for statement::PrintStatement {
|
impl Interpret for statement::PrintStatement {
|
||||||
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
|
||||||
let res = self.0.interpret(w)?;
|
let res = self.0.interpret(w)?;
|
||||||
println!("{:?}", res);
|
println!("{:?}", res);
|
||||||
Ok(res)
|
Ok(res)
|
||||||
|
@ -18,13 +18,13 @@ impl Interpret for statement::PrintStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for statement::ExpressionStatement {
|
impl Interpret for statement::ExpressionStatement {
|
||||||
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
|
||||||
self.0.interpret(w)
|
self.0.interpret(w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpret for statement::VariableAssignmentStatement {
|
impl Interpret for statement::VariableAssignmentStatement {
|
||||||
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
|
fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
|
||||||
let expr_val = self.node.interpret(w)?;
|
let expr_val = self.node.interpret(w)?;
|
||||||
// Clone for now, later this will use a GC and won't need to clone
|
// Clone for now, later this will use a GC and won't need to clone
|
||||||
w.set_var(self.var_name.clone(), expr_val.clone());
|
w.set_var(self.var_name.clone(), expr_val.clone());
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use crate::ast::expression;
|
use crate::ast::expression;
|
||||||
use from_variants::FromVariants;
|
use from_variants::FromVariants;
|
||||||
use gc::trace::GCTrace;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, PartialOrd, Clone, FromVariants)]
|
#[derive(Debug, PartialEq, PartialOrd, Clone, FromVariants)]
|
||||||
pub enum Primitive {
|
pub enum Value {
|
||||||
Int(i32),
|
Int(i32),
|
||||||
Float(f32),
|
Float(f32),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
|
@ -12,9 +11,7 @@ pub enum Primitive {
|
||||||
String(String),
|
String(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl GCTrace for Primitive {}
|
impl From<expression::Literal> for Value {
|
||||||
|
|
||||||
impl From<expression::Literal> for Primitive {
|
|
||||||
fn from(l: expression::Literal) -> Self {
|
fn from(l: expression::Literal) -> Self {
|
||||||
match_any::match_any!(l,
|
match_any::match_any!(l,
|
||||||
expression::Literal::Int(v) | expression::Literal::Bool(v) | expression::Literal::Float(v) | expression::Literal::String(v) => v.into(),
|
expression::Literal::Int(v) | expression::Literal::Bool(v) | expression::Literal::Float(v) | expression::Literal::String(v) => v.into(),
|
||||||
|
@ -23,13 +20,13 @@ impl From<expression::Literal> for Primitive {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Primitive {
|
impl Default for Value {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Nil
|
Self::Nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Primitive {
|
impl Value {
|
||||||
pub fn truthy(&self) -> bool {
|
pub fn truthy(&self) -> bool {
|
||||||
!(matches!(*self, Self::Bool(false)))
|
!(matches!(*self, Self::Bool(false)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,44 +1,23 @@
|
||||||
use std::{cell::RefCell, collections::HashMap};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use gc::{allocator::GCAllocator, gc_ref::GcRef, trace::GCTrace};
|
|
||||||
|
|
||||||
use crate::ast::statement::Statement;
|
use crate::ast::statement::Statement;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ast_walker::{Interpret, RuntimeError},
|
ast_walker::{Interpret, RuntimeError},
|
||||||
types::Primitive,
|
types::Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, GCTrace)]
|
#[derive(Default)]
|
||||||
pub struct Environment {
|
|
||||||
variables: HashMap<String, Primitive>,
|
|
||||||
parent: Option<GcRef<RefCell<Environment>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Environment {
|
|
||||||
pub fn set_var(&mut self, name: String, v: Primitive) -> Option<Primitive> {
|
|
||||||
self.variables.insert(name, v)
|
|
||||||
}
|
|
||||||
pub fn get_var(&self, name: &str) -> Option<Primitive> {
|
|
||||||
self.variables
|
|
||||||
.get(name)
|
|
||||||
.cloned()
|
|
||||||
.or_else(|| self.parent.as_ref().and_then(|v| v.borrow().get_var(name)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct World {
|
pub struct World {
|
||||||
env: GcRef<Environment>,
|
variables: HashMap<String, Value>,
|
||||||
_gc: GCAllocator,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl World {
|
impl World {
|
||||||
pub fn set_var(&mut self, _name: String, _v: Primitive) -> Option<Primitive> {
|
pub fn set_var(&mut self, name: String, v: Value) -> Option<Value> {
|
||||||
todo!()
|
self.variables.insert(name, v)
|
||||||
// self.env.set_var(name, v)
|
|
||||||
}
|
}
|
||||||
pub fn get_var(&self, name: &str) -> Option<Primitive> {
|
pub fn get_var(&mut self, name: &str) -> Option<&Value> {
|
||||||
self.env.get_var(name)
|
self.variables.get(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,17 +25,11 @@ impl World {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
pub fn exec(&mut self, nodes: Vec<Statement>) -> Result<Primitive, RuntimeError> {
|
pub fn exec(&mut self, nodes: Vec<Statement>) -> Result<Value, RuntimeError> {
|
||||||
nodes
|
let mut last_res = Value::Nil;
|
||||||
.into_iter()
|
for statement in nodes {
|
||||||
.try_fold(Primitive::Nil, |_, stmnt| stmnt.interpret(self))
|
last_res = statement.interpret(self)?;
|
||||||
}
|
}
|
||||||
}
|
Ok(last_res)
|
||||||
|
|
||||||
impl Default for World {
|
|
||||||
fn default() -> Self {
|
|
||||||
let mut gc = GCAllocator::default();
|
|
||||||
let env = gc.alloc(Environment::default());
|
|
||||||
Self { env, _gc: gc }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ impl<'a, 'b> Lexer<'a, 'b> {
|
||||||
}
|
}
|
||||||
found_period = true;
|
found_period = true;
|
||||||
}
|
}
|
||||||
c.is_ascii_digit() || c == '.'
|
c.is_digit(10) || c == '.'
|
||||||
});
|
});
|
||||||
let res = if found_period {
|
let res = if found_period {
|
||||||
num_str
|
num_str
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub mod lexer;
|
||||||
use ast::parser::ParseAllResult;
|
use ast::parser::ParseAllResult;
|
||||||
use ast::statement::Statement;
|
use ast::statement::Statement;
|
||||||
use interpreter::ast_walker::{Interpret, RuntimeError};
|
use interpreter::ast_walker::{Interpret, RuntimeError};
|
||||||
use interpreter::types::Primitive;
|
use interpreter::types::Value;
|
||||||
use interpreter::world::World;
|
use interpreter::world::World;
|
||||||
use lexer::{token::Token, Lexer, LexingError};
|
use lexer::{token::Token, Lexer, LexingError};
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ pub fn parse(tokens: Vec<Token>) -> ParseAllResult {
|
||||||
parser.parse_all()
|
parser.parse_all()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec(nodes: Vec<Statement>) -> Result<Primitive, RuntimeError> {
|
pub fn exec(nodes: Vec<Statement>) -> Result<Value, RuntimeError> {
|
||||||
let mut last_res = Primitive::Nil;
|
let mut last_res = Value::Nil;
|
||||||
let mut world = World::new();
|
let mut world = World::new();
|
||||||
for statement in nodes {
|
for statement in nodes {
|
||||||
last_res = statement.interpret(&mut world)?;
|
last_res = statement.interpret(&mut world)?;
|
||||||
|
@ -33,7 +33,7 @@ pub fn exec(nodes: Vec<Statement>) -> Result<Primitive, RuntimeError> {
|
||||||
Ok(last_res)
|
Ok(last_res)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(code: &str) -> Result<Primitive, run::Error> {
|
pub fn run(code: &str) -> Result<Value, run::Error> {
|
||||||
let tokens = lex(code, None)?;
|
let tokens = lex(code, None)?;
|
||||||
let nodes = parse(tokens)?;
|
let nodes = parse(tokens)?;
|
||||||
Ok(exec(nodes)?)
|
Ok(exec(nodes)?)
|
||||||
|
|
Loading…
Reference in a new issue