diff --git a/Cargo.lock b/Cargo.lock index b8f3dcea5c8..5c9b2cdfe17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,7 +81,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d9b665789884a7e8fb06c84b295e923b03ca51edbb7d08f91a6a50322ecbfe6" dependencies = [ "anstyle", - "unicode-width", + "unicode-width 0.1.12", ] [[package]] @@ -255,9 +255,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "blake2" @@ -284,7 +284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" dependencies = [ "cc", - "glob 0.3.1", + "glob", "threadpool", "zeroize", ] @@ -304,9 +304,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecount" @@ -430,7 +430,7 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" dependencies = [ - "glob 0.3.1", + "glob", "libc 0.2.158", "libloading", ] @@ -443,7 +443,7 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "bitflags 1.3.2", "textwrap 0.11.0", - "unicode-width", + "unicode-width 0.1.12", ] [[package]] @@ -525,15 +525,6 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" -[[package]] -name = "cmake" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" -dependencies = [ - "cc", -] - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -541,7 +532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ "termcolor", - "unicode-width", + "unicode-width 0.1.12", ] [[package]] @@ -1199,7 +1190,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2845a73bbd781e691ab7c2a028c579727cd254942e8ced57ff73e0eafd60de87" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.8.0", "byteorder", "core-foundation", "core-graphics", @@ -1317,12 +1308,6 @@ dependencies = [ "weezl", ] -[[package]] -name = "glob" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" - [[package]] name = "glob" version = "0.3.1" @@ -1625,7 +1610,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.8.0", "libc 0.2.158", ] @@ -1638,7 +1623,7 @@ dependencies = [ "bindgen", "bzip2-sys", "cc", - "glob 0.3.1", + "glob", "libc 0.2.158", "libz-sys", "lz4-sys", @@ -2325,11 +2310,12 @@ dependencies = [ "strum", "syn 1.0.109", "tempfile", - "wabt", "walkdir", "wasm-benchmarks-lib", "wasmi", "wasmparser 0.107.0", + "wasmprinter 0.224.0", + "wat", ] [[package]] @@ -2378,7 +2364,6 @@ dependencies = [ "scrypto-test", "serde", "serde_json", - "wabt", "walkdir", ] @@ -2443,8 +2428,8 @@ dependencies = [ "serde", "serde_json", "trybuild", - "wabt", "walkdir", + "wat", ] [[package]] @@ -2577,9 +2562,9 @@ checksum = "9b5e1305200330d3dd5c9b16ca43eba268993036ba19a2b2cadadee1b9166ab4" dependencies = [ "anyhow", "paste", - "wasm-encoder", + "wasm-encoder 0.29.0", "wasmparser 0.107.0", - "wasmprinter", + "wasmprinter 0.2.63", ] [[package]] @@ -2797,7 +2782,7 @@ version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.8.0", "errno", "libc 0.2.158", "linux-raw-sys", @@ -2993,7 +2978,7 @@ dependencies = [ "scrypto-compiler", "serde_json", "tuple-return", - "wabt", + "wat", ] [[package]] @@ -3184,7 +3169,7 @@ dependencies = [ "bytecount", "cargo_metadata", "error-chain", - "glob 0.3.1", + "glob", "pulldown-cmark", "tempfile", "walkdir", @@ -3370,7 +3355,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width", + "unicode-width 0.1.12", ] [[package]] @@ -3520,7 +3505,7 @@ version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "207aa50d36c4be8d8c6ea829478be44a372c6a77669937bb39c698e52f1491e8" dependencies = [ - "glob 0.3.1", + "glob", "serde", "serde_derive", "serde_json", @@ -3569,6 +3554,12 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "utf8parse" version = "0.2.2" @@ -3608,29 +3599,6 @@ version = "0.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dcc60c0624df774c82a0ef104151231d37da4962957d691c011c852b2473314" -[[package]] -name = "wabt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bef93d5e6c81a293bccf107cf43aa47239382f455ba14869d36695d8963b9c" -dependencies = [ - "serde", - "serde_derive", - "serde_json", - "wabt-sys", -] - -[[package]] -name = "wabt-sys" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4e043159f63e16986e713e9b5e1c06043df4848565bf672e27c523864c7791" -dependencies = [ - "cc", - "cmake", - "glob 0.2.11", -] - [[package]] name = "walkdir" version = "2.3.3" @@ -3718,6 +3686,16 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-encoder" +version = "0.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7249cf8cb0c6b9cb42bce90c0a5feb276fbf963fa385ff3d818ab3d90818ed6" +dependencies = [ + "leb128", + "wasmparser 0.224.0", +] + [[package]] name = "wasm-opt" version = "0.114.2" @@ -3822,6 +3800,17 @@ dependencies = [ "semver", ] +[[package]] +name = "wasmparser" +version = "0.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65881a664fdd43646b647bb27bf186ab09c05bf56779d40aed4c6dce47d423f5" +dependencies = [ + "bitflags 2.8.0", + "indexmap 2.7.0", + "semver", +] + [[package]] name = "wasmparser-nostd" version = "0.100.2" @@ -3841,6 +3830,39 @@ dependencies = [ "wasmparser 0.111.0", ] +[[package]] +name = "wasmprinter" +version = "0.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc039e211f6c2137425726f0d76fdd9c439a442e5272bc3627a19274d0eb9686" +dependencies = [ + "anyhow", + "termcolor", + "wasmparser 0.224.0", +] + +[[package]] +name = "wast" +version = "224.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d722a51e62b669d17e5a9f6bc8ec210178b37d869114355aa46989686c5c6391" +dependencies = [ + "bumpalo", + "leb128", + "memchr", + "unicode-width 0.2.0", + "wasm-encoder 0.224.0", +] + +[[package]] +name = "wat" +version = "1.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dece6a7dd5bcbcf8d256606c7fb3faa36286d46bf3f98185407719a5ceede2" +dependencies = [ + "wast", +] + [[package]] name = "web-sys" version = "0.3.70" diff --git a/Cargo.toml b/Cargo.toml index c7737a4bae8..012520085bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -129,7 +129,8 @@ tar = { version = "0.4.40" } # Used in radix-clis temp-env = { version = "0.2.0" } # Used in radix-clis tempfile = { version = "3.8.0" } trybuild = { version = "1.0.85" } -wabt = { version = "0.10.0" } +wat = { version = "1.224.0" } # Used in tests to parse '*.wat' files +wasmprinter = { version = "0.224.0" } # Used in tests to convert '*.wasm' to '*.wat' walkdir = { version = "2.3.3", default-features = false } wasmi = { version = "=0.39.1" } # Used for WASM Execution in the Engine. Requires explicit upgrades for testing non-determinism. wasm-opt = { version = "0.114.1" } diff --git a/examples/everything/Cargo.lock b/examples/everything/Cargo.lock index 43529b8affa..efc11e53f43 100644 --- a/examples/everything/Cargo.lock +++ b/examples/everything/Cargo.lock @@ -27,7 +27,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d9b665789884a7e8fb06c84b295e923b03ca51edbb7d08f91a6a50322ecbfe6" dependencies = [ "anstyle", - "unicode-width", + "unicode-width 0.1.12", ] [[package]] @@ -74,9 +74,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "blake2" @@ -103,7 +103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" dependencies = [ "cc", - "glob 0.3.1", + "glob", "threadpool", "zeroize", ] @@ -118,6 +118,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "bytecount" version = "0.6.3" @@ -181,15 +187,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cmake" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" -dependencies = [ - "cc", -] - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -197,7 +194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ "termcolor", - "unicode-width", + "unicode-width 0.1.12", ] [[package]] @@ -476,12 +473,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "glob" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" - [[package]] name = "glob" version = "0.3.1" @@ -1052,7 +1043,7 @@ checksum = "9b5e1305200330d3dd5c9b16ca43eba268993036ba19a2b2cadadee1b9166ab4" dependencies = [ "anyhow", "paste", - "wasm-encoder", + "wasm-encoder 0.29.0", "wasmparser 0.107.0", "wasmprinter", ] @@ -1115,7 +1106,7 @@ version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.8.0", "errno", "libc", "linux-raw-sys", @@ -1264,7 +1255,7 @@ dependencies = [ "scrypto", "scrypto-compiler", "serde_json", - "wabt", + "wat", ] [[package]] @@ -1374,7 +1365,7 @@ dependencies = [ "bytecount", "cargo_metadata", "error-chain", - "glob 0.3.1", + "glob", "pulldown-cmark", "tempfile", "walkdir", @@ -1593,6 +1584,12 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "uuid" version = "1.4.1" @@ -1608,29 +1605,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wabt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bef93d5e6c81a293bccf107cf43aa47239382f455ba14869d36695d8963b9c" -dependencies = [ - "serde", - "serde_derive", - "serde_json", - "wabt-sys", -] - -[[package]] -name = "wabt-sys" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4e043159f63e16986e713e9b5e1c06043df4848565bf672e27c523864c7791" -dependencies = [ - "cc", - "cmake", - "glob 0.2.11", -] - [[package]] name = "walkdir" version = "2.3.3" @@ -1656,6 +1630,16 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-encoder" +version = "0.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7249cf8cb0c6b9cb42bce90c0a5feb276fbf963fa385ff3d818ab3d90818ed6" +dependencies = [ + "leb128", + "wasmparser 0.224.0", +] + [[package]] name = "wasm-opt" version = "0.114.2" @@ -1760,6 +1744,17 @@ dependencies = [ "semver", ] +[[package]] +name = "wasmparser" +version = "0.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65881a664fdd43646b647bb27bf186ab09c05bf56779d40aed4c6dce47d423f5" +dependencies = [ + "bitflags 2.8.0", + "indexmap 2.7.0", + "semver", +] + [[package]] name = "wasmparser-nostd" version = "0.100.2" @@ -1779,6 +1774,28 @@ dependencies = [ "wasmparser 0.111.0", ] +[[package]] +name = "wast" +version = "224.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d722a51e62b669d17e5a9f6bc8ec210178b37d869114355aa46989686c5c6391" +dependencies = [ + "bumpalo", + "leb128", + "memchr", + "unicode-width 0.2.0", + "wasm-encoder 0.224.0", +] + +[[package]] +name = "wat" +version = "1.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dece6a7dd5bcbcf8d256606c7fb3faa36286d46bf3f98185407719a5ceede2" +dependencies = [ + "wast", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/examples/hello-world/Cargo.lock b/examples/hello-world/Cargo.lock index 07af087f44a..b8b466b10a2 100644 --- a/examples/hello-world/Cargo.lock +++ b/examples/hello-world/Cargo.lock @@ -27,7 +27,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d9b665789884a7e8fb06c84b295e923b03ca51edbb7d08f91a6a50322ecbfe6" dependencies = [ "anstyle", - "unicode-width", + "unicode-width 0.1.12", ] [[package]] @@ -74,9 +74,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "blake2" @@ -103,7 +103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" dependencies = [ "cc", - "glob 0.3.1", + "glob", "threadpool", "zeroize", ] @@ -118,6 +118,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "bytecount" version = "0.6.3" @@ -181,15 +187,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cmake" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" -dependencies = [ - "cc", -] - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -197,7 +194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ "termcolor", - "unicode-width", + "unicode-width 0.1.12", ] [[package]] @@ -468,12 +465,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "glob" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" - [[package]] name = "glob" version = "0.3.1" @@ -1052,7 +1043,7 @@ checksum = "9b5e1305200330d3dd5c9b16ca43eba268993036ba19a2b2cadadee1b9166ab4" dependencies = [ "anyhow", "paste", - "wasm-encoder", + "wasm-encoder 0.29.0", "wasmparser 0.107.0", "wasmprinter", ] @@ -1115,7 +1106,7 @@ version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.8.0", "errno", "libc", "linux-raw-sys", @@ -1264,7 +1255,7 @@ dependencies = [ "scrypto", "scrypto-compiler", "serde_json", - "wabt", + "wat", ] [[package]] @@ -1374,7 +1365,7 @@ dependencies = [ "bytecount", "cargo_metadata", "error-chain", - "glob 0.3.1", + "glob", "pulldown-cmark", "tempfile", "walkdir", @@ -1593,6 +1584,12 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "uuid" version = "1.4.1" @@ -1608,29 +1605,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wabt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bef93d5e6c81a293bccf107cf43aa47239382f455ba14869d36695d8963b9c" -dependencies = [ - "serde", - "serde_derive", - "serde_json", - "wabt-sys", -] - -[[package]] -name = "wabt-sys" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4e043159f63e16986e713e9b5e1c06043df4848565bf672e27c523864c7791" -dependencies = [ - "cc", - "cmake", - "glob 0.2.11", -] - [[package]] name = "walkdir" version = "2.3.3" @@ -1656,6 +1630,16 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-encoder" +version = "0.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7249cf8cb0c6b9cb42bce90c0a5feb276fbf963fa385ff3d818ab3d90818ed6" +dependencies = [ + "leb128", + "wasmparser 0.224.0", +] + [[package]] name = "wasm-opt" version = "0.114.2" @@ -1760,6 +1744,17 @@ dependencies = [ "semver", ] +[[package]] +name = "wasmparser" +version = "0.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65881a664fdd43646b647bb27bf186ab09c05bf56779d40aed4c6dce47d423f5" +dependencies = [ + "bitflags 2.8.0", + "indexmap 2.7.0", + "semver", +] + [[package]] name = "wasmparser-nostd" version = "0.100.2" @@ -1779,6 +1774,28 @@ dependencies = [ "wasmparser 0.111.0", ] +[[package]] +name = "wast" +version = "224.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d722a51e62b669d17e5a9f6bc8ec210178b37d869114355aa46989686c5c6391" +dependencies = [ + "bumpalo", + "leb128", + "memchr", + "unicode-width 0.2.0", + "wasm-encoder 0.224.0", +] + +[[package]] +name = "wat" +version = "1.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dece6a7dd5bcbcf8d256606c7fb3faa36286d46bf3f98185407719a5ceede2" +dependencies = [ + "wast", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/radix-clis/assets/template/Cargo.lock_template b/radix-clis/assets/template/Cargo.lock_template index 4a04851d5bc..f0b6c7a835b 100644 --- a/radix-clis/assets/template/Cargo.lock_template +++ b/radix-clis/assets/template/Cargo.lock_template @@ -27,7 +27,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d9b665789884a7e8fb06c84b295e923b03ca51edbb7d08f91a6a50322ecbfe6" dependencies = [ "anstyle", - "unicode-width", + "unicode-width 0.1.12", ] [[package]] @@ -74,9 +74,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "blake2" @@ -103,7 +103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" dependencies = [ "cc", - "glob 0.3.1", + "glob", "threadpool", "zeroize", ] @@ -118,6 +118,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "bytecount" version = "0.6.3" @@ -181,15 +187,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cmake" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" -dependencies = [ - "cc", -] - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -197,7 +194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ "termcolor", - "unicode-width", + "unicode-width 0.1.12", ] [[package]] @@ -468,12 +465,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "glob" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" - [[package]] name = "glob" version = "0.3.1" @@ -1044,7 +1035,7 @@ checksum = "9b5e1305200330d3dd5c9b16ca43eba268993036ba19a2b2cadadee1b9166ab4" dependencies = [ "anyhow", "paste", - "wasm-encoder", + "wasm-encoder 0.29.0", "wasmparser 0.107.0", "wasmprinter", ] @@ -1107,7 +1098,7 @@ version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.8.0", "errno", "libc", "linux-raw-sys", @@ -1256,7 +1247,7 @@ dependencies = [ "scrypto", "scrypto-compiler", "serde_json", - "wabt", + "wat", ] [[package]] @@ -1366,7 +1357,7 @@ dependencies = [ "bytecount", "cargo_metadata", "error-chain", - "glob 0.3.1", + "glob", "pulldown-cmark", "tempfile", "walkdir", @@ -1585,6 +1576,12 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "uuid" version = "1.4.1" @@ -1600,29 +1597,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wabt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bef93d5e6c81a293bccf107cf43aa47239382f455ba14869d36695d8963b9c" -dependencies = [ - "serde", - "serde_derive", - "serde_json", - "wabt-sys", -] - -[[package]] -name = "wabt-sys" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4e043159f63e16986e713e9b5e1c06043df4848565bf672e27c523864c7791" -dependencies = [ - "cc", - "cmake", - "glob 0.2.11", -] - [[package]] name = "walkdir" version = "2.3.3" @@ -1648,6 +1622,16 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-encoder" +version = "0.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7249cf8cb0c6b9cb42bce90c0a5feb276fbf963fa385ff3d818ab3d90818ed6" +dependencies = [ + "leb128", + "wasmparser 0.224.0", +] + [[package]] name = "wasm-opt" version = "0.114.2" @@ -1752,6 +1736,17 @@ dependencies = [ "semver", ] +[[package]] +name = "wasmparser" +version = "0.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65881a664fdd43646b647bb27bf186ab09c05bf56779d40aed4c6dce47d423f5" +dependencies = [ + "bitflags 2.8.0", + "indexmap 2.7.0", + "semver", +] + [[package]] name = "wasmparser-nostd" version = "0.100.2" @@ -1771,6 +1766,28 @@ dependencies = [ "wasmparser 0.111.0", ] +[[package]] +name = "wast" +version = "224.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d722a51e62b669d17e5a9f6bc8ec210178b37d869114355aa46989686c5c6391" +dependencies = [ + "bumpalo", + "leb128", + "memchr", + "unicode-width 0.2.0", + "wasm-encoder 0.224.0", +] + +[[package]] +name = "wat" +version = "1.224.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dece6a7dd5bcbcf8d256606c7fb3faa36286d46bf3f98185407719a5ceede2" +dependencies = [ + "wast", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/radix-common/src/constants/wasm.rs b/radix-common/src/constants/wasm.rs index 9c073bfbad4..4c9106eea77 100644 --- a/radix-common/src/constants/wasm.rs +++ b/radix-common/src/constants/wasm.rs @@ -4,8 +4,11 @@ pub const MAX_MEMORY_SIZE_IN_PAGES: u32 = 64; #[cfg(feature = "coverage")] pub const MAX_MEMORY_SIZE_IN_PAGES: u32 = 512; -/// The maximum initial table size -pub const MAX_INITIAL_TABLE_SIZE: u32 = 1024; +/// The maximum number of tables if `reference-types` feature enabled +pub const MAX_NUMBER_OF_TABLES: u32 = 64; + +/// The maximum table size +pub const MAX_TABLE_SIZE: u32 = 1024; /// The max number of labels of a table jump, excluding the default pub const MAX_NUMBER_OF_BR_TABLE_TARGETS: u32 = 256; diff --git a/radix-engine-monkey-tests/Cargo.toml b/radix-engine-monkey-tests/Cargo.toml index 11f2f1a0a13..008ef5ff6aa 100644 --- a/radix-engine-monkey-tests/Cargo.toml +++ b/radix-engine-monkey-tests/Cargo.toml @@ -21,7 +21,6 @@ radix-engine-profiling = { workspace = true, optional = true, features = ["resou radix-engine-profiling-derive = { workspace = true } scrypto-test = { workspace = true } -wabt = { workspace = true } rand = { workspace = true } rand_chacha = { workspace = true } rayon = { workspace = true } diff --git a/radix-engine-tests/Cargo.toml b/radix-engine-tests/Cargo.toml index 575e46609bb..7d29a2ee5b2 100644 --- a/radix-engine-tests/Cargo.toml +++ b/radix-engine-tests/Cargo.toml @@ -27,7 +27,7 @@ lazy_static = { workspace = true } [dev-dependencies] radix-transactions = { workspace = true } -wabt = { workspace = true } +wat = { workspace = true } criterion = { workspace = true, features = ["html_reports"] } scrypto = { workspace = true } rand = { workspace = true } diff --git a/radix-engine-tests/assets/blueprints/.cargo/config.toml b/radix-engine-tests/assets/blueprints/.cargo/config.toml index 435ed755ec2..f4e8c002fc2 100644 --- a/radix-engine-tests/assets/blueprints/.cargo/config.toml +++ b/radix-engine-tests/assets/blueprints/.cargo/config.toml @@ -1,2 +1,2 @@ [build] -target = "wasm32-unknown-unknown" \ No newline at end of file +target = "wasm32-unknown-unknown" diff --git a/radix-engine-tests/assets/metering/anemone/cost_publish_large_package.csv b/radix-engine-tests/assets/metering/anemone/cost_publish_large_package.csv index 4e1918b02de..1a9a951b898 100644 --- a/radix-engine-tests/assets/metering/anemone/cost_publish_large_package.csv +++ b/radix-engine-tests/assets/metering/anemone/cost_publish_large_package.csv @@ -1,15 +1,15 @@ -Total Cost (XRD) , 304.85429235219, 100.0% -- Execution Cost (XRD) , 4.9487847, 1.6% -- Finalization Cost (XRD) , 0.07669735, 0.0% -- Storage Cost (XRD) , 299.82881030219, 98.4% +Total Cost (XRD) , 304.85682950537, 100.0% +- Execution Cost (XRD) , 4.94884215, 1.6% +- Finalization Cost (XRD) , 0.0766975, 0.0% +- Storage Cost (XRD) , 299.83128985537, 98.4% - Tipping Cost (XRD) , 0, 0.0% - Royalty Cost (XRD) , 0, 0.0% -Execution Cost Breakdown , 98975694, 100.0% +Execution Cost Breakdown , 98976843, 100.0% - AfterInvoke , 326, 0.0% - AllocateNodeId , 1552, 0.0% -- BeforeInvoke , 2096226, 2.1% +- BeforeInvoke , 2096252, 2.1% - CloseSubstate , 18318, 0.0% -- CreateNode , 4203572, 4.2% +- CreateNode , 4203598, 4.2% - DropNode , 20742, 0.0% - EmitEvent , 1128, 0.0% - LockFee , 500, 0.0% @@ -31,16 +31,16 @@ Execution Cost Breakdown , - RunNativeCode::create_with_data , 27471, 0.0% - RunNativeCode::get_amount_FungibleVault , 14451, 0.0% - RunNativeCode::lock_fee , 45243, 0.0% -- RunNativeCode::publish_wasm_advanced , 46852012, 47.3% +- RunNativeCode::publish_wasm_advanced , 46852589, 47.3% - RunWasmCode::Faucet_lock_fee , 24589, 0.0% - SetSubstate , 403, 0.0% -- ValidateTxPayload , 41911240, 42.3% +- ValidateTxPayload , 41911760, 42.3% - VerifyTxSignatures , 7000, 0.0% - WriteSubstate , 5386, 0.0% -Finalization Cost Breakdown , 1533947, 100.0% +Finalization Cost Breakdown , 1533950, 100.0% - CommitEvents , 10016, 0.7% - CommitIntentStatus , 0, 0.0% - CommitLogs , 0, 0.0% - CommitStateUpdates::GlobalGenericComponent , 100018, 6.5% -- CommitStateUpdates::GlobalPackage , 1123866, 73.3% +- CommitStateUpdates::GlobalPackage , 1123869, 73.3% - CommitStateUpdates::InternalFungibleVault , 300047, 19.6% diff --git a/radix-engine-tests/assets/metering/babylon/cost_publish_large_package.csv b/radix-engine-tests/assets/metering/babylon/cost_publish_large_package.csv index 4e1918b02de..1a9a951b898 100644 --- a/radix-engine-tests/assets/metering/babylon/cost_publish_large_package.csv +++ b/radix-engine-tests/assets/metering/babylon/cost_publish_large_package.csv @@ -1,15 +1,15 @@ -Total Cost (XRD) , 304.85429235219, 100.0% -- Execution Cost (XRD) , 4.9487847, 1.6% -- Finalization Cost (XRD) , 0.07669735, 0.0% -- Storage Cost (XRD) , 299.82881030219, 98.4% +Total Cost (XRD) , 304.85682950537, 100.0% +- Execution Cost (XRD) , 4.94884215, 1.6% +- Finalization Cost (XRD) , 0.0766975, 0.0% +- Storage Cost (XRD) , 299.83128985537, 98.4% - Tipping Cost (XRD) , 0, 0.0% - Royalty Cost (XRD) , 0, 0.0% -Execution Cost Breakdown , 98975694, 100.0% +Execution Cost Breakdown , 98976843, 100.0% - AfterInvoke , 326, 0.0% - AllocateNodeId , 1552, 0.0% -- BeforeInvoke , 2096226, 2.1% +- BeforeInvoke , 2096252, 2.1% - CloseSubstate , 18318, 0.0% -- CreateNode , 4203572, 4.2% +- CreateNode , 4203598, 4.2% - DropNode , 20742, 0.0% - EmitEvent , 1128, 0.0% - LockFee , 500, 0.0% @@ -31,16 +31,16 @@ Execution Cost Breakdown , - RunNativeCode::create_with_data , 27471, 0.0% - RunNativeCode::get_amount_FungibleVault , 14451, 0.0% - RunNativeCode::lock_fee , 45243, 0.0% -- RunNativeCode::publish_wasm_advanced , 46852012, 47.3% +- RunNativeCode::publish_wasm_advanced , 46852589, 47.3% - RunWasmCode::Faucet_lock_fee , 24589, 0.0% - SetSubstate , 403, 0.0% -- ValidateTxPayload , 41911240, 42.3% +- ValidateTxPayload , 41911760, 42.3% - VerifyTxSignatures , 7000, 0.0% - WriteSubstate , 5386, 0.0% -Finalization Cost Breakdown , 1533947, 100.0% +Finalization Cost Breakdown , 1533950, 100.0% - CommitEvents , 10016, 0.7% - CommitIntentStatus , 0, 0.0% - CommitLogs , 0, 0.0% - CommitStateUpdates::GlobalGenericComponent , 100018, 6.5% -- CommitStateUpdates::GlobalPackage , 1123866, 73.3% +- CommitStateUpdates::GlobalPackage , 1123869, 73.3% - CommitStateUpdates::InternalFungibleVault , 300047, 19.6% diff --git a/radix-engine-tests/assets/metering/bottlenose/cost_publish_large_package.csv b/radix-engine-tests/assets/metering/bottlenose/cost_publish_large_package.csv index fcc7dd5cfe0..eb35363a6d0 100644 --- a/radix-engine-tests/assets/metering/bottlenose/cost_publish_large_package.csv +++ b/radix-engine-tests/assets/metering/bottlenose/cost_publish_large_package.csv @@ -1,16 +1,16 @@ -Total Cost (XRD) , 304.85633430219, 100.0% -- Execution Cost (XRD) , 4.95082665, 1.6% -- Finalization Cost (XRD) , 0.07669735, 0.0% -- Storage Cost (XRD) , 299.82881030219, 98.4% +Total Cost (XRD) , 304.85887145537, 100.0% +- Execution Cost (XRD) , 4.9508841, 1.6% +- Finalization Cost (XRD) , 0.0766975, 0.0% +- Storage Cost (XRD) , 299.83128985537, 98.4% - Tipping Cost (XRD) , 0, 0.0% - Royalty Cost (XRD) , 0, 0.0% -Execution Cost Breakdown , 99016533, 100.0% +Execution Cost Breakdown , 99017682, 100.0% - AfterInvoke , 326, 0.0% - AllocateNodeId , 1552, 0.0% -- BeforeInvoke , 2096226, 2.1% +- BeforeInvoke , 2096252, 2.1% - CheckReference , 40011, 0.0% - CloseSubstate , 18318, 0.0% -- CreateNode , 4203572, 4.2% +- CreateNode , 4203598, 4.2% - DropNode , 20742, 0.0% - EmitEvent , 1128, 0.0% - LockFee , 500, 0.0% @@ -32,16 +32,16 @@ Execution Cost Breakdown , - RunNativeCode::create_with_data , 27471, 0.0% - RunNativeCode::get_amount_FungibleVault , 14451, 0.0% - RunNativeCode::lock_fee , 45243, 0.0% -- RunNativeCode::publish_wasm_advanced , 46852012, 47.3% +- RunNativeCode::publish_wasm_advanced , 46852589, 47.3% - RunWasmCode::Faucet_lock_fee , 24589, 0.0% - SetSubstate , 403, 0.0% -- ValidateTxPayload , 41911240, 42.3% +- ValidateTxPayload , 41911760, 42.3% - VerifyTxSignatures , 7000, 0.0% - WriteSubstate , 5386, 0.0% -Finalization Cost Breakdown , 1533947, 100.0% +Finalization Cost Breakdown , 1533950, 100.0% - CommitEvents , 10016, 0.7% - CommitIntentStatus , 0, 0.0% - CommitLogs , 0, 0.0% - CommitStateUpdates::GlobalGenericComponent , 100018, 6.5% -- CommitStateUpdates::GlobalPackage , 1123866, 73.3% +- CommitStateUpdates::GlobalPackage , 1123869, 73.3% - CommitStateUpdates::InternalFungibleVault , 300047, 19.6% diff --git a/radix-engine-tests/assets/metering/cuttlefish-part2/cost_publish_large_package.csv b/radix-engine-tests/assets/metering/cuttlefish-part2/cost_publish_large_package.csv index 52550e65374..ee04c9aecbf 100644 --- a/radix-engine-tests/assets/metering/cuttlefish-part2/cost_publish_large_package.csv +++ b/radix-engine-tests/assets/metering/cuttlefish-part2/cost_publish_large_package.csv @@ -1,16 +1,16 @@ -Total Cost (XRD) , 304.84433435219, 100.0% -- Execution Cost (XRD) , 4.9388267, 1.6% -- Finalization Cost (XRD) , 0.07669735, 0.0% -- Storage Cost (XRD) , 299.82881030219, 98.4% +Total Cost (XRD) , 304.84687150537, 100.0% +- Execution Cost (XRD) , 4.93888415, 1.6% +- Finalization Cost (XRD) , 0.0766975, 0.0% +- Storage Cost (XRD) , 299.83128985537, 98.4% - Tipping Cost (XRD) , 0, 0.0% - Royalty Cost (XRD) , 0, 0.0% -Execution Cost Breakdown , 98776534, 100.0% +Execution Cost Breakdown , 98777683, 100.0% - AfterInvoke , 326, 0.0% - AllocateNodeId , 1552, 0.0% -- BeforeInvoke , 2096226, 2.1% +- BeforeInvoke , 2096252, 2.1% - CheckReference , 40011, 0.0% - CloseSubstate , 17673, 0.0% -- CreateNode , 4203572, 4.3% +- CreateNode , 4203598, 4.3% - DropNode , 20742, 0.0% - EmitEvent , 1128, 0.0% - GetOwnedNodes , 1000, 0.0% @@ -33,18 +33,18 @@ Execution Cost Breakdown , - RunNativeCode::create_with_data , 27471, 0.0% - RunNativeCode::get_amount_FungibleVault , 14451, 0.0% - RunNativeCode::lock_fee , 45243, 0.0% -- RunNativeCode::publish_wasm_advanced , 46852012, 47.4% +- RunNativeCode::publish_wasm_advanced , 46852589, 47.4% - RunWasmCode::Faucet_lock_fee , 25290, 0.0% - SetCallFrameData , 606, 0.0% - SetSubstate , 403, 0.0% - SwitchStack , 1000, 0.0% -- ValidateTxPayload , 41911240, 42.4% +- ValidateTxPayload , 41911760, 42.4% - VerifyTxSignatures , 7000, 0.0% - WriteSubstate , 5386, 0.0% -Finalization Cost Breakdown , 1533947, 100.0% +Finalization Cost Breakdown , 1533950, 100.0% - CommitEvents , 10016, 0.7% - CommitIntentStatus , 0, 0.0% - CommitLogs , 0, 0.0% - CommitStateUpdates::GlobalGenericComponent , 100018, 6.5% -- CommitStateUpdates::GlobalPackage , 1123866, 73.3% +- CommitStateUpdates::GlobalPackage , 1123869, 73.3% - CommitStateUpdates::InternalFungibleVault , 300047, 19.6% diff --git a/radix-engine-tests/assets/metering/cuttlefish/cost_publish_large_package.csv b/radix-engine-tests/assets/metering/cuttlefish/cost_publish_large_package.csv index 52550e65374..ee04c9aecbf 100644 --- a/radix-engine-tests/assets/metering/cuttlefish/cost_publish_large_package.csv +++ b/radix-engine-tests/assets/metering/cuttlefish/cost_publish_large_package.csv @@ -1,16 +1,16 @@ -Total Cost (XRD) , 304.84433435219, 100.0% -- Execution Cost (XRD) , 4.9388267, 1.6% -- Finalization Cost (XRD) , 0.07669735, 0.0% -- Storage Cost (XRD) , 299.82881030219, 98.4% +Total Cost (XRD) , 304.84687150537, 100.0% +- Execution Cost (XRD) , 4.93888415, 1.6% +- Finalization Cost (XRD) , 0.0766975, 0.0% +- Storage Cost (XRD) , 299.83128985537, 98.4% - Tipping Cost (XRD) , 0, 0.0% - Royalty Cost (XRD) , 0, 0.0% -Execution Cost Breakdown , 98776534, 100.0% +Execution Cost Breakdown , 98777683, 100.0% - AfterInvoke , 326, 0.0% - AllocateNodeId , 1552, 0.0% -- BeforeInvoke , 2096226, 2.1% +- BeforeInvoke , 2096252, 2.1% - CheckReference , 40011, 0.0% - CloseSubstate , 17673, 0.0% -- CreateNode , 4203572, 4.3% +- CreateNode , 4203598, 4.3% - DropNode , 20742, 0.0% - EmitEvent , 1128, 0.0% - GetOwnedNodes , 1000, 0.0% @@ -33,18 +33,18 @@ Execution Cost Breakdown , - RunNativeCode::create_with_data , 27471, 0.0% - RunNativeCode::get_amount_FungibleVault , 14451, 0.0% - RunNativeCode::lock_fee , 45243, 0.0% -- RunNativeCode::publish_wasm_advanced , 46852012, 47.4% +- RunNativeCode::publish_wasm_advanced , 46852589, 47.4% - RunWasmCode::Faucet_lock_fee , 25290, 0.0% - SetCallFrameData , 606, 0.0% - SetSubstate , 403, 0.0% - SwitchStack , 1000, 0.0% -- ValidateTxPayload , 41911240, 42.4% +- ValidateTxPayload , 41911760, 42.4% - VerifyTxSignatures , 7000, 0.0% - WriteSubstate , 5386, 0.0% -Finalization Cost Breakdown , 1533947, 100.0% +Finalization Cost Breakdown , 1533950, 100.0% - CommitEvents , 10016, 0.7% - CommitIntentStatus , 0, 0.0% - CommitLogs , 0, 0.0% - CommitStateUpdates::GlobalGenericComponent , 100018, 6.5% -- CommitStateUpdates::GlobalPackage , 1123866, 73.3% +- CommitStateUpdates::GlobalPackage , 1123869, 73.3% - CommitStateUpdates::InternalFungibleVault , 300047, 19.6% diff --git a/radix-engine-tests/assets/metering/dugong/cost_publish_large_package.csv b/radix-engine-tests/assets/metering/dugong/cost_publish_large_package.csv index 52550e65374..ee04c9aecbf 100644 --- a/radix-engine-tests/assets/metering/dugong/cost_publish_large_package.csv +++ b/radix-engine-tests/assets/metering/dugong/cost_publish_large_package.csv @@ -1,16 +1,16 @@ -Total Cost (XRD) , 304.84433435219, 100.0% -- Execution Cost (XRD) , 4.9388267, 1.6% -- Finalization Cost (XRD) , 0.07669735, 0.0% -- Storage Cost (XRD) , 299.82881030219, 98.4% +Total Cost (XRD) , 304.84687150537, 100.0% +- Execution Cost (XRD) , 4.93888415, 1.6% +- Finalization Cost (XRD) , 0.0766975, 0.0% +- Storage Cost (XRD) , 299.83128985537, 98.4% - Tipping Cost (XRD) , 0, 0.0% - Royalty Cost (XRD) , 0, 0.0% -Execution Cost Breakdown , 98776534, 100.0% +Execution Cost Breakdown , 98777683, 100.0% - AfterInvoke , 326, 0.0% - AllocateNodeId , 1552, 0.0% -- BeforeInvoke , 2096226, 2.1% +- BeforeInvoke , 2096252, 2.1% - CheckReference , 40011, 0.0% - CloseSubstate , 17673, 0.0% -- CreateNode , 4203572, 4.3% +- CreateNode , 4203598, 4.3% - DropNode , 20742, 0.0% - EmitEvent , 1128, 0.0% - GetOwnedNodes , 1000, 0.0% @@ -33,18 +33,18 @@ Execution Cost Breakdown , - RunNativeCode::create_with_data , 27471, 0.0% - RunNativeCode::get_amount_FungibleVault , 14451, 0.0% - RunNativeCode::lock_fee , 45243, 0.0% -- RunNativeCode::publish_wasm_advanced , 46852012, 47.4% +- RunNativeCode::publish_wasm_advanced , 46852589, 47.4% - RunWasmCode::Faucet_lock_fee , 25290, 0.0% - SetCallFrameData , 606, 0.0% - SetSubstate , 403, 0.0% - SwitchStack , 1000, 0.0% -- ValidateTxPayload , 41911240, 42.4% +- ValidateTxPayload , 41911760, 42.4% - VerifyTxSignatures , 7000, 0.0% - WriteSubstate , 5386, 0.0% -Finalization Cost Breakdown , 1533947, 100.0% +Finalization Cost Breakdown , 1533950, 100.0% - CommitEvents , 10016, 0.7% - CommitIntentStatus , 0, 0.0% - CommitLogs , 0, 0.0% - CommitStateUpdates::GlobalGenericComponent , 100018, 6.5% -- CommitStateUpdates::GlobalPackage , 1123866, 73.3% +- CommitStateUpdates::GlobalPackage , 1123869, 73.3% - CommitStateUpdates::InternalFungibleVault , 300047, 19.6% diff --git a/radix-engine-tests/assets/wasm/multi_value_function_return_multiple_values.wat b/radix-engine-tests/assets/wasm/multi_value_function_return_multiple_values.wat new file mode 100644 index 00000000000..5408f0507ea --- /dev/null +++ b/radix-engine-tests/assets/wasm/multi_value_function_return_multiple_values.wat @@ -0,0 +1,38 @@ +(module + + ;; Internal function returns two values + (func $return_two_values (result i32 i32) + (i32.const ${a}) + (i32.const ${b}) + ) + + ;; Exported function that adds two values returned by $return_two_values + (func $Test_f (param $0 i64) (result i64) + (local $sum i32) + + call $return_two_values + + (i32.add) + (local.set $sum) + + ;; Encode () in SBOR at address 0x0 + (i32.const 0) + (i32.const 92) ;; prefix + (i32.store8) + (i32.const 1) + (i32.const 4) ;; i32 value kind + (i32.store8) + (i32.const 2) + (local.get $sum) + (i32.store) + + ;; Return slice (ptr = 0, len = 6) + (i64.const 6) + ) + + ;; Define memory with an initial size of 1 page (64 KiB) + (memory $0 1) + (export "memory" (memory $0)) + (export "Test_f" (func $Test_f)) +) + diff --git a/radix-engine-tests/assets/wasm/multi_value_if_return_multiple_values.wat b/radix-engine-tests/assets/wasm/multi_value_if_return_multiple_values.wat new file mode 100644 index 00000000000..5a8b6f3f06e --- /dev/null +++ b/radix-engine-tests/assets/wasm/multi_value_if_return_multiple_values.wat @@ -0,0 +1,40 @@ +(module + + ;; Exported function that adds two values + (func $Test_f (param $0 i64) (result i64) + (local $sum i32) + + i32.const 1 + ;; if that returns two values + if (result i32 i32) + (i32.const ${a}) + (i32.const ${b}) + else + (i32.const 0) + (i32.const 0) + end + + (i32.add) + (local.set $sum) + + ;; Encode () in SBOR at address 0x0 + (i32.const 0) + (i32.const 92) ;; prefix + (i32.store8) + (i32.const 1) + (i32.const 4) ;; i32 value kind + (i32.store8) + (i32.const 2) + (local.get $sum) + (i32.store) + + ;; Return slice (ptr = 0, len = 6) + (i64.const 6) + ) + + ;; Define memory with an initial size of 1 page (64 KiB) + (memory $0 1) + (export "memory" (memory $0)) + (export "Test_f" (func $Test_f)) +) + diff --git a/radix-engine-tests/assets/wasm/multi_value_loop_or_block_params.wat b/radix-engine-tests/assets/wasm/multi_value_loop_or_block_params.wat new file mode 100644 index 00000000000..7ba5609dbb8 --- /dev/null +++ b/radix-engine-tests/assets/wasm/multi_value_loop_or_block_params.wat @@ -0,0 +1,36 @@ +(module + + ;; Exported function that adds two values returned by $return_two_values + (func $Test_f (param $0 i64) (result i64) + (local $sum i32) + + (i32.const ${a}) + ;; Section that expects i32 on the stack + (${loop_or_block} $name (param i32) (result i32) + (i32.const ${b}) + (i32.add) + ) + + (local.set $sum) + + ;; Encode () in SBOR at address 0x0 + (i32.const 0) + (i32.const 92) ;; prefix + (i32.store8) + (i32.const 1) + (i32.const 4) ;; i32 value kind + (i32.store8) + (i32.const 2) + (local.get $sum) + (i32.store) + + ;; Return slice (ptr = 0, len = 6) + (i64.const 6) + ) + + ;; Define memory with an initial size of 1 page (64 KiB) + (memory $0 1) + (export "memory" (memory $0)) + (export "Test_f" (func $Test_f)) +) + diff --git a/radix-engine-tests/assets/wasm/multi_value_loop_or_block_return_multiple_values.wat b/radix-engine-tests/assets/wasm/multi_value_loop_or_block_return_multiple_values.wat new file mode 100644 index 00000000000..5d8c43f66bc --- /dev/null +++ b/radix-engine-tests/assets/wasm/multi_value_loop_or_block_return_multiple_values.wat @@ -0,0 +1,36 @@ +(module + + ;; Exported function that adds two values + (func $Test_f (param $0 i64) (result i64) + (local $sum i32) + + ;; Section that returns two values + (${loop_or_block} $name (param) (result i32 i32) + (i32.const ${a}) + (i32.const ${b}) + ) + + (i32.add) + (local.set $sum) + + ;; Encode () in SBOR at address 0x0 + (i32.const 0) + (i32.const 92) ;; prefix + (i32.store8) + (i32.const 1) + (i32.const 4) ;; i32 value kind + (i32.store8) + (i32.const 2) + (local.get $sum) + (i32.store) + + ;; Return slice (ptr = 0, len = 6) + (i64.const 6) + ) + + ;; Define memory with an initial size of 1 page (64 KiB) + (memory $0 1) + (export "memory" (memory $0)) + (export "Test_f" (func $Test_f)) +) + diff --git a/radix-engine-tests/assets/wasm/recursion.wat b/radix-engine-tests/assets/wasm/recursion.wat index cf634cd3c9f..d8208334663 100644 --- a/radix-engine-tests/assets/wasm/recursion.wat +++ b/radix-engine-tests/assets/wasm/recursion.wat @@ -6,10 +6,13 @@ (local.get $0) (i32.const 2) ) - (return - (i32.const 1) + (then + (return + (i32.const 1) + ) ) ) + (return (i32.add (call $f @@ -54,4 +57,4 @@ (memory $0 1) (export "memory" (memory $0)) (export "Test_f" (func $Test_f)) -) \ No newline at end of file +) diff --git a/radix-engine-tests/assets/wasm/reference_types_externref.wat b/radix-engine-tests/assets/wasm/reference_types_externref.wat new file mode 100644 index 00000000000..1000441e9f3 --- /dev/null +++ b/radix-engine-tests/assets/wasm/reference_types_externref.wat @@ -0,0 +1,28 @@ +(module + ;; Define a table with a externref items + (table $ref_table 2 externref) + + ;; Exported function that adds two values returned by $return_two_values + (func $Test_f (param $0 i64) (result i64) + + ;; Encode () in SBOR at address 0x0 + (i32.const 0) + (i32.const 92) ;; prefix + (i32.store8) + (i32.const 1) + (i32.const 4) ;; i32 value kind + (i32.store8) + (i32.const 2) + (i32.const 0) ;; value + (i32.store) + + ;; Return slice (ptr = 0, len = 6) + (i64.const 6) + ) + + ;; Define memory with an initial size of 1 page (64 KiB) + (memory $0 1) + (export "memory" (memory $0)) + (export "Test_f" (func $Test_f)) +) + diff --git a/radix-engine-tests/assets/wasm/reference_types_ref_func.wat b/radix-engine-tests/assets/wasm/reference_types_ref_func.wat new file mode 100644 index 00000000000..9a9c7183ebc --- /dev/null +++ b/radix-engine-tests/assets/wasm/reference_types_ref_func.wat @@ -0,0 +1,59 @@ +(module + ;; Define a function table with an initial size of 3 and a maximum size of 4 + (table $t 3 4 funcref) + (type $func_type (func (param i32 i32) (result i32))) + + ;; Initialize the table with the 3 functions + (elem (i32.const 0) $add $multiply $subtract) + + ;; Function 0: Adds two numbers + (func $add (type $func_type) + (local.get 0) + (local.get 1) + (i32.add) + ) + + ;; Function 1: Multiplies two numbers + (func $multiply (type $func_type) + (local.get 0) + (local.get 1) + (i32.mul) + ) + + ;; Function 2: Subtracts two numbers + (func $subtract (type $func_type) + (local.get 0) + (local.get 1) + (i32.sub) + ) + + ;; Function that overwrites entry at given index in function table + (func $Test_f (param $0 i64) (result i64) + (local $result i32) + + ;; Overwrite function at given index + (table.set $t + (i32.const ${index}) ;; Index + (ref.func $add) ;; Reference to $add function + ) + + ;; Encode () in SBOR at address 0x0 + (i32.const 0) + (i32.const 92) ;; prefix + (i32.store8) + (i32.const 1) + (i32.const 4) ;; i32 value kind + (i32.store8) + (i32.const 2) + (i32.const 0) ;; value + (i32.store) + + ;; Return slice (ptr = 0, len = 6) + (i64.const 6) + ) + + ;; Define memory with an initial size of 1 page (64 KiB) + (memory $0 1) + (export "memory" (memory $0)) + (export "Test_f" (func $Test_f)) +) diff --git a/radix-engine-tests/assets/wasm/reference_types_tables.wat b/radix-engine-tests/assets/wasm/reference_types_tables.wat new file mode 100644 index 00000000000..ed4b4f4695b --- /dev/null +++ b/radix-engine-tests/assets/wasm/reference_types_tables.wat @@ -0,0 +1,86 @@ +(module + ;; Define a function table with an initial size of 3 and a maximum size of 4 + (table $t 3 4 funcref) + (type $func_type (func (param i32 i32) (result i32))) + + ;; Initialize the table with the 3 functions + (elem (i32.const 0) $add $multiply $subtract) + + ;; Function 0: Adds two numbers + (func $add (type $func_type) + (local.get 0) + (local.get 1) + (i32.add) + ) + + ;; Function 1: Multiplies two numbers + (func $multiply (type $func_type) + (local.get 0) + (local.get 1) + (i32.mul) + ) + + ;; Function 2: Subtracts two numbers + (func $subtract (type $func_type) + (local.get 0) + (local.get 1) + (i32.sub) + ) + + ;; Function to grow the table and add a new element + (func $grow_table + (local $ref_func funcref) + ;; ref.func not yet supported in 'wasm-instrument' + ;; see https://github.com/radixdlt/wasm-instrument/blob/405166c526aa60fa2af4e4b1122b156dbcc1bb15/src/stack_limiter/max_height.rs#L455 + ;; (local.set $ref_func + ;; (ref.func $add) + ;; ) + ;; use table.get instead to get funcref + (local.set $ref_func + (table.get $t + ;; Get $add function at the index 0 + (i32.const 0) + ) + ) + (table.grow $t + (local.get $ref_func) ;; Initial value of the new entries + (i32.const 1) ;; Number of entries to grow + ) + ;; table.grow returns previous size, drop it + (drop) + ) + + ;; Function that grows table and calls some function in the table + (func $Test_f (param $0 i64) (result i64) + (local $result i32) + + (call $grow_table) + + (i32.const ${a}) + (i32.const ${b}) + (call_indirect + (type $func_type) + (i32.const ${index}) ;; Call function at given index + ) + (local.set $result) ;; value + + ;; Encode () in SBOR at address 0x0 + (i32.const 0) + (i32.const 92) ;; prefix + (i32.store8) + (i32.const 1) + (i32.const 4) ;; i32 value kind + (i32.store8) + (i32.const 2) + (local.get $result) ;; value + (i32.store) + + ;; Return slice (ptr = 0, len = 6) + (i64.const 6) + ) + + ;; Define memory with an initial size of 1 page (64 KiB) + (memory $0 1) + (export "memory" (memory $0)) + (export "Test_f" (func $Test_f)) +) diff --git a/radix-engine-tests/benches/costing.rs b/radix-engine-tests/benches/costing.rs index b15a80ff9ff..d08b95e5524 100644 --- a/radix-engine-tests/benches/costing.rs +++ b/radix-engine-tests/benches/costing.rs @@ -14,7 +14,6 @@ use radix_engine_tests::common::*; use radix_substate_store_queries::typed_substate_layout::{CodeHash, PackageDefinition}; use sbor::rust::iter; use scrypto_test::prelude::*; -use wabt::wat2wasm; fn generate_interesting_bytes_of_length(length: usize) -> Vec { include_workspace_asset_bytes!("radix-transaction-scenarios", "radiswap.rpd") @@ -176,8 +175,7 @@ fn bench_validate_secp256k1(c: &mut Criterion) { fn bench_spin_loop_v1(c: &mut Criterion) { // Prepare code let code = - wat2wasm(&include_local_wasm_str!("loop.wat").replace("${n}", &i32::MAX.to_string())) - .unwrap(); + wat2wasm(&include_local_wasm_str!("loop.wat").replace("${n}", &i32::MAX.to_string())); let mut ledger = LedgerSimulatorBuilder::new().build(); let package_address = ledger.publish_package_simple(PackagePublishingSource::PublishExisting( code, @@ -210,7 +208,7 @@ fn bench_spin_loop_v1(c: &mut Criterion) { // There is only one instruction `br` per iteration. // It's extremely helpful for stress testing the `consume_wasm_execution_units` host function. fn bench_spin_loop_v2(c: &mut Criterion) { - let code = wat2wasm(&include_local_wasm_str!("loop_v2.wat")).unwrap(); + let code = wat2wasm(&include_local_wasm_str!("loop_v2.wat")); let mut ledger = LedgerSimulatorBuilder::new().build(); let package_address = ledger.publish_package_simple(PackagePublishingSource::PublishExisting( code, @@ -338,7 +336,7 @@ macro_rules! bench_instantiate { c.bench_function(concat!("costing::instantiate_", $what), |b| { b.iter(|| { let wasm_engine = DefaultWasmEngine::default(); - wasm_engine.instantiate(CodeHash(Hash([0u8; 32])), &instrumented_code); + wasm_engine.instantiate(CodeHash(Hash([0u8; 32])), &instrumented_code, ScryptoVmVersion::latest()); }) }); @@ -374,7 +372,7 @@ fn bench_deserialize_wasm(c: &mut Criterion) { let code = include_workspace_asset_bytes!("radix-transaction-scenarios", "radiswap.wasm"); c.bench_function("costing::deserialize_wasm", |b| { - b.iter(|| WasmModule::init(code).unwrap()) + b.iter(|| WasmModule::init(code, ScryptoVmVersion::latest()).unwrap()) }); } diff --git a/radix-engine-tests/tests/blueprints/tx_processor.rs b/radix-engine-tests/tests/blueprints/tx_processor.rs index 63b8f772a9b..6d41b6df988 100644 --- a/radix-engine-tests/tests/blueprints/tx_processor.rs +++ b/radix-engine-tests/tests/blueprints/tx_processor.rs @@ -10,7 +10,6 @@ use radix_substate_store_impls::memory_db::InMemorySubstateDatabase; use radix_transactions::prelude::*; use scrypto::{crypto::hash, data::manifest::model::ManifestBlobRef, types::PackageAddress}; use scrypto_test::prelude::*; -use wabt::wat2wasm; #[test] fn test_blob_replacement_beyond_blob_size_limit() { @@ -90,7 +89,7 @@ fn test_blob_replacement_within_blob_size_limit() { fn publish_test_package( sim: &mut LedgerSimulator, ) -> PackageAddress { - let code = wat2wasm(include_local_wasm_str!("basic_package.wat")).unwrap(); + let code = wat2wasm(include_local_wasm_str!("basic_package.wat")); let manifest = ManifestBuilder::new() .lock_fee_from_faucet() .publish_package_advanced( diff --git a/radix-engine-tests/tests/vm/wasm_memory.rs b/radix-engine-tests/tests/vm/wasm_memory.rs index 302f78e7faa..ebd20bc0ebc 100644 --- a/radix-engine-tests/tests/vm/wasm_memory.rs +++ b/radix-engine-tests/tests/vm/wasm_memory.rs @@ -3,13 +3,13 @@ use radix_common::prelude::*; use radix_engine::errors::*; use radix_engine::system::system_modules::costing::SystemLoanFeeReserve; use radix_engine::transaction::CostingParameters; -use radix_engine::vm::wasm::*; use radix_engine::vm::wasm_runtime::NoOpWasmRuntime; +use radix_engine::vm::{wasm::*, ScryptoVmVersion}; use radix_engine_interface::blueprints::package::CodeHash; use radix_engine_interface::prelude::*; use radix_engine_tests::common::*; use radix_transactions::model::TransactionCostingParameters; -use wabt::wat2wasm; +use scrypto_test::prelude::wat2wasm; const KB: u64 = 1024; const MB: u64 = 1024 * KB; @@ -66,9 +66,10 @@ macro_rules! write_memory_err { #[test] fn test_wasm_memory_grow_read_write() { // Arrange - let code = wat2wasm(&include_local_wasm_str!("memory_boundaries.wat")).unwrap(); + let code = wat2wasm(&include_local_wasm_str!("memory_boundaries.wat")); let wasm_engine = DefaultWasmEngine::default(); - let mut instance = wasm_engine.instantiate(CodeHash(Hash([0u8; 32])), &code); + let mut instance = + wasm_engine.instantiate(CodeHash(Hash([0u8; 32])), &code, ScryptoVmVersion::latest()); let fee_reserve = SystemLoanFeeReserve::new( CostingParameters::babylon_genesis(), @@ -159,9 +160,10 @@ fn test_wasm_memory_grow_read_write() { #[test] fn test_wasm_memory_is_clean() { // Arrange - let code = wat2wasm(&include_local_wasm_str!("memory_boundaries.wat")).unwrap(); + let code = wat2wasm(&include_local_wasm_str!("memory_boundaries.wat")); let wasm_engine = DefaultWasmEngine::default(); - let mut instance = wasm_engine.instantiate(CodeHash(Hash([0u8; 32])), &code); + let mut instance = + wasm_engine.instantiate(CodeHash(Hash([0u8; 32])), &code, ScryptoVmVersion::latest()); let fee_reserve = SystemLoanFeeReserve::new( CostingParameters::babylon_genesis(), diff --git a/radix-engine-tests/tests/vm/wasm_non_mvp.rs b/radix-engine-tests/tests/vm/wasm_non_mvp.rs index daa1aaa5ce4..0a502679345 100644 --- a/radix-engine-tests/tests/vm/wasm_non_mvp.rs +++ b/radix-engine-tests/tests/vm/wasm_non_mvp.rs @@ -1,103 +1,455 @@ use paste::paste; use radix_common::prelude::*; -use radix_engine::vm::wasm::WasmModule; +use radix_engine::vm::{ + wasm::{PrepareError, WasmModule}, + ScryptoVmVersion, +}; use radix_engine_tests::common::*; use scrypto_test::prelude::*; +macro_rules! get_ledger { + ($version:expr) => { + LedgerSimulatorBuilder::new() + .with_custom_protocol(|builder: radix_engine::updates::ProtocolBuilder| { + builder.from_bootstrap_to($version) + }) + .build() + }; +} + +macro_rules! manifest_execute_test_function { + ($ledger:expr, $package_address:expr) => {{ + let manifest = ManifestBuilder::new() + .lock_fee_from_faucet() + .call_function($package_address, "Test", "f", manifest_args!()) + .build(); + $ledger.execute_manifest(manifest, vec![]) + }}; +} + // Verify WASM sign-extensions, which were enabled by default to the wasm32 target // since rust 1.70.0 // see: https://github.com/rust-lang/rust/issues/109807 -macro_rules! assert_sign_extensions { - ($type:expr, $instruction:expr, $input:expr, $output:expr) => { - paste! { - #[test] - fn []() { - // Arrange - let value_kind = BasicValueKind::[<$type:upper>].as_u8().to_string(); - let slice_len = ( - 1 + // prefix byte - 1 + // value kind byte - std::mem::size_of::<$type>() // value bytes - ).to_string(); - let input = $input as $type; - - // Act - let code = wat2wasm(&include_local_wasm_str!("sign_extensions.wat") - .replace("${base}", stringify!($type)) - .replace("${instruction}", $instruction) - .replace("${initial}", &input.to_string()) - .replace("${value_kind}", &value_kind) - .replace("${slice_len}", &slice_len)); - - assert!(WasmModule::init(&code).unwrap().contains_sign_ext_ops()); - - let mut ledger = LedgerSimulatorBuilder::new().build(); - let package_address = ledger.publish_package( - (code, single_function_package_definition("Test", "f")), - BTreeMap::new(), - OwnerRole::None, - ); - let manifest = ManifestBuilder::new() - .lock_fee_from_faucet() - .call_function(package_address, "Test", "f", manifest_args!()) - .build(); - let receipt = ledger.execute_manifest(manifest, vec![]); - - // Assert - let outcome: $type = receipt.expect_commit(true).output(1); - assert_eq!(outcome, $output as $type); +mod sign_extensions { + use super::*; + + macro_rules! assert_sign_extensions { + ($type:expr, $instruction:expr, $input:expr, $output:expr) => { + paste! { + #[test] + fn []() { + // Arrange + let value_kind = BasicValueKind::[<$type:upper>].as_u8().to_string(); + let slice_len = ( + 1 + // prefix byte + 1 + // value kind byte + std::mem::size_of::<$type>() // value bytes + ).to_string(); + let input = $input as $type; + + // Act + let code = wat2wasm(&include_local_wasm_str!("sign_extensions.wat") + .replace("${base}", stringify!($type)) + .replace("${instruction}", $instruction) + .replace("${initial}", &input.to_string()) + .replace("${value_kind}", &value_kind) + .replace("${slice_len}", &slice_len)); + + assert!(WasmModule::init(&code, ScryptoVmVersion::latest()).unwrap().contains_sign_ext_ops()); + + let mut ledger = LedgerSimulatorBuilder::new().build(); + let package_address = ledger.publish_package( + (code, single_function_package_definition("Test", "f")), + BTreeMap::new(), + OwnerRole::None, + ); + let receipt = manifest_execute_test_function!(ledger, package_address); + + // Assert + let outcome: $type = receipt.expect_commit(true).output(1); + assert_eq!(outcome, $output as $type); + } } - } - }; + }; + } + + assert_sign_extensions!(i32, "extend8_s", 0x44332211, 0x11); + assert_sign_extensions!(i32, "extend16_s", 0x44332211, 0x2211); + assert_sign_extensions!(i64, "extend8_s", 0x665544332211, 0x11); + assert_sign_extensions!(i64, "extend16_s", 0x665544332211, 0x2211); + assert_sign_extensions!(i64, "extend32_s", 0x665544332211, 0x44332211); } -assert_sign_extensions!(i32, "extend8_s", 0x44332211, 0x11); -assert_sign_extensions!(i32, "extend16_s", 0x44332211, 0x2211); -assert_sign_extensions!(i64, "extend8_s", 0x665544332211, 0x11); -assert_sign_extensions!(i64, "extend16_s", 0x665544332211, 0x2211); -assert_sign_extensions!(i64, "extend32_s", 0x665544332211, 0x44332211); - -#[test] -fn test_wasm_non_mvp_mutable_globals_import() { - // Arrange - let code = wat2wasm(&include_local_wasm_str!("mutable_globals_import.wat")); - - // Act - let mut ledger = LedgerSimulatorBuilder::new().build(); - let manifest = ManifestBuilder::new() - .lock_fee_from_faucet() - .publish_package_advanced( - None, - code, - single_function_package_definition("Test", "f"), +mod mutable_globals { + use super::*; + + #[test] + fn test_wasm_non_mvp_mutable_globals_import() { + // Arrange + let code = wat2wasm(&include_local_wasm_str!("mutable_globals_import.wat")); + + // Act + let mut ledger = LedgerSimulatorBuilder::new().build(); + let manifest = ManifestBuilder::new() + .lock_fee_from_faucet() + .publish_package_advanced( + None, + code, + single_function_package_definition("Test", "f"), + BTreeMap::new(), + OwnerRole::None, + ) + .build(); + let receipt = ledger.execute_manifest(manifest, vec![]); + + // Assert + receipt.expect_commit_failure_containing_error("InvalidImport"); + } + + #[test] + fn test_wasm_non_mvp_mutable_globals_export() { + // Arrange + let code = wat2wasm(&include_local_wasm_str!("mutable_globals_export.wat")); + + // Act + let mut ledger = LedgerSimulatorBuilder::new().build(); + let package_address = ledger.publish_package( + (code, single_function_package_definition("Test", "f")), BTreeMap::new(), OwnerRole::None, - ) - .build(); - let receipt = ledger.execute_manifest(manifest, vec![]); + ); + let receipt = manifest_execute_test_function!(ledger, package_address); - // Assert - receipt.expect_commit_failure_containing_error("InvalidImport"); + // Assert + assert!(receipt.is_commit_success()); + } } -#[test] -fn test_wasm_non_mvp_mutable_globals_export() { - // Arrange - let code = wat2wasm(&include_local_wasm_str!("mutable_globals_export.wat")); - - // Act - let mut ledger = LedgerSimulatorBuilder::new().build(); - let package_address = ledger.publish_package( - (code, single_function_package_definition("Test", "f")), - BTreeMap::new(), - OwnerRole::None, - ); - let manifest = ManifestBuilder::new() - .lock_fee_from_faucet() - .call_function(package_address, "Test", "f", manifest_args!()) - .build(); - let receipt = ledger.execute_manifest(manifest, vec![]); - - // Assert - assert!(receipt.is_commit_success()); +// Verify WASM multi-value, which was enabled by default to the wasm32 target +// since rust 1.82.0 (which switched to LLVM 19) +// see: https://blog.rust-lang.org/2024/09/24/webassembly-targets-change-in-default-target-features.html +mod multi_value { + use super::*; + + #[test] + fn test_wasm_non_mvp_multi_value_function_return_multiple_values_cuttlefish_failure() { + // Arrange + let code = wat2wasm( + &include_local_wasm_str!("multi_value_function_return_multiple_values.wat") + .replace("${a}", "10") + .replace("${b}", "20"), + ); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Cuttlefish); + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + + // Assert + receipt.expect_specific_failure(|error| match error { + RuntimeError::ApplicationError(ApplicationError::PackageError( + PackageError::InvalidWasm(PrepareError::ValidationError(message)), + )) => message.contains( + "func type returns multiple values but the multi-value feature is not enabled", + ), + _ => false, + }); + } + + #[test] + fn test_wasm_non_mvp_multi_value_function_return_multiple_values_dugong_success() { + // Arrange + let code = wat2wasm( + &include_local_wasm_str!("multi_value_function_return_multiple_values.wat") + .replace("${a}", "10") + .replace("${b}", "20"), + ); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Dugong); + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + + // Assert + let package_address = receipt.expect_commit(true).new_package_addresses()[0]; + + // Act + let receipt = manifest_execute_test_function!(ledger, package_address); + + // Assert + let outcome: i32 = receipt.expect_commit(true).output(1); + assert_eq!(outcome, 30); + } + + #[test] + fn test_wasm_non_mvp_multi_value_if_return_multiple_values_cuttlefish_failure() { + // Arrange + let code = wat2wasm( + &include_local_wasm_str!("multi_value_if_return_multiple_values.wat") + .replace("${a}", "10") + .replace("${b}", "20"), + ); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Cuttlefish); + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + + // Assert + receipt.expect_specific_failure(|error| match error { + RuntimeError::ApplicationError(ApplicationError::PackageError( + PackageError::InvalidWasm(PrepareError::ValidationError(message)), + )) => message.contains( + "func type returns multiple values but the multi-value feature is not enabled", + ), + _ => false, + }); + } + + #[test] + fn test_wasm_non_mvp_multi_value_return_multiple_values_cuttlefish_failure() { + for section in ["block", "loop"] { + // Arrange + let code = wat2wasm( + &include_local_wasm_str!("multi_value_loop_or_block_return_multiple_values.wat") + .replace("${loop_or_block}", section) + .replace("${a}", "10") + .replace("${b}", "20"), + ); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Cuttlefish); + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + + // Assert + receipt.expect_specific_failure(|error| match error { + RuntimeError::ApplicationError(ApplicationError::PackageError( + PackageError::InvalidWasm(PrepareError::ValidationError(message)), + )) => message.contains( + "func type returns multiple values but the multi-value feature is not enabled", + ), + _ => false, + }); + } + } + + #[test] + fn test_wasm_non_mvp_multi_value_return_multiple_values_dugong_success() { + for section in ["block", "loop"] { + // Arrange + let code = wat2wasm( + &include_local_wasm_str!("multi_value_loop_or_block_return_multiple_values.wat") + .replace("${loop_or_block}", section) + .replace("${a}", "10") + .replace("${b}", "20"), + ); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Dugong); + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + + // Assert + let package_address = receipt.expect_commit(true).new_package_addresses()[0]; + + // Act + let receipt = manifest_execute_test_function!(ledger, package_address); + + // Assert + let outcome: i32 = receipt.expect_commit(true).output(1); + assert_eq!(outcome, 30); + } + } + + #[test] + fn test_wasm_non_mvp_multi_value_params_cuttlefish_failure() { + for section in ["block", "loop"] { + // Arrange + let code = wat2wasm( + &include_local_wasm_str!("multi_value_loop_or_block_params.wat") + .replace("${loop_or_block}", section) + .replace("${a}", "10") + .replace("${b}", "20"), + ); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Cuttlefish); + + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + + // Assert + receipt.expect_specific_failure(|error| { + match error { + RuntimeError::ApplicationError(ApplicationError::PackageError( + PackageError::InvalidWasm(PrepareError::ValidationError(message)), + )) => message.contains( + "blocks, loops, and ifs may only produce a resulttype when multi-value is not enabled", + ), + _ => false, + } + }); + } + } + + #[test] + fn test_wasm_non_mvp_multi_value_params_dugong_success() { + for section in ["block", "loop"] { + // Arrange + let code = wat2wasm( + &include_local_wasm_str!("multi_value_loop_or_block_params.wat") + .replace("${loop_or_block}", section) + .replace("${a}", "10") + .replace("${b}", "20"), + ); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Dugong); + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + + // Assert + let package_address = receipt.expect_commit(true).new_package_addresses()[0]; + + // Act + let receipt = manifest_execute_test_function!(ledger, package_address); + + // Assert + let outcome: i32 = receipt.expect_commit(true).output(1); + assert_eq!(outcome, 30); + } + } +} + +// Verify WASM reference-types, which was enabled by default to the wasm32 target +// since rust 1.82.0 (which switched to LLVM 19) +// see: https://blog.rust-lang.org/2024/09/24/webassembly-targets-change-in-default-target-features.html +mod reference_types { + use super::*; + + #[test] + fn test_wasm_non_mvp_reference_types_externref_cuttlefish_failure() { + // Arrange + let code = wat2wasm(&include_local_wasm_str!("reference_types_externref.wat")); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Cuttlefish); + + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + + // Assert + receipt.expect_specific_failure(|error| match error { + RuntimeError::ApplicationError(ApplicationError::PackageError( + PackageError::InvalidWasm(PrepareError::ValidationError(message)), + )) => message.contains("reference types support is not enabled"), + _ => false, + }); + } + + #[test] + fn test_wasm_non_mvp_reference_types_externref_dugong_success() { + // Arrange + let code = wat2wasm(&include_local_wasm_str!("reference_types_externref.wat")); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Dugong); + + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + // Assert + let package_address = receipt.expect_commit(true).new_package_addresses()[0]; + + // Act + let receipt = manifest_execute_test_function!(ledger, package_address); + + // Assert + receipt.expect_commit(true); + } + + #[test] + fn test_wasm_non_mvp_reference_types_tables_cuttlefish_failure() { + // Arrange + let code = wat2wasm( + &include_local_wasm_str!("reference_types_tables.wat") + .replace("${index}", "0") + .replace("${a}", "20") + .replace("${b}", "10"), + ); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Cuttlefish); + + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + + // Assert + receipt.expect_specific_failure(|error| match error { + RuntimeError::ApplicationError(ApplicationError::PackageError( + PackageError::InvalidWasm(PrepareError::ValidationError(message)), + )) => message.contains("reference types support is not enabled"), + _ => false, + }); + } + + #[test] + fn test_wasm_non_mvp_reference_types_tables_dugong_success() { + for (index, result) in [ + ("0", 30), // Add + ("1", 200), // Multiply + ("2", 10), // Subtract + ] { + // Arrange + let code = wat2wasm( + &include_local_wasm_str!("reference_types_tables.wat") + .replace("${index}", index) + .replace("${a}", "20") + .replace("${b}", "10"), + ); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Dugong); + + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + // Assert + let package_address = receipt.expect_commit(true).new_package_addresses()[0]; + + // Act + let receipt = manifest_execute_test_function!(ledger, package_address); + + // Assert + let outcome: i32 = receipt.expect_commit(true).output(1); + assert_eq!(outcome, result); + } + } + + #[test] + fn test_wasm_non_mvp_reference_types_ref_func_should_success() { + // TODO WASM this test demonstrates that RefFunc (and some other instructions enabled in + // reference-types) are not supported in 'wasm-instrument' + // see https://github.com/radixdlt/wasm-instrument/blob/405166c526aa60fa2af4e4b1122b156dbcc1bb15/src/stack_limiter/max_height.rs#L455 + // It would be perfect to update the 'wasm-instrument' crate. + // If not it shall be carefully investigated if it is safe to enable 'reference-types' + // (all WASM-related tests are running fine when 'reference-types' are enabled, + // as if the Rust compiler (LLVM) was not using those instructions) + + // Arrange + let code = wat2wasm( + &include_local_wasm_str!("reference_types_ref_func.wat").replace("${index}", "0"), + ); + + // Act + let mut ledger = get_ledger!(ProtocolVersion::Dugong); + + let receipt = + ledger.try_publish_package((code, single_function_package_definition("Test", "f"))); + // Assert + // This test should success but it returns below error + // thread 'vm::wasm_non_mvp::reference_types::test_wasm_non_mvp_reference_types_ref_func_failure' panicked at + // /home/ubuntu/.cargo/registry/src/index.crates.io-6f17d22bba15001f/radix-wasm-instrument-1.0.0/src/stack_limiter/max_height.rs:455:17: + // not yet implemented: some reference types proposal are not supported + let _package_address = receipt.expect_commit(true).new_package_addresses()[0]; + } } diff --git a/radix-engine-tests/tests/vm/wasm_validation.rs b/radix-engine-tests/tests/vm/wasm_validation.rs index 5ef10fc328c..af46c6131ca 100644 --- a/radix-engine-tests/tests/vm/wasm_validation.rs +++ b/radix-engine-tests/tests/vm/wasm_validation.rs @@ -37,7 +37,9 @@ fn invalid_export_name_should_fail() { "a!", "a-", "a\u{221A}", - "\0", + // TODO WASM: wat parser does not allow '\0', so cannot generate WASM module for further + // validations. Use old wabt::wat2wasm or get rid of this test case? + // "\0", "a\'", "self", "crate", diff --git a/radix-engine/Cargo.toml b/radix-engine/Cargo.toml index 25b7fb4680b..287470748e1 100644 --- a/radix-engine/Cargo.toml +++ b/radix-engine/Cargo.toml @@ -49,7 +49,8 @@ wasmi = { workspace = true } lazy_static = { workspace = true } [dev-dependencies] -wabt = { workspace = true } +wat = { workspace = true } +wasmprinter = { workspace = true } criterion = { workspace = true, features = ["html_reports"] } wasm-benchmarks-lib = { path = "./wasm-benchmarks-lib", default-features = false } diff --git a/radix-engine/src/updates/bottlenose.rs b/radix-engine/src/updates/bottlenose.rs index 7d5ee61e8ae..346300bfb62 100644 --- a/radix-engine/src/updates/bottlenose.rs +++ b/radix-engine/src/updates/bottlenose.rs @@ -35,7 +35,7 @@ pub struct BottlenoseSettings { /// Imposes a limits on the blobs in the transaction processor pub impose_a_limit_on_transaction_processor_blobs: UpdateSetting, - /// Adds differed reference cost checks. + /// Adds differed reference cost checks. pub apply_costing_for_ref_checks: UpdateSetting, /// Add restrictions to use of role key in role list. @@ -331,7 +331,7 @@ fn generate_locker_package_state_updates() -> StateUpdates { (NativeCodeId::LockerCode1 as u64).to_be_bytes().to_vec(), Default::default(), false, - &VmBoot::latest(), + &VmBoot::bottlenose(), ) .unwrap_or_else(|err| { panic!( diff --git a/radix-engine/src/updates/dugong.rs b/radix-engine/src/updates/dugong.rs index eb1603e1556..21877eec6ea 100644 --- a/radix-engine/src/updates/dugong.rs +++ b/radix-engine/src/updates/dugong.rs @@ -4,6 +4,8 @@ use crate::internal_prelude::*; #[derive(Clone, ScryptoSbor)] pub struct DugongSettings { pub native_entity_metadata_updates: UpdateSetting, + /// Enables WASM proposals: reference-types and multi-value + pub vm_boot_wasm_new_features: UpdateSetting, } impl UpdateSettings for DugongSettings { @@ -16,12 +18,14 @@ impl UpdateSettings for DugongSettings { fn all_enabled_as_default_for_network(network: &NetworkDefinition) -> Self { Self { native_entity_metadata_updates: UpdateSetting::enabled_as_default_for_network(network), + vm_boot_wasm_new_features: UpdateSetting::enabled_as_default_for_network(network), } } fn all_disabled() -> Self { Self { native_entity_metadata_updates: UpdateSetting::Disabled, + vm_boot_wasm_new_features: UpdateSetting::Disabled, } } @@ -51,6 +55,7 @@ fn generate_main_batch( store: &dyn SubstateDatabase, DugongSettings { native_entity_metadata_updates, + vm_boot_wasm_new_features, }: &DugongSettings, ) -> ProtocolUpdateBatch { let mut batch = ProtocolUpdateBatch::empty(); @@ -63,6 +68,13 @@ fn generate_main_batch( ); } + if let UpdateSetting::Enabled(NoSettings) = &vm_boot_wasm_new_features { + batch.mut_add_flash( + "dugong-vm-boot-wasm-new-features", + generate_dugong_vm_boot_wasm_new_features(), + ); + } + batch } @@ -98,3 +110,14 @@ fn generate_dugong_native_metadata_updates() -> StateUpdates { state_updates } + +fn generate_dugong_vm_boot_wasm_new_features() -> StateUpdates { + StateUpdates::empty().set_substate( + TRANSACTION_TRACKER, + BOOT_LOADER_PARTITION, + BootLoaderField::VmBoot, + VmBoot::V1 { + scrypto_version: ScryptoVmVersion::wasm_new_features().into(), + }, + ) +} diff --git a/radix-engine/src/utils/package_extractor.rs b/radix-engine/src/utils/package_extractor.rs index 654d28f802e..6d33f1cfff7 100644 --- a/radix-engine/src/utils/package_extractor.rs +++ b/radix-engine/src/utils/package_extractor.rs @@ -21,15 +21,18 @@ impl From for ExtractSchemaError { } } -pub fn extract_definition(code: &[u8]) -> Result { - let function_exports = WasmModule::init(code) +pub fn extract_definition( + code: &[u8], + version: ScryptoVmVersion, +) -> Result { + let function_exports = WasmModule::init(code, version) .and_then(WasmModule::to_bytes)? .1 .into_iter() .filter(|s| s.ends_with("_schema")); // Validate WASM - let validator = ScryptoV1WasmValidator::new(ScryptoVmVersion::latest()); + let validator = ScryptoV1WasmValidator::new(version); let code_hash = CodeHash(Hash([0u8; 32])); let instrumented_code = validator .validate(&code, iter::empty()) @@ -51,7 +54,7 @@ pub fn extract_definition(code: &[u8]) -> Result { pub wasm_engine: W, - pub wasm_validator_config: WasmValidatorConfigV1, } impl Default for ScryptoVm { fn default() -> Self { Self { wasm_engine: W::default(), - wasm_validator_config: WasmValidatorConfigV1::new(), } } } @@ -28,10 +26,14 @@ impl ScryptoVm { package_address: &PackageAddress, code_hash: CodeHash, instrumented_code: &[u8], + version: ScryptoVmVersion, ) -> ScryptoVmInstance { ScryptoVmInstance { - instance: self.wasm_engine.instantiate(code_hash, instrumented_code), + instance: self + .wasm_engine + .instantiate(code_hash, instrumented_code, version), package_address: *package_address, + version, } } } @@ -39,6 +41,7 @@ impl ScryptoVm { pub struct ScryptoVmInstance { instance: I, package_address: PackageAddress, + version: ScryptoVmVersion, } impl VmInvoke for ScryptoVmInstance { @@ -48,14 +51,14 @@ impl VmInvoke for ScryptoVmInstance { export_name: &str, args: &IndexedScryptoValue, api: &mut Y, - vm_api: &V, + _vm_api: &V, ) -> Result { let rtn = { let mut runtime: Box = Box::new(ScryptoRuntime::new( api, self.package_address, export_name.to_string(), - vm_api.get_scrypto_version(), + self.version, )); let mut input = Vec::new(); diff --git a/radix-engine/src/vm/versions.rs b/radix-engine/src/vm/versions.rs index af1f8097eee..e98fe613a67 100644 --- a/radix-engine/src/vm/versions.rs +++ b/radix-engine/src/vm/versions.rs @@ -6,11 +6,12 @@ pub enum ScryptoVmVersion { V1_0, V1_1, V1_2, + V1_3, } impl ScryptoVmVersion { pub const fn latest() -> ScryptoVmVersion { - Self::cuttlefish() + Self::dugong() } pub const fn babylon_genesis() -> ScryptoVmVersion { @@ -21,16 +22,28 @@ impl ScryptoVmVersion { Self::V1_1 } + pub const fn bottlenose() -> ScryptoVmVersion { + Self::V1_1 + } + pub const fn cuttlefish() -> ScryptoVmVersion { Self::V1_2 } + pub const fn dugong() -> ScryptoVmVersion { + Self::V1_3 + } + pub const fn crypto_utils_v1() -> ScryptoVmVersion { - Self::V1_1 + Self::anemone() } pub const fn crypto_utils_v2() -> ScryptoVmVersion { - Self::V1_2 + Self::cuttlefish() + } + + pub const fn wasm_new_features() -> ScryptoVmVersion { + Self::dugong() } } @@ -48,6 +61,7 @@ impl TryFrom for ScryptoVmVersion { 0 => Ok(Self::V1_0), 1 => Ok(Self::V1_1), 2 => Ok(Self::V1_2), + 3 => Ok(Self::V1_3), v => Err(Self::Error::FromIntError(v)), } } @@ -65,7 +79,7 @@ mod test { #[test] fn test_scrypto_vm_version() { let v = ScryptoVmVersion::latest(); - assert_eq!(v, ScryptoVmVersion::V1_2); + assert_eq!(v, ScryptoVmVersion::V1_3); assert_eq!(ScryptoVmVersion::crypto_utils_v1(), ScryptoVmVersion::V1_1); } @@ -77,9 +91,9 @@ mod test { let v: ScryptoVmVersion = 1u64.try_into().unwrap(); assert_eq!(v, ScryptoVmVersion::V1_1); - let e = ScryptoVmVersion::try_from(3u64).unwrap_err(); + let e = ScryptoVmVersion::try_from(4u64).unwrap_err(); - assert_eq!(e, ScryptoVmVersionError::FromIntError(3u64)); + assert_eq!(e, ScryptoVmVersionError::FromIntError(4u64)); } #[test] @@ -87,5 +101,12 @@ mod test { assert!(ScryptoVmVersion::crypto_utils_v1() == ScryptoVmVersion::V1_1); assert!(ScryptoVmVersion::crypto_utils_v1() > ScryptoVmVersion::V1_0); assert!(ScryptoVmVersion::crypto_utils_v1() < ScryptoVmVersion::crypto_utils_v2()); + + assert!(ScryptoVmVersion::babylon_genesis() == ScryptoVmVersion::V1_0); + assert!(ScryptoVmVersion::anemone() > ScryptoVmVersion::babylon_genesis()); + // Anemone == Bottlenose in terms of ScryptoVmVersion + assert!(ScryptoVmVersion::bottlenose() == ScryptoVmVersion::anemone()); + assert!(ScryptoVmVersion::cuttlefish() > ScryptoVmVersion::bottlenose()); + assert!(ScryptoVmVersion::dugong() > ScryptoVmVersion::cuttlefish()); } } diff --git a/radix-engine/src/vm/vm.rs b/radix-engine/src/vm/vm.rs index 70f43bd2378..0d2e6dbfeda 100644 --- a/radix-engine/src/vm/vm.rs +++ b/radix-engine/src/vm/vm.rs @@ -36,18 +36,24 @@ impl VmBoot { } pub fn latest() -> Self { - Self::bottlenose() + Self::dugong() + } + + pub fn dugong() -> Self { + Self::V1 { + scrypto_version: ScryptoVmVersion::dugong().into(), + } } pub fn bottlenose() -> Self { Self::V1 { - scrypto_version: ScryptoVmVersion::V1_1.into(), + scrypto_version: ScryptoVmVersion::bottlenose().into(), } } pub fn babylon_genesis() -> Self { Self::V1 { - scrypto_version: ScryptoVmVersion::V1_0.into(), + scrypto_version: ScryptoVmVersion::babylon_genesis().into(), } } } @@ -66,7 +72,7 @@ impl VmApi for VmBoot { } /// This trait is intended to encapsulate the data and types required to -/// initalize the VMs in the engine. +/// initialize the VMs in the engine. /// /// The canonical implementation is [`VmModules`] - but we have this trait /// as well so that functions can take an `&impl VmInitialize` parameter, @@ -267,6 +273,7 @@ impl<'g, W: WasmEngine + 'g, E: NativeVmExtension> SystemCallbackObject for Vm<' address, export.code_hash, &instrumented_code.instrumented_code, + vm_api.get_scrypto_version(), ) }; diff --git a/radix-engine/src/vm/wasm/errors.rs b/radix-engine/src/vm/wasm/errors.rs index 645ed86f835..ed1052be3f3 100644 --- a/radix-engine/src/vm/wasm/errors.rs +++ b/radix-engine/src/vm/wasm/errors.rs @@ -88,6 +88,7 @@ pub enum InvalidMemory { } #[derive(Debug, PartialEq, Eq, Clone, Sbor)] +// TODO WASM is it safe to refactor to be up-to-date with reference-types feature? pub enum InvalidTable { /// More than one table defined, against WebAssembly MVP spec MoreThanOneTable, diff --git a/radix-engine/src/vm/wasm/mod.rs b/radix-engine/src/vm/wasm/mod.rs index 2942b1e7224..2d2ac478748 100644 --- a/radix-engine/src/vm/wasm/mod.rs +++ b/radix-engine/src/vm/wasm/mod.rs @@ -2,6 +2,7 @@ mod constants; mod errors; mod prepare; mod traits; +mod wasm_features_config; mod wasm_validator; mod wasm_validator_config; mod wasmi; @@ -12,6 +13,7 @@ pub use constants::*; pub use errors::*; pub use prepare::*; pub use traits::*; +pub use wasm_features_config::*; pub use wasm_validator::*; pub use wasm_validator_config::*; pub use weights::*; diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index b12cbe64846..c04eb899c5b 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -1,7 +1,7 @@ extern crate radix_wasm_instrument as wasm_instrument; use crate::internal_prelude::*; -use crate::vm::wasm::{constants::*, errors::*, PrepareError}; +use crate::vm::wasm::{constants::*, errors::*, PrepareError, WasmFeaturesConfig}; use num_traits::CheckedAdd; use radix_engine_interface::blueprints::package::BlueprintDefinitionInit; use syn::Ident; @@ -18,41 +18,21 @@ use crate::vm::ScryptoVmVersion; #[derive(Debug)] pub struct WasmModule { module: ModuleInfo, + features: WasmFeatures, } impl WasmModule { - pub fn init(code: &[u8]) -> Result { + pub fn init(code: &[u8], version: ScryptoVmVersion) -> Result { // deserialize let module = ModuleInfo::new(code).map_err(|_| PrepareError::DeserializationError)?; - // Radix Engine supports MVP + proposals: mutable globals and sign-extension-ops - let features = WasmFeatures { - mutable_global: true, - saturating_float_to_int: false, - sign_extension: true, - reference_types: false, - multi_value: false, - bulk_memory: false, - simd: false, - relaxed_simd: false, - threads: false, - tail_call: false, - floats: false, - multi_memory: false, - exceptions: false, - memory64: false, - extended_const: false, - component_model: false, - function_references: false, - memory_control: false, - gc: false, - }; + let features = WasmFeaturesConfig::from_scrypto_vm_version(version).features; module .validate(features) .map_err(|err| PrepareError::ValidationError(err.to_string()))?; - Ok(Self { module }) + Ok(Self { module, features }) } pub fn enforce_no_start_function(self) -> Result { @@ -1064,24 +1044,42 @@ impl WasmModule { Ok(self) } - pub fn enforce_table_limit(self, max_initial_table_size: u32) -> Result { + pub fn enforce_table_limit( + self, + max_number_of_tables: u32, + max_table_size: u32, + ) -> Result { let section = self .module .table_section() .map_err(|err| PrepareError::ModuleInfoError(err.to_string()))?; if let Some(section) = section { - if section.len() > 1 { + let max_number_of_tables = if !self.features.reference_types { // Sanity check MVP rule + 1 + } else { + max_number_of_tables + }; + + if section.len() > max_number_of_tables as usize { return Err(PrepareError::InvalidTable(InvalidTable::MoreThanOneTable)); } if let Some(table) = section.get(0) { - if table.ty.initial > max_initial_table_size { + if table.ty.initial > max_table_size { return Err(PrepareError::InvalidTable( InvalidTable::InitialTableSizeLimitExceeded, )); } + + if let Some(maximum) = table.ty.maximum { + if maximum > max_table_size { + return Err(PrepareError::InvalidTable( + InvalidTable::InitialTableSizeLimitExceeded, + )); + } + } } } @@ -1267,7 +1265,7 @@ impl WasmModule { Ok(self) } - pub fn ensure_instantiatable(self) -> Result { + pub fn ensure_instantiatable(self, version: ScryptoVmVersion) -> Result { // During instantiation time, the following procedures are applied: // 1. Resolve imports with external values @@ -1285,7 +1283,7 @@ impl WasmModule { // Because the offset can be an `InitExpr` that requires evaluation against an WASM instance, // we're using the `wasmi` logic as a shortcut. let code = self.module.bytes(); - WasmiModule::new(&code[..]) + WasmiModule::new(&code[..], version) .map_err(|_| PrepareError::NotCompilable)? .instantiate() .map_err(|e| PrepareError::NotInstantiatable { @@ -1396,27 +1394,47 @@ mod tests { }; use radix_engine_interface::blueprints::package::BlueprintType; use sbor::basic_well_known_types::{ANY_TYPE, UNIT_TYPE}; - use wabt::{wat2wasm_with_features, Features}; macro_rules! wat2wasm { ($wat: expr) => {{ - let mut features = Features::new(); - features.enable_sign_extension(); - features.enable_mutable_globals(); - let code = wat2wasm_with_features($wat, features).unwrap(); - code + wat::parse_str($wat).unwrap() }}; } macro_rules! assert_invalid_wasm { ($wat: expr, $err: expr) => { let code = wat2wasm!($wat); - assert_eq!($err, WasmModule::init(&code).unwrap_err()); + assert_eq!( + $err, + WasmModule::init(&code, ScryptoVmVersion::latest()).unwrap_err() + ); }; ($wat: expr, $err: expr, $func: expr) => { let code = wat2wasm!($wat); - assert_eq!($err, WasmModule::init(&code).and_then($func).unwrap_err()); + assert_eq!( + $err, + WasmModule::init(&code, ScryptoVmVersion::latest()) + .and_then($func) + .unwrap_err() + ); + }; + + ($wat: expr, $err: expr, $func: expr, $version: expr) => { + let code = wat2wasm!($wat); + assert_eq!( + $err, + WasmModule::init(&code, $version) + .and_then($func) + .unwrap_err() + ); + }; + } + + macro_rules! assert_valid_wasm { + ($wat: expr, $func: expr, $version: expr) => { + let code = wat2wasm!($wat); + assert!(WasmModule::init(&code, $version).and_then($func).is_ok()); }; } @@ -1637,6 +1655,8 @@ mod tests { // PrepareError::InvalidMemory(InvalidMemory::TooManyMemories), // |x| WasmModule::enforce_memory_limit(x, 5) // ); + + // Assert memory initial size assert_invalid_wasm!( r#" (module @@ -1646,6 +1666,16 @@ mod tests { PrepareError::InvalidMemory(InvalidMemory::MemorySizeLimitExceeded), |x| WasmModule::enforce_memory_limit_and_inject_max(x, 5) ); + // Assert memory maximum size + assert_invalid_wasm!( + r#" + (module + (memory 5 6) + ) + "#, + PrepareError::InvalidMemory(InvalidMemory::MemorySizeLimitExceeded), + |x| WasmModule::enforce_memory_limit_and_inject_max(x, 5) + ); assert_invalid_wasm!( r#" (module @@ -1659,6 +1689,51 @@ mod tests { #[test] fn test_table() { + // Multiple tables not allowed until `reference-types` enabled (Dugong) + // We won't get `InvalidTable::MoreThanOneTable` error because wasmparser + // detects multiple tables first during WASM validation stage. + assert_invalid_wasm!( + r#" + (module + (table 1 5 funcref) + (table 5 5 funcref) + ) + "#, + PrepareError::ValidationError( + "WasmParserError(BinaryReaderError { multiple tables (at offset 0xa) })" + .to_string() + ), + |x| WasmModule::enforce_table_limit(x, 2, 5), + ScryptoVmVersion::cuttlefish() + ); + + // Multiple tables not allowed until Dugong + assert_valid_wasm!( + r#" + (module + (table 1 5 funcref) + (table 5 5 funcref) + ) + "#, + |x| WasmModule::enforce_table_limit(x, 2, 5), + ScryptoVmVersion::dugong() + ); + + // Multiple tables are allowed since `reference-types` has been enabled (Dugong) + assert_invalid_wasm!( + r#" + (module + (table 1 5 funcref) + (table 5 5 funcref) + (table 5 5 funcref) + ) + "#, + // TODO WASM this error is misleading + PrepareError::InvalidTable(InvalidTable::MoreThanOneTable), + |x| WasmModule::enforce_table_limit(x, 2, 5) + ); + + // Assert table initial size assert_invalid_wasm!( r#" (module @@ -1666,7 +1741,17 @@ mod tests { ) "#, PrepareError::InvalidTable(InvalidTable::InitialTableSizeLimitExceeded), - |x| WasmModule::enforce_table_limit(x, 5) + |x| WasmModule::enforce_table_limit(x, 1, 5) + ); + // Assert table maximum size + assert_invalid_wasm!( + r#" + (module + (table 5 6 funcref) + ) + "#, + PrepareError::InvalidTable(InvalidTable::InitialTableSizeLimitExceeded), + |x| WasmModule::enforce_table_limit(x, 1, 5) ); } @@ -1862,7 +1947,9 @@ mod tests { "# ); - assert!(WasmModule::init(&code).unwrap().contains_sign_ext_ops()); + assert!(WasmModule::init(&code, ScryptoVmVersion::latest()) + .unwrap() + .contains_sign_ext_ops()); let code = wat2wasm!( r#" @@ -1875,6 +1962,8 @@ mod tests { "# ); - assert!(!WasmModule::init(&code).unwrap().contains_sign_ext_ops()); + assert!(!WasmModule::init(&code, ScryptoVmVersion::latest()) + .unwrap() + .contains_sign_ext_ops()); } } diff --git a/radix-engine/src/vm/wasm/traits.rs b/radix-engine/src/vm/wasm/traits.rs index d5958ee85c4..1ac38c7195f 100644 --- a/radix-engine/src/vm/wasm/traits.rs +++ b/radix-engine/src/vm/wasm/traits.rs @@ -287,5 +287,10 @@ pub trait WasmEngine { /// Instantiate a Scrypto module. /// /// The code must have been validated and instrumented! - fn instantiate(&self, code_hash: CodeHash, instrumented_code: &[u8]) -> Self::WasmInstance; + fn instantiate( + &self, + code_hash: CodeHash, + instrumented_code: &[u8], + version: ScryptoVmVersion, + ) -> Self::WasmInstance; } diff --git a/radix-engine/src/vm/wasm/wasm_features_config.rs b/radix-engine/src/vm/wasm/wasm_features_config.rs new file mode 100644 index 00000000000..f881edcd737 --- /dev/null +++ b/radix-engine/src/vm/wasm/wasm_features_config.rs @@ -0,0 +1,145 @@ +use crate::vm::ScryptoVmVersion; +use radix_rust::prelude::String; +use wasmparser::WasmFeatures; + +macro_rules! cflag { + ($flag:expr, $name:expr) => { + if $flag { + concat!(" -m", $name) + } else { + concat!(" -mno-", $name) + } + }; +} + +#[derive(Debug, Clone)] +pub struct WasmFeaturesConfig { + pub features: WasmFeatures, +} + +impl Default for WasmFeaturesConfig { + fn default() -> Self { + Self::latest() + } +} + +// The Radix Engine supports the WASM MVP and below proposals: +// - since Babylon: +// a) mutable-globals +// b) sign-extension-ops +// - since Dugong +// a) mutable-globals +// b) sign-extension-ops +// c) reference-types +// Enabling this is safe since Rust does not support `externref`. +// Regarding indirect function calls—which are common in Rust code—there is no issue with the 5-byte LEB128 encoding. +// The proposal has been around for a while and WebAssembly engines, including `wasmi`, have had sufficient time to stabilize it. +// d) multi-value +// This feature allows to specify +// - multiple return values for function, blocks, loops and if sections. +// - what types are expected to be present on the stack at the start of the block or loop +// sections. +// +// Multi-value feature that has been enabled refer only to the WebAssembly language features. +// It does not change the ABI used by LLVM (see https://github.com/llvm/llvm-project/pull/80923/files#diff-ec770381d76c859f5f572db789175fe44410a72608f58ad5dbb14335ba56eb97R672). +// It means that it safe to enable this feature. +// +// New features have been enabled by default in LLVM version 19, which has been used in Rust since 1.82. +// To ensure compatibility with Rust versions 1.82 and later, both features must be enabled. +// More details: https://blog.rust-lang.org/2024/09/24/webassembly-targets-change-in-default-target-features.html +impl WasmFeaturesConfig { + pub const fn mvp() -> Self { + Self { + features: WasmFeatures { + mutable_global: false, + sign_extension: false, + reference_types: false, + multi_value: false, + saturating_float_to_int: false, + bulk_memory: false, + simd: false, + relaxed_simd: false, + threads: false, + tail_call: false, + floats: false, + multi_memory: false, + exceptions: false, + memory64: false, + extended_const: false, + component_model: false, + function_references: false, + memory_control: false, + gc: false, + }, + } + } + + pub const fn set_mutable_global(mut self, enabled: bool) -> Self { + self.features.mutable_global = enabled; + self + } + + pub const fn set_sign_extension(mut self, enabled: bool) -> Self { + self.features.sign_extension = enabled; + self + } + + pub const fn set_reference_types(mut self, enabled: bool) -> Self { + self.features.reference_types = enabled; + self + } + + pub const fn set_multi_value(mut self, enabled: bool) -> Self { + self.features.multi_value = enabled; + self + } + + pub const fn babylon_genesis() -> Self { + Self::mvp() + .set_mutable_global(true) + .set_sign_extension(true) + } + + pub const fn anemone() -> Self { + Self::babylon_genesis() + } + + pub const fn bottlenose() -> Self { + Self::anemone() + } + + pub const fn cuttlefish() -> Self { + Self::bottlenose() + } + + pub const fn dugong() -> Self { + Self::cuttlefish() + .set_reference_types(true) + .set_multi_value(true) + } + + pub const fn latest() -> Self { + Self::dugong() + } + + pub const fn from_scrypto_vm_version(version: ScryptoVmVersion) -> Self { + match version { + ScryptoVmVersion::V1_0 => Self::babylon_genesis(), + ScryptoVmVersion::V1_1 => Self::anemone(), + ScryptoVmVersion::V1_2 => Self::cuttlefish(), + ScryptoVmVersion::V1_3 => Self::dugong(), + } + } + + // More on CFLAGS for WASM: https://clang.llvm.org/docs/ClangCommandLineReference.html#webassembly + pub fn into_target_cflags(&self) -> String { + let mut cflags = String::from("-mcpu=mvp"); + // Assuming that remaining options have sensible defaults + cflags += cflag!(self.features.mutable_global, "mutable-globals"); + cflags += cflag!(self.features.sign_extension, "sign-ext"); + cflags += cflag!(self.features.reference_types, "reference-types"); + cflags += cflag!(self.features.multi_value, "multivalue"); + + cflags + } +} diff --git a/radix-engine/src/vm/wasm/wasm_validator.rs b/radix-engine/src/vm/wasm/wasm_validator.rs index 5ea47462863..76b49570393 100644 --- a/radix-engine/src/vm/wasm/wasm_validator.rs +++ b/radix-engine/src/vm/wasm/wasm_validator.rs @@ -5,7 +5,8 @@ use radix_engine_interface::blueprints::package::BlueprintDefinitionInit; pub struct ScryptoV1WasmValidator { pub max_memory_size_in_pages: u32, - pub max_initial_table_size: u32, + pub max_number_of_tables: u32, + pub max_table_size: u32, pub max_number_of_br_table_targets: u32, pub max_number_of_functions: u32, pub max_number_of_function_params: u32, @@ -23,7 +24,8 @@ impl ScryptoV1WasmValidator { Self { max_memory_size_in_pages: MAX_MEMORY_SIZE_IN_PAGES, - max_initial_table_size: MAX_INITIAL_TABLE_SIZE, + max_number_of_tables: MAX_NUMBER_OF_TABLES, + max_table_size: MAX_TABLE_SIZE, max_number_of_br_table_targets: MAX_NUMBER_OF_BR_TABLE_TARGETS, max_number_of_functions: MAX_NUMBER_OF_FUNCTIONS, max_number_of_function_params: MAX_NUMBER_OF_FUNCTION_PARAMS, @@ -41,12 +43,12 @@ impl ScryptoV1WasmValidator { code: &[u8], blueprints: I, ) -> Result<(Vec, Vec), PrepareError> { - WasmModule::init(code)? + WasmModule::init(code, self.version)? .enforce_no_start_function()? .enforce_import_constraints(self.version)? .enforce_export_names()? .enforce_memory_limit_and_inject_max(self.max_memory_size_in_pages)? - .enforce_table_limit(self.max_initial_table_size)? + .enforce_table_limit(self.max_number_of_tables, self.max_table_size)? .enforce_br_table_limit(self.max_number_of_br_table_targets)? .enforce_function_limit( self.max_number_of_functions, @@ -57,7 +59,7 @@ impl ScryptoV1WasmValidator { .enforce_export_constraints(blueprints)? .inject_instruction_metering(&self.instrumenter_config)? .inject_stack_metering(self.instrumenter_config.max_stack_size())? - .ensure_instantiatable()? + .ensure_instantiatable(self.version)? .ensure_compilable()? .to_bytes() } @@ -66,14 +68,13 @@ impl ScryptoV1WasmValidator { #[cfg(test)] mod tests { use radix_engine_interface::blueprints::package::PackageDefinition; - use wabt::{wasm2wat, wat2wasm}; use super::ScryptoV1WasmValidator; use super::ScryptoVmVersion; #[test] fn test_validate() { - let code = wat2wasm( + let code = wat::parse_str( r#" (module @@ -106,7 +107,7 @@ mod tests { ) .unwrap(); - let instrumented_code = wasm2wat( + let instrumented_code = wasmprinter::print_bytes( ScryptoV1WasmValidator::new(ScryptoVmVersion::latest()) .validate( &code, @@ -125,6 +126,10 @@ mod tests { (type (;0;) (func (param i64) (result i64))) (type (;1;) (func (param i64))) (import "env" "gas" (func (;0;) (type 1))) + (memory (;0;) 1 64) + (global (;0;) (mut i32) i32.const 0) + (export "memory" (memory 0)) + (export "Test_f" (func 2)) (func (;1;) (type 0) (param i64) (result i64) i64.const 14788284 call 0 @@ -140,7 +145,8 @@ mod tests { i32.const 2 i32.const 0 i32.store8 - i64.const 3) + i64.const 3 + ) (func (;2;) (type 0) (param i64) (result i64) local.get 0 global.get 0 @@ -150,18 +156,16 @@ mod tests { global.get 0 i32.const 1024 i32.gt_u - if ;; label = @1 + if ;; label = @1 unreachable end call 1 global.get 0 i32.const 4 i32.sub - global.set 0) - (memory (;0;) 1 64) - (global (;0;) (mut i32) (i32.const 0)) - (export "memory" (memory 0)) - (export "Test_f" (func 2))) + global.set 0 + ) +) "# ) } diff --git a/radix-engine/src/vm/wasm/wasm_validator_config.rs b/radix-engine/src/vm/wasm/wasm_validator_config.rs index f291c4f760d..f9a272082a6 100644 --- a/radix-engine/src/vm/wasm/wasm_validator_config.rs +++ b/radix-engine/src/vm/wasm/wasm_validator_config.rs @@ -214,8 +214,20 @@ impl Rules for WasmValidatorConfigV1 { I64Extend16S => Some(self.weights.i64extendsi32), I64Extend32S => Some(self.weights.i64extendsi32), + // Reference types proposal + // TODO WASM Adjust weights accordingly + TypedSelect { .. } + | RefNull { .. } + | RefIsNull { .. } + | RefFunc { .. } + | TableFill { .. } + | TableGet { .. } + | TableSet { .. } + | TableGrow { .. } + | TableSize { .. } => Some(self.weights.fallback), + // Bulk memory proposal - | MemoryInit { .. } + MemoryInit { .. } | DataDrop { .. } | MemoryCopy { .. } | MemoryFill { .. } @@ -246,17 +258,6 @@ impl Rules for WasmValidatorConfigV1 { // Memory control proposal | MemoryDiscard { .. } - // Reference types proposal - | TypedSelect { .. } - | RefNull { .. } - | RefIsNull { .. } - | RefFunc { .. } - | TableFill { .. } - | TableGet { .. } - | TableSet { .. } - | TableGrow { .. } - | TableSize { .. } - // Relaxed SIMD proposal | I8x16RelaxedSwizzle { .. } | I32x4RelaxedTruncF32x4S { .. } diff --git a/radix-engine/src/vm/wasm/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index 08fb0465078..4600325e20b 100644 --- a/radix-engine/src/vm/wasm/wasmi.rs +++ b/radix-engine/src/vm/wasm/wasmi.rs @@ -11,6 +11,7 @@ use radix_engine_interface::blueprints::package::CodeHash; use sbor::rust::mem::MaybeUninit; #[cfg(not(feature = "fuzzing"))] use sbor::rust::sync::Arc; +use wasm::WasmFeaturesConfig; use wasmi::core::HostError; use wasmi::errors::InstantiationError; use wasmi::*; @@ -958,9 +959,36 @@ pub enum WasmiInstantiationError { } impl WasmiModule { - pub fn new(code: &[u8]) -> Result { + pub fn new(code: &[u8], version: ScryptoVmVersion) -> Result { let mut config = wasmi::Config::default(); + // In previous versions we didn't adjust `wasmi` config according to the WASM features. + // This is not a big issue, since the code at this stage is already validated in terms + // of WASM features (see `WasmModule::init()`) + // But since Dugong we want to keep it aligned + if version >= ScryptoVmVersion::dugong() { + let features = WasmFeaturesConfig::from_scrypto_vm_version(version).features; + + config.wasm_mutable_global(features.mutable_global); + config.wasm_sign_extension(features.sign_extension); + config.wasm_saturating_float_to_int(features.saturating_float_to_int); + config.wasm_multi_value(features.multi_value); + config.wasm_multi_memory(features.multi_memory); + config.wasm_bulk_memory(features.bulk_memory); + config.wasm_reference_types(features.reference_types); + config.wasm_tail_call(features.tail_call); + config.wasm_extended_const(features.extended_const); + config.floats(features.floats); + // Below features are not configurable in `wasmi` + // component_model, + // simd + // relaxed_simd + // threads + // exceptions + // memory64 + // memory_control + } + // In order to speed compilation we deliberately // - use LazyTranslation compilation mode // - compiling without WASM validation (Module::new_checked()) @@ -2098,7 +2126,12 @@ impl WasmEngine for WasmiEngine { type WasmInstance = WasmiInstance; #[allow(unused_variables)] - fn instantiate(&self, code_hash: CodeHash, instrumented_code: &[u8]) -> WasmiInstance { + fn instantiate( + &self, + code_hash: CodeHash, + instrumented_code: &[u8], + version: ScryptoVmVersion, + ) -> WasmiInstance { #[cfg(not(feature = "fuzzing"))] { #[cfg(not(feature = "moka"))] @@ -2113,7 +2146,8 @@ impl WasmEngine for WasmiEngine { } } - let module = WasmiModule::new(instrumented_code).expect("Failed to compile module"); + let module = + WasmiModule::new(instrumented_code, version).expect("Failed to compile module"); let instance = module.instantiate_unchecked(); #[cfg(not(feature = "fuzzing"))] @@ -2143,7 +2177,6 @@ impl WasmEngine for WasmiEngine { #[cfg(test)] mod tests { use super::*; - use wabt::{wat2wasm, wat2wasm_with_features, ErrorKind, Features}; use wasmi::Global; static MODULE_MUTABLE_GLOBALS: &str = r#" @@ -2168,26 +2201,6 @@ mod tests { ) "#; - // This test is not wasmi-specific, but decided to put it here along with next one - #[test] - fn test_wasm_non_mvp_mutable_globals_build_with_feature_disabled() { - let mut features = Features::new(); - features.disable_mutable_globals(); - - assert!( - match wat2wasm_with_features(MODULE_MUTABLE_GLOBALS, features) { - Err(err) => { - match err.kind() { - ErrorKind::Validate(msg) => { - msg.contains("mutable globals cannot be imported") - } - _ => false, - } - } - Ok(_) => false, - } - ) - } pub fn run_module_with_mutable_global( module: &Module, mut store: StoreContextMut, @@ -2218,10 +2231,10 @@ mod tests { #[test] fn test_wasm_non_mvp_mutable_globals_execute_code() { - // wat2wasm has "mutable-globals" enabled by default - let code = wat2wasm(MODULE_MUTABLE_GLOBALS).unwrap(); + // wat::parse_str has all features enabled by default + let code = wat::parse_str(MODULE_MUTABLE_GLOBALS).unwrap(); - let wasmi_module = WasmiModule::new(&code).unwrap(); + let wasmi_module = WasmiModule::new(&code, ScryptoVmVersion::latest()).unwrap(); let module = wasmi_module.module; let mut store = Store::new(&module.engine(), WasmiInstanceEnv::new()); diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index d90294bc550..31d3bae4d94 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -99,7 +99,7 @@ impl<'y, Y: SystemApi> WasmRuntime for ScryptoRuntime<'y, Y> { // Practically speaking, there is little gain of keeping multiple buffers open before // [multi-value](https://github.com/WebAssembly/multi-value/blob/master/proposals/multi-value/Overview.md) is supported and used. // We reduce it to `4` so that the amount of memory that a transaction can consume is reduced, which is beneficial for parallel execution. - ScryptoVmVersion::V1_2 => 4, + ScryptoVmVersion::V1_2 | ScryptoVmVersion::V1_3 => 4, }; if self.buffers.len() >= max_number_of_buffers { return Err(InvokeError::SelfError(WasmRuntimeError::TooManyBuffers)); diff --git a/radix-transaction-scenarios/generated-protocol-updates/dugong/protocol_update_summary.txt b/radix-transaction-scenarios/generated-protocol-updates/dugong/protocol_update_summary.txt index 9bd64579ebd..990685fafe8 100644 --- a/radix-transaction-scenarios/generated-protocol-updates/dugong/protocol_update_summary.txt +++ b/radix-transaction-scenarios/generated-protocol-updates/dugong/protocol_update_summary.txt @@ -2,5 +2,5 @@ Name: Dugong ========= SUMMARY HASHES ========= These Dugong hashes are permitted to change only until the protocol update is deployed to a permanent network, else it can cause divergence. -State changes: 95b66449fe6829bb (allowed to change if not deployed to any network) -Events : 07c81f1e6d320830 (allowed to change if not deployed to any network) +State changes: e2829337379687de (allowed to change if not deployed to any network) +Events : 2a6146032d8e884d (allowed to change if not deployed to any network) diff --git a/radix-transaction-scenarios/generated-protocol-updates/dugong/receipts/00-00-01--dugong-vm-boot-wasm-new-features.txt b/radix-transaction-scenarios/generated-protocol-updates/dugong/receipts/00-00-01--dugong-vm-boot-wasm-new-features.txt new file mode 100644 index 00000000000..8f0c9c43c47 --- /dev/null +++ b/radix-transaction-scenarios/generated-protocol-updates/dugong/receipts/00-00-01--dugong-vm-boot-wasm-new-features.txt @@ -0,0 +1,26 @@ +TRANSACTION STATUS: COMMITTED SUCCESS + +TRANSACTION COST: 0 XRD +├─ Network execution: 0 XRD, 0 execution cost units +├─ Network finalization: 0 XRD, 0 finalization cost units +├─ Tip: 0 XRD +├─ Network Storage: 0 XRD +└─ Royalties: 0 XRD + +LOGS: 0 + +EVENTS: 0 + +STATE UPDATES: 1 entity +└─ transactiontracker_sim1stxxxxxxxxxxtxtrakxxxxxxxxx006844685494xxxxxxxxx4d5zd2 across 1 partitions + └─ Partition(32): 1 change + └─ Set: VmBoot + Value: VmBoot::V1 { + scrypto_version: 3u64, + } + +OUTPUTS: 0 + +BALANCE CHANGES: 0 + +NEW ENTITIES: 0 \ No newline at end of file diff --git a/radix-transaction-scenarios/generated-protocol-updates/dugong/receipts/00-00-01--status-summary.txt b/radix-transaction-scenarios/generated-protocol-updates/dugong/receipts/00-00-02--status-summary.txt similarity index 100% rename from radix-transaction-scenarios/generated-protocol-updates/dugong/receipts/00-00-01--status-summary.txt rename to radix-transaction-scenarios/generated-protocol-updates/dugong/receipts/00-00-02--status-summary.txt diff --git a/scrypto-compiler/src/lib.rs b/scrypto-compiler/src/lib.rs index 054a6ad8c3f..f16514ce4bf 100644 --- a/scrypto-compiler/src/lib.rs +++ b/scrypto-compiler/src/lib.rs @@ -2,6 +2,7 @@ use cargo_toml::Manifest; use fslock::{LockFile, ToOsStr}; use radix_common::prelude::*; use radix_engine::utils::{extract_definition, ExtractSchemaError}; +use radix_engine::vm::{wasm::WasmFeaturesConfig, ScryptoVmVersion}; use radix_engine_interface::{blueprints::package::PackageDefinition, types::Level}; use radix_rust::prelude::{IndexMap, IndexSet}; use std::cmp::Ordering; @@ -16,11 +17,6 @@ const BUILD_TARGET: &str = "wasm32-unknown-unknown"; const SCRYPTO_NO_SCHEMA: &str = "scrypto/no-schema"; const SCRYPTO_COVERAGE: &str = "scrypto/coverage"; -// Radix Engine supports WASM MVP + proposals: mmutable-globals and sign-extension-ops -// (see radix-engine/src/vm/wasm.prepare.rs) -// More on CFLAGS for WASM: https://clang.llvm.org/docs/ClangCommandLineReference.html#webassembly -const TARGET_CLAGS_FOR_WASM: &str = "-mcpu=mvp -mmutable-globals -msign-ext"; - #[derive(Debug)] pub enum ScryptoCompilerError { /// Returns IO Error which occurred during compilation and optional context information. @@ -30,27 +26,27 @@ pub enum ScryptoCompilerError { IOErrorWithPath(io::Error, PathBuf, Option), /// Returns process exit status in case of 'cargo build' fail. CargoBuildFailure(ExitStatus), - /// Returns `cargo metadata` command stderr output, path to Cargo.toml for which cargo metadata + /// Returns `cargo metadata` command stderr output, path to `Cargo.toml` for which cargo metadata /// command failed and process exit status. CargoMetadataFailure(String, PathBuf, ExitStatus), - /// Returns path to Cargo.toml for which results of cargo metadata command is not not valid json + /// Returns path to `Cargo.toml` for which results of cargo metadata command is not a valid json /// or target directory field is missing. CargoTargetDirectoryResolutionError(String), /// Compiler is unable to generate target binary file name. CargoTargetBinaryResolutionError, - /// Returns path to Cargo.toml which was failed to load. + /// Returns path to `Cargo.toml` which was failed to load. CargoManifestLoadFailure(String), - /// Returns path to Cargo.toml which cannot be found. + /// Returns path to `Cargo.toml`` which cannot be found. CargoManifestFileNotFound(String), /// Provided package ID is not a member of the workspace. CargoWrongPackageId(String), /// Returns WASM Optimization error. WasmOptimizationError(wasm_opt::OptimizationError), - /// Returns error occured during schema extraction. + /// Returns error occurred during schema extraction. SchemaExtractionError(ExtractSchemaError), - /// Returns error occured during schema encoding. + /// Returns error occurred during schema encoding. SchemaEncodeError(EncodeError), - /// Returns error occured during schema decoding. + /// Returns error occurred during schema decoding. SchemaDecodeError(DecodeError), /// Returned when trying to compile workspace without any scrypto packages. NothingToCompile, @@ -66,7 +62,7 @@ pub struct ScryptoCompilerInputParams { pub profile: Profile, /// List of environment variables to set or unset during compilation. /// By default it includes compilation flags for C libraries to configure WASM with the same - /// features as Radix Engine. + /// features as Radix Engine, eg. /// TARGET_CFLAGS="-mcpu=mvp -mmutable-globals -msign-ext" pub environment_variables: IndexMap, /// List of features, used for 'cargo build --features'. Optional field. @@ -84,13 +80,15 @@ pub struct ScryptoCompilerInputParams { /// Defaults to false. pub ignore_locked_env_var: bool, /// List of custom options, passed as 'cargo build' arguments without any modifications. Optional field. - /// Add each option as separate entry (for instance: '-j 1' must be added as two entires: '-j' and '1' one by one). + /// Add each option as separate entry (for instance: '-j 1' must be added as two entries: '-j' and '1' one by one). pub custom_options: IndexSet, /// If specified optimizes the built wasm using Binaryen's wasm-opt tool. /// Default configuration is equivalent to running the following commands in the CLI: /// wasm-opt -0z --strip-debug --strip-dwarf --strip-producers --dce $some_path $some_path pub wasm_optimization: Option, - /// If set to true then compiler informs about the compilation progress + /// Scrypto VM version. If not specified then the latest version will be used. + pub scrypto_vm_version: ScryptoVmVersion, + /// If set to true then compiler informs about the compilation progress. pub verbose: bool, } impl Default for ScryptoCompilerInputParams { @@ -111,7 +109,7 @@ impl Default for ScryptoCompilerInputParams { environment_variables: indexmap!( "TARGET_CFLAGS".to_string() => EnvironmentVariableAction::Set( - TARGET_CLAGS_FOR_WASM.to_string() + WasmFeaturesConfig::default().into_target_cflags() ) ), features: indexset!(), @@ -122,6 +120,7 @@ impl Default for ScryptoCompilerInputParams { ignore_locked_env_var: false, locked: false, wasm_optimization, + scrypto_vm_version: ScryptoVmVersion::latest(), verbose: false, }; // Apply default log level features @@ -273,10 +272,10 @@ where /// Programmatic implementation of Scrypto compiler which is a wrapper around rust cargo tool. /// To create an instance of `ScryptoCompiler` use `builder()` constructor which implements builder pattern, /// provide any required parameter @see `ScryptoCompilerInputParams` and finally call `compile()` function. -/// `ScryptoCompiler` supports worspace compilation by providing workspace manifest as `manifest_path` parameter of -/// running compiler from directory containg workspace Cargo.toml file. Only packages with defined metadata group: +/// `ScryptoCompiler` supports workspace compilation by providing workspace manifest as `manifest_path` parameter of +/// running compiler from directory containing workspace Cargo.toml file. Only packages with defined metadata group: /// [package.metadata.scrypto] will be used during workspace compilation (so workspace manifest can contain also non -/// Scrypto packages). Alternativelly packages for workspace compilation can be provided in `package` input parameter, +/// Scrypto packages). Alternatively packages for workspace compilation can be provided in `package` input parameter, /// metadata is not validated in that case. /// Compilation results consists of list of `BuildArtifacts` which contains generated WASM file path and its content /// and path to RPD file with package definition and `PackageDefinition` struct. @@ -601,7 +600,7 @@ impl ScryptoCompiler { )?)) } - // Basing on manifest path returns target directory, target binary WASM path and target binary PRD path + // Basing on manifest path returns target directory, target binary WASM path and target binary '*.rpd' path fn prepare_paths_for_manifest( input_params: &ScryptoCompilerInputParams, manifest_path: &Path, @@ -946,10 +945,10 @@ impl ScryptoCompiler { // used for unit tests fn prepare_command_phase_2(&mut self, command: &mut Command) { - self.prepare_command(command, false); // build without schema and with userchoosen profile + self.prepare_command(command, false); // build without schema and with user choosen profile } - // Compile without schema and with optional wasm optimisations - this is the final .wasm file + // Compile without schema and with optional wasm optimisations - this is the final '*.wasm' file fn compile_phase_2( &mut self, command: &mut Command, @@ -979,8 +978,8 @@ impl ScryptoCompiler { })?; let code_hash = hash(&code); - let package_definition = - extract_definition(&code).map_err(ScryptoCompilerError::SchemaExtractionError)?; + let package_definition = extract_definition(&code, self.input_params.scrypto_vm_version) + .map_err(ScryptoCompilerError::SchemaExtractionError)?; std::fs::write( &manifest_def.target_output_binary_rpd_path, @@ -1037,7 +1036,7 @@ impl ScryptoCompiler { .ok_or(ScryptoCompilerError::CargoBuildFailure(status)) } - // Return paths to the Scrypto cache for given manifest deifinition and code hash + // Return paths to the Scrypto cache for given manifest definition and code hash fn get_scrypto_cache_paths( &self, manifest_def: &CompilerManifestDefinition, @@ -1048,10 +1047,11 @@ impl ScryptoCompiler { // They are applied in 2nd compilation, which means one can receive different WASMs // for the same WASM files from 1st compilation. let options = format!( - "{:?}/{:?}/{:?}", + "{:?}-{:?}-{:?}-{:?}", code_hash, self.input_params.profile.as_target_directory_name(), - self.input_params.wasm_optimization + self.input_params.wasm_optimization, + self.input_params.scrypto_vm_version ); let hash_dir = hash(options); @@ -1147,7 +1147,7 @@ impl ScryptoCompiler { let (rpd_cache_path, wasm_cache_path) = self.get_scrypto_cache_paths(manifest_def, code_hash, false)?; - // Get WASM and RPD files only if they both exist + // Get '*.wasm' and '*.rpd' files only if they both exist if std::fs::metadata(&rpd_cache_path).is_ok() && std::fs::metadata(&wasm_cache_path).is_ok() { let rpd = std::fs::read(&rpd_cache_path).map_err(|e| { @@ -1382,6 +1382,11 @@ impl ScryptoCompilerBuilder { self } + pub fn scrypto_vm_version(&mut self, scrypto_vm_version: ScryptoVmVersion) -> &mut Self { + self.input_params.scrypto_vm_version = scrypto_vm_version; + self + } + pub fn custom_options(&mut self, options: &[&str]) -> &mut Self { self.input_params .custom_options @@ -1504,9 +1509,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); } #[test] @@ -1535,9 +1540,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); } #[test] @@ -1565,9 +1570,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", target_path.display(), manifest_path.display())); } #[test] @@ -1601,9 +1606,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/log-debug --features scrypto/log-trace --features feature_1 --release --no-default-features", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/log-debug --features scrypto/log-trace --features feature_1 --release --no-default-features", default_target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/log-debug --features scrypto/log-trace --features feature_1 --features scrypto/no-schema --profile release --no-default-features", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/log-debug --features scrypto/log-trace --features feature_1 --features scrypto/no-schema --profile release --no-default-features", default_target_path.display(), manifest_path.display())); } #[test] @@ -1633,9 +1638,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --release", default_target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); } #[test] fn test_command_output_workspace() { @@ -1663,9 +1668,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --package test_blueprint --package test_blueprint_2 --package test_blueprint_3 --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --package test_blueprint --package test_blueprint_2 --package test_blueprint_3 --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --package test_blueprint --package test_blueprint_2 --package test_blueprint_3 --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --package test_blueprint --package test_blueprint_2 --package test_blueprint_3 --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); } #[test] @@ -1698,9 +1703,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --package test_blueprint --package test_blueprint_3 --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --package test_blueprint --package test_blueprint_3 --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --package test_blueprint --package test_blueprint_3 --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --package test_blueprint --package test_blueprint_3 --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); } #[test] @@ -1730,9 +1735,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile dev", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile dev", default_target_path.display(), manifest_path.display())); } #[test] @@ -1763,9 +1768,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", default_target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/no-schema --profile release", default_target_path.display(), manifest_path.display())); } #[test] @@ -1797,9 +1802,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/coverage --features scrypto/no-schema --profile release", target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/coverage --features scrypto/no-schema --profile release", target_path.display(), manifest_path.display())); } #[test] @@ -1836,9 +1841,9 @@ mod tests { // Assert assert_eq!(cmd_to_string(&cmd_phase_1), - format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", target_path.display(), manifest_path.display())); + format!("TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --release", target_path.display(), manifest_path.display())); assert_eq!(cmd_to_string(&cmd_phase_2), - format!("CARGO_ENCODED_RUSTFLAGS='-Clto=off\x1f-Cinstrument-coverage\x1f-Zno-profiler-runtime\x1f--emit=llvm-ir' TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/coverage --features scrypto/no-schema --profile release", target_path.display(), manifest_path.display())); + format!("CARGO_ENCODED_RUSTFLAGS='-Clto=off\x1f-Cinstrument-coverage\x1f-Zno-profiler-runtime\x1f--emit=llvm-ir' TARGET_CFLAGS='-mcpu=mvp -mmutable-globals -msign-ext -mreference-types -mmultivalue' cargo build --target wasm32-unknown-unknown --target-dir {} --manifest-path {} --features scrypto/log-error --features scrypto/log-warn --features scrypto/log-info --features scrypto/coverage --features scrypto/no-schema --profile release", target_path.display(), manifest_path.display())); } #[test] diff --git a/scrypto-compiler/tests/compilation.rs b/scrypto-compiler/tests/compilation.rs index 14051455602..6b27c126524 100644 --- a/scrypto-compiler/tests/compilation.rs +++ b/scrypto-compiler/tests/compilation.rs @@ -2,10 +2,9 @@ mod tests { use radix_common::prelude::*; use radix_engine::utils::ExtractSchemaError; - use radix_engine::vm::wasm::PrepareError; + use radix_engine::vm::{wasm::PrepareError, ScryptoVmVersion}; use radix_engine_interface::types::Level; use scrypto_compiler::*; - use std::process::Command; use std::{env, path::PathBuf, process::Stdio}; use tempdir::TempDir; @@ -455,73 +454,42 @@ mod tests { } #[test] - fn test_compilation_with_wasm_reference_types_disabled() { + fn test_compilation_with_wasm_reference_types_enabled_old_protocol() { // Arrange let mut blueprint_manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); blueprint_manifest_path.extend(["tests", "assets", "call_indirect", "Cargo.toml"]); // Act - // ScryptoCompiler compiles WASM by default with reference-types disabled. let status = ScryptoCompiler::builder() + .scrypto_vm_version(ScryptoVmVersion::cuttlefish()) .manifest_path(blueprint_manifest_path) .compile(); // Assert - assert!(status.is_ok(), "{:?}", status); + // Error is expected here because Radix Engine expects WASM with reference-types disabled. + // See `call_indirect.c` for more details. + assert_matches!( + status.unwrap_err(), + ScryptoCompilerError::SchemaExtractionError( + ExtractSchemaError::InvalidWasm(PrepareError::ValidationError(msg))) if msg.contains("reference-types not enabled: zero byte expected") + ) } #[test] - fn test_compilation_with_wasm_reference_types_enabled() { + fn test_compilation_with_wasm_reference_types_enabled_dugong() { // Arrange let mut blueprint_manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); blueprint_manifest_path.extend(["tests", "assets", "call_indirect", "Cargo.toml"]); - // Check clang/LLVM version - let clang_version = Command::new("clang").arg("--version").output().unwrap(); - - // clang --version exemplary output - // Ubuntu clang version 17.0.6 (++20231209124227+6009708b4367-1~exp1~20231209124336.77) - // Target: x86_64-pc-linux-gnu - // Thread model: posix - // InstalledDir: /usr/lib/llvm-17/bin - let clang_version = String::from_utf8_lossy(&clang_version.stdout); - let mut idx = clang_version - .find("clang version") - .expect("Failed to get clang version"); - idx += "clang version ".len(); - let version = &clang_version[idx..] - .split_whitespace() - .next() - .expect("Failed to get version"); - let major_version = version - .split(".") - .next() - .expect("Failed to get major version"); - let major_version: u8 = major_version.parse().unwrap(); - - let action = if major_version >= 19 { - // Since LLVM 19 reference-types are enabled by default, no dedicated CFLAGS needed. - // Unset TARGET_CFLAGS to build with default WASM features. - EnvironmentVariableAction::Unset - } else { - // In previous versions reference-types must be enabled explicitly. - EnvironmentVariableAction::Set("-mreference-types".to_string()) - }; // Act let status = ScryptoCompiler::builder() - .env("TARGET_CFLAGS", action) + .scrypto_vm_version(ScryptoVmVersion::dugong()) .manifest_path(blueprint_manifest_path) .compile(); // Assert - // Error is expected here because Radix Engine expects WASM with reference-types disabled. - // See `call_indirect.c` for more details. - assert_matches!( - status.unwrap_err(), - ScryptoCompilerError::SchemaExtractionError( - ExtractSchemaError::InvalidWasm(PrepareError::ValidationError(msg))) if msg.contains("reference-types not enabled: zero byte expected") - ) + assert!(status.is_ok(), "{:?}", status); } } diff --git a/scrypto-test/Cargo.toml b/scrypto-test/Cargo.toml index 0fbb5915d21..072ee5f6e71 100644 --- a/scrypto-test/Cargo.toml +++ b/scrypto-test/Cargo.toml @@ -23,7 +23,7 @@ scrypto-compiler = { workspace = true } # Included to re-export some useful things into the scrypto-test prelude scrypto = { workspace = true } -wabt = { workspace = true } +wat = { workspace = true } ouroboros = { workspace = true } paste = { workspace = true } serde_json = { workspace = true } diff --git a/scrypto-test/src/ledger_simulator/ledger_simulator.rs b/scrypto-test/src/ledger_simulator/ledger_simulator.rs index 555d47fa979..7ac1161de53 100644 --- a/scrypto-test/src/ledger_simulator/ledger_simulator.rs +++ b/scrypto-test/src/ledger_simulator/ledger_simulator.rs @@ -2422,17 +2422,15 @@ pub fn is_costing_error(e: &RuntimeError) -> bool { pub fn is_wasm_error(e: &RuntimeError) -> bool { matches!(e, RuntimeError::VmError(VmError::Wasm(..))) } -pub fn wat2wasm(wat: &str) -> Vec { - let mut features = wabt::Features::new(); - features.enable_sign_extension(); - wabt::wat2wasm_with_features( +pub fn wat2wasm(wat: &str) -> Vec { + // It parses with all WASM features enabled + wat::parse_str( wat.replace("${memcpy}", include_str!("snippets/memcpy.wat")) .replace("${memmove}", include_str!("snippets/memmove.wat")) .replace("${memset}", include_str!("snippets/memset.wat")), - features, ) - .expect("Failed to compiled WAT into WASM") + .expect("Failed to compile WAT into WASM") } pub fn single_function_package_definition(