diff --git a/Cargo.lock b/Cargo.lock index 77cb70e..651ce61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -203,7 +203,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "syn-solidity 0.4.2", "tiny-keccak", ] @@ -219,7 +219,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -235,7 +235,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "syn-solidity 0.8.12", "tiny-keccak", ] @@ -251,7 +251,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "syn-solidity 0.8.12", ] @@ -371,7 +371,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -805,7 +805,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -822,7 +822,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -1366,9 +1366,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -1524,7 +1524,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2004,7 +2004,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2220,7 +2220,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2246,7 +2246,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2264,7 +2264,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2288,7 +2288,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2299,7 +2299,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2340,7 +2340,7 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2351,7 +2351,7 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2364,7 +2364,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2384,7 +2384,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "unicode-xid", ] @@ -2438,7 +2438,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2478,7 +2478,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.87", + "syn 2.0.89", "termcolor", "toml 0.8.19", "walkdir", @@ -2626,7 +2626,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2637,7 +2637,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2728,7 +2728,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -2930,7 +2930,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -3066,7 +3066,7 @@ dependencies = [ "proc-macro2", "quote", "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?rev=a77940bac783108fcae783c553528c8d5328e5b2)", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -3078,7 +3078,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -3088,7 +3088,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?rev=a77940bac783108fcae dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -3218,7 +3218,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -3402,9 +3402,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", @@ -3635,9 +3635,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", @@ -3815,7 +3815,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -3894,13 +3894,13 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] @@ -3971,7 +3971,7 @@ source = "git+https://github.com/TheDan64/inkwell.git?rev=7b410298b6a93450adaa90 dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4049,9 +4049,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" [[package]] name = "jni" @@ -4196,7 +4196,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4313,9 +4313,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.162" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] name = "libm" @@ -4484,7 +4484,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4498,7 +4498,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4509,7 +4509,7 @@ checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4520,7 +4520,7 @@ checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -4560,7 +4560,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.40", + "rustix 0.38.41", ] [[package]] @@ -4707,7 +4707,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -5383,7 +5383,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?rev=a77940bac783108fcae dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -6148,7 +6148,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?rev=a77940bac783108fcae dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -6768,9 +6768,9 @@ checksum = "16b56e3a2420138bdb970f84dfb9c774aea80fa0e7371549eedec0d80c209c67" [[package]] name = "parity-scale-codec" -version = "3.6.12" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +checksum = "8be4817d39f3272f69c59fe05d0535ae6456c2dc2fa1ba02910296c7e0a5c590" dependencies = [ "arrayvec", "bitvec", @@ -6778,19 +6778,20 @@ dependencies = [ "bytes", "impl-trait-for-tuples", "parity-scale-codec-derive", + "rustversion", "serde", ] [[package]] name = "parity-scale-codec-derive" -version = "3.6.12" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +checksum = "8781a75c6205af67215f382092b6e0a4ff3734798523e69073d4bcd294ec767b" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] @@ -6890,7 +6891,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7526,7 +7527,7 @@ dependencies = [ "polkavm-common 0.9.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7538,7 +7539,7 @@ dependencies = [ "polkavm-common 0.14.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7548,7 +7549,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429" dependencies = [ "polkavm-derive-impl 0.9.0", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7558,7 +7559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b569754b15060d03000c09e3bf11509d527f60b75d79b4c30c3625b5071d9702" dependencies = [ "polkavm-derive-impl 0.14.0", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7667,7 +7668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7748,7 +7749,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -7759,14 +7760,14 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "307e3004becf10f5a6e0d59d20f3cd28231b0e0827a96cd3e0ce6d14bc1e4bb3" dependencies = [ "unicode-ident", ] @@ -7924,7 +7925,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -8349,9 +8350,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.40" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -8362,9 +8363,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.16" +version = "0.23.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" +checksum = "7f1a745511c54ba6d4465e8d5dfbd81b45791756de28d4981af70d6dca128f1e" dependencies = [ "log", "once_cell", @@ -8613,7 +8614,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -8641,14 +8642,14 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "scale-info" -version = "2.11.5" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa7ffc1c0ef49b0452c6e2986abf2b07743320641ffd5fc63d552458e3b779b" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ "bitvec", "cfg-if", @@ -8660,14 +8661,14 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.5" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46385cc24172cf615450267463f937c10072516359b3ff1cb24228a4a08bf951" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -8698,9 +8699,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] @@ -8878,7 +8879,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" dependencies = [ - "semver-parser 0.10.2", + "semver-parser 0.10.3", ] [[package]] @@ -8898,9 +8899,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "semver-parser" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" dependencies = [ "pest", ] @@ -8946,14 +8947,14 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -9489,7 +9490,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9729,7 +9730,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.10.0" -source = "git+https://github.com/paritytech/polkadot-sdk#a77940bac783108fcae783c553528c8d5328e5b2" +source = "git+https://github.com/paritytech/polkadot-sdk#56d97c3ad8c86e602bc7ac368751210517c4309f" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -9780,7 +9781,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?rev=a77940bac783108fcae dependencies = [ "quote", "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?rev=a77940bac783108fcae783c553528c8d5328e5b2)", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9790,17 +9791,17 @@ source = "git+https://github.com/paritytech/polkadot-sdk?rev=a77940bac783108fcae dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#a77940bac783108fcae783c553528c8d5328e5b2" +source = "git+https://github.com/paritytech/polkadot-sdk#56d97c3ad8c86e602bc7ac368751210517c4309f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -9816,7 +9817,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk#a77940bac783108fcae783c553528c8d5328e5b2" +source = "git+https://github.com/paritytech/polkadot-sdk#56d97c3ad8c86e602bc7ac368751210517c4309f" dependencies = [ "environmental", "parity-scale-codec", @@ -10025,7 +10026,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#a77940bac783108fcae783c553528c8d5328e5b2" +source = "git+https://github.com/paritytech/polkadot-sdk#56d97c3ad8c86e602bc7ac368751210517c4309f" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -10051,20 +10052,20 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#a77940bac783108fcae783c553528c8d5328e5b2" +source = "git+https://github.com/paritytech/polkadot-sdk#56d97c3ad8c86e602bc7ac368751210517c4309f" dependencies = [ "Inflector", "expander", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -10146,7 +10147,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?rev=a77940bac783108fcae [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#a77940bac783108fcae783c553528c8d5328e5b2" +source = "git+https://github.com/paritytech/polkadot-sdk#56d97c3ad8c86e602bc7ac368751210517c4309f" [[package]] name = "sp-storage" @@ -10163,7 +10164,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#a77940bac783108fcae783c553528c8d5328e5b2" +source = "git+https://github.com/paritytech/polkadot-sdk#56d97c3ad8c86e602bc7ac368751210517c4309f" dependencies = [ "impl-serde", "parity-scale-codec", @@ -10198,7 +10199,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#a77940bac783108fcae783c553528c8d5328e5b2" +source = "git+https://github.com/paritytech/polkadot-sdk#56d97c3ad8c86e602bc7ac368751210517c4309f" dependencies = [ "parity-scale-codec", "tracing", @@ -10277,7 +10278,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -10295,7 +10296,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#a77940bac783108fcae783c553528c8d5328e5b2" +source = "git+https://github.com/paritytech/polkadot-sdk#56d97c3ad8c86e602bc7ac368751210517c4309f" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -10527,7 +10528,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -10654,9 +10655,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -10672,7 +10673,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -10684,7 +10685,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -10695,7 +10696,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -10719,7 +10720,7 @@ dependencies = [ "cfg-if", "fastrand", "once_cell", - "rustix 0.38.40", + "rustix 0.38.41", "windows-sys 0.59.0", ] @@ -10764,7 +10765,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -10876,7 +10877,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -11006,7 +11007,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -11144,9 +11145,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-normalization" @@ -11306,7 +11307,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "wasm-bindgen-shared", ] @@ -11340,7 +11341,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -11698,15 +11699,15 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.40", + "rustix 0.38.41", "windows-sys 0.48.0", ] [[package]] name = "wide" -version = "0.7.28" +version = "0.7.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b828f995bf1e9622031f8009f8481a85406ce1f4d4588ff746d872043e855690" +checksum = "58e6db2670d2be78525979e9a5f9c69d296fd7d670549fe9ebf70f8708cb5019" dependencies = [ "bytemuck", "safe_arch", @@ -12007,7 +12008,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -12066,7 +12067,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "synstructure", ] @@ -12088,7 +12089,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -12108,7 +12109,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", "synstructure", ] @@ -12129,7 +12130,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -12151,7 +12152,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] diff --git a/crates/linker/src/lib.rs b/crates/linker/src/lib.rs index e49bb37..2670df9 100644 --- a/crates/linker/src/lib.rs +++ b/crates/linker/src/lib.rs @@ -29,9 +29,9 @@ fn invoke_lld(cmd_args: &[&str]) -> bool { unsafe { LLDELFLink(args.as_ptr(), args.len()) == 0 } } -pub fn polkavm_linker>(code: T) -> anyhow::Result> { +pub fn polkavm_linker>(code: T, strip_binary: bool) -> anyhow::Result> { let mut config = polkavm_linker::Config::default(); - config.set_strip(true); + config.set_strip(strip_binary); config.set_optimize(true); polkavm_linker::program_from_elf(config, code.as_ref()) diff --git a/crates/llvm-context/src/debug_config/mod.rs b/crates/llvm-context/src/debug_config/mod.rs index f44cb19..f60ae6e 100644 --- a/crates/llvm-context/src/debug_config/mod.rs +++ b/crates/llvm-context/src/debug_config/mod.rs @@ -13,41 +13,52 @@ use self::ir_type::IRType; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct DebugConfig { /// The directory to dump the IRs to. - pub output_directory: PathBuf, + pub output_directory: Option, + /// Whether debug info should be emitted. + pub emit_debug_info: bool, } impl DebugConfig { /// A shortcut constructor. - pub fn new(output_directory: PathBuf) -> Self { - Self { output_directory } + pub const fn new(output_directory: Option, emit_debug_info: bool) -> Self { + Self { + output_directory, + emit_debug_info, + } } /// Dumps the Yul IR. pub fn dump_yul(&self, contract_path: &str, code: &str) -> anyhow::Result<()> { - let mut file_path = self.output_directory.to_owned(); - let full_file_name = Self::full_file_name(contract_path, None, IRType::Yul); - file_path.push(full_file_name); - std::fs::write(file_path, code)?; + if let Some(output_directory) = self.output_directory.as_ref() { + let mut file_path = output_directory.to_owned(); + let full_file_name = Self::full_file_name(contract_path, None, IRType::Yul); + file_path.push(full_file_name); + std::fs::write(file_path, code)?; + } Ok(()) } /// Dumps the EVM legacy assembly IR. pub fn dump_evmla(&self, contract_path: &str, code: &str) -> anyhow::Result<()> { - let mut file_path = self.output_directory.to_owned(); - let full_file_name = Self::full_file_name(contract_path, None, IRType::EVMLA); - file_path.push(full_file_name); - std::fs::write(file_path, code)?; + if let Some(output_directory) = self.output_directory.as_ref() { + let mut file_path = output_directory.to_owned(); + let full_file_name = Self::full_file_name(contract_path, None, IRType::EVMLA); + file_path.push(full_file_name); + std::fs::write(file_path, code)?; + } Ok(()) } /// Dumps the Ethereal IR. pub fn dump_ethir(&self, contract_path: &str, code: &str) -> anyhow::Result<()> { - let mut file_path = self.output_directory.to_owned(); - let full_file_name = Self::full_file_name(contract_path, None, IRType::EthIR); - file_path.push(full_file_name); - std::fs::write(file_path, code)?; + if let Some(output_directory) = self.output_directory.as_ref() { + let mut file_path = output_directory.to_owned(); + let full_file_name = Self::full_file_name(contract_path, None, IRType::EthIR); + file_path.push(full_file_name); + std::fs::write(file_path, code)?; + } Ok(()) } @@ -58,12 +69,15 @@ impl DebugConfig { contract_path: &str, module: &inkwell::module::Module, ) -> anyhow::Result<()> { - let llvm_code = module.print_to_string().to_string(); + if let Some(output_directory) = self.output_directory.as_ref() { + let llvm_code = module.print_to_string().to_string(); - let mut file_path = self.output_directory.to_owned(); - let full_file_name = Self::full_file_name(contract_path, Some("unoptimized"), IRType::LLVM); - file_path.push(full_file_name); - std::fs::write(file_path, llvm_code)?; + let mut file_path = output_directory.to_owned(); + let full_file_name = + Self::full_file_name(contract_path, Some("unoptimized"), IRType::LLVM); + file_path.push(full_file_name); + std::fs::write(file_path, llvm_code)?; + } Ok(()) } @@ -74,32 +88,39 @@ impl DebugConfig { contract_path: &str, module: &inkwell::module::Module, ) -> anyhow::Result<()> { - let llvm_code = module.print_to_string().to_string(); + if let Some(output_directory) = self.output_directory.as_ref() { + let llvm_code = module.print_to_string().to_string(); - let mut file_path = self.output_directory.to_owned(); - let full_file_name = Self::full_file_name(contract_path, Some("optimized"), IRType::LLVM); - file_path.push(full_file_name); - std::fs::write(file_path, llvm_code)?; + let mut file_path = output_directory.to_owned(); + let full_file_name = + Self::full_file_name(contract_path, Some("optimized"), IRType::LLVM); + file_path.push(full_file_name); + std::fs::write(file_path, llvm_code)?; + } Ok(()) } /// Dumps the assembly. pub fn dump_assembly(&self, contract_path: &str, code: &str) -> anyhow::Result<()> { - let mut file_path = self.output_directory.to_owned(); - let full_file_name = Self::full_file_name(contract_path, None, IRType::Assembly); - file_path.push(full_file_name); - std::fs::write(file_path, code)?; + if let Some(output_directory) = self.output_directory.as_ref() { + let mut file_path = output_directory.to_owned(); + let full_file_name = Self::full_file_name(contract_path, None, IRType::Assembly); + file_path.push(full_file_name); + std::fs::write(file_path, code)?; + } Ok(()) } /// Dumps the code object. pub fn dump_object(&self, contract_path: &str, code: &[u8]) -> anyhow::Result<()> { - let mut file_path = self.output_directory.to_owned(); - let full_file_name = Self::full_file_name(contract_path, None, IRType::SO); - file_path.push(full_file_name); - std::fs::write(file_path, code)?; + if let Some(output_directory) = self.output_directory.as_ref() { + let mut file_path = output_directory.to_owned(); + let full_file_name = Self::full_file_name(contract_path, None, IRType::SO); + file_path.push(full_file_name); + std::fs::write(file_path, code)?; + } Ok(()) } @@ -112,10 +133,12 @@ impl DebugConfig { contract_suffix: Option<&str>, stage_json: &Vec, ) -> anyhow::Result<()> { - let mut file_path = self.output_directory.to_owned(); - let full_file_name = Self::full_file_name(contract_path, contract_suffix, IRType::JSON); - file_path.push(full_file_name); - std::fs::write(file_path, stage_json)?; + if let Some(output_directory) = self.output_directory.as_ref() { + let mut file_path = output_directory.to_owned(); + let full_file_name = Self::full_file_name(contract_path, contract_suffix, IRType::JSON); + file_path.push(full_file_name); + std::fs::write(file_path, stage_json)?; + } Ok(()) } diff --git a/crates/llvm-context/src/lib.rs b/crates/llvm-context/src/lib.rs index 82397fd..72aad25 100644 --- a/crates/llvm-context/src/lib.rs +++ b/crates/llvm-context/src/lib.rs @@ -16,6 +16,7 @@ pub use self::polkavm::context::argument::Argument as PolkaVMArgument; pub use self::polkavm::context::attribute::Attribute as PolkaVMAttribute; pub use self::polkavm::context::build::Build as PolkaVMBuild; pub use self::polkavm::context::code_type::CodeType as PolkaVMCodeType; +pub use self::polkavm::context::debug_info::DebugInfo; pub use self::polkavm::context::evmla_data::EVMLAData as PolkaVMContextEVMLAData; pub use self::polkavm::context::function::block::evmla_data::key::Key as PolkaVMFunctionBlockKey; pub use self::polkavm::context::function::block::evmla_data::EVMLAData as PolkaVMFunctionBlockEVMLAData; diff --git a/crates/llvm-context/src/optimizer/settings/mod.rs b/crates/llvm-context/src/optimizer/settings/mod.rs index ac312ff..56dd7c0 100644 --- a/crates/llvm-context/src/optimizer/settings/mod.rs +++ b/crates/llvm-context/src/optimizer/settings/mod.rs @@ -9,7 +9,7 @@ use itertools::Itertools; use self::size_level::SizeLevel; -/// The LLVM optimizer settings. +/// The LLVM optimizer and code-gen settings. #[derive(Debug, Serialize, Deserialize, Clone, Eq)] pub struct Settings { /// The middle-end optimization level. diff --git a/crates/llvm-context/src/polkavm/context/debug_info.rs b/crates/llvm-context/src/polkavm/context/debug_info.rs index d90ad01..5c61f04 100644 --- a/crates/llvm-context/src/polkavm/context/debug_info.rs +++ b/crates/llvm-context/src/polkavm/context/debug_info.rs @@ -1,7 +1,43 @@ //! The LLVM debug information. +use std::cell::RefCell; + use inkwell::debug_info::AsDIScope; -use num::Zero; +use inkwell::debug_info::DIScope; + +/// Debug info scope stack +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ScopeStack<'ctx> { + stack: Vec>, +} + +// Abstract the type of the DIScope stack. +impl<'ctx> ScopeStack<'ctx> { + pub fn from(item: DIScope<'ctx>) -> Self { + Self { stack: vec![item] } + } + + /// Return the top of the scope stack, or None if the stack is empty. + pub fn top(&self) -> Option> { + self.stack.last().copied() + } + + /// Push a scope onto the stack. + pub fn push(&mut self, scope: DIScope<'ctx>) { + self.stack.push(scope) + } + + /// Pop the scope at the top of the stack and return it. + /// Return None if the stack is empty. + pub fn pop(&mut self) -> Option> { + self.stack.pop() + } + + /// Return the number of scopes on the stack. + pub fn len(&self) -> usize { + self.stack.len() + } +} /// The LLVM debug information. pub struct DebugInfo<'ctx> { @@ -9,6 +45,8 @@ pub struct DebugInfo<'ctx> { compile_unit: inkwell::debug_info::DICompileUnit<'ctx>, /// The debug info builder. builder: inkwell::debug_info::DebugInfoBuilder<'ctx>, + /// Enclosing debug info scopes. + scope_stack: RefCell>, } impl<'ctx> DebugInfo<'ctx> { @@ -35,19 +73,43 @@ impl<'ctx> DebugInfo<'ctx> { Self { compile_unit, builder, + scope_stack: RefCell::new(ScopeStack::from(compile_unit.as_debug_info_scope())), } } + /// Prepare an LLVM-IR module for debug-info generation + pub fn initialize_module( + &self, + llvm: &'ctx inkwell::context::Context, + module: &inkwell::module::Module<'ctx>, + ) { + let debug_metadata_value = llvm + .i32_type() + .const_int(inkwell::debug_info::debug_metadata_version() as u64, false); + module.add_basic_value_flag( + "Debug Info Version", + inkwell::module::FlagBehavior::Warning, + debug_metadata_value, + ); + self.push_scope(self.compilation_unit().get_file().as_debug_info_scope()); + } + + /// Finalize debug-info for an LLVM-IR module. + pub fn finalize_module(&self) { + self.builder().finalize() + } + /// Creates a function info. pub fn create_function( &self, name: &str, ) -> anyhow::Result> { + let flags = inkwell::debug_info::DIFlagsConstants::ZERO; let subroutine_type = self.builder.create_subroutine_type( self.compile_unit.get_file(), - Some(self.create_type(revive_common::BIT_LENGTH_FIELD)?), + Some(self.create_word_type(Some(flags))?.as_type()), &[], - inkwell::debug_info::DIFlags::zero(), + flags, ); let function = self.builder.create_function( @@ -60,7 +122,7 @@ impl<'ctx> DebugInfo<'ctx> { true, false, 1, - inkwell::debug_info::DIFlags::zero(), + flags, false, ); @@ -74,24 +136,55 @@ impl<'ctx> DebugInfo<'ctx> { Ok(function) } - /// Creates a primitive type info. - pub fn create_type( + /// Creates primitive integer type debug-info. + pub fn create_primitive_type( &self, bit_length: usize, - ) -> anyhow::Result> { + flags: Option, + ) -> anyhow::Result> { + let di_flags = flags.unwrap_or(inkwell::debug_info::DIFlagsConstants::ZERO); + let di_encoding: u32 = 0; + let type_name = String::from("U") + bit_length.to_string().as_str(); self.builder - .create_basic_type( - "U256", - bit_length as u64, - 0, - inkwell::debug_info::DIFlags::zero(), - ) - .map(|basic_type| basic_type.as_type()) + .create_basic_type(type_name.as_str(), bit_length as u64, di_encoding, di_flags) .map_err(|error| anyhow::anyhow!("Debug info error: {}", error)) } - /// Finalizes the builder. - pub fn finalize(&self) { - self.builder.finalize(); + /// Returns the debug-info model of word-sized integer types. + pub fn create_word_type( + &self, + flags: Option, + ) -> anyhow::Result> { + self.create_primitive_type(revive_common::BIT_LENGTH_WORD, flags) + } + + /// Return the DIBuilder. + pub fn builder(&self) -> &inkwell::debug_info::DebugInfoBuilder<'ctx> { + &self.builder + } + + /// Return the compilation unit. { + pub fn compilation_unit(&self) -> &inkwell::debug_info::DICompileUnit<'ctx> { + &self.compile_unit + } + + /// Push a debug-info scope onto the stack. + pub fn push_scope(&self, scope: DIScope<'ctx>) { + self.scope_stack.borrow_mut().push(scope) + } + + /// Pop the top of the debug-info scope stack and return it. + pub fn pop_scope(&self) -> Option> { + self.scope_stack.borrow_mut().pop() + } + + /// Return the top of the debug-info scope stack. + pub fn top_scope(&self) -> Option> { + self.scope_stack.borrow().top() + } + + /// Return the number of debug-info scopes on the scope stack. + pub fn num_scopes(&self) -> usize { + self.scope_stack.borrow().len() } } diff --git a/crates/llvm-context/src/polkavm/context/function/declaration.rs b/crates/llvm-context/src/polkavm/context/function/declaration.rs index c4c41f6..f95ea2d 100644 --- a/crates/llvm-context/src/polkavm/context/function/declaration.rs +++ b/crates/llvm-context/src/polkavm/context/function/declaration.rs @@ -17,4 +17,8 @@ impl<'ctx> Declaration<'ctx> { ) -> Self { Self { r#type, value } } + + pub fn function_value(&self) -> inkwell::values::FunctionValue<'ctx> { + self.value + } } diff --git a/crates/llvm-context/src/polkavm/context/function/mod.rs b/crates/llvm-context/src/polkavm/context/function/mod.rs index 1a63631..9527e41 100644 --- a/crates/llvm-context/src/polkavm/context/function/mod.rs +++ b/crates/llvm-context/src/polkavm/context/function/mod.rs @@ -11,6 +11,8 @@ pub mod yul_data; use std::collections::HashMap; +use inkwell::debug_info::AsDIScope; + use crate::optimizer::settings::size_level::SizeLevel; use crate::optimizer::Optimizer; use crate::polkavm::context::attribute::Attribute; @@ -94,6 +96,14 @@ impl<'ctx> Function<'ctx> { self.declaration } + /// Returns the debug-info scope. + pub fn get_debug_scope(&self) -> Option> { + self.declaration() + .function_value() + .get_subprogram() + .map(|scp| scp.as_debug_info_scope()) + } + /// Returns the N-th parameter of the function. pub fn get_nth_param(&self, index: usize) -> inkwell::values::BasicValueEnum<'ctx> { self.declaration() diff --git a/crates/llvm-context/src/polkavm/context/function/runtime/deploy_code.rs b/crates/llvm-context/src/polkavm/context/function/runtime/deploy_code.rs index 8649da3..279b1e8 100644 --- a/crates/llvm-context/src/polkavm/context/function/runtime/deploy_code.rs +++ b/crates/llvm-context/src/polkavm/context/function/runtime/deploy_code.rs @@ -54,12 +54,14 @@ where } fn into_llvm(self, context: &mut Context) -> anyhow::Result<()> { - context.set_current_function(runtime::FUNCTION_DEPLOY_CODE)?; + context.set_current_function(runtime::FUNCTION_DEPLOY_CODE, None)?; context.set_basic_block(context.current_function().borrow().entry_block()); context.set_code_type(CodeType::Deploy); self.inner.into_llvm(context)?; + context.set_debug_location(0, 0, None)?; + match context .basic_block() .get_last_instruction() @@ -72,8 +74,11 @@ where } context.set_basic_block(context.current_function().borrow().return_block()); + context.set_debug_location(0, 0, None)?; context.build_return(None); + context.pop_debug_scope(); + Ok(()) } } diff --git a/crates/llvm-context/src/polkavm/context/function/runtime/entry.rs b/crates/llvm-context/src/polkavm/context/function/runtime/entry.rs index 397434a..582c926 100644 --- a/crates/llvm-context/src/polkavm/context/function/runtime/entry.rs +++ b/crates/llvm-context/src/polkavm/context/function/runtime/entry.rs @@ -125,6 +125,8 @@ impl Entry { where D: Dependency + Clone, { + context.set_debug_location(0, 0, None)?; + let is_deploy = context .current_function() .borrow() @@ -214,7 +216,7 @@ where true, ); - context.set_current_function(runtime::FUNCTION_ENTRY)?; + context.set_current_function(runtime::FUNCTION_ENTRY, None)?; context.set_basic_block(context.current_function().borrow().entry_block()); Self::initialize_globals(context)?; @@ -225,6 +227,8 @@ where context.set_basic_block(context.current_function().borrow().return_block()); context.build_unreachable(); + context.pop_debug_scope(); + Ok(()) } } diff --git a/crates/llvm-context/src/polkavm/context/function/runtime/immutable_data_load.rs b/crates/llvm-context/src/polkavm/context/function/runtime/immutable_data_load.rs index e9e1665..dbb21e5 100644 --- a/crates/llvm-context/src/polkavm/context/function/runtime/immutable_data_load.rs +++ b/crates/llvm-context/src/polkavm/context/function/runtime/immutable_data_load.rs @@ -34,7 +34,7 @@ where } fn into_llvm(self, context: &mut Context) -> anyhow::Result<()> { - context.set_current_function(runtime::FUNCTION_LOAD_IMMUTABLE_DATA)?; + context.set_current_function(runtime::FUNCTION_LOAD_IMMUTABLE_DATA, None)?; context.set_basic_block(context.current_function().borrow().entry_block()); let immutable_data_size_pointer = context @@ -111,6 +111,8 @@ where context.set_basic_block(return_block); context.build_return(None); + context.pop_debug_scope(); + Ok(()) } } diff --git a/crates/llvm-context/src/polkavm/context/function/runtime/runtime_code.rs b/crates/llvm-context/src/polkavm/context/function/runtime/runtime_code.rs index 439340c..8cf1435 100644 --- a/crates/llvm-context/src/polkavm/context/function/runtime/runtime_code.rs +++ b/crates/llvm-context/src/polkavm/context/function/runtime/runtime_code.rs @@ -54,11 +54,14 @@ where } fn into_llvm(self, context: &mut Context) -> anyhow::Result<()> { - context.set_current_function(runtime::FUNCTION_RUNTIME_CODE)?; + context.set_current_function(runtime::FUNCTION_RUNTIME_CODE, None)?; context.set_basic_block(context.current_function().borrow().entry_block()); context.set_code_type(CodeType::Runtime); + self.inner.into_llvm(context)?; + context.set_debug_location(0, 0, None)?; + match context .basic_block() .get_last_instruction() @@ -73,6 +76,8 @@ where context.set_basic_block(context.current_function().borrow().return_block()); context.build_unreachable(); + context.pop_debug_scope(); + Ok(()) } } diff --git a/crates/llvm-context/src/polkavm/context/mod.rs b/crates/llvm-context/src/polkavm/context/mod.rs index 9feb925..65c4ac5 100644 --- a/crates/llvm-context/src/polkavm/context/mod.rs +++ b/crates/llvm-context/src/polkavm/context/mod.rs @@ -5,7 +5,7 @@ pub mod argument; pub mod attribute; pub mod build; pub mod code_type; -// pub mod debug_info; +pub mod debug_info; pub mod evmla_data; pub mod function; pub mod global; @@ -21,6 +21,8 @@ use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; +use inkwell::debug_info::AsDIScope; +use inkwell::debug_info::DIScope; use inkwell::types::BasicType; use inkwell::values::BasicValue; @@ -35,7 +37,7 @@ use self::address_space::AddressSpace; use self::attribute::Attribute; use self::build::Build; use self::code_type::CodeType; -// use self::debug_info::DebugInfo; +use self::debug_info::DebugInfo; use self::evmla_data::EVMLAData; use self::function::declaration::Declaration as FunctionDeclaration; use self::function::intrinsics::Intrinsics; @@ -85,9 +87,9 @@ where /// Whether to append the metadata hash at the end of bytecode. include_metadata_hash: bool, /// The debug info of the current module. - // debug_info: DebugInfo<'ctx>, + debug_info: Option>, /// The debug configuration telling whether to dump the needed IRs. - debug_config: Option, + debug_config: DebugConfig, /// The Solidity data. solidity_data: Option, @@ -207,7 +209,7 @@ where optimizer: Optimizer, dependency_manager: Option, include_metadata_hash: bool, - debug_config: Option, + debug_config: DebugConfig, ) -> Self { Self::link_stdlib_module(llvm, &module); Self::link_polkavm_imports(llvm, &module); @@ -216,6 +218,11 @@ where let intrinsics = Intrinsics::new(llvm, &module); let llvm_runtime = LLVMRuntime::new(llvm, &module, &optimizer); + let debug_info = debug_config.emit_debug_info.then(|| { + let debug_info = DebugInfo::new(&module); + debug_info.initialize_module(llvm, &module); + debug_info + }); Self { llvm, @@ -232,7 +239,8 @@ where dependency_manager, include_metadata_hash, - // debug_info, + + debug_info, debug_config, solidity_data: None, @@ -255,9 +263,9 @@ where let target_machine = TargetMachine::new(Target::PVM, self.optimizer.settings())?; target_machine.set_target_data(self.module()); - if let Some(ref debug_config) = self.debug_config { - debug_config.dump_llvm_ir_unoptimized(contract_path, self.module())?; - } + self.debug_config + .dump_llvm_ir_unoptimized(contract_path, self.module())?; + self.verify().map_err(|error| { anyhow::anyhow!( "The contract `{}` unoptimized LLVM IR verification error: {}", @@ -275,9 +283,10 @@ where error ) })?; - if let Some(ref debug_config) = self.debug_config { - debug_config.dump_llvm_ir_optimized(contract_path, self.module())?; - } + + self.debug_config + .dump_llvm_ir_optimized(contract_path, self.module())?; + self.verify().map_err(|error| { anyhow::anyhow!( "The contract `{}` optimized LLVM IR verification error: {}", @@ -298,11 +307,11 @@ where let shared_object = revive_linker::link(buffer.as_slice())?; - if let Some(ref debug_config) = self.debug_config { - debug_config.dump_object(contract_path, &shared_object)?; - } + self.debug_config + .dump_object(contract_path, &shared_object)?; - let polkavm_bytecode = revive_linker::polkavm_linker(shared_object)?; + let polkavm_bytecode = + revive_linker::polkavm_linker(shared_object, !self.debug_config().emit_debug_info)?; let build = match crate::polkavm::build_assembly_text( contract_path, @@ -428,6 +437,21 @@ where ) -> anyhow::Result>>> { let value = self.module().add_function(name, r#type, linkage); + if self.debug_info().is_some() { + self.builder().unset_current_debug_location(); + let func_scope = match value.get_subprogram() { + None => { + let fn_name = value.get_name().to_str()?; + let scp = self.build_function_debug_info(fn_name, 0)?; + value.set_subprogram(scp); + scp + } + Some(scp) => scp, + }; + self.push_debug_scope(func_scope.as_debug_info_scope()); + self.set_debug_location(0, 0, Some(func_scope.as_debug_info_scope()))?; + } + let entry_block = self.llvm.append_basic_block(value, "entry"); let return_block = self.llvm.append_basic_block(value, "return"); @@ -461,6 +485,8 @@ where let function = Rc::new(RefCell::new(function)); self.functions.insert(name.to_string(), function.clone()); + self.pop_debug_scope(); + Ok(function) } @@ -476,15 +502,95 @@ where .expect("Must be declared before use") } - /// Sets the current active function. - pub fn set_current_function(&mut self, name: &str) -> anyhow::Result<()> { + /// Sets the current active function. If debug-info generation is enabled, + /// constructs a debug-scope and pushes in on the scope-stack. + pub fn set_current_function(&mut self, name: &str, line: Option) -> anyhow::Result<()> { let function = self.functions.get(name).cloned().ok_or_else(|| { anyhow::anyhow!("Failed to activate an undeclared function `{}`", name) })?; self.current_function = Some(function); + + if let Some(scope) = self.current_function().borrow().get_debug_scope() { + self.push_debug_scope(scope); + } + self.set_debug_location(line.unwrap_or_default(), 0, None)?; + Ok(()) } + /// Builds a debug-info scope for a function. + pub fn build_function_debug_info( + &self, + name: &str, + line_no: u32, + ) -> anyhow::Result> { + let Some(debug_info) = self.debug_info() else { + anyhow::bail!("expected debug-info builders"); + }; + let builder = debug_info.builder(); + let file = debug_info.compilation_unit().get_file(); + let scope = file.as_debug_info_scope(); + let flags = inkwell::debug_info::DIFlagsConstants::PUBLIC; + let return_type = debug_info.create_word_type(Some(flags))?.as_type(); + let subroutine_type = builder.create_subroutine_type(file, Some(return_type), &[], flags); + + Ok(builder.create_function( + scope, + name, + None, + file, + line_no, + subroutine_type, + false, + true, + 1, + flags, + false, + )) + } + + /// Set the debug info location. + /// + /// No-op if the emitting debug info is disabled. + /// + /// If `scope` is `None` the top scope will be used. + pub fn set_debug_location( + &self, + line: u32, + column: u32, + scope: Option>, + ) -> anyhow::Result<()> { + let Some(debug_info) = self.debug_info() else { + return Ok(()); + }; + let scope = match scope { + Some(scp) => scp, + None => debug_info.top_scope().expect("expected a debug-info scope"), + }; + let location = + debug_info + .builder() + .create_debug_location(self.llvm(), line, column, scope, None); + + self.builder().set_current_debug_location(location); + + Ok(()) + } + + /// Pushes a debug-info scope to the stack. + pub fn push_debug_scope(&self, scope: DIScope<'ctx>) { + if let Some(debug_info) = self.debug_info() { + debug_info.push_scope(scope); + } + } + + /// Pops the top of the debug-info scope stack. + pub fn pop_debug_scope(&self) { + if let Some(debug_info) = self.debug_info() { + debug_info.pop_scope(); + } + } + /// Pushes a new loop context to the stack. pub fn push_loop( &mut self, @@ -554,9 +660,14 @@ where .expect("The dependency manager is unset") } + /// Returns the debug info. + pub fn debug_info(&self) -> Option<&DebugInfo<'ctx>> { + self.debug_info.as_ref() + } + /// Returns the debug config reference. - pub fn debug_config(&self) -> Option<&DebugConfig> { - self.debug_config.as_ref() + pub fn debug_config(&self) -> &DebugConfig { + &self.debug_config } /// Appends a new basic block to the current function. diff --git a/crates/llvm-context/src/polkavm/context/tests.rs b/crates/llvm-context/src/polkavm/context/tests.rs index 5498822..3e40481 100644 --- a/crates/llvm-context/src/polkavm/context/tests.rs +++ b/crates/llvm-context/src/polkavm/context/tests.rs @@ -15,7 +15,7 @@ pub fn create_context( let module = llvm.create_module("test"); let optimizer = Optimizer::new(optimizer_settings); - Context::::new(llvm, module, optimizer, None, true, None) + Context::::new(llvm, module, optimizer, None, true, Default::default()) } #[test] diff --git a/crates/llvm-context/src/polkavm/mod.rs b/crates/llvm-context/src/polkavm/mod.rs index 5c88713..b6395b6 100644 --- a/crates/llvm-context/src/polkavm/mod.rs +++ b/crates/llvm-context/src/polkavm/mod.rs @@ -29,7 +29,7 @@ pub fn build_assembly_text( contract_path: &str, bytecode: &[u8], metadata_hash: Option<[u8; revive_common::BYTE_LENGTH_WORD]>, - debug_config: Option<&DebugConfig>, + debug_config: &DebugConfig, ) -> anyhow::Result { let program_blob = ProgramBlob::parse(bytecode.into()) .map_err(anyhow::Error::msg) @@ -49,9 +49,7 @@ pub fn build_assembly_text( format!("Failed to convert disassembled code to string for contract: {contract_path}") })?; - if let Some(debug_config) = debug_config { - debug_config.dump_assembly(contract_path, &assembly_text)?; - } + debug_config.dump_assembly(contract_path, &assembly_text)?; Ok(Build::new( assembly_text.to_owned(), @@ -98,7 +96,7 @@ pub trait Dependency { path: &str, optimizer_settings: OptimizerSettings, include_metadata_hash: bool, - debug_config: Option, + debug_config: DebugConfig, ) -> anyhow::Result; /// Resolves a full contract path. @@ -118,7 +116,7 @@ impl Dependency for DummyDependency { _path: &str, _optimizer_settings: OptimizerSettings, _include_metadata_hash: bool, - _debug_config: Option, + _debug_config: DebugConfig, ) -> anyhow::Result { Ok(String::new()) } diff --git a/crates/solidity/src/evmla/assembly/mod.rs b/crates/solidity/src/evmla/assembly/mod.rs index 06ac8e9..6e0a56e 100644 --- a/crates/solidity/src/evmla/assembly/mod.rs +++ b/crates/solidity/src/evmla/assembly/mod.rs @@ -212,9 +212,10 @@ where ) -> anyhow::Result<()> { let full_path = self.full_path().to_owned(); - if let Some(debug_config) = context.debug_config() { - debug_config.dump_evmla(full_path.as_str(), self.to_string().as_str())?; - } + context + .debug_config() + .dump_evmla(full_path.as_str(), self.to_string().as_str())?; + let deploy_code_blocks = EtherealIR::get_blocks( context.evmla().version.to_owned(), revive_llvm_context::PolkaVMCodeType::Deploy, @@ -228,9 +229,11 @@ where .ok_or_else(|| anyhow::anyhow!("Runtime code data not found"))? .remove("0") .expect("Always exists"); - if let Some(debug_config) = context.debug_config() { - debug_config.dump_evmla(full_path.as_str(), data.to_string().as_str())?; - } + + context + .debug_config() + .dump_evmla(full_path.as_str(), data.to_string().as_str())?; + let runtime_code_instructions = match data { Data::Assembly(assembly) => assembly .code @@ -253,9 +256,11 @@ where blocks.extend(runtime_code_blocks); let mut ethereal_ir = EtherealIR::new(context.evmla().version.to_owned(), extra_metadata, blocks)?; - if let Some(debug_config) = context.debug_config() { - debug_config.dump_ethir(full_path.as_str(), ethereal_ir.to_string().as_str())?; - } + + context + .debug_config() + .dump_ethir(full_path.as_str(), ethereal_ir.to_string().as_str())?; + ethereal_ir.declare(context)?; ethereal_ir.into_llvm(context)?; diff --git a/crates/solidity/src/evmla/ethereal_ir/function/mod.rs b/crates/solidity/src/evmla/ethereal_ir/function/mod.rs index 52547cd..afb6efb 100644 --- a/crates/solidity/src/evmla/ethereal_ir/function/mod.rs +++ b/crates/solidity/src/evmla/ethereal_ir/function/mod.rs @@ -1175,7 +1175,7 @@ where } fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext) -> anyhow::Result<()> { - context.set_current_function(self.name.as_str())?; + context.set_current_function(self.name.as_str(), None)?; for (key, blocks) in self.blocks.iter() { for (index, block) in blocks.iter().enumerate() { @@ -1297,6 +1297,8 @@ where } } + context.pop_debug_scope(); + Ok(()) } } diff --git a/crates/solidity/src/lib.rs b/crates/solidity/src/lib.rs index b5c38ab..1edc20a 100644 --- a/crates/solidity/src/lib.rs +++ b/crates/solidity/src/lib.rs @@ -54,7 +54,7 @@ pub fn yul( solc: &mut SolcCompiler, optimizer_settings: revive_llvm_context::OptimizerSettings, include_metadata_hash: bool, - debug_config: Option, + debug_config: revive_llvm_context::DebugConfig, ) -> anyhow::Result { let path = match input_files.len() { 1 => input_files.first().expect("Always exists"), @@ -85,7 +85,7 @@ pub fn llvm_ir( input_files: &[PathBuf], optimizer_settings: revive_llvm_context::OptimizerSettings, include_metadata_hash: bool, - debug_config: Option, + debug_config: revive_llvm_context::DebugConfig, ) -> anyhow::Result { let path = match input_files.len() { 1 => input_files.first().expect("Always exists"), @@ -119,7 +119,7 @@ pub fn standard_output( allow_paths: Option, remappings: Option>, suppressed_warnings: Option>, - debug_config: Option, + debug_config: revive_llvm_context::DebugConfig, ) -> anyhow::Result { let solc_version = solc.version()?; let solc_pipeline = SolcPipeline::new(&solc_version, force_evmla); @@ -178,7 +178,7 @@ pub fn standard_output( libraries, solc_pipeline, &solc_version, - debug_config.as_ref(), + &debug_config, )?; let build = project.compile(optimizer_settings, include_metadata_hash, debug_config)?; @@ -195,7 +195,7 @@ pub fn standard_json( base_path: Option, include_paths: Vec, allow_paths: Option, - debug_config: Option, + debug_config: revive_llvm_context::DebugConfig, ) -> anyhow::Result<()> { let solc_version = solc.version()?; let solc_pipeline = SolcPipeline::new(&solc_version, force_evmla); @@ -240,7 +240,7 @@ pub fn standard_json( libraries, solc_pipeline, &solc_version, - debug_config.as_ref(), + &debug_config, )?; if detect_missing_libraries { @@ -271,7 +271,7 @@ pub fn combined_json( allow_paths: Option, remappings: Option>, suppressed_warnings: Option>, - debug_config: Option, + debug_config: revive_llvm_context::DebugConfig, output_directory: Option, overwrite: bool, ) -> anyhow::Result<()> { diff --git a/crates/solidity/src/process/input.rs b/crates/solidity/src/process/input.rs index 203ea66..e80290e 100644 --- a/crates/solidity/src/process/input.rs +++ b/crates/solidity/src/process/input.rs @@ -19,7 +19,7 @@ pub struct Input { /// The optimizer settings. pub optimizer_settings: revive_llvm_context::OptimizerSettings, /// The debug output config. - pub debug_config: Option, + pub debug_config: revive_llvm_context::DebugConfig, } impl Input { @@ -29,7 +29,7 @@ impl Input { project: Project, include_metadata_hash: bool, optimizer_settings: revive_llvm_context::OptimizerSettings, - debug_config: Option, + debug_config: revive_llvm_context::DebugConfig, ) -> Self { Self { contract, diff --git a/crates/solidity/src/process/mod.rs b/crates/solidity/src/process/mod.rs index 3d882ae..5135503 100644 --- a/crates/solidity/src/process/mod.rs +++ b/crates/solidity/src/process/mod.rs @@ -85,17 +85,16 @@ pub fn call(input: Input) -> anyhow::Result { })?; #[cfg(debug_assertions)] - if let Some(dbg_config) = &input.debug_config { - dbg_config - .dump_stage_output(&input.contract.path, Some("stage"), &input_json) - .map_err(|error| { - anyhow::anyhow!( - "{:?} failed to log the recursive process output: {:?}", - executable, - error, - ) - })?; - } + input + .debug_config + .dump_stage_output(&input.contract.path, Some("stage"), &input_json) + .map_err(|error| { + anyhow::anyhow!( + "{:?} failed to log the recursive process output: {:?}", + executable, + error, + ) + })?; process .stdin diff --git a/crates/solidity/src/project/contract/mod.rs b/crates/solidity/src/project/contract/mod.rs index fdbdb3f..24d56fd 100644 --- a/crates/solidity/src/project/contract/mod.rs +++ b/crates/solidity/src/project/contract/mod.rs @@ -79,7 +79,7 @@ impl Contract { project: Project, optimizer_settings: revive_llvm_context::OptimizerSettings, include_metadata_hash: bool, - debug_config: Option, + debug_config: revive_llvm_context::DebugConfig, ) -> anyhow::Result { let llvm = inkwell::context::Context::create(); let optimizer = revive_llvm_context::Optimizer::new(optimizer_settings); @@ -104,6 +104,7 @@ impl Contract { let module = match self.ir { IR::LLVMIR(ref llvm_ir) => { + // Create the output module let memory_buffer = inkwell::memory_buffer::MemoryBuffer::create_from_memory_range_copy( llvm_ir.source.as_bytes(), @@ -114,6 +115,7 @@ impl Contract { } _ => llvm.create_module(self.path.as_str()), }; + let mut context = revive_llvm_context::PolkaVMContext::new( &llvm, module, @@ -151,6 +153,10 @@ impl Contract { ) })?; + if let Some(debug_info) = context.debug_info() { + debug_info.finalize_module() + } + let build = context.build(self.path.as_str(), metadata_hash)?; Ok(ContractBuild::new( diff --git a/crates/solidity/src/project/mod.rs b/crates/solidity/src/project/mod.rs index c6fc5df..cca89e6 100644 --- a/crates/solidity/src/project/mod.rs +++ b/crates/solidity/src/project/mod.rs @@ -63,7 +63,7 @@ impl Project { self, optimizer_settings: revive_llvm_context::OptimizerSettings, include_metadata_hash: bool, - debug_config: Option, + debug_config: revive_llvm_context::DebugConfig, ) -> anyhow::Result { let project = self.clone(); let results: BTreeMap> = self @@ -238,7 +238,7 @@ impl revive_llvm_context::PolkaVMDependency for Project { identifier: &str, optimizer_settings: revive_llvm_context::OptimizerSettings, include_metadata_hash: bool, - debug_config: Option, + debug_config: revive_llvm_context::DebugConfig, ) -> anyhow::Result { let contract_path = project.resolve_path(identifier)?; let contract = project diff --git a/crates/solidity/src/resolc/arguments.rs b/crates/solidity/src/resolc/arguments.rs index bb877a9..01d997a 100644 --- a/crates/solidity/src/resolc/arguments.rs +++ b/crates/solidity/src/resolc/arguments.rs @@ -138,6 +138,11 @@ pub struct Arguments { #[structopt(long = "suppress-warnings")] pub suppress_warnings: Option>, + /// Generate source based debug information in the output code file. This only has an effect + /// with the LLVM-IR code generator and is ignored otherwise. + #[structopt(short = 'g')] + pub emit_source_debug_info: bool, + /// Dump all IRs to files in the specified directory. /// Only for testing and debugging. #[structopt(long = "debug-output-dir")] diff --git a/crates/solidity/src/resolc/main.rs b/crates/solidity/src/resolc/main.rs index 881895b..9861f24 100644 --- a/crates/solidity/src/resolc/main.rs +++ b/crates/solidity/src/resolc/main.rs @@ -66,11 +66,12 @@ fn main_inner() -> anyhow::Result<()> { let debug_config = match arguments.debug_output_directory { Some(ref debug_output_directory) => { std::fs::create_dir_all(debug_output_directory.as_path())?; - Some(revive_llvm_context::DebugConfig::new( - debug_output_directory.to_owned(), - )) + revive_llvm_context::DebugConfig::new( + Some(debug_output_directory.to_owned()), + arguments.emit_source_debug_info, + ) } - None => None, + None => revive_llvm_context::DebugConfig::new(None, arguments.emit_source_debug_info), }; let (input_files, remappings) = arguments.split_input_files_and_remappings()?; diff --git a/crates/solidity/src/solc/standard_json/output/mod.rs b/crates/solidity/src/solc/standard_json/output/mod.rs index 0d64285..c590688 100644 --- a/crates/solidity/src/solc/standard_json/output/mod.rs +++ b/crates/solidity/src/solc/standard_json/output/mod.rs @@ -56,7 +56,7 @@ impl Output { libraries: BTreeMap>, pipeline: SolcPipeline, solc_version: &SolcVersion, - debug_config: Option<&revive_llvm_context::DebugConfig>, + debug_config: &revive_llvm_context::DebugConfig, ) -> anyhow::Result { if let SolcPipeline::EVMLA = pipeline { self.preprocess_dependencies()?; @@ -90,9 +90,7 @@ impl Output { continue; } - if let Some(debug_config) = debug_config { - debug_config.dump_yul(full_path.as_str(), ir_optimized.as_str())?; - } + debug_config.dump_yul(full_path.as_str(), ir_optimized.as_str())?; let mut lexer = Lexer::new(ir_optimized.to_owned()); let object = Object::parse(&mut lexer, None).map_err(|error| { diff --git a/crates/solidity/src/test_utils.rs b/crates/solidity/src/test_utils.rs index ef80629..855a011 100644 --- a/crates/solidity/src/test_utils.rs +++ b/crates/solidity/src/test_utils.rs @@ -23,6 +23,9 @@ static EVM_BLOB_CACHE: Lazy>>> = Lazy::new(Def static EVM_RUNTIME_BLOB_CACHE: Lazy>>> = Lazy::new(Default::default); +const DEBUG_CONFIG: revive_llvm_context::DebugConfig = + revive_llvm_context::DebugConfig::new(None, true); + #[derive(Hash, PartialEq, Eq)] struct CachedBlob { contract_name: String, @@ -102,9 +105,10 @@ pub fn build_solidity_with_options( let mut output = solc.standard_json(input, pipeline, None, vec![], None)?; - let project = output.try_to_project(sources, libraries, pipeline, &solc_version, None)?; + let project = + output.try_to_project(sources, libraries, pipeline, &solc_version, &DEBUG_CONFIG)?; - let build: crate::Build = project.compile(optimizer_settings, false, None)?; + let build: crate::Build = project.compile(optimizer_settings, false, DEBUG_CONFIG)?; build.write_to_standard_json(&mut output, &solc_version)?; Ok(output) @@ -194,7 +198,8 @@ pub fn build_solidity_and_detect_missing_libraries( let mut output = solc.standard_json(input, pipeline, None, vec![], None)?; - let project = output.try_to_project(sources, libraries, pipeline, &solc_version, None)?; + let project = + output.try_to_project(sources, libraries, pipeline, &solc_version, &DEBUG_CONFIG)?; let missing_libraries = project.get_missing_libraries(); missing_libraries.write_to_standard_json(&mut output, &solc.version()?)?; @@ -212,7 +217,7 @@ pub fn build_yul(source_code: &str) -> anyhow::Result<()> { let project = Project::try_from_yul_string(PathBuf::from("test.yul").as_path(), source_code, None)?; - let _build = project.compile(optimizer_settings, false, None)?; + let _build = project.compile(optimizer_settings, false, DEBUG_CONFIG)?; Ok(()) } diff --git a/crates/solidity/src/tests/cli-tests/src/entities.ts b/crates/solidity/src/tests/cli-tests/src/entities.ts index 48a6c37..a232ad1 100644 --- a/crates/solidity/src/tests/cli-tests/src/entities.ts +++ b/crates/solidity/src/tests/cli-tests/src/entities.ts @@ -3,8 +3,11 @@ import * as path from 'path'; const outputDir = 'artifacts'; const binExtension = ':C.pvm'; const asmExtension = ':C.pvmasm'; +const llvmExtension = '.ll' const contractSolFilename = 'contract.sol'; const contractYulFilename = 'contract.yul'; +const contractOptimizedLLVMFilename = contractSolFilename + '.C.optimized'; +const contractUnoptimizedLLVMFilename = contractSolFilename + '.C.unoptimized'; const pathToOutputDir = path.join(__dirname, '..', outputDir); const pathToContracts = path.join(__dirname, '..', 'src', 'contracts'); const pathToBasicYulContract = path.join(pathToContracts, 'yul', contractYulFilename); @@ -16,8 +19,11 @@ export const paths = { outputDir: outputDir, binExtension: binExtension, asmExtension: asmExtension, + llvmExtension: llvmExtension, contractSolFilename: contractSolFilename, contractYulFilename: contractYulFilename, + contractOptimizedLLVMFilename: contractOptimizedLLVMFilename, + contractUnoptimizedLLVMFilename: contractUnoptimizedLLVMFilename, pathToOutputDir: pathToOutputDir, pathToContracts: pathToContracts, pathToBasicSolContract: pathToBasicSolContract, diff --git a/crates/solidity/src/tests/cli-tests/tests/common.test.ts b/crates/solidity/src/tests/cli-tests/tests/common.test.ts index ea5a8f7..afd624f 100644 --- a/crates/solidity/src/tests/cli-tests/tests/common.test.ts +++ b/crates/solidity/src/tests/cli-tests/tests/common.test.ts @@ -1,4 +1,4 @@ -import {executeCommand, isFolderExist, isFileExist, isFileEmpty} from "../src/helper"; +import { executeCommand, isFolderExist, isFileExist, isFileEmpty } from "../src/helper"; import { paths } from '../src/entities'; @@ -76,3 +76,69 @@ describe("Default run a command from the help", () => { expect(result.output).not.toMatch(/([Ee]rror|[Ww]arning|[Ff]ail)/i); }); }); + +describe("Run resolc with source debug information", () => { + const commands = [ + `resolc -g ${paths.pathToBasicSolContract} --bin --asm --output-dir "${paths.pathToOutputDir}"`, + `resolc --disable-solc-optimizer -g ${paths.pathToBasicSolContract} --bin --asm --output-dir "${paths.pathToOutputDir}"` + ]; // potential issue on resolc with full path on Windows cmd`; + + for (var idx in commands) { + const command = commands[idx]; + const result = executeCommand(command); + + it("Compiler run successful", () => { + expect(result.output).toMatch(/(Compiler run successful.)/i); + }); + it("Exit code = 0", () => { + expect(result.exitCode).toBe(0); + }); + it("Output dir is created", () => { + expect(isFolderExist(paths.pathToOutputDir)).toBe(true); + }); + it("Output files are created", () => { // a bug on windows + expect(isFileExist(paths.pathToOutputDir, paths.contractSolFilename, paths.binExtension)).toBe(true); + expect(isFileExist(paths.pathToOutputDir, paths.contractSolFilename, paths.asmExtension)).toBe(true); + }); + it("the output files are not empty", () => { + expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false); + expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false); + }); + it("No 'Error'/'Fail' in the output", () => { + expect(result.output).not.toMatch(/([Ee]rror|[Ff]ail)/i); + }); + } +}); + +describe("Run resolc with source debug information, check LLVM debug-info", () => { + const commands = [ + `resolc -g ${paths.pathToBasicSolContract} --debug-output-dir="${paths.pathToOutputDir}"`, + `resolc -g --disable-solc-optimizer ${paths.pathToBasicSolContract} --debug-output-dir="${paths.pathToOutputDir}"` + ]; // potential issue on resolc with full path on Windows cmd`; + + for (var idx in commands) { + const command = commands[idx]; + const result = executeCommand(command); + + it("Compiler run successful", () => { + expect(result.output).toMatch(/(Compiler run successful.)/i); + }); + it("Exit code = 0", () => { + expect(result.exitCode).toBe(0); + }); + it("Output dir is created", () => { + expect(isFolderExist(paths.pathToOutputDir)).toBe(true); + }); + it("Output files are created", () => { // a bug on windows + expect(isFileExist(paths.pathToOutputDir, paths.contractOptimizedLLVMFilename, paths.llvmExtension)).toBe(true); + expect(isFileExist(paths.pathToOutputDir, paths.contractUnoptimizedLLVMFilename, paths.llvmExtension)).toBe(true); + }); + it("the output files are not empty", () => { + expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false); + expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false); + }); + it("No 'Error'/'Fail' in the output", () => { + expect(result.output).not.toMatch(/([Ee]rror|[Ff]ail)/i); + }); + } +}); diff --git a/crates/solidity/src/yul/lexer/mod.rs b/crates/solidity/src/yul/lexer/mod.rs index b7296e4..ca26e8f 100644 --- a/crates/solidity/src/yul/lexer/mod.rs +++ b/crates/solidity/src/yul/lexer/mod.rs @@ -21,7 +21,7 @@ pub struct Lexer { /// The input source code. input: String, /// The number of characters processed so far. - offset: usize, + offset: u32, /// The current location. location: Location, /// The peeked lexeme, waiting to be fetched. @@ -48,8 +48,17 @@ impl Lexer { return Ok(peeked); } - while self.offset < self.input.len() { - let input = &self.input[self.offset..]; + while self.offset + < self + .input + .len() + .try_into() + .map_err(|_| Error::InvalidLexeme { + location: self.location, + sequence: Default::default(), + })? + { + let input = &self.input[(self.offset as usize)..]; if input.starts_with(|character| char::is_ascii_whitespace(&character)) { if input.starts_with('\n') { @@ -101,12 +110,13 @@ impl Lexer { return Ok(token); } - let end = self.input[self.offset..] + let end = self.input[(self.offset as usize)..] .find(char::is_whitespace) .unwrap_or(self.input.len()); return Err(Error::InvalidLexeme { location: self.location, - sequence: self.input[self.offset..self.offset + end].to_owned(), + sequence: self.input[(self.offset as usize)..(self.offset as usize) + end] + .to_owned(), }); } diff --git a/crates/solidity/src/yul/lexer/token/lexeme/comment/multi_line.rs b/crates/solidity/src/yul/lexer/token/lexeme/comment/multi_line.rs index 248ad0f..84dbf58 100644 --- a/crates/solidity/src/yul/lexer/token/lexeme/comment/multi_line.rs +++ b/crates/solidity/src/yul/lexer/token/lexeme/comment/multi_line.rs @@ -19,12 +19,20 @@ impl Comment { let end_position = input.find(Self::END).unwrap_or(input.len()); let input = &input[..end_position]; - let length = end_position + Self::END.len(); - let lines = input.matches('\n').count(); + let length = (end_position + Self::END.len()) + .try_into() + .expect("the YUL should be of reasonable size"); + let lines = input + .matches('\n') + .count() + .try_into() + .expect("the YUL should be of reasonable size"); let columns = match input.rfind('\n') { Some(new_line) => end_position - (new_line + 1), None => end_position, - }; + } + .try_into() + .expect("the YUL should be of reasonable size"); Token::new(Location::new(lines, columns), Lexeme::Comment, length) } diff --git a/crates/solidity/src/yul/lexer/token/lexeme/comment/single_line.rs b/crates/solidity/src/yul/lexer/token/lexeme/comment/single_line.rs index 9afacdd..c30c2e5 100644 --- a/crates/solidity/src/yul/lexer/token/lexeme/comment/single_line.rs +++ b/crates/solidity/src/yul/lexer/token/lexeme/comment/single_line.rs @@ -17,7 +17,9 @@ impl Comment { /// Returns the comment's length, including the trimmed whitespace around it. pub fn parse(input: &str) -> Token { let end_position = input.find(Self::END).unwrap_or(input.len()); - let length = end_position + Self::END.len(); + let length = (end_position + Self::END.len()) + .try_into() + .expect("the YUL should be of reasonable size"); Token::new(Location::new(1, 1), Lexeme::Comment, length) } diff --git a/crates/solidity/src/yul/lexer/token/lexeme/identifier.rs b/crates/solidity/src/yul/lexer/token/lexeme/identifier.rs index 9a2a6d4..df2aa89 100644 --- a/crates/solidity/src/yul/lexer/token/lexeme/identifier.rs +++ b/crates/solidity/src/yul/lexer/token/lexeme/identifier.rs @@ -26,7 +26,10 @@ impl Identifier { let end = input.find(Self::cannot_continue).unwrap_or(input.len()); let inner = input[..end].to_string(); - let length = inner.len(); + let length = inner + .len() + .try_into() + .expect("the YUL should be of reasonable size"); if let Some(token) = Keyword::parse(inner.as_str()) { return Some(token); diff --git a/crates/solidity/src/yul/lexer/token/lexeme/keyword.rs b/crates/solidity/src/yul/lexer/token/lexeme/keyword.rs index 6686158..c32cbe4 100644 --- a/crates/solidity/src/yul/lexer/token/lexeme/keyword.rs +++ b/crates/solidity/src/yul/lexer/token/lexeme/keyword.rs @@ -58,6 +58,9 @@ impl Keyword { if length != input.len() { return None; } + let length = length + .try_into() + .expect("the YUL should be of reasonable size"); Some(Token::new(Location::new(0, length), lexeme, length)) } diff --git a/crates/solidity/src/yul/lexer/token/lexeme/literal/integer.rs b/crates/solidity/src/yul/lexer/token/lexeme/literal/integer.rs index d60ad0f..354ed58 100644 --- a/crates/solidity/src/yul/lexer/token/lexeme/literal/integer.rs +++ b/crates/solidity/src/yul/lexer/token/lexeme/literal/integer.rs @@ -54,6 +54,10 @@ impl Integer { return None; }; + let length = length + .try_into() + .expect("the YUL should be of reasonable size"); + let token = Token::new( Location::new(0, length), Lexeme::Literal(Literal::Integer(value)), diff --git a/crates/solidity/src/yul/lexer/token/lexeme/literal/string.rs b/crates/solidity/src/yul/lexer/token/lexeme/literal/string.rs index 234e51e..458b6a1 100644 --- a/crates/solidity/src/yul/lexer/token/lexeme/literal/string.rs +++ b/crates/solidity/src/yul/lexer/token/lexeme/literal/string.rs @@ -69,6 +69,9 @@ impl String { .to_owned(); let literal = Self::new(string, is_hex_string); + let length = length + .try_into() + .expect("the YUL should be of reasonable size"); Some(Token::new( Location::new(0, length), diff --git a/crates/solidity/src/yul/lexer/token/location.rs b/crates/solidity/src/yul/lexer/token/location.rs index bc3441a..672182b 100644 --- a/crates/solidity/src/yul/lexer/token/location.rs +++ b/crates/solidity/src/yul/lexer/token/location.rs @@ -7,9 +7,9 @@ use serde::Serialize; #[derive(Debug, Serialize, Deserialize, Clone, Copy, Eq)] pub struct Location { /// The line number, starting from 1. - pub line: usize, + pub line: u32, /// The column number, starting from 1. - pub column: usize, + pub column: u32, } impl Default for Location { @@ -20,13 +20,13 @@ impl Default for Location { impl Location { /// Creates a default location. - pub fn new(line: usize, column: usize) -> Self { + pub fn new(line: u32, column: u32) -> Self { Self { line, column } } /// Mutates the location by shifting the original one down by `lines` and /// setting the column to `column`. - pub fn shift_down(&mut self, lines: usize, column: usize) { + pub fn shift_down(&mut self, lines: u32, column: u32) { if lines == 0 { self.shift_right(column); return; @@ -37,7 +37,7 @@ impl Location { } /// Mutates the location by shifting the original one rightward by `columns`. - pub fn shift_right(&mut self, columns: usize) { + pub fn shift_right(&mut self, columns: u32) { self.column += columns; } } diff --git a/crates/solidity/src/yul/lexer/token/mod.rs b/crates/solidity/src/yul/lexer/token/mod.rs index da10d26..30d9fa4 100644 --- a/crates/solidity/src/yul/lexer/token/mod.rs +++ b/crates/solidity/src/yul/lexer/token/mod.rs @@ -15,12 +15,12 @@ pub struct Token { /// The lexeme. pub lexeme: Lexeme, /// The token length, including whitespaces. - pub length: usize, + pub length: u32, } impl Token { /// A shortcut constructor. - pub fn new(location: Location, lexeme: Lexeme, length: usize) -> Self { + pub fn new(location: Location, lexeme: Lexeme, length: u32) -> Self { Self { location, lexeme, diff --git a/crates/solidity/src/yul/parser/error.rs b/crates/solidity/src/yul/parser/error.rs index ac49fe5..33daf3e 100644 --- a/crates/solidity/src/yul/parser/error.rs +++ b/crates/solidity/src/yul/parser/error.rs @@ -57,4 +57,7 @@ pub enum Error { /// The list of invalid attributes. values: BTreeSet, }, + /// Invalid code length. + #[error("The line or column length exceed the maximum of u32::MAX")] + InvalidLength, } diff --git a/crates/solidity/src/yul/parser/statement/assignment.rs b/crates/solidity/src/yul/parser/statement/assignment.rs index 007378d..d93d34c 100644 --- a/crates/solidity/src/yul/parser/statement/assignment.rs +++ b/crates/solidity/src/yul/parser/statement/assignment.rs @@ -47,7 +47,11 @@ impl Assignment { .into()); } }; - let length = identifier.inner.len(); + let length = identifier + .inner + .len() + .try_into() + .map_err(|_| Error::Parser(ParserError::InvalidLength))?; match lexer.peek()? { Token { @@ -115,6 +119,8 @@ where mut self, context: &mut revive_llvm_context::PolkaVMContext, ) -> anyhow::Result<()> { + context.set_debug_location(self.location.line, 0, None)?; + let value = match self.initializer.into_llvm(context)? { Some(value) => value, None => return Ok(()), @@ -142,6 +148,8 @@ where context.build_store(tuple_pointer, value.to_llvm())?; for (index, binding) in self.bindings.into_iter().enumerate() { + context.set_debug_location(self.location.line, 0, None)?; + let field_pointer = context.build_gep( tuple_pointer, &[ diff --git a/crates/solidity/src/yul/parser/statement/block.rs b/crates/solidity/src/yul/parser/statement/block.rs index ffa2c63..b4ba92d 100644 --- a/crates/solidity/src/yul/parser/statement/block.rs +++ b/crates/solidity/src/yul/parser/statement/block.rs @@ -5,6 +5,8 @@ use std::collections::HashSet; use serde::Deserialize; use serde::Serialize; +use inkwell::debug_info::AsDIScope; + use crate::yul::error::Error; use crate::yul::lexer::token::lexeme::symbol::Symbol; use crate::yul::lexer::token::lexeme::Lexeme; @@ -153,9 +155,26 @@ where function.into_llvm(context)?; } - context.set_current_function(current_function.as_str())?; + context.set_current_function(current_function.as_str(), Some(self.location.line))?; + + if let Some(debug_info) = context.debug_info() { + let di_builder = debug_info.builder(); + let di_scope = debug_info.top_scope().expect("expected a debug-info scope"); + let di_block_scope = di_builder + .create_lexical_block( + di_scope, + debug_info.compilation_unit().get_file(), + self.location.line, + 0, + ) + .as_debug_info_scope(); + context.push_debug_scope(di_block_scope); + context.set_debug_location(self.location.line, 0, None)?; + } + context.set_basic_block(current_block); for statement in local_statements.into_iter() { + context.set_debug_location(statement.location().line, 0, None)?; if context.basic_block().get_terminator().is_some() { break; } @@ -194,6 +213,8 @@ where } } + context.pop_debug_scope(); + Ok(()) } } diff --git a/crates/solidity/src/yul/parser/statement/expression/mod.rs b/crates/solidity/src/yul/parser/statement/expression/mod.rs index 10432dc..80a5a62 100644 --- a/crates/solidity/src/yul/parser/statement/expression/mod.rs +++ b/crates/solidity/src/yul/parser/statement/expression/mod.rs @@ -55,7 +55,11 @@ impl Expression { .into()); } }; - let length = identifier.inner.len(); + let length = identifier + .inner + .len() + .try_into() + .map_err(|_| Error::Parser(ParserError::InvalidLength))?; match lexer.peek()? { Token { diff --git a/crates/solidity/src/yul/parser/statement/function_definition.rs b/crates/solidity/src/yul/parser/statement/function_definition.rs index 7ff9775..fb5eb6b 100644 --- a/crates/solidity/src/yul/parser/statement/function_definition.rs +++ b/crates/solidity/src/yul/parser/statement/function_definition.rs @@ -4,6 +4,7 @@ use std::collections::BTreeSet; use std::collections::HashSet; use inkwell::types::BasicType; + use serde::Deserialize; use serde::Serialize; @@ -229,14 +230,15 @@ where mut self, context: &mut revive_llvm_context::PolkaVMContext, ) -> anyhow::Result<()> { - context.set_current_function(self.identifier.as_str())?; - let r#return = context.current_function().borrow().r#return(); - + context.set_current_function(self.identifier.as_str(), Some(self.location.line))?; context.set_basic_block(context.current_function().borrow().entry_block()); + + let r#return = context.current_function().borrow().r#return(); match r#return { revive_llvm_context::PolkaVMFunctionReturn::None => {} revive_llvm_context::PolkaVMFunctionReturn::Primitive { pointer } => { let identifier = self.result.pop().expect("Always exists"); + let r#type = identifier.r#type.unwrap_or_default(); context.build_store(pointer, r#type.into_llvm(context).const_zero())?; context @@ -288,6 +290,8 @@ where } self.body.into_llvm(context)?; + context.set_debug_location(self.location.line, 0, None)?; + match context .basic_block() .get_last_instruction() @@ -314,6 +318,8 @@ where } } + context.pop_debug_scope(); + Ok(()) } } diff --git a/crates/solidity/src/yul/parser/statement/object.rs b/crates/solidity/src/yul/parser/statement/object.rs index 5c08d38..4f10102 100644 --- a/crates/solidity/src/yul/parser/statement/object.rs +++ b/crates/solidity/src/yul/parser/statement/object.rs @@ -2,6 +2,8 @@ use std::collections::HashSet; +use inkwell::debug_info::AsDIScope; + use serde::Deserialize; use serde::Serialize; @@ -217,16 +219,30 @@ where } fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext) -> anyhow::Result<()> { + if let Some(debug_info) = context.debug_info() { + let di_builder = debug_info.builder(); + let object_name: &str = self.identifier.as_str(); + let di_parent_scope = debug_info + .top_scope() + .expect("expected an existing debug-info scope"); + let object_scope = di_builder.create_namespace(di_parent_scope, object_name, true); + context.push_debug_scope(object_scope.as_debug_info_scope()); + } + if self.identifier.ends_with("_deployed") { revive_llvm_context::PolkaVMImmutableDataLoadFunction.into_llvm(context)?; revive_llvm_context::PolkaVMRuntimeCodeFunction::new(self.code).into_llvm(context)?; } else { revive_llvm_context::PolkaVMDeployCodeFunction::new(self.code).into_llvm(context)?; } + context.set_debug_location(self.location.line, 0, None)?; if let Some(object) = self.inner_object { object.into_llvm(context)?; } + context.set_debug_location(self.location.line, 0, None)?; + + context.pop_debug_scope(); Ok(()) } diff --git a/crates/solidity/src/yul/parser/statement/variable_declaration.rs b/crates/solidity/src/yul/parser/statement/variable_declaration.rs index 3733cca..8232fda 100644 --- a/crates/solidity/src/yul/parser/statement/variable_declaration.rs +++ b/crates/solidity/src/yul/parser/statement/variable_declaration.rs @@ -101,7 +101,9 @@ where ) -> anyhow::Result<()> { if self.bindings.len() == 1 { let identifier = self.bindings.remove(0); - let r#type = identifier.r#type.unwrap_or_default().into_llvm(context); + context.set_debug_location(self.location.line, 0, None)?; + let identifier_type = identifier.r#type.clone().unwrap_or_default(); + let r#type = identifier_type.into_llvm(context); let pointer = context.build_alloca(r#type, identifier.inner.as_str()); context .current_function() @@ -116,7 +118,7 @@ where .current_function() .borrow_mut() .yul_mut() - .insert_constant(identifier.inner, constant); + .insert_constant(identifier.inner.clone(), constant); } value.to_llvm() @@ -131,6 +133,8 @@ where } for (index, binding) in self.bindings.iter().enumerate() { + context.set_debug_location(self.location.line, 0, None)?; + let yul_type = binding .r#type .to_owned()