diff --git a/Cargo.lock b/Cargo.lock index a03a226b4aa8..2506a2c5ac13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -841,25 +841,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "cranelift-wasm" -version = "0.113.0" -dependencies = [ - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", - "hashbrown 0.14.3", - "itertools 0.12.1", - "log", - "serde", - "serde_derive", - "smallvec", - "target-lexicon", - "wasmparser", - "wasmtime-types", - "wat", -] - [[package]] name = "crc32fast" version = "1.3.2" @@ -3652,8 +3633,8 @@ dependencies = [ "cranelift-entity", "cranelift-frontend", "cranelift-native", - "cranelift-wasm", "gimli", + "itertools 0.12.1", "log", "object", "smallvec", @@ -3750,7 +3731,6 @@ dependencies = [ "cranelift-interpreter", "cranelift-native", "cranelift-reader", - "cranelift-wasm", "env_logger 0.11.5", "libfuzzer-sys", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index 74ee00055611..2e9cf3538002 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -223,7 +223,6 @@ test-programs-artifacts = { path = 'crates/test-programs/artifacts' } pulley-interpreter = { path = 'pulley', version = "=0.2.0" } pulley-interpreter-fuzz = { path = 'pulley/fuzz' } -cranelift-wasm = { path = "cranelift/wasm", version = "0.113.0" } cranelift-codegen = { path = "cranelift/codegen", version = "0.113.0", default-features = false, features = ["std", "unwind"] } cranelift-frontend = { path = "cranelift/frontend", version = "0.113.0" } cranelift-entity = { path = "cranelift/entity", version = "0.113.0" } diff --git a/cranelift/codegen/src/ir/entities.rs b/cranelift/codegen/src/ir/entities.rs index e4ed6d55a030..005007471b35 100644 --- a/cranelift/codegen/src/ir/entities.rs +++ b/cranelift/codegen/src/ir/entities.rs @@ -181,9 +181,6 @@ impl DynamicType { /// /// You can create a `GlobalValue` in the following ways: /// -/// - When compiling to WASM, you can use it to load values from a -/// [`VmContext`](super::GlobalValueData::VMContext) using -/// [`FuncEnvironment::make_global`](https://docs.rs/cranelift-wasm/*/cranelift_wasm/trait.FuncEnvironment.html#tymethod.make_global). /// - When compiling to native code, you can use it for objects in static memory with /// [`Module::declare_data_in_func`](https://docs.rs/cranelift-module/*/cranelift_module/trait.Module.html#method.declare_data_in_func). /// - For any compilation target, it can be registered with @@ -329,9 +326,6 @@ impl JumpTable { /// - [`Module::declare_func_in_func`](https://docs.rs/cranelift-module/*/cranelift_module/trait.Module.html#method.declare_func_in_func) /// for functions declared elsewhere in the same native /// [`Module`](https://docs.rs/cranelift-module/*/cranelift_module/trait.Module.html) -/// - [`FuncEnvironment::make_direct_func`](https://docs.rs/cranelift-wasm/*/cranelift_wasm/trait.FuncEnvironment.html#tymethod.make_direct_func) -/// for functions declared in the same WebAssembly -/// [`FuncEnvironment`](https://docs.rs/cranelift-wasm/*/cranelift_wasm/trait.FuncEnvironment.html#tymethod.make_direct_func) /// /// While the order is stable, it is arbitrary. #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] diff --git a/cranelift/codegen/src/ir/pcc.rs b/cranelift/codegen/src/ir/pcc.rs index 33a515cac670..5ebfbbb503d1 100644 --- a/cranelift/codegen/src/ir/pcc.rs +++ b/cranelift/codegen/src/ir/pcc.rs @@ -23,7 +23,7 @@ //! specifically the memory-access sequences. In practice, each such //! sequence is likely to be a carefully-controlled sequence of IR //! operations from, e.g., a sandboxing compiler (such as -//! `cranelift-wasm`) so adding annotations here to communicate +//! Wasmtime) so adding annotations here to communicate //! intent (ranges, bounds-checks, and the like) is no problem. //! //! Facts are attached to SSA values in CLIF, and are maintained diff --git a/cranelift/docs/index.md b/cranelift/docs/index.md index 735403b92afe..b9f18dd3aa56 100644 --- a/cranelift/docs/index.md +++ b/cranelift/docs/index.md @@ -26,9 +26,6 @@ This crate contains the meta-language utilities and descriptions used by the code generator. - - [cranelift-wasm](https://docs.rs/cranelift-wasm) - This crate translates WebAssembly code into Cranelift IR. - - [cranelift-frontend](https://docs.rs/cranelift-frontend) This crate provides utilities for translating code into Cranelift IR. diff --git a/cranelift/wasm/Cargo.toml b/cranelift/wasm/Cargo.toml deleted file mode 100644 index c51f2e3a459f..000000000000 --- a/cranelift/wasm/Cargo.toml +++ /dev/null @@ -1,39 +0,0 @@ -[package] -name = "cranelift-wasm" -version = "0.113.0" -authors = ["The Cranelift Project Developers"] -description = "Translator from WebAssembly to Cranelift IR" -documentation = "https://docs.rs/cranelift-wasm" -repository = "https://github.com/bytecodealliance/wasmtime" -license = "Apache-2.0 WITH LLVM-exception" -categories = ["no-std", "wasm"] -readme = "README.md" -keywords = ["webassembly", "wasm"] -edition.workspace = true -rust-version.workspace = true - -[lints] -workspace = true - -[dependencies] -wasmparser = { workspace = true, features = ['validate'] } -cranelift-codegen = { workspace = true } -cranelift-entity = { workspace = true } -cranelift-frontend = { workspace = true } -wasmtime-types = { workspace = true } -hashbrown = { workspace = true, optional = true } -itertools = "0.12.0" -log = { workspace = true } -serde = { workspace = true, optional = true } -serde_derive = { workspace = true, optional = true } -smallvec = { workspace = true } - -[dev-dependencies] -wat = { workspace = true } -target-lexicon = { workspace = true } - -[features] -default = ["std"] -std = ["cranelift-codegen/std", "cranelift-frontend/std"] -core = ["hashbrown", "cranelift-codegen/core", "cranelift-frontend/core"] -enable-serde = ["serde", "serde_derive", "cranelift-codegen/enable-serde"] diff --git a/cranelift/wasm/LICENSE b/cranelift/wasm/LICENSE deleted file mode 100644 index f9d81955f4bc..000000000000 --- a/cranelift/wasm/LICENSE +++ /dev/null @@ -1,220 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ---- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. - diff --git a/cranelift/wasm/README.md b/cranelift/wasm/README.md deleted file mode 100644 index 556b4b9eded4..000000000000 --- a/cranelift/wasm/README.md +++ /dev/null @@ -1,8 +0,0 @@ -This crate performs the translation from a wasm module in binary format to the -in-memory form of the [Cranelift IR]. - -If you're looking for a complete WebAssembly implementation that uses this -library, see [Wasmtime]. - -[Wasmtime]: https://github.com/bytecodealliance/wasmtime -[Cranelift IR]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/ir.md diff --git a/cranelift/wasm/src/environ/mod.rs b/cranelift/wasm/src/environ/mod.rs deleted file mode 100644 index b5e5aa04bb84..000000000000 --- a/cranelift/wasm/src/environ/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! Support for configurable wasm translation. - -#[macro_use] -mod spec; - -pub use crate::environ::spec::{ - FuncEnvironment, GlobalVariable, ModuleEnvironment, StructFieldsVec, TargetEnvironment, -}; diff --git a/cranelift/wasm/src/lib.rs b/cranelift/wasm/src/lib.rs deleted file mode 100644 index 92965e79a4a1..000000000000 --- a/cranelift/wasm/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! Performs translation from a wasm module in binary format to the in-memory form -//! of Cranelift IR. More particularly, it translates the code of all the functions bodies and -//! interacts with an environment implementing the -//! [`ModuleEnvironment`](trait.ModuleEnvironment.html) -//! trait to deal with tables, globals and linear memory. -//! -//! The main function of this module is [`translate_module`](fn.translate_module.html). - -#![deny(missing_docs)] -#![no_std] - -#[cfg(not(feature = "std"))] -#[macro_use] -extern crate alloc as std; -#[cfg(feature = "std")] -#[macro_use] -extern crate std; - -#[cfg(not(feature = "std"))] -use hashbrown::{ - hash_map, - hash_map::Entry::{Occupied, Vacant}, - HashMap, -}; -#[cfg(feature = "std")] -use std::collections::{ - hash_map, - hash_map::Entry::{Occupied, Vacant}, - HashMap, -}; - -mod code_translator; -mod environ; -mod func_translator; -mod heap; -mod module_translator; -mod sections_translator; -mod state; -mod table; -mod translation_utils; - -pub use crate::environ::{ - FuncEnvironment, GlobalVariable, ModuleEnvironment, StructFieldsVec, TargetEnvironment, -}; -pub use crate::func_translator::FuncTranslator; -pub use crate::heap::{Heap, HeapData, HeapStyle}; -pub use crate::module_translator::translate_module; -pub use crate::state::FuncTranslationState; -pub use crate::table::{TableData, TableSize}; -pub use crate::translation_utils::*; -pub use cranelift_frontend::FunctionBuilder; -pub use wasmtime_types::*; - -// Convenience reexport of the wasmparser crate that we're linking against, -// since a number of types in `wasmparser` show up in the public API of -// `cranelift-wasm`. -pub use wasmparser; - -/// Version number of this crate. -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/cranelift/wasm/src/module_translator.rs b/cranelift/wasm/src/module_translator.rs deleted file mode 100644 index e78c90d49cd0..000000000000 --- a/cranelift/wasm/src/module_translator.rs +++ /dev/null @@ -1,120 +0,0 @@ -//! Translation skeleton that traverses the whole WebAssembly module and call helper functions -//! to deal with each part of it. -use crate::environ::ModuleEnvironment; -use crate::sections_translator::{ - parse_data_section, parse_element_section, parse_export_section, parse_function_section, - parse_global_section, parse_import_section, parse_memory_section, parse_start_section, - parse_table_section, parse_tag_section, parse_type_section, -}; -use crate::WasmResult; -use cranelift_codegen::timing; -use std::prelude::v1::*; -use wasmparser::{Parser, Payload, Validator}; - -/// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cranelift IR -/// [`Function`](cranelift_codegen::ir::Function). -pub fn translate_module<'data>( - data: &'data [u8], - environ: &mut dyn ModuleEnvironment<'data>, -) -> WasmResult<()> { - let _tt = timing::wasm_translate_module(); - let mut validator = Validator::new_with_features(environ.wasm_features()); - - for payload in Parser::new(0).parse_all(data) { - match payload? { - Payload::Version { - num, - encoding, - range, - } => { - validator.version(num, encoding, &range)?; - } - Payload::End(offset) => { - validator.end(offset)?; - } - - Payload::TypeSection(types) => { - validator.type_section(&types)?; - parse_type_section(types, environ)?; - } - - Payload::ImportSection(imports) => { - validator.import_section(&imports)?; - parse_import_section(imports, environ)?; - } - - Payload::FunctionSection(functions) => { - validator.function_section(&functions)?; - parse_function_section(functions, environ)?; - } - - Payload::TableSection(tables) => { - validator.table_section(&tables)?; - parse_table_section(tables, environ)?; - } - - Payload::MemorySection(memories) => { - validator.memory_section(&memories)?; - parse_memory_section(memories, environ)?; - } - - Payload::TagSection(tags) => { - validator.tag_section(&tags)?; - parse_tag_section(tags, environ)?; - } - - Payload::GlobalSection(globals) => { - validator.global_section(&globals)?; - parse_global_section(globals, environ)?; - } - - Payload::ExportSection(exports) => { - validator.export_section(&exports)?; - parse_export_section(exports, environ)?; - } - - Payload::StartSection { func, range } => { - validator.start_section(func, &range)?; - parse_start_section(func, environ)?; - } - - Payload::ElementSection(elements) => { - validator.element_section(&elements)?; - parse_element_section(elements, environ)?; - } - - Payload::CodeSectionStart { count, range, .. } => { - validator.code_section_start(count, &range)?; - environ.reserve_function_bodies(count, range.start as u64); - } - - Payload::CodeSectionEntry(body) => { - let func_validator = validator - .code_section_entry(&body)? - .into_validator(Default::default()); - environ.define_function_body(func_validator, body)?; - } - - Payload::DataSection(data) => { - validator.data_section(&data)?; - parse_data_section(data, environ)?; - } - - Payload::DataCountSection { count, range } => { - validator.data_count_section(count, &range)?; - - // NOTE: the count here is the total segment count, not the passive segment count - environ.reserve_passive_data(count)?; - } - - Payload::CustomSection(s) => environ.custom_section(s.name(), s.data())?, - - other => { - validator.payload(&other)?; - panic!("unimplemented section {other:?}"); - } - } - } - - Ok(()) -} diff --git a/cranelift/wasm/src/sections_translator.rs b/cranelift/wasm/src/sections_translator.rs deleted file mode 100644 index 8943dab70b1b..000000000000 --- a/cranelift/wasm/src/sections_translator.rs +++ /dev/null @@ -1,333 +0,0 @@ -//! Helper functions to gather information for each of the non-function sections of a -//! WebAssembly module. -//! -//! The code of these helper functions is straightforward since they only read metadata -//! about linear memories, tables, globals, etc. and store them for later use. -//! -//! The special case of the initialize expressions for table elements offsets or global variables -//! is handled, according to the semantics of WebAssembly, to only specific expressions that are -//! interpreted on the fly. -use crate::environ::ModuleEnvironment; -use crate::wasm_unsupported; -use crate::{ - DataIndex, ElemIndex, FuncIndex, GlobalIndex, MemoryIndex, TableIndex, Tag, TagIndex, - TypeIndex, WasmError, WasmResult, -}; -use cranelift_entity::packed_option::ReservedValue; -use cranelift_entity::{EntityRef, Unsigned}; -use std::boxed::Box; -use std::vec::Vec; -use wasmparser::{ - Data, DataKind, DataSectionReader, Element, ElementItems, ElementKind, ElementSectionReader, - Export, ExportSectionReader, ExternalKind, FunctionSectionReader, GlobalSectionReader, - ImportSectionReader, MemorySectionReader, Operator, TableSectionReader, TagSectionReader, - TagType, TypeRef, TypeSectionReader, -}; -use wasmtime_types::ConstExpr; - -fn tag(e: TagType) -> Tag { - match e.kind { - wasmparser::TagKind::Exception => Tag { - ty: TypeIndex::from_u32(e.func_type_idx), - }, - } -} - -/// Parses the Type section of the wasm module. -pub fn parse_type_section<'a>( - types: TypeSectionReader<'a>, - environ: &mut dyn ModuleEnvironment<'a>, -) -> WasmResult<()> { - let count = types.count(); - environ.reserve_types(count)?; - - for ty in types.into_iter_err_on_gc_types() { - let ty = environ.convert_func_type(&ty?); - environ.declare_type_func(ty)?; - } - Ok(()) -} - -/// Parses the Import section of the wasm module. -pub fn parse_import_section<'data>( - imports: ImportSectionReader<'data>, - environ: &mut dyn ModuleEnvironment<'data>, -) -> WasmResult<()> { - environ.reserve_imports(imports.count())?; - - for entry in imports { - let import = entry?; - match import.ty { - TypeRef::Func(sig) => { - environ.declare_func_import( - TypeIndex::from_u32(sig), - import.module, - import.name, - )?; - } - TypeRef::Memory(ty) => { - environ.declare_memory_import(ty.into(), import.module, import.name)?; - } - TypeRef::Tag(e) => { - environ.declare_tag_import(tag(e), import.module, import.name)?; - } - TypeRef::Global(ty) => { - let ty = environ.convert_global_type(&ty); - environ.declare_global_import(ty, import.module, import.name)?; - } - TypeRef::Table(ty) => { - let ty = environ.convert_table_type(&ty)?; - environ.declare_table_import(ty, import.module, import.name)?; - } - } - } - - environ.finish_imports()?; - Ok(()) -} - -/// Parses the Function section of the wasm module. -pub fn parse_function_section( - functions: FunctionSectionReader, - environ: &mut dyn ModuleEnvironment, -) -> WasmResult<()> { - let num_functions = functions.count(); - if num_functions == std::u32::MAX { - // We reserve `u32::MAX` for our own use in cranelift-entity. - return Err(WasmError::ImplLimitExceeded); - } - - environ.reserve_func_types(num_functions)?; - - for entry in functions { - let sigindex = entry?; - environ.declare_func_type(TypeIndex::from_u32(sigindex))?; - } - - Ok(()) -} - -/// Parses the Table section of the wasm module. -pub fn parse_table_section( - tables: TableSectionReader, - environ: &mut dyn ModuleEnvironment, -) -> WasmResult<()> { - environ.reserve_tables(tables.count())?; - - for entry in tables { - let ty = environ.convert_table_type(&entry?.ty)?; - environ.declare_table(ty)?; - } - - Ok(()) -} - -/// Parses the Memory section of the wasm module. -pub fn parse_memory_section( - memories: MemorySectionReader, - environ: &mut dyn ModuleEnvironment, -) -> WasmResult<()> { - environ.reserve_memories(memories.count())?; - - for entry in memories { - environ.declare_memory(entry?.into())?; - } - - Ok(()) -} - -/// Parses the Tag section of the wasm module. -pub fn parse_tag_section( - tags: TagSectionReader, - environ: &mut dyn ModuleEnvironment, -) -> WasmResult<()> { - environ.reserve_tags(tags.count())?; - - for entry in tags { - let tag = tag(entry?); - environ.declare_tag(tag)?; - } - - Ok(()) -} - -/// Parses the Global section of the wasm module. -pub fn parse_global_section( - globals: GlobalSectionReader, - environ: &mut dyn ModuleEnvironment, -) -> WasmResult<()> { - environ.reserve_globals(globals.count())?; - - for entry in globals { - let wasmparser::Global { ty, init_expr } = entry?; - let (initializer, _escaped) = ConstExpr::from_wasmparser(init_expr)?; - let ty = environ.convert_global_type(&ty); - environ.declare_global(ty, initializer)?; - } - - Ok(()) -} - -/// Parses the Export section of the wasm module. -pub fn parse_export_section<'data>( - exports: ExportSectionReader<'data>, - environ: &mut dyn ModuleEnvironment<'data>, -) -> WasmResult<()> { - environ.reserve_exports(exports.count())?; - - for entry in exports { - let Export { - name, - ref kind, - index, - } = entry?; - - // The input has already been validated, so we should be able to - // assume valid UTF-8 and use `from_utf8_unchecked` if performance - // becomes a concern here. - let index = usize::try_from(index)?; - match *kind { - ExternalKind::Func => environ.declare_func_export(FuncIndex::new(index), name)?, - ExternalKind::Table => environ.declare_table_export(TableIndex::new(index), name)?, - ExternalKind::Memory => environ.declare_memory_export(MemoryIndex::new(index), name)?, - ExternalKind::Tag => environ.declare_tag_export(TagIndex::new(index), name)?, - ExternalKind::Global => environ.declare_global_export(GlobalIndex::new(index), name)?, - } - } - - environ.finish_exports()?; - Ok(()) -} - -/// Parses the Start section of the wasm module. -pub fn parse_start_section(index: u32, environ: &mut dyn ModuleEnvironment) -> WasmResult<()> { - environ.declare_start_func(FuncIndex::from_u32(index))?; - Ok(()) -} - -fn read_elems(items: &ElementItems) -> WasmResult> { - let mut elems = Vec::new(); - match items { - ElementItems::Functions(funcs) => { - for func in funcs.clone() { - elems.push(FuncIndex::from_u32(func?)); - } - } - ElementItems::Expressions(_ty, funcs) => { - for func in funcs.clone() { - let idx = match func?.get_binary_reader().read_operator()? { - Operator::RefNull { .. } => FuncIndex::reserved_value(), - Operator::RefFunc { function_index } => FuncIndex::from_u32(function_index), - s => { - return Err(WasmError::Unsupported(format!( - "unsupported init expr in element section: {s:?}" - ))); - } - }; - elems.push(idx); - } - } - } - Ok(elems.into_boxed_slice()) -} - -/// Parses the Element section of the wasm module. -pub fn parse_element_section<'data>( - elements: ElementSectionReader<'data>, - environ: &mut dyn ModuleEnvironment, -) -> WasmResult<()> { - environ.reserve_table_elements(elements.count())?; - - for (index, entry) in elements.into_iter().enumerate() { - let Element { - kind, - items, - range: _, - } = entry?; - let segments = read_elems(&items)?; - match kind { - ElementKind::Active { - table_index, - offset_expr, - } => { - let mut offset_expr_reader = offset_expr.get_binary_reader(); - let (base, offset) = match offset_expr_reader.read_operator()? { - Operator::I32Const { value } => (None, u64::from(value.unsigned())), - Operator::I64Const { value } => (None, value.unsigned()), - Operator::GlobalGet { global_index } => { - (Some(GlobalIndex::from_u32(global_index)), 0) - } - ref s => { - return Err(wasm_unsupported!( - "unsupported init expr in element section: {:?}", - s - )); - } - }; - environ.declare_table_elements( - TableIndex::from_u32(table_index.unwrap_or(0)), - base, - offset, - segments, - )? - } - ElementKind::Passive => { - let index = ElemIndex::from_u32(u32::try_from(index)?); - environ.declare_passive_element(index, segments)?; - } - ElementKind::Declared => { - environ.declare_elements(segments)?; - } - } - } - Ok(()) -} - -/// Parses the Data section of the wasm module. -pub fn parse_data_section<'data>( - data: DataSectionReader<'data>, - environ: &mut dyn ModuleEnvironment<'data>, -) -> WasmResult<()> { - environ.reserve_data_initializers(data.count())?; - - for (index, entry) in data.into_iter().enumerate() { - let Data { - kind, - data, - range: _, - } = entry?; - match kind { - DataKind::Active { - memory_index, - offset_expr, - } => { - let mut offset_expr_reader = offset_expr.get_binary_reader(); - let (base, offset) = match offset_expr_reader.read_operator()? { - Operator::I32Const { value } => (None, u64::try_from(value)?), - Operator::I64Const { value } => (None, u64::try_from(value)?), - Operator::GlobalGet { global_index } => { - (Some(GlobalIndex::from_u32(global_index)), 0) - } - ref s => { - return Err(wasm_unsupported!( - "unsupported init expr in data section: {:?}", - s - )) - } - }; - environ.declare_data_initialization( - MemoryIndex::from_u32(memory_index), - base, - offset, - data, - )?; - } - DataKind::Passive => { - let index = DataIndex::from_u32(u32::try_from(index)?); - environ.declare_passive_data(index, data)?; - } - } - } - - Ok(()) -} diff --git a/crates/cranelift/Cargo.toml b/crates/cranelift/Cargo.toml index 8cf85ff2df5c..719d570b6ae5 100644 --- a/crates/cranelift/Cargo.toml +++ b/crates/cranelift/Cargo.toml @@ -18,7 +18,6 @@ workspace = true anyhow = { workspace = true } log = { workspace = true } wasmtime-environ = { workspace = true, features = ['compile'] } -cranelift-wasm = { workspace = true } cranelift-codegen = { workspace = true, features = ["host-arch"] } cranelift-frontend = { workspace = true } cranelift-entity = { workspace = true } @@ -32,6 +31,7 @@ smallvec = { workspace = true } thiserror = { workspace = true } cfg-if = { workspace = true } wasmtime-versioned-export-macros = { workspace = true } +itertools = "0.12" [features] all-arch = ["cranelift-codegen/all-arch"] diff --git a/crates/cranelift/src/compiler.rs b/crates/cranelift/src/compiler.rs index 024eb63cea0b..fae60c9a19a8 100644 --- a/crates/cranelift/src/compiler.rs +++ b/crates/cranelift/src/compiler.rs @@ -1,5 +1,6 @@ use crate::debug::DwarfSectionRelocTarget; use crate::func_environ::FuncEnvironment; +use crate::translate::{FuncEnvironment as _, FuncTranslator}; use crate::DEBUG_ASSERT_TRAP_CODE; use crate::{array_call_signature, CompiledFunction, ModuleTextBuilder}; use crate::{builder::LinkOptions, wasm_call_signature, BuiltinFunctionSignatures}; @@ -15,9 +16,6 @@ use cranelift_codegen::print_errors::pretty_error; use cranelift_codegen::{CompiledCode, Context}; use cranelift_entity::PrimaryMap; use cranelift_frontend::FunctionBuilder; -use cranelift_wasm::{ - DefinedFuncIndex, FuncEnvironment as _, FuncTranslator, WasmFuncType, WasmValType, -}; use object::write::{Object, StandardSegment, SymbolId}; use object::{RelocationEncoding, RelocationFlags, RelocationKind, SectionKind}; use std::any::Any; @@ -28,10 +26,10 @@ use std::path; use std::sync::{Arc, Mutex}; use wasmparser::{FuncValidatorAllocations, FunctionBody}; use wasmtime_environ::{ - AddressMapSection, BuiltinFunctionIndex, CacheStore, CompileError, FlagValue, FunctionBodyData, - FunctionLoc, ModuleTranslation, ModuleTypesBuilder, PtrSize, RelocationTarget, - StackMapInformation, StaticModuleIndex, TrapEncodingBuilder, Tunables, VMOffsets, - WasmFunctionInfo, + AddressMapSection, BuiltinFunctionIndex, CacheStore, CompileError, DefinedFuncIndex, FlagValue, + FunctionBodyData, FunctionLoc, ModuleTranslation, ModuleTypesBuilder, PtrSize, + RelocationTarget, StackMapInformation, StaticModuleIndex, TrapEncodingBuilder, Tunables, + VMOffsets, WasmFuncType, WasmFunctionInfo, WasmValType, }; #[cfg(feature = "component-model")] diff --git a/crates/cranelift/src/compiler/component.rs b/crates/cranelift/src/compiler/component.rs index 7223029e23e9..b196e56374f5 100644 --- a/crates/cranelift/src/compiler/component.rs +++ b/crates/cranelift/src/compiler/component.rs @@ -5,10 +5,9 @@ use anyhow::Result; use cranelift_codegen::ir::{self, InstBuilder, MemFlags}; use cranelift_codegen::isa::{CallConv, TargetIsa}; use cranelift_frontend::FunctionBuilder; -use cranelift_wasm::ModuleInternedTypeIndex; use std::any::Any; use wasmtime_environ::component::*; -use wasmtime_environ::{PtrSize, Tunables, WasmValType}; +use wasmtime_environ::{ModuleInternedTypeIndex, PtrSize, Tunables, WasmValType}; struct TrampolineCompiler<'a> { compiler: &'a Compiler, diff --git a/crates/cranelift/src/debug/transform/expression.rs b/crates/cranelift/src/debug/transform/expression.rs index 19015ea1ef42..292465afd7de 100644 --- a/crates/cranelift/src/debug/transform/expression.rs +++ b/crates/cranelift/src/debug/transform/expression.rs @@ -2,12 +2,12 @@ use super::address_transform::AddressTransform; use crate::debug::ModuleMemoryOffset; +use crate::translate::get_vmctx_value_label; use anyhow::{Context, Error, Result}; use cranelift_codegen::ir::ValueLabel; use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::LabelValueLoc; use cranelift_codegen::ValueLabelsRanges; -use cranelift_wasm::get_vmctx_value_label; use gimli::{write, Expression, Operation, Reader, ReaderOffset}; use std::cmp::PartialEq; use std::collections::{HashMap, HashSet}; diff --git a/crates/cranelift/src/debug/transform/simulate.rs b/crates/cranelift/src/debug/transform/simulate.rs index 2e0875a97736..87ff712aabaf 100644 --- a/crates/cranelift/src/debug/transform/simulate.rs +++ b/crates/cranelift/src/debug/transform/simulate.rs @@ -2,9 +2,9 @@ use super::expression::{CompiledExpression, FunctionFrameInfo}; use super::utils::{add_internal_types, append_vmctx_info}; use super::AddressTransform; use crate::debug::{Compilation, ModuleMemoryOffset}; +use crate::translate::get_vmctx_value_label; use anyhow::{Context, Error}; use cranelift_codegen::isa::TargetIsa; -use cranelift_wasm::get_vmctx_value_label; use gimli::write; use gimli::LineEncoding; use std::collections::{HashMap, HashSet}; diff --git a/crates/cranelift/src/func_environ.rs b/crates/cranelift/src/func_environ.rs index f2392754639d..cc0301ac206b 100644 --- a/crates/cranelift/src/func_environ.rs +++ b/crates/cranelift/src/func_environ.rs @@ -1,3 +1,7 @@ +use crate::translate::{ + FuncEnvironment as _, FuncTranslationState, GlobalVariable, Heap, HeapData, HeapStyle, + StructFieldsVec, TableData, TableSize, TargetEnvironment, +}; use crate::{gc, BuiltinFunctionSignatures}; use cranelift_codegen::cursor::FuncCursor; use cranelift_codegen::ir::condcodes::IntCC; @@ -11,18 +15,14 @@ use cranelift_entity::packed_option::ReservedValue; use cranelift_entity::{EntityRef, PrimaryMap, SecondaryMap}; use cranelift_frontend::FunctionBuilder; use cranelift_frontend::Variable; -use cranelift_wasm::{ - EngineOrModuleTypeIndex, FuncEnvironment as _, FuncIndex, FuncTranslationState, GlobalIndex, - GlobalVariable, Heap, HeapData, HeapStyle, IndexType, Memory, MemoryIndex, StructFieldsVec, - Table, TableData, TableIndex, TableSize, TargetEnvironment, TypeIndex, WasmCompositeType, - WasmFuncType, WasmHeapTopType, WasmHeapType, WasmResult, WasmValType, -}; use smallvec::SmallVec; use std::mem; use wasmparser::Operator; use wasmtime_environ::{ - BuiltinFunctionIndex, MemoryPlan, MemoryStyle, Module, ModuleTranslation, ModuleTypesBuilder, - PtrSize, TableStyle, Tunables, TypeConvert, VMOffsets, + BuiltinFunctionIndex, EngineOrModuleTypeIndex, FuncIndex, GlobalIndex, IndexType, Memory, + MemoryIndex, MemoryPlan, MemoryStyle, Module, ModuleTranslation, ModuleTypesBuilder, PtrSize, + Table, TableIndex, TableStyle, Tunables, TypeConvert, TypeIndex, VMOffsets, WasmCompositeType, + WasmFuncType, WasmHeapTopType, WasmHeapType, WasmResult, WasmValType, }; use wasmtime_environ::{FUNCREF_INIT_BIT, FUNCREF_MASK}; @@ -1643,7 +1643,9 @@ impl<'module_environment> TargetEnvironment for FuncEnvironment<'module_environm } } -impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'module_environment> { +impl<'module_environment> crate::translate::FuncEnvironment + for FuncEnvironment<'module_environment> +{ fn heaps(&self) -> &PrimaryMap { &self.heaps } @@ -1979,7 +1981,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m fn translate_custom_global_get( &mut self, builder: &mut FunctionBuilder, - index: cranelift_wasm::GlobalIndex, + index: GlobalIndex, ) -> WasmResult { let ty = self.module.globals[index].wasm_ty; debug_assert!( @@ -2006,7 +2008,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m fn translate_custom_global_set( &mut self, builder: &mut FunctionBuilder, - index: cranelift_wasm::GlobalIndex, + index: GlobalIndex, value: ir::Value, ) -> WasmResult<()> { let ty = self.module.globals[index].wasm_ty; @@ -2288,7 +2290,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m // any other type of global at the same index would, getting or // setting them requires ref counting barriers. Therefore, we need // to use `GlobalVariable::Custom`, as that is the only kind of - // `GlobalVariable` for which `cranelift-wasm` supports custom + // `GlobalVariable` for which translation supports custom // access translation. return Ok(GlobalVariable::Custom); } diff --git a/crates/cranelift/src/gc.rs b/crates/cranelift/src/gc.rs index 09ffabeae783..1c14295e2955 100644 --- a/crates/cranelift/src/gc.rs +++ b/crates/cranelift/src/gc.rs @@ -8,8 +8,7 @@ use crate::func_environ::FuncEnvironment; use cranelift_codegen::ir; use cranelift_frontend::FunctionBuilder; -use cranelift_wasm::{TypeIndex, WasmRefType, WasmResult}; -use wasmtime_environ::GcTypeLayouts; +use wasmtime_environ::{GcTypeLayouts, TypeIndex, WasmRefType, WasmResult}; #[cfg(feature = "gc")] mod enabled; diff --git a/crates/cranelift/src/gc/disabled.rs b/crates/cranelift/src/gc/disabled.rs index c740cc3e4e52..fdc7b655b304 100644 --- a/crates/cranelift/src/gc/disabled.rs +++ b/crates/cranelift/src/gc/disabled.rs @@ -1,11 +1,10 @@ //! `GcCompiler` implementation when GC support is disabled. use super::GcCompiler; -use crate::func_environ::FuncEnvironment; +use crate::translate::func_environ::FuncEnvironment; use cranelift_codegen::ir; use cranelift_frontend::FunctionBuilder; -use cranelift_wasm::{wasm_unsupported, WasmHeapType, WasmResult}; -use wasmtime_environ::TypeIndex; +use wasmtime_environ::{wasm_unsupported, TypeIndex, WasmHeapType, WasmResult}; fn disabled() -> WasmResult { Err(wasm_unsupported!( diff --git a/crates/cranelift/src/gc/enabled.rs b/crates/cranelift/src/gc/enabled.rs index 95fa1881b874..a613b921dd05 100644 --- a/crates/cranelift/src/gc/enabled.rs +++ b/crates/cranelift/src/gc/enabled.rs @@ -1,15 +1,16 @@ use super::GcCompiler; use crate::func_environ::FuncEnvironment; +use crate::translate::{StructFieldsVec, TargetEnvironment}; use cranelift_codegen::{ cursor::FuncCursor, ir::{self, condcodes::IntCC, InstBuilder}, }; use cranelift_frontend::FunctionBuilder; -use cranelift_wasm::{ - ModuleInternedTypeIndex, StructFieldsVec, TargetEnvironment, TypeIndex, WasmCompositeType, +use wasmtime_environ::{ + GcStructLayout, ModuleInternedTypeIndex, PtrSize, TypeIndex, WasmCompositeType, WasmHeapTopType, WasmHeapType, WasmRefType, WasmResult, WasmStorageType, WasmValType, + I31_DISCRIMINANT, NON_NULL_NON_I31_MASK, }; -use wasmtime_environ::{GcStructLayout, PtrSize, I31_DISCRIMINANT, NON_NULL_NON_I31_MASK}; mod drc; diff --git a/crates/cranelift/src/gc/enabled/drc.rs b/crates/cranelift/src/gc/enabled/drc.rs index cd351772eee6..5db21bb7289d 100644 --- a/crates/cranelift/src/gc/enabled/drc.rs +++ b/crates/cranelift/src/gc/enabled/drc.rs @@ -2,10 +2,10 @@ //! barriers. use super::{unbarriered_load_gc_ref, unbarriered_store_gc_ref}; +use crate::translate::TargetEnvironment; use crate::{func_environ::FuncEnvironment, gc::GcCompiler}; use cranelift_codegen::ir::{self, InstBuilder}; use cranelift_frontend::FunctionBuilder; -use cranelift_wasm::TargetEnvironment; use smallvec::SmallVec; use wasmtime_environ::{ drc::DrcTypeLayouts, GcTypeLayouts, PtrSize, TypeIndex, VMGcKind, WasmCompositeType, diff --git a/crates/cranelift/src/lib.rs b/crates/cranelift/src/lib.rs index 467a994eb0fb..b1f69e1d5ce0 100644 --- a/crates/cranelift/src/lib.rs +++ b/crates/cranelift/src/lib.rs @@ -11,11 +11,11 @@ use cranelift_codegen::{ settings, FinalizedMachReloc, FinalizedRelocTarget, MachTrap, }; use cranelift_entity::PrimaryMap; -use cranelift_wasm::{FuncIndex, WasmFuncType, WasmHeapTopType, WasmHeapType, WasmValType}; use target_lexicon::Architecture; use wasmtime_environ::{ - BuiltinFunctionIndex, FlagValue, RelocationTarget, Trap, TrapInformation, Tunables, + BuiltinFunctionIndex, FlagValue, FuncIndex, RelocationTarget, Trap, TrapInformation, Tunables, + WasmFuncType, WasmHeapTopType, WasmHeapType, WasmValType, }; pub use builder::builder; @@ -31,6 +31,7 @@ mod compiler; mod debug; mod func_environ; mod gc; +mod translate; /// Trap code used for debug assertions we emit in our JIT code. const DEBUG_ASSERT_TRAP_CODE: u16 = u16::MAX; diff --git a/cranelift/wasm/src/code_translator.rs b/crates/cranelift/src/translate/code_translator.rs similarity index 99% rename from cranelift/wasm/src/code_translator.rs rename to crates/cranelift/src/translate/code_translator.rs index a4e81ef87b80..c74bd59489f6 100644 --- a/cranelift/wasm/src/code_translator.rs +++ b/crates/cranelift/src/translate/code_translator.rs @@ -73,14 +73,11 @@ mod bounds_checks; -use super::{hash_map, HashMap}; -use crate::environ::{FuncEnvironment, GlobalVariable, StructFieldsVec}; -use crate::state::{ControlStackFrame, ElseData, FuncTranslationState}; -use crate::translation_utils::{ +use crate::translate::environ::{FuncEnvironment, GlobalVariable, StructFieldsVec}; +use crate::translate::state::{ControlStackFrame, ElseData, FuncTranslationState}; +use crate::translate::translation_utils::{ block_with_params, blocktype_params_results, f32_translation, f64_translation, }; -use crate::wasm_unsupported; -use crate::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex, WasmResult}; use core::{i32, u32}; use cranelift_codegen::ir::condcodes::{FloatCC, IntCC}; use cranelift_codegen::ir::immediates::Offset32; @@ -92,8 +89,12 @@ use cranelift_codegen::packed_option::ReservedValue; use cranelift_frontend::{FunctionBuilder, Variable}; use itertools::Itertools; use smallvec::SmallVec; +use std::collections::{hash_map, HashMap}; use std::vec::Vec; use wasmparser::{FuncValidator, MemArg, Operator, WasmModuleResources}; +use wasmtime_environ::{ + wasm_unsupported, FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex, WasmResult, +}; /// Given a `Reachability`, unwrap the inner `T` or, when unreachable, set /// `state.reachable = false` and return. @@ -172,7 +173,6 @@ pub fn translate_operator( ***********************************************************************************/ Operator::GlobalGet { global_index } => { let val = match state.get_global(builder.func, *global_index, environ)? { - GlobalVariable::Const(val) => val, GlobalVariable::Memory { gv, offset, ty } => { let addr = builder.ins().global_value(environ.pointer_type(), gv); let mut flags = ir::MemFlags::trusted(); @@ -187,7 +187,6 @@ pub fn translate_operator( } Operator::GlobalSet { global_index } => { match state.get_global(builder.func, *global_index, environ)? { - GlobalVariable::Const(_) => panic!("global #{} is a constant", *global_index), GlobalVariable::Memory { gv, offset, ty } => { let addr = builder.ins().global_value(environ.pointer_type(), gv); let mut flags = ir::MemFlags::trusted(); diff --git a/cranelift/wasm/src/code_translator/bounds_checks.rs b/crates/cranelift/src/translate/code_translator/bounds_checks.rs similarity index 99% rename from cranelift/wasm/src/code_translator/bounds_checks.rs rename to crates/cranelift/src/translate/code_translator/bounds_checks.rs index cd1ca3282a64..82ba2a1eddcf 100644 --- a/cranelift/wasm/src/code_translator/bounds_checks.rs +++ b/crates/cranelift/src/translate/code_translator/bounds_checks.rs @@ -20,14 +20,14 @@ //! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! use super::Reachability; -use crate::{FuncEnvironment, HeapData, HeapStyle}; +use crate::translate::{FuncEnvironment, HeapData, HeapStyle}; use cranelift_codegen::{ cursor::{Cursor, FuncCursor}, ir::{self, condcodes::IntCC, InstBuilder, RelSourceLoc}, ir::{Expr, Fact}, }; use cranelift_frontend::FunctionBuilder; -use wasmtime_types::WasmResult; +use wasmtime_environ::WasmResult; use Reachability::*; /// Helper used to emit bounds checks (as necessary) and compute the native diff --git a/crates/cranelift/src/translate/environ/mod.rs b/crates/cranelift/src/translate/environ/mod.rs new file mode 100644 index 000000000000..e6378ebd9371 --- /dev/null +++ b/crates/cranelift/src/translate/environ/mod.rs @@ -0,0 +1,8 @@ +//! Support for configurable wasm translation. + +#[macro_use] +mod spec; + +pub use crate::translate::environ::spec::{ + FuncEnvironment, GlobalVariable, StructFieldsVec, TargetEnvironment, +}; diff --git a/cranelift/wasm/src/environ/spec.rs b/crates/cranelift/src/translate/environ/spec.rs similarity index 73% rename from cranelift/wasm/src/environ/spec.rs rename to crates/cranelift/src/translate/environ/spec.rs index 2a46fb4d9210..ef408431ab3c 100644 --- a/cranelift/wasm/src/environ/spec.rs +++ b/crates/cranelift/src/translate/environ/spec.rs @@ -6,12 +6,8 @@ //! //! [Wasmtime]: https://github.com/bytecodealliance/wasmtime -use crate::state::FuncTranslationState; -use crate::{ - DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Heap, HeapData, Memory, MemoryIndex, - Table, TableIndex, Tag, TagIndex, TypeConvert, TypeIndex, WasmError, WasmFuncType, - WasmHeapType, WasmResult, -}; +use crate::translate::state::FuncTranslationState; +use crate::translate::{Heap, HeapData}; use cranelift_codegen::cursor::FuncCursor; use cranelift_codegen::ir::immediates::Offset32; use cranelift_codegen::ir::{self, InstBuilder, Type}; @@ -19,17 +15,15 @@ use cranelift_codegen::isa::{TargetFrontendConfig, TargetIsa}; use cranelift_entity::PrimaryMap; use cranelift_frontend::FunctionBuilder; use smallvec::SmallVec; -use std::boxed::Box; -use std::string::ToString; -use wasmparser::{FuncValidator, FunctionBody, Operator, ValidatorResources, WasmFeatures}; -use wasmtime_types::{ConstExpr, ModuleInternedTypeIndex}; +use wasmparser::Operator; +use wasmtime_environ::{ + FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeConvert, TypeIndex, WasmHeapType, + WasmResult, +}; /// The value of a WebAssembly global variable. #[derive(Clone, Copy)] pub enum GlobalVariable { - /// This is a constant global with a value known at compile time. - Const(ir::Value), - /// This is a variable in memory that should be referenced through a `GlobalValue`. Memory { /// The address of the global variable storage. @@ -62,11 +56,6 @@ pub trait TargetEnvironment: TypeConvert { ir::Type::int(u16::from(self.target_config().pointer_bits())).unwrap() } - /// Get the size of a native pointer, in bytes. - fn pointer_bytes(&self) -> u8 { - self.target_config().pointer_bytes() - } - /// Get the Cranelift reference type to use for the given Wasm reference /// type. /// @@ -820,265 +809,3 @@ pub trait FuncEnvironment: TargetEnvironment { builder.ins().fcvt_to_uint(ty, val) } } - -/// An object satisfying the `ModuleEnvironment` trait can be passed as argument to the -/// [`translate_module`](fn.translate_module.html) function. These methods should not be called -/// by the user, they are only for `cranelift-wasm` internal use. -pub trait ModuleEnvironment<'data>: TypeConvert { - /// Provides the number of types up front. By default this does nothing, but - /// implementations can use this to preallocate memory if desired. - fn reserve_types(&mut self, _num: u32) -> WasmResult<()> { - Ok(()) - } - - /// Declares a function signature to the environment. - fn declare_type_func(&mut self, wasm_func_type: WasmFuncType) -> WasmResult<()>; - - /// Translates a type index to its signature index, only called for type - /// indices which point to functions. - fn type_to_signature(&self, index: TypeIndex) -> WasmResult { - let _ = index; - Err(WasmError::Unsupported("module linking".to_string())) - } - - /// Provides the number of imports up front. By default this does nothing, but - /// implementations can use this to preallocate memory if desired. - fn reserve_imports(&mut self, _num: u32) -> WasmResult<()> { - Ok(()) - } - - /// Declares a function import to the environment. - fn declare_func_import( - &mut self, - index: TypeIndex, - module: &'data str, - field: &'data str, - ) -> WasmResult<()>; - - /// Declares a table import to the environment. - fn declare_table_import( - &mut self, - table: Table, - module: &'data str, - field: &'data str, - ) -> WasmResult<()>; - - /// Declares a memory import to the environment. - fn declare_memory_import( - &mut self, - memory: Memory, - module: &'data str, - field: &'data str, - ) -> WasmResult<()>; - - /// Declares an tag import to the environment. - fn declare_tag_import( - &mut self, - tag: Tag, - module: &'data str, - field: &'data str, - ) -> WasmResult<()> { - let _ = (tag, module, field); - Err(WasmError::Unsupported("wasm tags".to_string())) - } - - /// Declares a global import to the environment. - fn declare_global_import( - &mut self, - global: Global, - module: &'data str, - field: &'data str, - ) -> WasmResult<()>; - - /// Notifies the implementation that all imports have been declared. - fn finish_imports(&mut self) -> WasmResult<()> { - Ok(()) - } - - /// Provides the number of defined functions up front. By default this does nothing, but - /// implementations can use this to preallocate memory if desired. - fn reserve_func_types(&mut self, _num: u32) -> WasmResult<()> { - Ok(()) - } - - /// Declares the type (signature) of a local function in the module. - fn declare_func_type(&mut self, index: TypeIndex) -> WasmResult<()>; - - /// Provides the number of defined tables up front. By default this does nothing, but - /// implementations can use this to preallocate memory if desired. - fn reserve_tables(&mut self, _num: u32) -> WasmResult<()> { - Ok(()) - } - - /// Declares a table to the environment. - fn declare_table(&mut self, table: Table) -> WasmResult<()>; - - /// Provides the number of defined memories up front. By default this does nothing, but - /// implementations can use this to preallocate memory if desired. - fn reserve_memories(&mut self, _num: u32) -> WasmResult<()> { - Ok(()) - } - - /// Declares a memory to the environment - fn declare_memory(&mut self, memory: Memory) -> WasmResult<()>; - - /// Provides the number of defined tags up front. By default this does nothing, but - /// implementations can use this to preallocate memory if desired. - fn reserve_tags(&mut self, _num: u32) -> WasmResult<()> { - Ok(()) - } - - /// Declares an tag to the environment - fn declare_tag(&mut self, tag: Tag) -> WasmResult<()> { - let _ = tag; - Err(WasmError::Unsupported("wasm tags".to_string())) - } - - /// Provides the number of defined globals up front. By default this does nothing, but - /// implementations can use this to preallocate memory if desired. - fn reserve_globals(&mut self, _num: u32) -> WasmResult<()> { - Ok(()) - } - - /// Declares a global to the environment. - fn declare_global(&mut self, global: Global, init: ConstExpr) -> WasmResult<()>; - - /// Provides the number of exports up front. By default this does nothing, but - /// implementations can use this to preallocate memory if desired. - fn reserve_exports(&mut self, _num: u32) -> WasmResult<()> { - Ok(()) - } - - /// Declares a function export to the environment. - fn declare_func_export(&mut self, func_index: FuncIndex, name: &'data str) -> WasmResult<()>; - - /// Declares a table export to the environment. - fn declare_table_export(&mut self, table_index: TableIndex, name: &'data str) - -> WasmResult<()>; - - /// Declares a memory export to the environment. - fn declare_memory_export( - &mut self, - memory_index: MemoryIndex, - name: &'data str, - ) -> WasmResult<()>; - - /// Declares an tag export to the environment. - fn declare_tag_export(&mut self, tag_index: TagIndex, name: &'data str) -> WasmResult<()> { - let _ = (tag_index, name); - Err(WasmError::Unsupported("wasm tags".to_string())) - } - - /// Declares a global export to the environment. - fn declare_global_export( - &mut self, - global_index: GlobalIndex, - name: &'data str, - ) -> WasmResult<()>; - - /// Notifies the implementation that all exports have been declared. - fn finish_exports(&mut self) -> WasmResult<()> { - Ok(()) - } - - /// Declares the optional start function. - fn declare_start_func(&mut self, index: FuncIndex) -> WasmResult<()>; - - /// Provides the number of element initializers up front. By default this does nothing, but - /// implementations can use this to preallocate memory if desired. - fn reserve_table_elements(&mut self, _num: u32) -> WasmResult<()> { - Ok(()) - } - - /// Fills a declared table with references to functions in the module. - fn declare_table_elements( - &mut self, - table_index: TableIndex, - base: Option, - offset: u64, - elements: Box<[FuncIndex]>, - ) -> WasmResult<()>; - - /// Declare a passive element segment. - fn declare_passive_element( - &mut self, - index: ElemIndex, - elements: Box<[FuncIndex]>, - ) -> WasmResult<()>; - - /// Indicates that a declarative element segment was seen in the wasm - /// module. - fn declare_elements(&mut self, elements: Box<[FuncIndex]>) -> WasmResult<()> { - let _ = elements; - Ok(()) - } - - /// Provides the number of passive data segments up front. - /// - /// By default this does nothing, but implementations may use this to - /// pre-allocate memory if desired. - fn reserve_passive_data(&mut self, count: u32) -> WasmResult<()> { - let _ = count; - Ok(()) - } - - /// Declare a passive data segment. - fn declare_passive_data(&mut self, data_index: DataIndex, data: &'data [u8]) -> WasmResult<()>; - - /// Indicates how many functions the code section reports and the byte - /// offset of where the code sections starts. - fn reserve_function_bodies(&mut self, bodies: u32, code_section_offset: u64) { - let _ = (bodies, code_section_offset); - } - - /// Provides the contents of a function body. - fn define_function_body( - &mut self, - validator: FuncValidator, - body: FunctionBody<'data>, - ) -> WasmResult<()>; - - /// Provides the number of data initializers up front. By default this does nothing, but - /// implementations can use this to preallocate memory if desired. - fn reserve_data_initializers(&mut self, _num: u32) -> WasmResult<()> { - Ok(()) - } - - /// Fills a declared memory with bytes at module instantiation. - fn declare_data_initialization( - &mut self, - memory_index: MemoryIndex, - base: Option, - offset: u64, - data: &'data [u8], - ) -> WasmResult<()>; - - /// Declares the name of a module to the environment. - /// - /// By default this does nothing, but implementations can use this to read - /// the module name subsection of the custom name section if desired. - fn declare_module_name(&mut self, _name: &'data str) {} - - /// Declares the name of a function to the environment. - /// - /// By default this does nothing, but implementations can use this to read - /// the function name subsection of the custom name section if desired. - fn declare_func_name(&mut self, _func_index: FuncIndex, _name: &'data str) {} - - /// Declares the name of a function's local to the environment. - /// - /// By default this does nothing, but implementations can use this to read - /// the local name subsection of the custom name section if desired. - fn declare_local_name(&mut self, _func_index: FuncIndex, _local_index: u32, _name: &'data str) { - } - - /// Indicates that a custom section has been found in the wasm file - fn custom_section(&mut self, _name: &'data str, _data: &'data [u8]) -> WasmResult<()> { - Ok(()) - } - - /// Returns the list of enabled wasm features this translation will be using. - fn wasm_features(&self) -> WasmFeatures { - WasmFeatures::default() - } -} diff --git a/cranelift/wasm/src/func_translator.rs b/crates/cranelift/src/translate/func_translator.rs similarity index 97% rename from cranelift/wasm/src/func_translator.rs rename to crates/cranelift/src/translate/func_translator.rs index d55d7fb38662..733520ae2673 100644 --- a/cranelift/wasm/src/func_translator.rs +++ b/crates/cranelift/src/translate/func_translator.rs @@ -4,16 +4,16 @@ //! function to Cranelift IR guided by a `FuncEnvironment` which provides information about the //! WebAssembly module and the runtime environment. -use crate::code_translator::{bitcast_wasm_returns, translate_operator}; -use crate::environ::FuncEnvironment; -use crate::state::FuncTranslationState; -use crate::translation_utils::get_vmctx_value_label; -use crate::WasmResult; +use crate::translate::code_translator::{bitcast_wasm_returns, translate_operator}; +use crate::translate::environ::FuncEnvironment; +use crate::translate::state::FuncTranslationState; +use crate::translate::translation_utils::get_vmctx_value_label; use cranelift_codegen::entity::EntityRef; use cranelift_codegen::ir::{self, Block, InstBuilder, ValueLabel}; use cranelift_codegen::timing; use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable}; use wasmparser::{BinaryReader, FuncValidator, FunctionBody, WasmModuleResources}; +use wasmtime_environ::WasmResult; /// WebAssembly to Cranelift IR function translator. /// diff --git a/cranelift/wasm/src/heap.rs b/crates/cranelift/src/translate/heap.rs similarity index 90% rename from cranelift/wasm/src/heap.rs rename to crates/cranelift/src/translate/heap.rs index c8adc66727e3..eff81c1e78f2 100644 --- a/cranelift/wasm/src/heap.rs +++ b/crates/cranelift/src/translate/heap.rs @@ -7,10 +7,6 @@ use cranelift_entity::entity_impl; /// /// While the order is stable, it is arbitrary. #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -#[cfg_attr( - feature = "enable-serde", - derive(serde_derive::Serialize, serde_derive::Deserialize) -)] pub struct Heap(u32); entity_impl!(Heap, "heap"); @@ -18,7 +14,7 @@ entity_impl!(Heap, "heap"); /// /// Code compiled from WebAssembly runs in a sandbox where it can't access all /// process memory. Instead, it is given a small set of memory areas to work in, -/// and all accesses are bounds checked. `cranelift-wasm` models this through +/// and all accesses are bounds checked. Wasmtime models this through /// the concept of *heaps*. /// /// Heap addresses can be smaller than the native pointer size, for example @@ -62,10 +58,6 @@ entity_impl!(Heap, "heap"); /// when the heap is resized. The bound of a dynamic heap is stored in a global /// value. #[derive(Clone, PartialEq, Hash)] -#[cfg_attr( - feature = "enable-serde", - derive(serde_derive::Serialize, serde_derive::Deserialize) -)] pub struct HeapData { /// The address of the start of the heap's storage. pub base: GlobalValue, @@ -97,10 +89,6 @@ pub struct HeapData { /// Style of heap including style-specific information. #[derive(Clone, PartialEq, Hash)] -#[cfg_attr( - feature = "enable-serde", - derive(serde_derive::Serialize, serde_derive::Deserialize) -)] pub enum HeapStyle { /// A dynamic heap can be relocated to a different base address when it is /// grown. diff --git a/crates/cranelift/src/translate/mod.rs b/crates/cranelift/src/translate/mod.rs new file mode 100644 index 000000000000..28354827447f --- /dev/null +++ b/crates/cranelift/src/translate/mod.rs @@ -0,0 +1,26 @@ +//! Performs translation from a wasm module in binary format to the in-memory form +//! of Cranelift IR. More particularly, it translates the code of all the functions bodies and +//! interacts with an environment implementing the +//! [`ModuleEnvironment`](trait.ModuleEnvironment.html) +//! trait to deal with tables, globals and linear memory. +//! +//! The main function of this module is [`translate_module`](fn.translate_module.html). +//! +//! Note that this module used to be the `cranelift-wasm` crate historically and +//! it's in a transitionary period of being slurped up into +//! `wasmtime-cranelift`. + +mod code_translator; +mod environ; +mod func_translator; +mod heap; +mod state; +mod table; +mod translation_utils; + +pub use self::environ::{FuncEnvironment, GlobalVariable, StructFieldsVec, TargetEnvironment}; +pub use self::func_translator::FuncTranslator; +pub use self::heap::{Heap, HeapData, HeapStyle}; +pub use self::state::FuncTranslationState; +pub use self::table::{TableData, TableSize}; +pub use self::translation_utils::*; diff --git a/cranelift/wasm/src/state.rs b/crates/cranelift/src/translate/state.rs similarity index 98% rename from cranelift/wasm/src/state.rs rename to crates/cranelift/src/translate/state.rs index d788157f84c7..80ef94dbed86 100644 --- a/cranelift/wasm/src/state.rs +++ b/crates/cranelift/src/translate/state.rs @@ -3,11 +3,12 @@ //! The `FuncTranslationState` struct defined in this module is used to keep track of the WebAssembly //! value and control stacks during the translation of a single function. -use crate::environ::{FuncEnvironment, GlobalVariable}; -use crate::{FuncIndex, GlobalIndex, Heap, MemoryIndex, TypeIndex, WasmResult}; -use crate::{HashMap, Occupied, Vacant}; +use crate::translate::environ::{FuncEnvironment, GlobalVariable}; +use crate::translate::Heap; use cranelift_codegen::ir::{self, Block, Inst, Value}; +use std::collections::hash_map::{Entry::Occupied, Entry::Vacant, HashMap}; use std::vec::Vec; +use wasmtime_environ::{FuncIndex, GlobalIndex, MemoryIndex, TypeIndex, WasmResult}; /// Information about the presence of an associated `else` for an `if`, or the /// lack thereof. @@ -240,7 +241,7 @@ pub struct FuncTranslationState { functions: HashMap, } -// Public methods that are exposed to non-`cranelift_wasm` API consumers. +// Public methods that are exposed to non- API consumers. impl FuncTranslationState { /// True if the current translation state expresses reachable code, false if it is unreachable. #[inline] diff --git a/cranelift/wasm/src/table.rs b/crates/cranelift/src/translate/table.rs similarity index 99% rename from cranelift/wasm/src/table.rs rename to crates/cranelift/src/translate/table.rs index 7d38924a09c9..d70955410597 100644 --- a/cranelift/wasm/src/table.rs +++ b/crates/cranelift/src/translate/table.rs @@ -1,4 +1,4 @@ -use crate::FuncEnvironment; +use crate::translate::FuncEnvironment; use cranelift_codegen::cursor::FuncCursor; use cranelift_codegen::ir::{self, condcodes::IntCC, immediates::Imm64, InstBuilder}; use cranelift_codegen::isa::TargetIsa; diff --git a/cranelift/wasm/src/translation_utils.rs b/crates/cranelift/src/translate/translation_utils.rs similarity index 97% rename from cranelift/wasm/src/translation_utils.rs rename to crates/cranelift/src/translate/translation_utils.rs index 588cfa5c3fce..601c7143cb7b 100644 --- a/cranelift/wasm/src/translation_utils.rs +++ b/crates/cranelift/src/translate/translation_utils.rs @@ -1,10 +1,10 @@ //! Helper functions and structures for the translation. -use crate::environ::TargetEnvironment; -use crate::WasmResult; +use crate::translate::environ::TargetEnvironment; use core::u32; use cranelift_codegen::ir; use cranelift_frontend::FunctionBuilder; use wasmparser::{FuncValidator, WasmModuleResources}; +use wasmtime_environ::WasmResult; /// Get the parameter and result types for the given Wasm blocktype. pub fn blocktype_params_results<'a, T>( diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 7525a359ddc2..f1a571ba355d 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -17,7 +17,6 @@ env_logger = { workspace = true } once_cell = { workspace = true } cranelift-codegen = { workspace = true, features = ["incremental-cache", "x86", "arm64", "s390x", "riscv64"] } cranelift-reader = { workspace = true } -cranelift-wasm = { workspace = true } cranelift-filetests = { workspace = true } cranelift-interpreter = { workspace = true } cranelift-fuzzgen = { workspace = true } diff --git a/scripts/publish.rs b/scripts/publish.rs index c72a1cb600e6..37d45ad5b7d0 100644 --- a/scripts/publish.rs +++ b/scripts/publish.rs @@ -34,7 +34,6 @@ const CRATES_TO_PUBLISH: &[&str] = &[ "cranelift-serde", "cranelift-module", "cranelift-frontend", - "cranelift-wasm", "cranelift-native", "cranelift-object", "cranelift-interpreter", @@ -108,7 +107,6 @@ const PUBLIC_CRATES: &[&str] = &[ "cranelift-serde", "cranelift-module", "cranelift-frontend", - "cranelift-wasm", "cranelift-native", "cranelift-object", "cranelift-interpreter", diff --git a/winch/codegen/src/codegen/mod.rs b/winch/codegen/src/codegen/mod.rs index 0edcd7fc417c..e185a5018ba1 100644 --- a/winch/codegen/src/codegen/mod.rs +++ b/winch/codegen/src/codegen/mod.rs @@ -547,7 +547,7 @@ where /// /// Winch follows almost the same principles as Cranelift when it comes to /// bounds checks, for a more detailed explanation refer to - /// [cranelift_wasm::code_translator::prepare_addr]. + /// prepare_addr in wasmtime-cranelift. /// /// Winch implementation differs in that, it defaults to the general case /// for dynamic heaps rather than optimizing for doing the least amount of