diff --git a/radix-engine/src/vm/scrypto_vm.rs b/radix-engine/src/vm/scrypto_vm.rs index 5563d74ef0..3fe5e67ec6 100644 --- a/radix-engine/src/vm/scrypto_vm.rs +++ b/radix-engine/src/vm/scrypto_vm.rs @@ -10,14 +10,12 @@ use radix_engine_profiling_derive::trace_resources; pub struct ScryptoVm { 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(), } } } diff --git a/radix-engine/src/vm/wasm/mod.rs b/radix-engine/src/vm/wasm/mod.rs index 2942b1e722..2d2ac47874 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 b12cbe6484..661c846c8b 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; @@ -10,7 +10,7 @@ use wasm_instrument::{ inject_stack_limiter, utils::module_info::ModuleInfo, }; -use wasmparser::{ExternalKind, FuncType, Operator, Type, TypeRef, ValType, WasmFeatures}; +use wasmparser::{ExternalKind, FuncType, Operator, Type, TypeRef, ValType}; use super::WasmiModule; use crate::vm::ScryptoVmVersion; @@ -25,28 +25,7 @@ impl WasmModule { // 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::default().features; module .validate(features) @@ -1082,6 +1061,15 @@ impl WasmModule { InvalidTable::InitialTableSizeLimitExceeded, )); } + // As of now (Jan 17, 2025) tables are not growable, because TableGrow operator is disabled + // in `wasmparser`, but let's add below check in case it is enabled in the future. + if let Some(maximum) = table.ty.maximum { + if maximum > max_initial_table_size { + return Err(PrepareError::InvalidTable( + InvalidTable::InitialTableSizeLimitExceeded, + )); + } + } } } 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 0000000000..5d7bb4a120 --- /dev/null +++ b/radix-engine/src/vm/wasm/wasm_features_config.rs @@ -0,0 +1,76 @@ +use radix_rust::prelude::String; +use wasmparser::WasmFeatures; + +#[derive(Debug, Clone)] +pub struct WasmFeaturesConfig { + pub features: WasmFeatures, +} + +impl Default for WasmFeaturesConfig { + fn default() -> Self { + Self { + // The Radix Engine supports the MVP and additional proposals, specifically: + // - mutable-globals and sign-extension-ops + // - reference-types and multi-value returns + // These features have been enabled by default in LLVM version 19, which Rust has used starting from version 1.82. + // To ensure compatibility with Rust versions 1.82 and later, both features must be enabled. + // + // - 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. + // - Multi-value returns + // This is also safe to enable because the Radix Engine has never used the Nightly `extern "wasm"` feature. + // You can find more details here: https://blog.rust-lang.org/2024/09/24/webassembly-targets-change-in-default-target-features.html + features: WasmFeatures { + mutable_global: true, + sign_extension: true, + reference_types: true, + multi_value: true, + 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, + }, + } + } +} + +macro_rules! cflag { + ($flag:expr, $name:expr) => { + if $flag { + concat!(" -m", $name) + } else { + concat!(" -mno-", $name) + } + }; +} + +impl WasmFeaturesConfig { + pub fn new() -> Self { + Self::default() + } + + // 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/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index 08fb046507..5bea131fa8 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::*; @@ -961,6 +962,27 @@ impl WasmiModule { pub fn new(code: &[u8]) -> Result { let mut config = wasmi::Config::default(); + let features = WasmFeaturesConfig::default().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()) diff --git a/scrypto-compiler/src/lib.rs b/scrypto-compiler/src/lib.rs index 054a6ad8c3..4805dc8bab 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; 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. @@ -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. @@ -111,7 +107,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!(), @@ -1504,9 +1500,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 +1531,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 +1561,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 +1597,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 +1629,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 +1659,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 +1694,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 +1726,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 +1759,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 +1793,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 +1832,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 1405145560..9be0761c50 100644 --- a/scrypto-compiler/tests/compilation.rs +++ b/scrypto-compiler/tests/compilation.rs @@ -1,11 +1,9 @@ #[cfg(test)] mod tests { use radix_common::prelude::*; - use radix_engine::utils::ExtractSchemaError; - use radix_engine::vm::wasm::PrepareError; + use radix_engine::vm::wasm::WasmFeaturesConfig; use radix_engine_interface::types::Level; use scrypto_compiler::*; - use std::process::Command; use std::{env, path::PathBuf, process::Stdio}; use tempdir::TempDir; @@ -455,14 +453,14 @@ mod tests { } #[test] - fn test_compilation_with_wasm_reference_types_disabled() { + fn test_compilation_of_code_using_reference_types() { // 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. + // ScryptoCompiler compiles WASM by default with reference-types enabled. let status = ScryptoCompiler::builder() .manifest_path(blueprint_manifest_path) .compile(); @@ -470,58 +468,4 @@ mod tests { // Assert assert!(status.is_ok(), "{:?}", status); } - - #[test] - fn test_compilation_with_wasm_reference_types_enabled() { - // 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) - .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") - ) - } }