From ee491384083fdcada517342fa8ca3573c3891317 Mon Sep 17 00:00:00 2001 From: Wolfgang Grieskamp Date: Tue, 31 Dec 2024 14:46:16 -0800 Subject: [PATCH] [move-vm][closures] Refactor: move abilities and closure mask into core types [PR 2/n vm closures] The type `AbilitySet` is required in `MoveTypeLayout`, and the type `ClosureMask` in `MoveValue`. This PRs moves those both types from file_format into the core types crate. --- Cargo.lock | 2 - api/types/src/move_types.rs | 7 +- .../src/tests/access_path_test.rs | 4 +- aptos-move/e2e-testsuite/src/tests/scripts.rs | 7 +- aptos-move/framework/src/extended_checks.rs | 3 +- aptos-move/framework/src/module_metadata.rs | 5 +- .../indexer-grpc-fullnode/Cargo.toml | 2 - .../indexer-grpc-fullnode/src/convert.rs | 2 +- .../move/bytecode_verifier_code_unit.rs | 7 +- .../move/bytecode_verifier_mixed.rs | 4 +- .../tests/serializer_tests.rs | 6 +- .../move-binary-format/src/binary_views.rs | 29 +- .../move-binary-format/src/check_bounds.rs | 15 +- .../move-binary-format/src/compatibility.rs | 5 +- .../src/compatibility_legacy.rs | 4 +- .../move-binary-format/src/deserializer.rs | 7 +- .../move-binary-format/src/file_format.rs | 442 +----------------- .../move/move-binary-format/src/normalized.rs | 6 +- .../src/proptest_types/functions.rs | 20 +- .../src/proptest_types/signature.rs | 4 +- .../src/proptest_types/types.rs | 7 +- .../move/move-binary-format/src/serializer.rs | 5 +- .../move/move-binary-format/src/views.rs | 2 +- .../src/unit_tests/dependencies_tests.rs | 3 +- .../src/unit_tests/generic_ops_tests.rs | 5 +- .../src/unit_tests/limit_tests.rs | 3 +- .../src/unit_tests/signature_tests.rs | 3 +- .../src/unit_tests/variant_name_test.rs | 8 +- .../fuzz/fuzz_targets/code_unit.rs | 7 +- .../fuzz/fuzz_targets/mixed.rs | 4 +- .../src/ability_field_requirements.rs | 6 +- .../src/dependencies.rs | 6 +- .../src/instruction_consistency.rs | 6 +- .../src/locals_safety/abstract_state.rs | 3 +- .../src/reference_safety/mod.rs | 7 +- .../regression_tests/reference_analysis.rs | 5 +- .../move-bytecode-verifier/src/signature.rs | 8 +- .../src/signature_v2.rs | 7 +- .../move-bytecode-verifier/src/type_safety.rs | 21 +- .../src/bytecode_generator.rs | 2 +- .../src/env_pipeline/ast_simplifier.rs | 2 +- .../src/env_pipeline/lambda_lifter.rs | 3 +- .../function_generator.rs | 5 +- .../src/pipeline/ability_processor.rs | 4 +- .../move-compiler/src/interface_generator.rs | 11 +- .../move/move-core/types/src/ability.rs | 356 ++++++++++++++ .../move/move-core/types/src/function.rs | 107 +++++ third_party/move/move-core/types/src/lib.rs | 2 + third_party/move/move-core/types/src/value.rs | 31 +- .../src/source_map.rs | 11 +- .../move-ir-to-bytecode/src/compiler.rs | 14 +- .../move-ir-to-bytecode/src/context.rs | 3 +- third_party/move/move-model/src/ast.rs | 4 +- .../src/builder/binary_module_loader.rs | 4 +- .../move/move-model/src/builder/builtins.rs | 8 +- .../move-model/src/builder/exp_builder.rs | 8 +- .../move-model/src/builder/model_builder.rs | 4 +- .../move-model/src/builder/module_builder.rs | 3 +- .../move/move-model/src/exp_rewriter.rs | 2 +- third_party/move/move-model/src/model.rs | 3 +- third_party/move/move-model/src/sourcifier.rs | 5 +- third_party/move/move-model/src/ty.rs | 3 +- .../move-prover/move-abigen/src/abigen.rs | 3 +- .../move-prover/move-docgen/src/docgen.rs | 6 +- .../src/tests/instantiation_tests.rs | 3 +- .../src/tests/loader_tests.rs | 3 +- .../src/tests/module_storage_tests.rs | 2 +- .../src/tests/vm_arguments_tests.rs | 11 +- .../move-vm/runtime/src/loader/function.rs | 6 +- .../runtime/src/runtime_type_checks.rs | 8 +- .../move-vm/test-utils/src/gas_schedule.rs | 5 +- .../types/src/loaded_data/runtime_types.rs | 12 +- .../move-vm/types/src/values/values_impl.rs | 1 - .../move-disassembler/src/disassembler.rs | 15 +- .../move-resource-viewer/src/fat_type.rs | 6 +- .../tools/move-resource-viewer/src/lib.rs | 5 +- 76 files changed, 746 insertions(+), 632 deletions(-) create mode 100644 third_party/move/move-core/types/src/ability.rs create mode 100644 third_party/move/move-core/types/src/function.rs diff --git a/Cargo.lock b/Cargo.lock index 6248ce77ab1d7..db6d8317dfe9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2269,9 +2269,7 @@ dependencies = [ "hex", "hyper 0.14.28", "itertools 0.13.0", - "move-binary-format", "move-core-types", - "move-package", "once_cell", "rand 0.7.3", "regex", diff --git a/api/types/src/move_types.rs b/api/types/src/move_types.rs index 3b0efb62b9bd6..22342761857e0 100644 --- a/api/types/src/move_types.rs +++ b/api/types/src/move_types.rs @@ -8,11 +8,10 @@ use aptos_resource_viewer::{AnnotatedMoveStruct, AnnotatedMoveValue}; use aptos_types::{account_config::CORE_CODE_ADDRESS, event::EventKey, transaction::Module}; use move_binary_format::{ access::ModuleAccess, - file_format::{ - Ability, AbilitySet, CompiledModule, CompiledScript, StructTypeParameter, Visibility, - }, + file_format::{CompiledModule, CompiledScript, StructTypeParameter, Visibility}, }; use move_core_types::{ + ability::{Ability, AbilitySet}, account_address::AccountAddress, identifier::Identifier, language_storage::{ModuleId, StructTag, TypeTag}, @@ -1225,8 +1224,8 @@ pub fn verify_identifier(identifier: &str) -> anyhow::Result<()> { mod tests { use super::*; use aptos_types::account_address::AccountAddress; - use move_binary_format::file_format::AbilitySet; use move_core_types::{ + ability::AbilitySet, identifier::Identifier, language_storage::{StructTag, TypeTag}, }; diff --git a/aptos-move/e2e-move-tests/src/tests/access_path_test.rs b/aptos-move/e2e-move-tests/src/tests/access_path_test.rs index 40fd2e9f5d08c..9805bce7ce9f6 100644 --- a/aptos-move/e2e-move-tests/src/tests/access_path_test.rs +++ b/aptos-move/e2e-move-tests/src/tests/access_path_test.rs @@ -7,7 +7,7 @@ use aptos_types::{ }; use move_binary_format::{ file_format::{ - AbilitySet, AddressIdentifierIndex, Bytecode::*, CodeUnit, Constant, ConstantPoolIndex, + AddressIdentifierIndex, Bytecode::*, CodeUnit, Constant, ConstantPoolIndex, FieldDefinition, FunctionDefinition, FunctionHandle, FunctionHandleIndex, IdentifierIndex, ModuleHandle, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, StructDefInstantiation, StructDefInstantiationIndex, StructDefinition, @@ -16,7 +16,7 @@ use move_binary_format::{ }, CompiledModule, }; -use move_core_types::{identifier::Identifier, vm_status::StatusCode}; +use move_core_types::{ability::AbilitySet, identifier::Identifier, vm_status::StatusCode}; #[test] fn access_path_panic() { diff --git a/aptos-move/e2e-testsuite/src/tests/scripts.rs b/aptos-move/e2e-testsuite/src/tests/scripts.rs index 413b7c845fb0c..f74a4a32f3136 100644 --- a/aptos-move/e2e-testsuite/src/tests/scripts.rs +++ b/aptos-move/e2e-testsuite/src/tests/scripts.rs @@ -9,11 +9,12 @@ use aptos_types::{ transaction::{ExecutionStatus, Script, TransactionStatus}, }; use move_binary_format::file_format::{ - empty_script, Ability, AbilitySet, AddressIdentifierIndex, Bytecode, FunctionHandle, - FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, IdentifierIndex, - ModuleHandle, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, + empty_script, AddressIdentifierIndex, Bytecode, FunctionHandle, FunctionHandleIndex, + FunctionInstantiation, FunctionInstantiationIndex, IdentifierIndex, ModuleHandle, + ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, }; use move_core_types::{ + ability::{Ability, AbilitySet}, identifier::Identifier, language_storage::{StructTag, TypeTag}, vm_status::{StatusCode, StatusCode::LINKER_ERROR}, diff --git a/aptos-move/framework/src/extended_checks.rs b/aptos-move/framework/src/extended_checks.rs index 7af1417403b42..11581b679413e 100644 --- a/aptos-move/framework/src/extended_checks.rs +++ b/aptos-move/framework/src/extended_checks.rs @@ -2,10 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{KnownAttribute, RandomnessAnnotation, RuntimeModuleMetadataV1}; -use move_binary_format::file_format::{Ability, AbilitySet, Visibility}; +use move_binary_format::file_format::Visibility; use move_cli::base::test_validation; use move_compiler::shared::known_attributes; use move_core_types::{ + ability::{Ability, AbilitySet}, account_address::AccountAddress, errmap::{ErrorDescription, ErrorMapping}, identifier::Identifier, diff --git a/aptos-move/framework/src/module_metadata.rs b/aptos-move/framework/src/module_metadata.rs index 262dfb5ec8428..bbbb2ade2ce83 100644 --- a/aptos-move/framework/src/module_metadata.rs +++ b/aptos-move/framework/src/module_metadata.rs @@ -11,12 +11,13 @@ use lru::LruCache; use move_binary_format::{ access::ModuleAccess, file_format::{ - Ability, AbilitySet, CompiledScript, FunctionDefinition, FunctionHandle, IdentifierIndex, - SignatureToken, StructDefinition, StructFieldInformation, StructHandle, TableIndex, + CompiledScript, FunctionDefinition, FunctionHandle, IdentifierIndex, SignatureToken, + StructDefinition, StructFieldInformation, StructHandle, TableIndex, }, CompiledModule, }; use move_core_types::{ + ability::{Ability, AbilitySet}, errmap::ErrorDescription, identifier::{IdentStr, Identifier}, language_storage::{ModuleId, StructTag}, diff --git a/ecosystem/indexer-grpc/indexer-grpc-fullnode/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-fullnode/Cargo.toml index 99587b126974d..6e191e1311f3f 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-fullnode/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-fullnode/Cargo.toml @@ -43,9 +43,7 @@ aptos-runtimes = { workspace = true } aptos-storage-interface = { workspace = true } aptos-types = { workspace = true } -move-binary-format = { workspace = true } move-core-types = { workspace = true } -move-package = { workspace = true } [dev-dependencies] goldenfile = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs index 5c8c0ab670bbe..73439a4978b61 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs @@ -26,7 +26,7 @@ use aptos_protos::{ }; use aptos_types::jwks::jwk::JWK; use hex; -use move_binary_format::file_format::Ability; +use move_core_types::ability::Ability; use std::time::Duration; pub fn convert_move_module_id(move_module_id: &MoveModuleId) -> transaction::MoveModuleId { diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_code_unit.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_code_unit.rs index 2a06bb0ef8be7..a720b1656ebf8 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_code_unit.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_code_unit.rs @@ -5,14 +5,13 @@ #![no_main] use libfuzzer_sys::fuzz_target; use move_binary_format::file_format::{ - empty_module, AbilitySet, CodeUnit, Constant, FieldDefinition, FunctionDefinition, - FunctionHandle, FunctionHandleIndex, IdentifierIndex, ModuleHandleIndex, Signature, - SignatureIndex, + empty_module, CodeUnit, Constant, FieldDefinition, FunctionDefinition, FunctionHandle, + FunctionHandleIndex, IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken::{Address, Bool, U128, U64}, StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, TypeSignature, Visibility, }; -use move_core_types::{account_address::AccountAddress, ident_str}; +use move_core_types::{ability::AbilitySet, account_address::AccountAddress, ident_str}; use utils::helpers::compiled_module_serde; mod utils; diff --git a/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_mixed.rs b/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_mixed.rs index 1cd96135e4586..e54457dfaac1d 100644 --- a/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_mixed.rs +++ b/testsuite/fuzzer/fuzz/fuzz_targets/move/bytecode_verifier_mixed.rs @@ -6,14 +6,14 @@ use arbitrary::Arbitrary; use libfuzzer_sys::fuzz_target; use move_binary_format::file_format::{ - empty_module, AbilitySet, Bytecode, CodeUnit, Constant, FieldDefinition, FunctionDefinition, + empty_module, Bytecode, CodeUnit, Constant, FieldDefinition, FunctionDefinition, FunctionHandle, FunctionHandleIndex, IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, SignatureToken::{Address, Bool}, StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, TypeSignature, Visibility, }; -use move_core_types::{account_address::AccountAddress, ident_str}; +use move_core_types::{ability::AbilitySet, account_address::AccountAddress, ident_str}; use utils::helpers::compiled_module_serde; mod utils; diff --git a/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.rs b/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.rs index b73e5328567a2..c88c5a82c87e1 100644 --- a/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.rs +++ b/third_party/move/move-binary-format/serializer-tests/tests/serializer_tests.rs @@ -6,12 +6,12 @@ use move_binary_format::{ access::ModuleAccess, deserializer::DeserializerConfig, file_format::{ - empty_module, AbilitySet, CompiledModule, FunctionHandle, IdentifierIndex, Signature, - SignatureIndex, SignatureToken, + empty_module, CompiledModule, FunctionHandle, IdentifierIndex, Signature, SignatureIndex, + SignatureToken, }, file_format_common::{IDENTIFIER_SIZE_MAX, VERSION_MAX}, }; -use move_core_types::identifier::Identifier; +use move_core_types::{ability::AbilitySet, identifier::Identifier}; use proptest::prelude::*; proptest! { diff --git a/third_party/move/move-binary-format/src/binary_views.rs b/third_party/move/move-binary-format/src/binary_views.rs index 74c9325c7e2e9..9f6e27dea4597 100644 --- a/third_party/move/move-binary-format/src/binary_views.rs +++ b/third_party/move/move-binary-format/src/binary_views.rs @@ -7,19 +7,20 @@ use crate::{ control_flow_graph::VMControlFlowGraph, errors::{PartialVMError, PartialVMResult}, file_format::{ - AbilitySet, AddressIdentifierIndex, CodeUnit, CompiledScript, Constant, ConstantPoolIndex, - FieldHandle, FieldHandleIndex, FieldInstantiation, FieldInstantiationIndex, - FunctionDefinition, FunctionDefinitionIndex, FunctionHandle, FunctionHandleIndex, - FunctionInstantiation, FunctionInstantiationIndex, IdentifierIndex, ModuleHandle, - ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, StructDefInstantiation, - StructDefInstantiationIndex, StructDefinition, StructDefinitionIndex, StructHandle, - StructHandleIndex, StructVariantHandle, StructVariantHandleIndex, - StructVariantInstantiation, StructVariantInstantiationIndex, VariantFieldHandle, - VariantFieldHandleIndex, VariantFieldInstantiation, VariantFieldInstantiationIndex, + AddressIdentifierIndex, CodeUnit, CompiledScript, Constant, ConstantPoolIndex, FieldHandle, + FieldHandleIndex, FieldInstantiation, FieldInstantiationIndex, FunctionDefinition, + FunctionDefinitionIndex, FunctionHandle, FunctionHandleIndex, FunctionInstantiation, + FunctionInstantiationIndex, IdentifierIndex, ModuleHandle, ModuleHandleIndex, Signature, + SignatureIndex, SignatureToken, StructDefInstantiation, StructDefInstantiationIndex, + StructDefinition, StructDefinitionIndex, StructHandle, StructHandleIndex, + StructVariantHandle, StructVariantHandleIndex, StructVariantInstantiation, + StructVariantInstantiationIndex, VariantFieldHandle, VariantFieldHandleIndex, + VariantFieldInstantiation, VariantFieldInstantiationIndex, }, CompiledModule, }; use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, identifier::{IdentStr, Identifier}, language_storage::ModuleId, @@ -342,7 +343,11 @@ impl<'a> BinaryIndexedView<'a> { TypeParameter(idx) => Ok(constraints[*idx as usize]), Vector(ty) => AbilitySet::polymorphic_abilities(AbilitySet::VECTOR, vec![false], vec![ self.abilities(ty, constraints)?, - ]), + ]) + .map_err(|e| { + PartialVMError::new(StatusCode::VERIFIER_INVARIANT_VIOLATION) + .with_message(e.to_string()) + }), Function(_, _, abilities) => Ok(*abilities), Struct(idx) => { let sh = self.struct_handle_at(*idx); @@ -360,6 +365,10 @@ impl<'a> BinaryIndexedView<'a> { sh.type_parameters.iter().map(|param| param.is_phantom), type_arguments, ) + .map_err(|e| { + PartialVMError::new(StatusCode::VERIFIER_INVARIANT_VIOLATION) + .with_message(e.to_string()) + }) }, } } diff --git a/third_party/move/move-binary-format/src/check_bounds.rs b/third_party/move/move-binary-format/src/check_bounds.rs index 1406085ac4c7a..6f259d57b722e 100644 --- a/third_party/move/move-binary-format/src/check_bounds.rs +++ b/third_party/move/move-binary-format/src/check_bounds.rs @@ -9,18 +9,17 @@ use crate::{ PartialVMError, PartialVMResult, }, file_format::{ - AbilitySet, Bytecode, CodeOffset, CodeUnit, CompiledModule, CompiledScript, Constant, - FieldDefinition, FieldHandle, FieldInstantiation, FunctionDefinition, - FunctionDefinitionIndex, FunctionHandle, FunctionInstantiation, LocalIndex, ModuleHandle, - Signature, SignatureIndex, SignatureToken, StructDefInstantiation, StructDefinition, - StructFieldInformation, StructHandle, StructVariantHandle, StructVariantInstantiation, - TableIndex, TypeParameterIndex, VariantFieldHandle, VariantFieldInstantiation, - VariantIndex, + Bytecode, CodeOffset, CodeUnit, CompiledModule, CompiledScript, Constant, FieldDefinition, + FieldHandle, FieldInstantiation, FunctionDefinition, FunctionDefinitionIndex, + FunctionHandle, FunctionInstantiation, LocalIndex, ModuleHandle, Signature, SignatureIndex, + SignatureToken, StructDefInstantiation, StructDefinition, StructFieldInformation, + StructHandle, StructVariantHandle, StructVariantInstantiation, TableIndex, + TypeParameterIndex, VariantFieldHandle, VariantFieldInstantiation, VariantIndex, }, internals::ModuleIndex, IndexKind, }; -use move_core_types::vm_status::StatusCode; +use move_core_types::{ability::AbilitySet, vm_status::StatusCode}; use std::{ cell::RefCell, collections::{btree_map, BTreeMap}, diff --git a/third_party/move/move-binary-format/src/compatibility.rs b/third_party/move/move-binary-format/src/compatibility.rs index be95e220456e6..3a2c1c4f6b4b2 100644 --- a/third_party/move/move-binary-format/src/compatibility.rs +++ b/third_party/move/move-binary-format/src/compatibility.rs @@ -6,8 +6,7 @@ use crate::{ access::ModuleAccess, errors::{PartialVMError, PartialVMResult}, file_format::{ - AbilitySet, Signature, SignatureToken, StructHandleIndex, StructTypeParameter, - VariantIndex, Visibility, + Signature, SignatureToken, StructHandleIndex, StructTypeParameter, VariantIndex, Visibility, }, file_format_common::VERSION_5, views::{ @@ -15,7 +14,7 @@ use crate::{ }, CompiledModule, }; -use move_core_types::vm_status::StatusCode; +use move_core_types::{ability::AbilitySet, vm_status::StatusCode}; use std::collections::BTreeSet; /// The result of a linking and layout compatibility check. Here is what the different combinations. NOTE that if `check_struct_layout` is false, type safety over a series of upgrades cannot be guaranteed. diff --git a/third_party/move/move-binary-format/src/compatibility_legacy.rs b/third_party/move/move-binary-format/src/compatibility_legacy.rs index 667dc0e09583b..1187d5e5eca6c 100644 --- a/third_party/move/move-binary-format/src/compatibility_legacy.rs +++ b/third_party/move/move-binary-format/src/compatibility_legacy.rs @@ -7,12 +7,12 @@ use crate::{ compatibility, errors::{PartialVMError, PartialVMResult}, - file_format::{AbilitySet, StructTypeParameter, Visibility}, + file_format::{StructTypeParameter, Visibility}, file_format_common::VERSION_5, normalized::Module, }; use compatibility::Compatibility; -use move_core_types::vm_status::StatusCode; +use move_core_types::{ability::AbilitySet, vm_status::StatusCode}; use std::collections::BTreeSet; impl Compatibility { diff --git a/third_party/move/move-binary-format/src/deserializer.rs b/third_party/move/move-binary-format/src/deserializer.rs index 1f8712f994ba6..cb1acace029d9 100644 --- a/third_party/move/move-binary-format/src/deserializer.rs +++ b/third_party/move/move-binary-format/src/deserializer.rs @@ -4,7 +4,12 @@ use crate::{check_bounds::BoundsChecker, errors::*, file_format::*, file_format_common::*}; use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, metadata::Metadata, state::VMState, + ability::{Ability, AbilitySet}, + account_address::AccountAddress, + function::ClosureMask, + identifier::Identifier, + metadata::Metadata, + state::VMState, vm_status::StatusCode, }; use serde::Serialize; diff --git a/third_party/move/move-binary-format/src/file_format.rs b/third_party/move/move-binary-format/src/file_format.rs index 5cd43f451b224..690f1d066dcb2 100644 --- a/third_party/move/move-binary-format/src/file_format.rs +++ b/third_party/move/move-binary-format/src/file_format.rs @@ -31,28 +31,24 @@ use crate::{ access::{ModuleAccess, ScriptAccess}, - errors::{PartialVMError, PartialVMResult}, file_format_common, internals::ModuleIndex, IndexKind, }; use move_bytecode_spec::bytecode_spec; use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, + function::ClosureMask, identifier::{IdentStr, Identifier}, language_storage::ModuleId, metadata::Metadata, - vm_status::StatusCode, }; #[cfg(any(test, feature = "fuzzing"))] use proptest::{collection::vec, prelude::*, strategy::BoxedStrategy}; use ref_cast::RefCast; use serde::{Deserialize, Serialize}; -use std::{ - collections::BTreeMap, - fmt::{self, Formatter}, - ops::BitOr, -}; +use std::fmt; use variant_count::VariantCount; /// Generic index into one of the tables in the binary format. @@ -762,339 +758,6 @@ impl Signature { /// type parameter in the `FunctionHandle` and `StructHandle`. pub type TypeParameterIndex = u16; -/// An `Ability` classifies what operations are permitted for a given type -#[repr(u8)] -#[derive(Debug, Clone, Eq, Copy, Hash, Ord, PartialEq, PartialOrd)] -#[cfg_attr(any(test, feature = "fuzzing"), derive(proptest_derive::Arbitrary))] -#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))] -pub enum Ability { - /// Allows values of types with this ability to be copied, via CopyLoc or ReadRef - Copy = 0x1, - /// Allows values of types with this ability to be dropped, via Pop, WriteRef, StLoc, Eq, Neq, - /// or if left in a local when Ret is invoked - /// Technically also needed for numeric operations (Add, BitAnd, Shift, etc), but all - /// of the types that can be used with those operations have Drop - Drop = 0x2, - /// Allows values of types with this ability to exist inside a struct in global storage - Store = 0x4, - /// Allows the type to serve as a key for global storage operations: MoveTo, MoveFrom, etc. - Key = 0x8, -} - -impl Ability { - fn from_u8(u: u8) -> Option { - match u { - 0x1 => Some(Ability::Copy), - 0x2 => Some(Ability::Drop), - 0x4 => Some(Ability::Store), - 0x8 => Some(Ability::Key), - _ => None, - } - } - - /// For a struct with ability `a`, each field needs to have the ability `a.requires()`. - /// Consider a generic type Foo, for Foo to have ability `a`, Foo must - /// have been declared with `a` and each type argument ti must have the ability `a.requires()` - pub fn requires(self) -> Self { - match self { - Self::Copy => Ability::Copy, - Self::Drop => Ability::Drop, - Self::Store => Ability::Store, - Self::Key => Ability::Store, - } - } - - /// An inverse of `requires`, where x is in a.required_by() iff x.requires() == a - pub fn required_by(self) -> AbilitySet { - match self { - Self::Copy => AbilitySet::EMPTY | Ability::Copy, - Self::Drop => AbilitySet::EMPTY | Ability::Drop, - Self::Store => AbilitySet::EMPTY | Ability::Store | Ability::Key, - Self::Key => AbilitySet::EMPTY, - } - } - - /// Returns an iterator that iterates over all abilities. - pub fn all() -> impl ExactSizeIterator { - use Ability::*; - - [Copy, Drop, Store, Key].into_iter() - } -} - -impl fmt::Display for Ability { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - Ability::Copy => write!(f, "copy"), - Ability::Drop => write!(f, "drop"), - Ability::Store => write!(f, "store"), - Ability::Key => write!(f, "key"), - } - } -} - -/// A set of `Ability`s -#[derive(Clone, Eq, Copy, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] -#[cfg_attr( - feature = "fuzzing", - derive(arbitrary::Arbitrary, dearbitrary::Dearbitrary) -)] -pub struct AbilitySet(u8); - -impl AbilitySet { - /// Ability set containing all abilities - pub const ALL: Self = Self( - // Cannot use AbilitySet bitor because it is not const - (Ability::Copy as u8) - | (Ability::Drop as u8) - | (Ability::Store as u8) - | (Ability::Key as u8), - ); - /// The empty ability set - pub const EMPTY: Self = Self(0); - /// Minimal abilities for all `Functions` - pub const FUNCTIONS: AbilitySet = Self(Ability::Drop as u8); - /// Maximal abilities for all `Functions`. This is used for identity when unifying function types. - pub const MAXIMAL_FUNCTIONS: AbilitySet = Self::PUBLIC_FUNCTIONS; - /// Abilities for `Bool`, `U8`, `U64`, `U128`, and `Address` - pub const PRIMITIVES: AbilitySet = - Self((Ability::Copy as u8) | (Ability::Drop as u8) | (Ability::Store as u8)); - /// Abilities for `private` user-defined/"primitive" functions (not closures). - /// These can be be changed in module upgrades, so should not be stored - pub const PRIVATE_FUNCTIONS: AbilitySet = Self((Ability::Copy as u8) | (Ability::Drop as u8)); - /// Abilities for `public` user-defined/"primitive" functions (not closures) - pub const PUBLIC_FUNCTIONS: AbilitySet = - Self((Ability::Copy as u8) | (Ability::Drop as u8) | (Ability::Store as u8)); - /// Abilities for `Reference` and `MutableReference` - pub const REFERENCES: AbilitySet = Self((Ability::Copy as u8) | (Ability::Drop as u8)); - /// Abilities for `Signer` - pub const SIGNER: AbilitySet = Self(Ability::Drop as u8); - /// Abilities for `Vector`, note they are predicated on the type argument - pub const VECTOR: AbilitySet = - Self((Ability::Copy as u8) | (Ability::Drop as u8) | (Ability::Store as u8)); - - pub fn singleton(ability: Ability) -> Self { - Self(ability as u8) - } - - pub fn is_empty(&self) -> bool { - self.0 == 0 - } - - pub fn iter(&self) -> impl Iterator + '_ { - Ability::all().filter(|a| self.has_ability(*a)) - } - - pub fn has_ability(self, ability: Ability) -> bool { - let a = ability as u8; - (a & self.0) == a - } - - pub fn has_copy(self) -> bool { - self.has_ability(Ability::Copy) - } - - pub fn has_drop(self) -> bool { - self.has_ability(Ability::Drop) - } - - pub fn has_store(self) -> bool { - self.has_ability(Ability::Store) - } - - pub fn has_key(self) -> bool { - self.has_ability(Ability::Key) - } - - #[allow(clippy::should_implement_trait)] - pub fn add(self, ability: Ability) -> Self { - Self(self.0 | ability as u8) - } - - pub fn remove(self, ability: Ability) -> Self { - Self(self.0 & (!(ability as u8))) - } - - pub fn intersect(self, other: Self) -> Self { - Self(self.0 & other.0) - } - - pub fn union(self, other: Self) -> Self { - Self(self.0 | other.0) - } - - pub fn setminus(self, other: Self) -> Self { - Self(self.0 & !other.0) - } - - pub fn requires(self) -> Self { - let mut requires = Self::EMPTY; - - for ability in Ability::all() { - if self.has_ability(ability) { - requires = requires.add(ability.requires()) - } - } - - requires - } - - #[inline] - fn is_subset_bits(sub: u8, sup: u8) -> bool { - (sub & sup) == sub - } - - pub fn is_subset(self, other: Self) -> bool { - Self::is_subset_bits(self.0, other.0) - } - - /// For a polymorphic type, its actual abilities correspond to its declared abilities but - /// predicated on its non-phantom type arguments having that ability. For `Key`, instead of needing - /// the same ability, the type arguments need `Store`. - pub fn polymorphic_abilities( - declared_abilities: Self, - declared_phantom_parameters: I1, - type_arguments: I2, - ) -> PartialVMResult - where - I1: IntoIterator, - I2: IntoIterator, - I1::IntoIter: ExactSizeIterator, - I2::IntoIter: ExactSizeIterator, - { - let declared_phantom_parameters = declared_phantom_parameters.into_iter(); - let type_arguments = type_arguments.into_iter(); - - if declared_phantom_parameters.len() != type_arguments.len() { - return Err( - PartialVMError::new(StatusCode::VERIFIER_INVARIANT_VIOLATION).with_message( - "the length of `declared_phantom_parameters` doesn't match the length of `type_arguments`".to_string(), - ), - ); - } - - // Conceptually this is performing the following operation: - // For any ability 'a' in `declared_abilities` - // 'a' is in the result only if - // for all (abi_i, is_phantom_i) in `type_arguments` s.t. !is_phantom then a.required() is a subset of abi_i - // - // So to do this efficiently, we can determine the required_by set for each ti - // and intersect them together along with the declared abilities - // This only works because for any ability y, |y.requires()| == 1 - let abs = type_arguments - .zip(declared_phantom_parameters) - .filter(|(_, is_phantom)| !is_phantom) - .map(|(ty_arg_abilities, _)| { - ty_arg_abilities - .into_iter() - .map(|a| a.required_by()) - .fold(AbilitySet::EMPTY, AbilitySet::union) - }) - .fold(declared_abilities, |acc, ty_arg_abilities| { - acc.intersect(ty_arg_abilities) - }); - Ok(abs) - } - - pub fn from_u8(byte: u8) -> Option { - // If there is a bit set in the read `byte`, that bit must be set in the - // `AbilitySet` containing all `Ability`s - // This corresponds the byte being a bit set subset of ALL - // The byte is a subset of ALL if the intersection of the two is the original byte - if Self::is_subset_bits(byte, Self::ALL.0) { - Some(Self(byte)) - } else { - None - } - } - - pub fn into_u8(self) -> u8 { - self.0 - } -} - -impl fmt::Display for AbilitySet { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.write_str( - &self - .iter() - .map(|a| a.to_string()) - .reduce(|l, r| format!("{} + {}", l, r)) - .unwrap_or_default(), - ) - } -} - -impl BitOr for AbilitySet { - type Output = Self; - - fn bitor(self, rhs: Ability) -> Self { - AbilitySet(self.0 | (rhs as u8)) - } -} - -impl BitOr for AbilitySet { - type Output = Self; - - fn bitor(self, rhs: Self) -> Self { - AbilitySet(self.0 | rhs.0) - } -} - -pub struct AbilitySetIterator { - set: AbilitySet, - idx: u8, -} - -impl Iterator for AbilitySetIterator { - type Item = Ability; - - fn next(&mut self) -> Option { - while self.idx <= 0x8 { - let next = Ability::from_u8(self.set.0 & self.idx); - self.idx <<= 1; - if next.is_some() { - return next; - } - } - None - } -} - -impl IntoIterator for AbilitySet { - type IntoIter = AbilitySetIterator; - type Item = Ability; - - fn into_iter(self) -> Self::IntoIter { - AbilitySetIterator { - idx: 0x1, - set: self, - } - } -} - -impl std::fmt::Debug for AbilitySet { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - write!(f, "[")?; - for ability in *self { - write!(f, "{:?}, ", ability)?; - } - write!(f, "]") - } -} - -#[cfg(any(test, feature = "fuzzing"))] -impl Arbitrary for AbilitySet { - type Parameters = (); - type Strategy = BoxedStrategy; - - fn arbitrary_with(_params: Self::Parameters) -> Self::Strategy { - proptest::bits::u8::masked(AbilitySet::ALL.0) - .prop_map(|u| AbilitySet::from_u8(u).expect("proptest mask failed for AbilitySet")) - .boxed() - } -} - /// An `AccessSpecifier` describes the resources accessed by a function. /// Here are some examples on source level: /// ```notest @@ -1538,105 +1201,6 @@ impl SignatureToken { } } -/// A `ClosureMask` is a value which determines how to distinguish those function arguments -/// which are captured and which are not when a closure is constructed. For instance, -/// with `_` representing an omitted argument, the mask for `f(a,_,b,_)` would have the argument -/// at index 0 and at index 2 captured. The mask can be used to transform lists of types. -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] -#[cfg_attr(any(test, feature = "fuzzing"), derive(proptest_derive::Arbitrary))] -#[cfg_attr(any(test, feature = "fuzzing"), proptest(no_params))] -#[cfg_attr( - feature = "fuzzing", - derive(arbitrary::Arbitrary), - derive(dearbitrary::Dearbitrary) -)] -pub struct ClosureMask { - pub mask: u64, -} - -impl fmt::Display for ClosureMask { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:b}", self.mask) - } -} - -impl ClosureMask { - pub fn new(mask: u64) -> Self { - Self { mask } - } - - /// Apply a closure mask to a list of elements, returning only those - /// where position `i` is set in the mask (if `collect_captured` is true) or not - /// set (otherwise). - pub fn extract(&self, tys: &[T], collect_captured: bool) -> Vec { - tys.iter() - .enumerate() - .filter_map(|(pos, x)| { - let set = (1 << pos) & self.mask != 0; - if set && collect_captured || !set && !collect_captured { - Some(x.clone()) - } else { - None - } - }) - .collect() - } - - /// Compose two lists of elements into one based on the given mask such that the - /// following holds: - /// ```ignore - /// mask.compose(mask.extract(v, true), mask.extract(v, false)) == v - /// ``` - /// This returns `None` if the provided lists are inconsistent w.r.t the mask - /// and cannot be composed. This should not happen in verified code, but - /// a caller should decide whether to crash or to error. - pub fn compose(&self, captured: &[T], provided: &[T]) -> Option> { - let mut result = BTreeMap::new(); // expect ordered enumeration - let mut cap_idx = 0; - let mut pro_idx = 0; - for i in 0..64 { - if cap_idx >= captured.len() && pro_idx >= provided.len() { - // all covered - break; - } - if (1 << i) & self.mask != 0 { - if cap_idx >= captured.len() { - // Inconsistency - return None; - } - result.insert(i, captured[cap_idx].clone()); - cap_idx += 1 - } else { - if pro_idx >= provided.len() { - // Inconsistency - return None; - } - result.insert(i, provided[pro_idx].clone()); - pro_idx += 1 - } - } - let map_len = result.len(); - let vec = result.into_values().collect::>(); - if vec.len() != map_len { - // Inconsistency: all indices must be contiguously covered - None - } else { - Some(vec) - } - } - - /// Return the max index of captured arguments - pub fn max_captured(&self) -> usize { - let mut i = 0; - let mut mask = self.mask; - while mask != 0 { - mask >>= 1; - i += 1 - } - i - } -} - /// A `Constant` is a serialized value along with its type. That type will be deserialized by the /// loader/evaluator #[derive(Clone, Debug, Eq, PartialEq, Hash)] diff --git a/third_party/move/move-binary-format/src/normalized.rs b/third_party/move/move-binary-format/src/normalized.rs index 4fe5b3508d0fa..d938f8fbcebfe 100644 --- a/third_party/move/move-binary-format/src/normalized.rs +++ b/third_party/move/move-binary-format/src/normalized.rs @@ -8,12 +8,12 @@ use crate::{ access::ModuleAccess, errors::{PartialVMError, PartialVMResult}, file_format::{ - AbilitySet, CompiledModule, FieldDefinition, FunctionDefinition, SignatureToken, - StructDefinition, StructFieldInformation, StructTypeParameter, TypeParameterIndex, - Visibility, + CompiledModule, FieldDefinition, FunctionDefinition, SignatureToken, StructDefinition, + StructFieldInformation, StructTypeParameter, TypeParameterIndex, Visibility, }, }; use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, identifier::{IdentStr, Identifier}, language_storage::{ModuleId, StructTag, TypeTag}, diff --git a/third_party/move/move-binary-format/src/proptest_types/functions.rs b/third_party/move/move-binary-format/src/proptest_types/functions.rs index f614ffcfbb8e6..5d6c07e5d1c69 100644 --- a/third_party/move/move-binary-format/src/proptest_types/functions.rs +++ b/third_party/move/move-binary-format/src/proptest_types/functions.rs @@ -4,15 +4,15 @@ use crate::{ file_format::{ - AbilitySet, AccessSpecifier, Bytecode, CodeOffset, CodeUnit, ConstantPoolIndex, - FieldHandle, FieldHandleIndex, FieldInstantiation, FieldInstantiationIndex, - FunctionDefinition, FunctionHandle, FunctionHandleIndex, FunctionInstantiation, - FunctionInstantiationIndex, IdentifierIndex, LocalIndex, ModuleHandleIndex, Signature, - SignatureIndex, SignatureToken, StructDefInstantiation, StructDefInstantiationIndex, - StructDefinition, StructDefinitionIndex, StructFieldInformation, StructHandle, - StructVariantHandle, StructVariantHandleIndex, StructVariantInstantiation, - StructVariantInstantiationIndex, TableIndex, VariantFieldHandle, VariantFieldHandleIndex, - VariantFieldInstantiation, VariantFieldInstantiationIndex, VariantIndex, Visibility, + AccessSpecifier, Bytecode, CodeOffset, CodeUnit, ConstantPoolIndex, FieldHandle, + FieldHandleIndex, FieldInstantiation, FieldInstantiationIndex, FunctionDefinition, + FunctionHandle, FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, + IdentifierIndex, LocalIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, + StructDefInstantiation, StructDefInstantiationIndex, StructDefinition, + StructDefinitionIndex, StructFieldInformation, StructHandle, StructVariantHandle, + StructVariantHandleIndex, StructVariantInstantiation, StructVariantInstantiationIndex, + TableIndex, VariantFieldHandle, VariantFieldHandleIndex, VariantFieldInstantiation, + VariantFieldInstantiationIndex, VariantIndex, Visibility, }, internals::ModuleIndex, proptest_types::{ @@ -21,7 +21,7 @@ use crate::{ TableSize, }, }; -use move_core_types::u256::U256; +use move_core_types::{ability::AbilitySet, u256::U256}; use proptest::{ collection::{vec, SizeRange}, option::of, diff --git a/third_party/move/move-binary-format/src/proptest_types/signature.rs b/third_party/move/move-binary-format/src/proptest_types/signature.rs index cd9f9d6725f7a..465c4272546cc 100644 --- a/third_party/move/move-binary-format/src/proptest_types/signature.rs +++ b/third_party/move/move-binary-format/src/proptest_types/signature.rs @@ -3,9 +3,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::file_format::{ - Ability, AbilitySet, Signature, SignatureToken, StructHandle, StructHandleIndex, TableIndex, - TypeParameterIndex, + Signature, SignatureToken, StructHandle, StructHandleIndex, TableIndex, TypeParameterIndex, }; +use move_core_types::ability::{Ability, AbilitySet}; use proptest::{ collection::{vec, SizeRange}, prelude::*, diff --git a/third_party/move/move-binary-format/src/proptest_types/types.rs b/third_party/move/move-binary-format/src/proptest_types/types.rs index 161586d503804..e54b0bdb9729c 100644 --- a/third_party/move/move-binary-format/src/proptest_types/types.rs +++ b/third_party/move/move-binary-format/src/proptest_types/types.rs @@ -4,9 +4,9 @@ use crate::{ file_format::{ - AbilitySet, FieldDefinition, IdentifierIndex, ModuleHandleIndex, SignatureToken, - StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, - StructTypeParameter, TableIndex, TypeSignature, VariantDefinition, + FieldDefinition, IdentifierIndex, ModuleHandleIndex, SignatureToken, StructDefinition, + StructFieldInformation, StructHandle, StructHandleIndex, StructTypeParameter, TableIndex, + TypeSignature, VariantDefinition, }, internals::ModuleIndex, proptest_types::{ @@ -14,6 +14,7 @@ use crate::{ signature::{AbilitySetGen, SignatureTokenGen}, }, }; +use move_core_types::ability::AbilitySet; use proptest::{ collection::{vec, SizeRange}, option, diff --git a/third_party/move/move-binary-format/src/serializer.rs b/third_party/move/move-binary-format/src/serializer.rs index fc412a6f0046a..5acf98f46caf5 100644 --- a/third_party/move/move-binary-format/src/serializer.rs +++ b/third_party/move/move-binary-format/src/serializer.rs @@ -18,7 +18,8 @@ use crate::{file_format::*, file_format_common::*}; use anyhow::{anyhow, bail, Result}; use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, metadata::Metadata, + ability::AbilitySet, account_address::AccountAddress, function::ClosureMask, + identifier::Identifier, metadata::Metadata, }; impl CompiledScript { @@ -161,7 +162,7 @@ fn serialize_struct_def_inst_index( } fn serialize_closure_mask(binary: &mut BinaryData, mask: &ClosureMask) -> Result<()> { - write_as_uleb128(binary, mask.mask, u64::MAX) + write_as_uleb128(binary, mask.bits(), u64::MAX) } fn seiralize_table_offset(binary: &mut BinaryData, offset: u32) -> Result<()> { diff --git a/third_party/move/move-binary-format/src/views.rs b/third_party/move/move-binary-format/src/views.rs index 60e3988260782..2280b2fb1212a 100644 --- a/third_party/move/move-binary-format/src/views.rs +++ b/third_party/move/move-binary-format/src/views.rs @@ -13,7 +13,7 @@ //! iterators to aid understanding of the file format and to make it easy to generate views. use crate::{access::ModuleAccess, file_format::*}; -use move_core_types::{identifier::IdentStr, language_storage::ModuleId}; +use move_core_types::{ability::AbilitySet, identifier::IdentStr, language_storage::ModuleId}; use std::{ collections::{BTreeMap, BTreeSet}, iter::DoubleEndedIterator, diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs index 0fb0b54bb01f4..18c5526271907 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/dependencies_tests.rs @@ -4,7 +4,8 @@ use move_binary_format::file_format::*; use move_bytecode_verifier::dependencies; use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, + ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, + vm_status::StatusCode, }; fn mk_script_function_module() -> CompiledModule { diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs index 7808e41642981..a6978e5f99e98 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/generic_ops_tests.rs @@ -5,7 +5,10 @@ use move_binary_format::file_format::*; use move_bytecode_verifier::InstructionConsistency; use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, + ability::{Ability, AbilitySet}, + account_address::AccountAddress, + identifier::Identifier, + vm_status::StatusCode, }; // Make a Module with 2 structs and 2 resources with one field each, and 2 functions. diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/limit_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/limit_tests.rs index 4156b1c567fda..f0584d76b8b84 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/limit_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/limit_tests.rs @@ -6,7 +6,8 @@ use move_bytecode_verifier::{ limits::LimitsVerifier, verify_module_with_config_for_test, VerifierConfig, }; use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, + ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, + vm_status::StatusCode, }; #[test] diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/signature_tests.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/signature_tests.rs index 4010c58543315..2a8c4922a7b50 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/signature_tests.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/signature_tests.rs @@ -10,7 +10,8 @@ use move_bytecode_verifier::{ }; use move_bytecode_verifier_invalid_mutations::signature::{FieldRefMutation, SignatureRefMutation}; use move_core_types::{ - account_address::AccountAddress, identifier::Identifier, vm_status::StatusCode, + ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, + vm_status::StatusCode, }; use proptest::{collection::vec, prelude::*, sample::Index as PropIndex}; diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/variant_name_test.rs b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/variant_name_test.rs index fd936241cd1af..f2aef395f0608 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/variant_name_test.rs +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/src/unit_tests/variant_name_test.rs @@ -3,9 +3,9 @@ use move_binary_format::{ file_format::{ - AbilitySet, AddressIdentifierIndex, FieldDefinition, IdentifierIndex, ModuleHandle, - ModuleHandleIndex, Signature, SignatureToken, StructDefinition, StructFieldInformation, - StructHandle, StructHandleIndex, StructTypeParameter, TypeSignature, VariantDefinition, + AddressIdentifierIndex, FieldDefinition, IdentifierIndex, ModuleHandle, ModuleHandleIndex, + Signature, SignatureToken, StructDefinition, StructFieldInformation, StructHandle, + StructHandleIndex, StructTypeParameter, TypeSignature, VariantDefinition, }, file_format_common::VERSION_7, CompiledModule, @@ -13,7 +13,7 @@ use move_binary_format::{ use move_bytecode_verifier::{ verifier::verify_module_with_config_for_test_with_version, VerifierConfig, }; -use move_core_types::{identifier::Identifier, vm_status::StatusCode}; +use move_core_types::{ability::AbilitySet, identifier::Identifier, vm_status::StatusCode}; /// Tests whether the name of a variant is in bounds. (That is, the IdentifierIndex /// is in bounds of the identifier table.) diff --git a/third_party/move/move-bytecode-verifier/fuzz/fuzz_targets/code_unit.rs b/third_party/move/move-bytecode-verifier/fuzz/fuzz_targets/code_unit.rs index 6000d81ca75d5..589e0c91d188a 100644 --- a/third_party/move/move-bytecode-verifier/fuzz/fuzz_targets/code_unit.rs +++ b/third_party/move/move-bytecode-verifier/fuzz/fuzz_targets/code_unit.rs @@ -4,14 +4,13 @@ #![no_main] use libfuzzer_sys::fuzz_target; use move_binary_format::file_format::{ - empty_module, AbilitySet, CodeUnit, Constant, FieldDefinition, FunctionDefinition, - FunctionHandle, FunctionHandleIndex, IdentifierIndex, ModuleHandleIndex, Signature, - SignatureIndex, + empty_module, CodeUnit, Constant, FieldDefinition, FunctionDefinition, FunctionHandle, + FunctionHandleIndex, IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken::{Address, Bool, U128, U64}, StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, TypeSignature, Visibility, }; -use move_core_types::{account_address::AccountAddress, ident_str}; +use move_core_types::{ability::AbilitySet, account_address::AccountAddress, ident_str}; fuzz_target!(|code_unit: CodeUnit| { let mut module = empty_module(); diff --git a/third_party/move/move-bytecode-verifier/fuzz/fuzz_targets/mixed.rs b/third_party/move/move-bytecode-verifier/fuzz/fuzz_targets/mixed.rs index 5aa9fac8eca4c..062052e72716b 100644 --- a/third_party/move/move-bytecode-verifier/fuzz/fuzz_targets/mixed.rs +++ b/third_party/move/move-bytecode-verifier/fuzz/fuzz_targets/mixed.rs @@ -5,14 +5,14 @@ use arbitrary::Arbitrary; use libfuzzer_sys::fuzz_target; use move_binary_format::file_format::{ - empty_module, AbilitySet, Bytecode, CodeUnit, Constant, FieldDefinition, FunctionDefinition, + empty_module, Bytecode, CodeUnit, Constant, FieldDefinition, FunctionDefinition, FunctionHandle, FunctionHandleIndex, IdentifierIndex, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, SignatureToken::{Address, Bool}, StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, TypeSignature, Visibility, }; -use move_core_types::{account_address::AccountAddress, ident_str}; +use move_core_types::{ability::AbilitySet, account_address::AccountAddress, ident_str}; #[derive(Arbitrary, Debug)] struct Mixed { diff --git a/third_party/move/move-bytecode-verifier/src/ability_field_requirements.rs b/third_party/move/move-bytecode-verifier/src/ability_field_requirements.rs index c4b67c9c87bda..4a5e5cb2fada6 100644 --- a/third_party/move/move-bytecode-verifier/src/ability_field_requirements.rs +++ b/third_party/move/move-bytecode-verifier/src/ability_field_requirements.rs @@ -8,12 +8,10 @@ use move_binary_format::{ access::ModuleAccess, binary_views::BinaryIndexedView, errors::{verification_error, Location, PartialVMResult, VMResult}, - file_format::{ - AbilitySet, CompiledModule, FieldDefinition, StructFieldInformation, TableIndex, - }, + file_format::{CompiledModule, FieldDefinition, StructFieldInformation, TableIndex}, IndexKind, }; -use move_core_types::vm_status::StatusCode; +use move_core_types::{ability::AbilitySet, vm_status::StatusCode}; pub fn verify_module(module: &CompiledModule) -> VMResult<()> { verify_module_impl(module).map_err(|e| e.finish(Location::Module(module.self_id()))) diff --git a/third_party/move/move-bytecode-verifier/src/dependencies.rs b/third_party/move/move-bytecode-verifier/src/dependencies.rs index 8593100e39746..c5bd916da720c 100644 --- a/third_party/move/move-bytecode-verifier/src/dependencies.rs +++ b/third_party/move/move-bytecode-verifier/src/dependencies.rs @@ -8,14 +8,16 @@ use move_binary_format::{ binary_views::BinaryIndexedView, errors::{verification_error, Location, PartialVMError, PartialVMResult, VMResult}, file_format::{ - AbilitySet, Bytecode, CodeOffset, CompiledModule, CompiledScript, FunctionDefinitionIndex, + Bytecode, CodeOffset, CompiledModule, CompiledScript, FunctionDefinitionIndex, FunctionHandleIndex, ModuleHandleIndex, SignatureToken, StructHandleIndex, StructTypeParameter, TableIndex, Visibility, }, file_format_common::VERSION_5, safe_unwrap, IndexKind, }; -use move_core_types::{identifier::Identifier, language_storage::ModuleId, vm_status::StatusCode}; +use move_core_types::{ + ability::AbilitySet, identifier::Identifier, language_storage::ModuleId, vm_status::StatusCode, +}; use std::collections::{BTreeMap, BTreeSet}; struct Context<'a, 'b> { diff --git a/third_party/move/move-bytecode-verifier/src/instruction_consistency.rs b/third_party/move/move-bytecode-verifier/src/instruction_consistency.rs index f42676c89b026..83d4a1f9e1ab6 100644 --- a/third_party/move/move-bytecode-verifier/src/instruction_consistency.rs +++ b/third_party/move/move-bytecode-verifier/src/instruction_consistency.rs @@ -11,12 +11,12 @@ use move_binary_format::{ binary_views::BinaryIndexedView, errors::{Location, PartialVMError, PartialVMResult, VMResult}, file_format::{ - Bytecode, ClosureMask, CodeOffset, CodeUnit, CompiledModule, CompiledScript, - FieldHandleIndex, FunctionDefinitionIndex, FunctionHandleIndex, StructDefinitionIndex, + Bytecode, CodeOffset, CodeUnit, CompiledModule, CompiledScript, FieldHandleIndex, + FunctionDefinitionIndex, FunctionHandleIndex, StructDefinitionIndex, StructVariantHandleIndex, TableIndex, VariantFieldHandleIndex, }, }; -use move_core_types::vm_status::StatusCode; +use move_core_types::{function::ClosureMask, vm_status::StatusCode}; pub struct InstructionConsistency<'a> { resolver: BinaryIndexedView<'a>, diff --git a/third_party/move/move-bytecode-verifier/src/locals_safety/abstract_state.rs b/third_party/move/move-bytecode-verifier/src/locals_safety/abstract_state.rs index 099a679ad7251..677ff6a8662a8 100644 --- a/third_party/move/move-bytecode-verifier/src/locals_safety/abstract_state.rs +++ b/third_party/move/move-bytecode-verifier/src/locals_safety/abstract_state.rs @@ -8,7 +8,7 @@ use crate::absint::{AbstractDomain, JoinResult}; use move_binary_format::{ binary_views::{BinaryIndexedView, FunctionView}, errors::{PartialVMError, PartialVMResult}, - file_format::{AbilitySet, CodeOffset, FunctionDefinitionIndex, LocalIndex}, + file_format::{CodeOffset, FunctionDefinitionIndex, LocalIndex}, }; use move_core_types::vm_status::StatusCode; @@ -24,6 +24,7 @@ pub(crate) enum LocalState { Available, } use crate::meter::{Meter, Scope}; +use move_core_types::ability::AbilitySet; use LocalState::*; pub(crate) const STEP_BASE_COST: u128 = 15; diff --git a/third_party/move/move-bytecode-verifier/src/reference_safety/mod.rs b/third_party/move/move-bytecode-verifier/src/reference_safety/mod.rs index 41e17f5cd66e2..a4b4082032c22 100644 --- a/third_party/move/move-bytecode-verifier/src/reference_safety/mod.rs +++ b/third_party/move/move-bytecode-verifier/src/reference_safety/mod.rs @@ -22,14 +22,13 @@ use move_binary_format::{ binary_views::{BinaryIndexedView, FunctionView}, errors::{PartialVMError, PartialVMResult}, file_format::{ - Bytecode, ClosureMask, CodeOffset, FunctionDefinitionIndex, FunctionHandle, - IdentifierIndex, SignatureIndex, SignatureToken, StructDefinition, StructVariantHandle, - VariantIndex, + Bytecode, CodeOffset, FunctionDefinitionIndex, FunctionHandle, IdentifierIndex, + SignatureIndex, SignatureToken, StructDefinition, StructVariantHandle, VariantIndex, }, safe_assert, safe_unwrap, views::FieldOrVariantIndex, }; -use move_core_types::vm_status::StatusCode; +use move_core_types::{function::ClosureMask, vm_status::StatusCode}; use std::collections::{BTreeSet, HashMap}; struct ReferenceSafetyAnalysis<'a> { diff --git a/third_party/move/move-bytecode-verifier/src/regression_tests/reference_analysis.rs b/third_party/move/move-bytecode-verifier/src/regression_tests/reference_analysis.rs index f2ac68a054591..5ed99efdce9ba 100644 --- a/third_party/move/move-bytecode-verifier/src/regression_tests/reference_analysis.rs +++ b/third_party/move/move-bytecode-verifier/src/regression_tests/reference_analysis.rs @@ -4,7 +4,7 @@ use crate::VerifierConfig; use move_binary_format::{ file_format::{ - empty_module, AbilitySet, AddressIdentifierIndex, + empty_module, AddressIdentifierIndex, Bytecode::{self, *}, CodeUnit, Constant, FieldDefinition, FunctionDefinition, FunctionHandle, FunctionHandleIndex, IdentifierIndex, ModuleHandle, ModuleHandleIndex, Signature, @@ -17,7 +17,8 @@ use move_binary_format::{ CompiledModule, }; use move_core_types::{ - account_address::AccountAddress, ident_str, identifier::Identifier, vm_status::StatusCode, + ability::AbilitySet, account_address::AccountAddress, ident_str, identifier::Identifier, + vm_status::StatusCode, }; #[test] diff --git a/third_party/move/move-bytecode-verifier/src/signature.rs b/third_party/move/move-bytecode-verifier/src/signature.rs index c1cf6358517e4..f8f5ce0c84afc 100644 --- a/third_party/move/move-bytecode-verifier/src/signature.rs +++ b/third_party/move/move-bytecode-verifier/src/signature.rs @@ -10,14 +10,14 @@ use move_binary_format::{ binary_views::BinaryIndexedView, errors::{Location, PartialVMError, PartialVMResult, VMResult}, file_format::{ - AbilitySet, Bytecode, CodeUnit, CompiledModule, CompiledScript, FieldDefinition, - FunctionDefinition, FunctionHandle, Signature, SignatureIndex, SignatureToken, - StructDefinition, StructFieldInformation, StructTypeParameter, TableIndex, + Bytecode, CodeUnit, CompiledModule, CompiledScript, FieldDefinition, FunctionDefinition, + FunctionHandle, Signature, SignatureIndex, SignatureToken, StructDefinition, + StructFieldInformation, StructTypeParameter, TableIndex, }, file_format_common::VERSION_6, IndexKind, }; -use move_core_types::vm_status::StatusCode; +use move_core_types::{ability::AbilitySet, vm_status::StatusCode}; pub struct SignatureChecker<'a> { resolver: BinaryIndexedView<'a>, diff --git a/third_party/move/move-bytecode-verifier/src/signature_v2.rs b/third_party/move/move-bytecode-verifier/src/signature_v2.rs index af1e78e6745ba..46630abd7931e 100644 --- a/third_party/move/move-bytecode-verifier/src/signature_v2.rs +++ b/third_party/move/move-bytecode-verifier/src/signature_v2.rs @@ -6,7 +6,7 @@ use move_binary_format::{ binary_views::BinaryIndexedView, errors::{Location, PartialVMError, PartialVMResult, VMResult}, file_format::{ - Ability, AbilitySet, Bytecode, CodeUnit, CompiledModule, CompiledScript, FieldDefinition, + Bytecode, CodeUnit, CompiledModule, CompiledScript, FieldDefinition, FieldInstantiationIndex, FunctionDefinition, FunctionHandle, FunctionHandleIndex, FunctionInstantiationIndex, SignatureIndex, SignatureToken, StructDefInstantiationIndex, StructDefinition, StructDefinitionIndex, StructFieldInformation, StructHandle, @@ -15,7 +15,10 @@ use move_binary_format::{ }, IndexKind, }; -use move_core_types::vm_status::StatusCode; +use move_core_types::{ + ability::{Ability, AbilitySet}, + vm_status::StatusCode, +}; use std::{ cell::RefCell, collections::{btree_map, BTreeMap}, diff --git a/third_party/move/move-bytecode-verifier/src/type_safety.rs b/third_party/move/move-bytecode-verifier/src/type_safety.rs index cf278862b7c31..4460db1ca343b 100644 --- a/third_party/move/move-bytecode-verifier/src/type_safety.rs +++ b/third_party/move/move-bytecode-verifier/src/type_safety.rs @@ -11,15 +11,18 @@ use move_binary_format::{ control_flow_graph::ControlFlowGraph, errors::{PartialVMError, PartialVMResult}, file_format::{ - Ability, AbilitySet, Bytecode, ClosureMask, CodeOffset, FunctionDefinitionIndex, - FunctionHandle, FunctionHandleIndex, LocalIndex, Signature, SignatureToken, - SignatureToken as ST, StructDefinition, StructDefinitionIndex, StructFieldInformation, - StructHandleIndex, VariantIndex, Visibility, + Bytecode, CodeOffset, FunctionDefinitionIndex, FunctionHandle, FunctionHandleIndex, + LocalIndex, Signature, SignatureToken, SignatureToken as ST, StructDefinition, + StructDefinitionIndex, StructFieldInformation, StructHandleIndex, VariantIndex, Visibility, }, safe_assert, safe_unwrap, views::FieldOrVariantIndex, }; -use move_core_types::vm_status::StatusCode; +use move_core_types::{ + ability::{Ability, AbilitySet}, + function::ClosureMask, + vm_status::StatusCode, +}; struct Locals<'a> { param_count: usize, @@ -357,7 +360,7 @@ fn clos_pack( let param_sign = verifier.resolver.signature_at(func_handle.parameters); let captured_param_tys = mask.extract(¶m_sign.0, true); let mut abilities = AbilitySet::ALL; - for ty in captured_param_tys.iter().rev() { + for ty in captured_param_tys.into_iter().rev() { abilities = abilities.intersect(verifier.abilities(ty)?); let arg = safe_unwrap!(verifier.stack.pop()); if (type_actuals.is_empty() && &arg != ty) @@ -404,7 +407,11 @@ fn clos_pack( verifier.push( meter, instantiate( - &SignatureToken::Function(not_captured_param_tys, ret_sign.0.to_vec(), abilities), + &SignatureToken::Function( + not_captured_param_tys.into_iter().cloned().collect(), + ret_sign.0.to_vec(), + abilities, + ), type_actuals, ), ) diff --git a/third_party/move/move-compiler-v2/src/bytecode_generator.rs b/third_party/move/move-compiler-v2/src/bytecode_generator.rs index cebd84c748329..f42e0177ebb2b 100644 --- a/third_party/move/move-compiler-v2/src/bytecode_generator.rs +++ b/third_party/move/move-compiler-v2/src/bytecode_generator.rs @@ -6,7 +6,7 @@ use crate::{experiments::Experiment, Options}; use codespan_reporting::diagnostic::Severity; use ethnum::U256; use itertools::Itertools; -use move_binary_format::file_format::Ability; +use move_core_types::ability::Ability; use move_model::{ ast::{Exp, ExpData, MatchArm, Operation, Pattern, SpecBlockTarget, TempIndex, Value}, exp_rewriter::{ExpRewriter, ExpRewriterFunctions, RewriteTarget}, diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/ast_simplifier.rs b/third_party/move/move-compiler-v2/src/env_pipeline/ast_simplifier.rs index 98a1b52f95860..ce8db6029356f 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/ast_simplifier.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/ast_simplifier.rs @@ -50,7 +50,7 @@ use codespan_reporting::diagnostic::Severity; use itertools::Itertools; use log::{debug, log_enabled, trace, Level}; -use move_binary_format::file_format::Ability; +use move_core_types::ability::Ability; use move_model::{ ast::{Exp, ExpData, Operation, Pattern, Value, VisitorPosition}, constant_folder::ConstantFolder, diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs b/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs index f3f661ba11f30..7622c2956ea2d 100644 --- a/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs +++ b/third_party/move/move-compiler-v2/src/env_pipeline/lambda_lifter.rs @@ -42,7 +42,8 @@ //! ``` use itertools::Itertools; -use move_binary_format::file_format::{AbilitySet, Visibility}; +use move_binary_format::file_format::Visibility; +use move_core_types::ability::AbilitySet; use move_model::{ ast::{self, Exp, ExpData, LambdaCaptureKind, Operation, Pattern, TempIndex}, exp_rewriter::{ExpRewriter, ExpRewriterFunctions, RewriteTarget}, diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/function_generator.rs b/third_party/move/move-compiler-v2/src/file_format_generator/function_generator.rs index ea383d6298e2f..904e88de4914b 100644 --- a/third_party/move/move-compiler-v2/src/file_format_generator/function_generator.rs +++ b/third_party/move/move-compiler-v2/src/file_format_generator/function_generator.rs @@ -16,6 +16,7 @@ use move_binary_format::{ file_format as FF, file_format::{CodeOffset, FunctionDefinitionIndex}, }; +use move_core_types::ability; use move_model::{ ast::{ExpData, Spec, SpecBlockTarget, TempIndex}, exp_rewriter::{ExpRewriter, ExpRewriterFunctions, RewriteTarget}, @@ -1200,7 +1201,7 @@ impl<'env> FunctionContext<'env> { self.module .env .type_abilities(self.temp_type(temp), &self.type_parameters) - .has_ability(FF::Ability::Copy) + .has_ability(ability::Ability::Copy) } /// Returns true of the given temporary can/should be dropped when flushing the stack. @@ -1208,7 +1209,7 @@ impl<'env> FunctionContext<'env> { self.module .env .type_abilities(self.temp_type(temp), &self.type_parameters) - .has_ability(FF::Ability::Drop) + .has_ability(ability::Ability::Drop) } } diff --git a/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs b/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs index f86b35fbe6e78..4af60ddc3bb70 100644 --- a/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs +++ b/third_party/move/move-compiler-v2/src/pipeline/ability_processor.rs @@ -30,7 +30,8 @@ use crate::pipeline::{ }; use abstract_domain_derive::AbstractDomain; use codespan_reporting::diagnostic::Severity; -use move_binary_format::file_format::{Ability, CodeOffset}; +use move_binary_format::file_format::CodeOffset; +use move_core_types::ability::Ability; use move_model::{ ast::TempIndex, exp_generator::ExpGenerator, @@ -47,7 +48,6 @@ use move_stackless_bytecode::{ stackless_control_flow_graph::StacklessControlFlowGraph, }; use std::collections::BTreeMap; - // ================================================================================================= // Processor diff --git a/third_party/move/move-compiler/src/interface_generator.rs b/third_party/move/move-compiler/src/interface_generator.rs index 8a78305aecc9d..83b0017fbb7b3 100644 --- a/third_party/move/move-compiler/src/interface_generator.rs +++ b/third_party/move/move-compiler/src/interface_generator.rs @@ -7,12 +7,15 @@ use anyhow::{anyhow, Result}; use move_binary_format::{ access::ModuleAccess, file_format::{ - Ability, AbilitySet, CompiledModule, FunctionDefinition, ModuleHandle, SignatureToken, - StructDefinition, StructFieldInformation, StructHandleIndex, StructTypeParameter, - TypeParameterIndex, Visibility, + CompiledModule, FunctionDefinition, ModuleHandle, SignatureToken, StructDefinition, + StructFieldInformation, StructHandleIndex, StructTypeParameter, TypeParameterIndex, + Visibility, }, }; -use move_core_types::language_storage::ModuleId; +use move_core_types::{ + ability::{Ability, AbilitySet}, + language_storage::ModuleId, +}; use std::{collections::BTreeMap, fs}; pub const NATIVE_INTERFACE: &str = "native_interface"; diff --git a/third_party/move/move-core/types/src/ability.rs b/third_party/move/move-core/types/src/ability.rs new file mode 100644 index 0000000000000..b2d30320d26ed --- /dev/null +++ b/third_party/move/move-core/types/src/ability.rs @@ -0,0 +1,356 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::bail; +#[cfg(any(test, feature = "fuzzing"))] +use proptest::{ + arbitrary::Arbitrary, + prelude::{BoxedStrategy, Strategy}, +}; +use serde::{Deserialize, Serialize}; +use std::{fmt, fmt::Formatter, ops::BitOr}; + +/// An `Ability` classifies what operations are permitted for a given type +#[repr(u8)] +#[derive(Debug, Clone, Eq, Copy, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(proptest_derive::Arbitrary))] +#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))] +pub enum Ability { + /// Allows values of types with this ability to be copied, via CopyLoc or ReadRef + Copy = 0x1, + /// Allows values of types with this ability to be dropped, via Pop, WriteRef, StLoc, Eq, Neq, + /// or if left in a local when Ret is invoked + /// Technically also needed for numeric operations (Add, BitAnd, Shift, etc), but all + /// of the types that can be used with those operations have Drop + Drop = 0x2, + /// Allows values of types with this ability to exist inside a struct in global storage + Store = 0x4, + /// Allows the type to serve as a key for global storage operations: MoveTo, MoveFrom, etc. + Key = 0x8, +} + +impl Ability { + fn from_u8(u: u8) -> Option { + match u { + 0x1 => Some(Ability::Copy), + 0x2 => Some(Ability::Drop), + 0x4 => Some(Ability::Store), + 0x8 => Some(Ability::Key), + _ => None, + } + } + + /// For a struct with ability `a`, each field needs to have the ability `a.requires()`. + /// Consider a generic type Foo, for Foo to have ability `a`, Foo must + /// have been declared with `a` and each type argument ti must have the ability `a.requires()` + pub fn requires(self) -> Self { + match self { + Self::Copy => Ability::Copy, + Self::Drop => Ability::Drop, + Self::Store => Ability::Store, + Self::Key => Ability::Store, + } + } + + /// An inverse of `requires`, where x is in a.required_by() iff x.requires() == a + pub fn required_by(self) -> AbilitySet { + match self { + Self::Copy => AbilitySet::EMPTY | Ability::Copy, + Self::Drop => AbilitySet::EMPTY | Ability::Drop, + Self::Store => AbilitySet::EMPTY | Ability::Store | Ability::Key, + Self::Key => AbilitySet::EMPTY, + } + } + + /// Returns an iterator that iterates over all abilities. + pub fn all() -> impl ExactSizeIterator { + use Ability::*; + + [Copy, Drop, Store, Key].into_iter() + } +} + +impl fmt::Display for Ability { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Ability::Copy => write!(f, "copy"), + Ability::Drop => write!(f, "drop"), + Ability::Store => write!(f, "store"), + Ability::Key => write!(f, "key"), + } + } +} + +/// A set of `Ability`s +#[derive(Clone, Eq, Copy, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] +#[cfg_attr( + feature = "fuzzing", + derive(arbitrary::Arbitrary, dearbitrary::Dearbitrary) +)] +pub struct AbilitySet(u8); + +impl AbilitySet { + /// Ability set containing all abilities + pub const ALL: Self = Self( + // Cannot use AbilitySet bitor because it is not const + (Ability::Copy as u8) + | (Ability::Drop as u8) + | (Ability::Store as u8) + | (Ability::Key as u8), + ); + /// The empty ability set + pub const EMPTY: Self = Self(0); + /// Minimal abilities for all `Functions` + pub const FUNCTIONS: AbilitySet = Self(Ability::Drop as u8); + /// Maximal abilities for all `Functions`. This is used for identity when unifying function types. + pub const MAXIMAL_FUNCTIONS: AbilitySet = Self::PUBLIC_FUNCTIONS; + /// Abilities for `Bool`, `U8`, `U64`, `U128`, and `Address` + pub const PRIMITIVES: AbilitySet = + Self((Ability::Copy as u8) | (Ability::Drop as u8) | (Ability::Store as u8)); + /// Abilities for `private` user-defined/"primitive" functions (not closures). + /// These can be be changed in module upgrades, so should not be stored + pub const PRIVATE_FUNCTIONS: AbilitySet = Self((Ability::Copy as u8) | (Ability::Drop as u8)); + /// Abilities for `public` user-defined/"primitive" functions (not closures) + pub const PUBLIC_FUNCTIONS: AbilitySet = + Self((Ability::Copy as u8) | (Ability::Drop as u8) | (Ability::Store as u8)); + /// Abilities for `Reference` and `MutableReference` + pub const REFERENCES: AbilitySet = Self((Ability::Copy as u8) | (Ability::Drop as u8)); + /// Abilities for `Signer` + pub const SIGNER: AbilitySet = Self(Ability::Drop as u8); + /// Abilities for `Vector`, note they are predicated on the type argument + pub const VECTOR: AbilitySet = + Self((Ability::Copy as u8) | (Ability::Drop as u8) | (Ability::Store as u8)); + + /// Create a representation as a display postfix if the ability set is not empty. + pub fn display_postfix(&self) -> String { + if self.is_empty() { + "".to_string() + } else { + format!(" has {}", self) + } + } + + pub fn singleton(ability: Ability) -> Self { + Self(ability as u8) + } + + pub fn is_empty(&self) -> bool { + self.0 == 0 + } + + pub fn iter(&self) -> impl Iterator + '_ { + Ability::all().filter(|a| self.has_ability(*a)) + } + + pub fn has_ability(self, ability: Ability) -> bool { + let a = ability as u8; + (a & self.0) == a + } + + pub fn has_copy(self) -> bool { + self.has_ability(Ability::Copy) + } + + pub fn has_drop(self) -> bool { + self.has_ability(Ability::Drop) + } + + pub fn has_store(self) -> bool { + self.has_ability(Ability::Store) + } + + pub fn has_key(self) -> bool { + self.has_ability(Ability::Key) + } + + #[allow(clippy::should_implement_trait)] + pub fn add(self, ability: Ability) -> Self { + Self(self.0 | ability as u8) + } + + pub fn remove(self, ability: Ability) -> Self { + Self(self.0 & (!(ability as u8))) + } + + pub fn intersect(self, other: Self) -> Self { + Self(self.0 & other.0) + } + + pub fn union(self, other: Self) -> Self { + Self(self.0 | other.0) + } + + pub fn setminus(self, other: Self) -> Self { + Self(self.0 & !other.0) + } + + pub fn requires(self) -> Self { + let mut requires = Self::EMPTY; + + for ability in Ability::all() { + if self.has_ability(ability) { + requires = requires.add(ability.requires()) + } + } + + requires + } + + #[inline] + fn is_subset_bits(sub: u8, sup: u8) -> bool { + (sub & sup) == sub + } + + pub fn is_subset(self, other: Self) -> bool { + Self::is_subset_bits(self.0, other.0) + } + + /// For a polymorphic type, its actual abilities correspond to its declared abilities but + /// predicated on its non-phantom type arguments having that ability. For `Key`, instead of needing + /// the same ability, the type arguments need `Store`. + pub fn polymorphic_abilities( + declared_abilities: Self, + declared_phantom_parameters: I1, + type_arguments: I2, + ) -> anyhow::Result + where + I1: IntoIterator, + I2: IntoIterator, + I1::IntoIter: ExactSizeIterator, + I2::IntoIter: ExactSizeIterator, + { + let declared_phantom_parameters = declared_phantom_parameters.into_iter(); + let type_arguments = type_arguments.into_iter(); + + if declared_phantom_parameters.len() != type_arguments.len() { + bail!("the length of `declared_phantom_parameters` doesn't match the length of `type_arguments`") + /* + return Err( + PartialVMError::new(StatusCode::VERIFIER_INVARIANT_VIOLATION).with_message( + "the length of `declared_phantom_parameters` doesn't match the length of `type_arguments`".to_string(), + ), + ); + */ + } + + // Conceptually this is performing the following operation: + // For any ability 'a' in `declared_abilities` + // 'a' is in the result only if + // for all (abi_i, is_phantom_i) in `type_arguments` s.t. !is_phantom then a.required() is a subset of abi_i + // + // So to do this efficiently, we can determine the required_by set for each ti + // and intersect them together along with the declared abilities + // This only works because for any ability y, |y.requires()| == 1 + let abs = type_arguments + .zip(declared_phantom_parameters) + .filter(|(_, is_phantom)| !is_phantom) + .map(|(ty_arg_abilities, _)| { + ty_arg_abilities + .into_iter() + .map(|a| a.required_by()) + .fold(AbilitySet::EMPTY, AbilitySet::union) + }) + .fold(declared_abilities, |acc, ty_arg_abilities| { + acc.intersect(ty_arg_abilities) + }); + Ok(abs) + } + + pub fn from_u8(byte: u8) -> Option { + // If there is a bit set in the read `byte`, that bit must be set in the + // `AbilitySet` containing all `Ability`s + // This corresponds the byte being a bit set subset of ALL + // The byte is a subset of ALL if the intersection of the two is the original byte + if Self::is_subset_bits(byte, Self::ALL.0) { + Some(Self(byte)) + } else { + None + } + } + + pub fn into_u8(self) -> u8 { + self.0 + } +} + +impl fmt::Display for AbilitySet { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str( + &self + .iter() + .map(|a| a.to_string()) + .reduce(|l, r| format!("{} + {}", l, r)) + .unwrap_or_default(), + ) + } +} + +impl BitOr for AbilitySet { + type Output = Self; + + fn bitor(self, rhs: Ability) -> Self { + AbilitySet(self.0 | (rhs as u8)) + } +} + +impl BitOr for AbilitySet { + type Output = Self; + + fn bitor(self, rhs: Self) -> Self { + AbilitySet(self.0 | rhs.0) + } +} + +pub struct AbilitySetIterator { + set: AbilitySet, + idx: u8, +} + +impl Iterator for AbilitySetIterator { + type Item = Ability; + + fn next(&mut self) -> Option { + while self.idx <= 0x8 { + let next = Ability::from_u8(self.set.0 & self.idx); + self.idx <<= 1; + if next.is_some() { + return next; + } + } + None + } +} + +impl IntoIterator for AbilitySet { + type IntoIter = AbilitySetIterator; + type Item = Ability; + + fn into_iter(self) -> Self::IntoIter { + AbilitySetIterator { + idx: 0x1, + set: self, + } + } +} + +impl fmt::Debug for AbilitySet { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + write!(f, "[")?; + for ability in *self { + write!(f, "{:?}, ", ability)?; + } + write!(f, "]") + } +} + +#[cfg(any(test, feature = "fuzzing"))] +impl Arbitrary for AbilitySet { + type Parameters = (); + type Strategy = BoxedStrategy; + + fn arbitrary_with(_params: Self::Parameters) -> Self::Strategy { + proptest::bits::u8::masked(AbilitySet::ALL.0) + .prop_map(|u| AbilitySet::from_u8(u).expect("proptest mask failed for AbilitySet")) + .boxed() + } +} diff --git a/third_party/move/move-core/types/src/function.rs b/third_party/move/move-core/types/src/function.rs new file mode 100644 index 0000000000000..aba217289b5c7 --- /dev/null +++ b/third_party/move/move-core/types/src/function.rs @@ -0,0 +1,107 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// A `ClosureMask` is a value which determines how to distinguish those function arguments +/// which are captured and which are not when a closure is constructed. For instance, +/// with `_` representing an omitted argument, the mask for `f(a,_,b,_)` would have the argument +/// at index 0 and at index 2 captured. The mask can be used to transform lists of types. +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "fuzzing"), derive(proptest_derive::Arbitrary))] +#[cfg_attr(any(test, feature = "fuzzing"), proptest(no_params))] +#[cfg_attr( + feature = "fuzzing", + derive(arbitrary::Arbitrary), + derive(dearbitrary::Dearbitrary) +)] +pub struct ClosureMask(u64); + +impl fmt::Display for ClosureMask { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:b}", self.0) + } +} + +impl ClosureMask { + pub const MAX_ARGS: usize = 64; + + pub fn new(mask: u64) -> Self { + Self(mask) + } + + pub fn bits(&self) -> u64 { + self.0 + } + + /// Apply a closure mask to a list of elements, returning only those + /// where position `i` is set in the mask (if `collect_captured` is true) or not + /// set (otherwise). + pub fn extract<'a, T>(&self, values: &'a [T], collect_captured: bool) -> Vec<&'a T> { + let mut mask = self.0; + values + .iter() + .filter(|_| { + let set = mask & 0x1 != 0; + mask >>= 1; + set && collect_captured || !set && !collect_captured + }) + .collect() + } + + /// Compose two lists of elements into one based on the given mask such that the + /// following holds: + /// ```ignore + /// mask.compose(mask.extract(v, true), mask.extract(v, false)) == v + /// ``` + /// This returns `None` if the provided lists are inconsistent w.r.t the mask + /// and cannot be composed. This should not happen in verified code, but + /// a caller should decide whether to crash or to error. + pub fn compose( + &self, + captured: impl IntoIterator, + provided: impl IntoIterator, + ) -> Option> { + let mut captured = captured.into_iter(); + let mut provided = provided.into_iter(); + let mut result = vec![]; + let mut mask = self.0; + while mask != 0 { + if mask & 0x1 != 0 { + result.push(captured.next()?) + } else { + result.push(provided.next()?) + } + mask >>= 1; + } + if captured.next().is_some() { + // Not all captured arguments consumed + return None; + } + result.extend(provided); + Some(result) + } + + /// Return the max index of captured arguments + pub fn max_captured(&self) -> usize { + let mut i = 0; + let mut mask = self.0; + while mask != 0 { + mask >>= 1; + i += 1 + } + i + } + + pub fn merge_placeholder_strings( + &self, + arity: usize, + captured: Vec, + ) -> Option> { + let provided = (0..arity - captured.len()) + .map(|_| "_".to_string()) + .collect::>(); + self.compose(captured, provided) + } +} diff --git a/third_party/move/move-core/types/src/lib.rs b/third_party/move/move-core/types/src/lib.rs index abcda6742d674..c6cad8c3772fc 100644 --- a/third_party/move/move-core/types/src/lib.rs +++ b/third_party/move/move-core/types/src/lib.rs @@ -5,9 +5,11 @@ //! Core types for Move. pub mod abi; +pub mod ability; pub mod account_address; pub mod effects; pub mod errmap; +pub mod function; pub mod gas_algebra; pub mod identifier; pub mod language_storage; diff --git a/third_party/move/move-core/types/src/value.rs b/third_party/move/move-core/types/src/value.rs index de4ef817e4832..18c7d10872230 100644 --- a/third_party/move/move-core/types/src/value.rs +++ b/third_party/move/move-core/types/src/value.rs @@ -2,6 +2,11 @@ // Copyright (c) The Move Contributors // SPDX-License-Identifier: Apache-2.0 +// The below is to deal with a strange problem with derive(Dearbitrary), which creates warnings +// of unused variables in derived code which cannot be turned off by applying the attribute +// just at the type in question. (Here, MoveStructLayout.) +#![allow(unused_variables)] + use crate::{ account_address::AccountAddress, identifier::Identifier, @@ -118,7 +123,10 @@ pub enum MoveValue { /// A layout associated with a named field #[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialEq, Eq)] -#[cfg_attr(any(test, feature = "fuzzing"), derive(arbitrary::Arbitrary))] +#[cfg_attr( + any(test, feature = "fuzzing"), + derive(arbitrary::Arbitrary, dearbitrary::Dearbitrary) +)] pub struct MoveFieldLayout { pub name: Identifier, pub layout: MoveTypeLayout, @@ -131,14 +139,20 @@ impl MoveFieldLayout { } #[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialEq, Eq)] -#[cfg_attr(any(test, feature = "fuzzing"), derive(arbitrary::Arbitrary))] +#[cfg_attr( + any(test, feature = "fuzzing"), + derive(arbitrary::Arbitrary, dearbitrary::Dearbitrary) +)] pub struct MoveVariantLayout { pub name: Identifier, pub fields: Vec, } #[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialEq, Eq)] -#[cfg_attr(any(test, feature = "fuzzing"), derive(arbitrary::Arbitrary))] +#[cfg_attr( + any(test, feature = "fuzzing"), + derive(arbitrary::Arbitrary, dearbitrary::Dearbitrary) +)] pub enum MoveStructLayout { /// The representation used by the MoveVM for plain structs Runtime(Vec), @@ -158,7 +172,10 @@ pub enum MoveStructLayout { /// Used to distinguish between aggregators ans snapshots. #[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialEq, Eq)] -#[cfg_attr(any(test, feature = "fuzzing"), derive(arbitrary::Arbitrary))] +#[cfg_attr( + any(test, feature = "fuzzing"), + derive(arbitrary::Arbitrary, dearbitrary::Dearbitrary) +)] pub enum IdentifierMappingKind { Aggregator, Snapshot, @@ -166,7 +183,11 @@ pub enum IdentifierMappingKind { } #[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialEq, Eq)] -#[cfg_attr(any(test, feature = "fuzzing"), derive(arbitrary::Arbitrary))] +#[cfg_attr( + any(test, feature = "fuzzing"), + derive(arbitrary::Arbitrary), + derive(dearbitrary::Dearbitrary) +)] pub enum MoveTypeLayout { #[serde(rename(serialize = "bool", deserialize = "bool"))] Bool, diff --git a/third_party/move/move-ir-compiler/move-bytecode-source-map/src/source_map.rs b/third_party/move/move-ir-compiler/move-bytecode-source-map/src/source_map.rs index 4f0b3364d55dc..485d81b210454 100644 --- a/third_party/move/move-ir-compiler/move-bytecode-source-map/src/source_map.rs +++ b/third_party/move/move-ir-compiler/move-bytecode-source-map/src/source_map.rs @@ -7,13 +7,15 @@ use move_binary_format::{ access::ModuleAccess, binary_views::BinaryIndexedView, file_format::{ - AbilitySet, CodeOffset, CodeUnit, ConstantPoolIndex, FunctionDefinitionIndex, LocalIndex, - MemberCount, ModuleHandleIndex, SignatureIndex, StructDefinition, StructDefinitionIndex, - TableIndex, VariantIndex, + CodeOffset, CodeUnit, ConstantPoolIndex, FunctionDefinitionIndex, LocalIndex, MemberCount, + ModuleHandleIndex, SignatureIndex, StructDefinition, StructDefinitionIndex, TableIndex, + VariantIndex, }, }; use move_command_line_common::files::FileHash; -use move_core_types::{account_address::AccountAddress, identifier::Identifier}; +use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, +}; use move_ir_types::{ ast::{ConstantName, ModuleIdent, ModuleName, NopLabel}, location::Loc, @@ -21,7 +23,6 @@ use move_ir_types::{ use move_symbol_pool::Symbol; use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, ops::Bound}; - //*************************************************************************** // Source location mapping //*************************************************************************** diff --git a/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/compiler.rs b/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/compiler.rs index c2be4e3537147..242c6d7e00cf5 100644 --- a/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/compiler.rs +++ b/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/compiler.rs @@ -6,16 +6,18 @@ use crate::context::{CompiledDependency, Context, MaterializedPools, TABLE_MAX_S use anyhow::{bail, format_err, Result}; use move_binary_format::{ file_format::{ - Ability, AbilitySet, Bytecode, CodeOffset, CodeUnit, CompiledModule, CompiledScript, - Constant, FieldDefinition, FunctionDefinition, FunctionSignature, ModuleHandle, Signature, - SignatureToken, StructDefinition, StructDefinitionIndex, StructFieldInformation, - StructHandleIndex, StructTypeParameter, TableIndex, TypeParameterIndex, TypeSignature, - Visibility, + Bytecode, CodeOffset, CodeUnit, CompiledModule, CompiledScript, Constant, FieldDefinition, + FunctionDefinition, FunctionSignature, ModuleHandle, Signature, SignatureToken, + StructDefinition, StructDefinitionIndex, StructFieldInformation, StructHandleIndex, + StructTypeParameter, TableIndex, TypeParameterIndex, TypeSignature, Visibility, }, file_format_common::VERSION_DEFAULT, }; use move_bytecode_source_map::source_map::SourceMap; -use move_core_types::value::{MoveTypeLayout, MoveValue}; +use move_core_types::{ + ability::{Ability, AbilitySet}, + value::{MoveTypeLayout, MoveValue}, +}; use move_ir_types::{ ast::{self, Bytecode as IRBytecode, Bytecode_ as IRBytecode_, *}, sp, diff --git a/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/context.rs b/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/context.rs index c29d923504085..46302f9d648b2 100644 --- a/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/context.rs +++ b/third_party/move/move-ir-compiler/move-ir-to-bytecode/src/context.rs @@ -6,7 +6,7 @@ use anyhow::{bail, format_err, Result}; use move_binary_format::{ access::ModuleAccess, file_format::{ - AbilitySet, AddressIdentifierIndex, CodeOffset, Constant, ConstantPoolIndex, FieldHandle, + AddressIdentifierIndex, CodeOffset, Constant, ConstantPoolIndex, FieldHandle, FieldHandleIndex, FieldInstantiation, FieldInstantiationIndex, FunctionDefinitionIndex, FunctionHandle, FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, FunctionSignature, IdentifierIndex, ModuleHandle, ModuleHandleIndex, Signature, @@ -17,6 +17,7 @@ use move_binary_format::{ }; use move_bytecode_source_map::source_map::SourceMap; use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, identifier::{IdentStr, Identifier}, }; diff --git a/third_party/move/move-model/src/ast.rs b/third_party/move/move-model/src/ast.rs index 7c5e120fd9de7..2ed4d52fbf9ae 100644 --- a/third_party/move/move-model/src/ast.rs +++ b/third_party/move/move-model/src/ast.rs @@ -19,9 +19,9 @@ use internment::LocalIntern; use itertools::{EitherOrBoth, Itertools}; use move_binary_format::{ file_format, - file_format::{AbilitySet, CodeOffset, Visibility}, + file_format::{CodeOffset, Visibility}, }; -use move_core_types::account_address::AccountAddress; +use move_core_types::{ability::AbilitySet, account_address::AccountAddress}; use num::BigInt; use std::{ borrow::Borrow, diff --git a/third_party/move/move-model/src/builder/binary_module_loader.rs b/third_party/move/move-model/src/builder/binary_module_loader.rs index 177f9b36cf4ed..0e3257929b187 100644 --- a/third_party/move/move-model/src/builder/binary_module_loader.rs +++ b/third_party/move/move-model/src/builder/binary_module_loader.rs @@ -18,7 +18,7 @@ use crate::{ use itertools::Itertools; use move_binary_format::{ file_format::{ - AbilitySet, FunctionDefinitionIndex, FunctionHandleIndex, MemberCount, SignatureToken, + FunctionDefinitionIndex, FunctionHandleIndex, MemberCount, SignatureToken, StructDefinitionIndex, StructHandleIndex, TableIndex, VariantIndex, Visibility, }, internals::ModuleIndex, @@ -29,7 +29,7 @@ use move_binary_format::{ CompiledModule, }; use move_bytecode_source_map::source_map::{SourceMap, SourceName}; -use move_core_types::{account_address::AccountAddress, language_storage}; +use move_core_types::{ability::AbilitySet, account_address::AccountAddress, language_storage}; use std::collections::BTreeMap; impl GlobalEnv { diff --git a/third_party/move/move-model/src/builder/builtins.rs b/third_party/move/move-model/src/builder/builtins.rs index 359a321a58d55..af14179e8e542 100644 --- a/third_party/move/move-model/src/builder/builtins.rs +++ b/third_party/move/move-model/src/builder/builtins.rs @@ -10,9 +10,11 @@ use crate::{ model::{Parameter, TypeParameter, TypeParameterKind}, ty::{Constraint, PrimitiveType, ReferenceKind, Type}, }; -use move_binary_format::file_format::{Ability, AbilitySet}; -use move_compiler::parser::ast::{self as PA}; -use move_core_types::u256::U256; +use move_compiler::parser::ast as PA; +use move_core_types::{ + ability::{Ability, AbilitySet}, + u256::U256, +}; use num::BigInt; use std::collections::BTreeMap; diff --git a/third_party/move/move-model/src/builder/exp_builder.rs b/third_party/move/move-model/src/builder/exp_builder.rs index f91e4dd28bd9f..b515e254d0899 100644 --- a/third_party/move/move-model/src/builder/exp_builder.rs +++ b/third_party/move/move-model/src/builder/exp_builder.rs @@ -29,7 +29,7 @@ use crate::{ }; use codespan_reporting::diagnostic::Severity; use itertools::Itertools; -use move_binary_format::file_format::{self, Ability, AbilitySet}; +use move_binary_format::file_format::{self}; use move_compiler::{ expansion::ast::{self as EA, Exp_}, hlir::ast as HA, @@ -37,7 +37,11 @@ use move_compiler::{ parser::ast::{self as PA, CallKind, Field}, shared::{unique_map::UniqueMap, Identifier, Name}, }; -use move_core_types::{account_address::AccountAddress, value::MoveValue}; +use move_core_types::{ + ability::{Ability, AbilitySet}, + account_address::AccountAddress, + value::MoveValue, +}; use move_ir_types::{ location::{sp, Spanned}, sp, diff --git a/third_party/move/move-model/src/builder/model_builder.rs b/third_party/move/move-model/src/builder/model_builder.rs index 55c3b34520c19..365b5641e0c1e 100644 --- a/third_party/move/move-model/src/builder/model_builder.rs +++ b/third_party/move/move-model/src/builder/model_builder.rs @@ -21,9 +21,9 @@ use crate::{ }; use codespan_reporting::diagnostic::Severity; use itertools::Itertools; -use move_binary_format::file_format::{AbilitySet, Visibility}; +use move_binary_format::file_format::Visibility; use move_compiler::{expansion::ast as EA, parser::ast as PA, shared::NumericalAddress}; -use move_core_types::account_address::AccountAddress; +use move_core_types::{ability::AbilitySet, account_address::AccountAddress}; use std::collections::{BTreeMap, BTreeSet}; /// A builder is used to enter a sequence of modules in acyclic dependency order into the model. The diff --git a/third_party/move/move-model/src/builder/module_builder.rs b/third_party/move/move-model/src/builder/module_builder.rs index 048b68444e709..6be654e3353fc 100644 --- a/third_party/move/move-model/src/builder/module_builder.rs +++ b/third_party/move/move-model/src/builder/module_builder.rs @@ -38,7 +38,7 @@ use codespan_reporting::diagnostic::Severity; use itertools::Itertools; use move_binary_format::{ access::ModuleAccess, - file_format::{Ability, AbilitySet, Constant, Visibility}, + file_format::{Constant, Visibility}, CompiledModule, }; use move_bytecode_source_map::source_map::SourceMap; @@ -48,6 +48,7 @@ use move_compiler::{ parser::ast as PA, shared::{unique_map::UniqueMap, Identifier, Name}, }; +use move_core_types::ability::{Ability, AbilitySet}; use move_ir_types::{ ast::ConstantName, location::{sp, Spanned}, diff --git a/third_party/move/move-model/src/exp_rewriter.rs b/third_party/move/move-model/src/exp_rewriter.rs index af93e0e72553f..ca704a96488c2 100644 --- a/third_party/move/move-model/src/exp_rewriter.rs +++ b/third_party/move/move-model/src/exp_rewriter.rs @@ -14,7 +14,7 @@ use crate::{ }; use codespan_reporting::diagnostic::Severity; use itertools::Itertools; -use move_binary_format::file_format::AbilitySet; +use move_core_types::ability::AbilitySet; use std::collections::{BTreeMap, BTreeSet}; /// Rewriter for expressions, allowing to substitute locals by expressions as well as instantiate diff --git a/third_party/move/move-model/src/model.rs b/third_party/move/move-model/src/model.rs index 175923e0dade2..99427f3e6e68f 100644 --- a/third_party/move/move-model/src/model.rs +++ b/third_party/move/move-model/src/model.rs @@ -45,7 +45,7 @@ use codespan_reporting::{ use itertools::Itertools; #[allow(unused_imports)] use log::{debug, info, warn}; -pub use move_binary_format::file_format::{AbilitySet, Visibility}; +pub use move_binary_format::file_format::Visibility; #[allow(deprecated)] use move_binary_format::normalized::Type as MType; use move_binary_format::{ @@ -64,6 +64,7 @@ use move_command_line_common::{ address::NumericalAddress, env::read_bool_env_var, files::FileHash, }; use move_compiler::command_line as cli; +pub use move_core_types::ability::AbilitySet; use move_core_types::{ account_address::AccountAddress, identifier::{IdentStr, Identifier}, diff --git a/third_party/move/move-model/src/sourcifier.rs b/third_party/move/move-model/src/sourcifier.rs index fb5e2754c9d7c..08a360e401357 100644 --- a/third_party/move/move-model/src/sourcifier.rs +++ b/third_party/move/move-model/src/sourcifier.rs @@ -11,14 +11,15 @@ use crate::{ emit, emitln, exp_builder::ExpBuilder, model::{ - AbilitySet, FieldEnv, FunId, FunctionEnv, GlobalEnv, ModuleId, NodeId, Parameter, - QualifiedId, QualifiedInstId, StructId, TypeParameter, Visibility, + FieldEnv, FunId, FunctionEnv, GlobalEnv, ModuleId, NodeId, Parameter, QualifiedId, + QualifiedInstId, StructId, TypeParameter, Visibility, }, symbol::Symbol, ty::{PrimitiveType, ReferenceKind, Type, TypeDisplayContext}, }; use itertools::Itertools; use move_binary_format::file_format::AccessKind; +use move_core_types::ability::AbilitySet; use std::collections::BTreeMap; // // ======================================================================================== diff --git a/third_party/move/move-model/src/ty.rs b/third_party/move/move-model/src/ty.rs index 6da025ea9c482..08079025c9cb1 100644 --- a/third_party/move/move-model/src/ty.rs +++ b/third_party/move/move-model/src/ty.rs @@ -18,11 +18,12 @@ use itertools::Itertools; use move_binary_format::normalized::Type as MType; use move_binary_format::{ access::ModuleAccess, - file_format::{Ability, AbilitySet, SignatureToken, TypeParameterIndex}, + file_format::{SignatureToken, TypeParameterIndex}, views::StructHandleView, CompiledModule, }; use move_core_types::{ + ability::{Ability, AbilitySet}, language_storage::{StructTag, TypeTag}, u256::U256, }; diff --git a/third_party/move/move-prover/move-abigen/src/abigen.rs b/third_party/move/move-prover/move-abigen/src/abigen.rs index c4af6d2ae4e4a..33d3ce46deda8 100644 --- a/third_party/move/move-prover/move-abigen/src/abigen.rs +++ b/third_party/move/move-prover/move-abigen/src/abigen.rs @@ -6,11 +6,12 @@ use anyhow::{anyhow, bail}; use heck::ToSnakeCase; #[allow(unused_imports)] use log::{debug, info, warn}; -use move_binary_format::{file_format::Ability, CompiledModule}; +use move_binary_format::CompiledModule; use move_bytecode_verifier::script_signature; use move_command_line_common::files::MOVE_COMPILED_EXTENSION; use move_core_types::{ abi::{ArgumentABI, ScriptABI, ScriptFunctionABI, TransactionScriptABI, TypeArgumentABI}, + ability::Ability, identifier::IdentStr, language_storage::{StructTag, TypeTag}, }; diff --git a/third_party/move/move-prover/move-docgen/src/docgen.rs b/third_party/move/move-prover/move-docgen/src/docgen.rs index c0941a2b946ee..aef88e7559bed 100644 --- a/third_party/move/move-prover/move-docgen/src/docgen.rs +++ b/third_party/move/move-prover/move-docgen/src/docgen.rs @@ -8,14 +8,14 @@ use itertools::Itertools; #[allow(unused_imports)] use log::{debug, info, warn}; use move_compiler::parser::keywords::{BUILTINS, CONTEXTUAL_KEYWORDS, KEYWORDS}; -use move_core_types::account_address::AccountAddress; +use move_core_types::{ability::AbilitySet, account_address::AccountAddress}; use move_model::{ ast::{Address, Attribute, AttributeValue, ModuleName, SpecBlockInfo, SpecBlockTarget}, code_writer::{CodeWriter, CodeWriterLabel}, emit, emitln, model::{ - AbilitySet, FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, ModuleId, NamedConstantEnv, - Parameter, QualifiedId, StructEnv, TypeParameter, + FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, ModuleId, NamedConstantEnv, Parameter, + QualifiedId, StructEnv, TypeParameter, }, symbol::Symbol, ty::TypeDisplayContext, diff --git a/third_party/move/move-vm/integration-tests/src/tests/instantiation_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/instantiation_tests.rs index 023fb737b28e4..17fdf9014e0c8 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/instantiation_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/instantiation_tests.rs @@ -2,12 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 use move_binary_format::file_format::{ - AbilitySet, AddressIdentifierIndex, Bytecode::*, CodeUnit, CompiledModule, FieldDefinition, + AddressIdentifierIndex, Bytecode::*, CodeUnit, CompiledModule, FieldDefinition, FunctionDefinition, FunctionHandle, FunctionHandleIndex, IdentifierIndex, ModuleHandle, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken::*, StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, StructTypeParameter, TypeSignature, }; use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, ident_str, identifier::Identifier, diff --git a/third_party/move/move-vm/integration-tests/src/tests/loader_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/loader_tests.rs index e63ac3c93f674..1c71b2ae410dd 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/loader_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/loader_tests.rs @@ -5,7 +5,7 @@ use crate::compiler::compile_modules_in_file; use move_binary_format::{ file_format::{ - empty_module, AbilitySet, AddressIdentifierIndex, Bytecode, CodeUnit, FunctionDefinition, + empty_module, AddressIdentifierIndex, Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, FunctionHandleIndex, IdentifierIndex, ModuleHandle, ModuleHandleIndex, SignatureIndex, StructHandle, StructTypeParameter, TableIndex, Visibility, }, @@ -13,6 +13,7 @@ use move_binary_format::{ }; use move_bytecode_verifier::VerifierConfig; use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, ident_str, identifier::{IdentStr, Identifier}, diff --git a/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs index d5a1f80b228fd..7e17e4bb44af9 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/module_storage_tests.rs @@ -3,8 +3,8 @@ use crate::compiler::{as_module, compile_units}; use bytes::Bytes; -use move_binary_format::file_format::{Ability, AbilitySet}; use move_core_types::{ + ability::{Ability, AbilitySet}, account_address::AccountAddress, ident_str, identifier::Identifier, diff --git a/third_party/move/move-vm/integration-tests/src/tests/vm_arguments_tests.rs b/third_party/move/move-vm/integration-tests/src/tests/vm_arguments_tests.rs index 7d50db34f2011..c288ca712108a 100644 --- a/third_party/move/move-vm/integration-tests/src/tests/vm_arguments_tests.rs +++ b/third_party/move/move-vm/integration-tests/src/tests/vm_arguments_tests.rs @@ -5,14 +5,15 @@ use move_binary_format::{ errors::VMResult, file_format::{ - empty_module, AbilitySet, AddressIdentifierIndex, Bytecode, CodeUnit, CompiledModule, - CompiledScript, FieldDefinition, FunctionDefinition, FunctionHandle, FunctionHandleIndex, - IdentifierIndex, ModuleHandle, ModuleHandleIndex, Signature, SignatureIndex, - SignatureToken, StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, - TableIndex, TypeSignature, Visibility, + empty_module, AddressIdentifierIndex, Bytecode, CodeUnit, CompiledModule, CompiledScript, + FieldDefinition, FunctionDefinition, FunctionHandle, FunctionHandleIndex, IdentifierIndex, + ModuleHandle, ModuleHandleIndex, Signature, SignatureIndex, SignatureToken, + StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, TableIndex, + TypeSignature, Visibility, }, }; use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, ident_str, identifier::Identifier, diff --git a/third_party/move/move-vm/runtime/src/loader/function.rs b/third_party/move/move-vm/runtime/src/loader/function.rs index 6f8672a24c946..d4dc9a7b18b7d 100644 --- a/third_party/move/move-vm/runtime/src/loader/function.rs +++ b/third_party/move/move-vm/runtime/src/loader/function.rs @@ -14,9 +14,11 @@ use move_binary_format::{ access::ModuleAccess, binary_views::BinaryIndexedView, errors::{PartialVMError, PartialVMResult}, - file_format::{AbilitySet, Bytecode, CompiledModule, FunctionDefinitionIndex, Visibility}, + file_format::{Bytecode, CompiledModule, FunctionDefinitionIndex, Visibility}, +}; +use move_core_types::{ + ability::AbilitySet, identifier::Identifier, language_storage::ModuleId, vm_status::StatusCode, }; -use move_core_types::{identifier::Identifier, language_storage::ModuleId, vm_status::StatusCode}; use move_vm_types::loaded_data::{ runtime_access_specifier::AccessSpecifier, runtime_types::{StructIdentifier, Type}, diff --git a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs index 567dd877755f6..494a37d56ee87 100644 --- a/third_party/move/move-vm/runtime/src/runtime_type_checks.rs +++ b/third_party/move/move-vm/runtime/src/runtime_type_checks.rs @@ -2,11 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{frame_type_cache::FrameTypeCache, interpreter::Stack, loader::Resolver}; -use move_binary_format::{ - errors::*, - file_format::{Ability, AbilitySet, Bytecode}, +use move_binary_format::{errors::*, file_format::Bytecode}; +use move_core_types::{ + ability::{Ability, AbilitySet}, + vm_status::StatusCode, }; -use move_core_types::vm_status::StatusCode; use move_vm_types::{loaded_data::runtime_types::Type, values::Locals}; pub(crate) trait RuntimeTypeCheck { diff --git a/third_party/move/move-vm/test-utils/src/gas_schedule.rs b/third_party/move/move-vm/test-utils/src/gas_schedule.rs index 67a25f88cc7b9..5a16c63e0be2f 100644 --- a/third_party/move/move-vm/test-utils/src/gas_schedule.rs +++ b/third_party/move/move-vm/test-utils/src/gas_schedule.rs @@ -10,8 +10,8 @@ use move_binary_format::{ errors::{PartialVMError, PartialVMResult}, file_format::{ - Bytecode, ClosureMask, CodeOffset, ConstantPoolIndex, FieldHandleIndex, - FieldInstantiationIndex, FunctionHandleIndex, FunctionInstantiationIndex, SignatureIndex, + Bytecode, CodeOffset, ConstantPoolIndex, FieldHandleIndex, FieldInstantiationIndex, + FunctionHandleIndex, FunctionInstantiationIndex, SignatureIndex, StructDefInstantiationIndex, StructDefinitionIndex, StructVariantHandleIndex, StructVariantInstantiationIndex, VariantFieldHandleIndex, VariantFieldInstantiationIndex, }, @@ -19,6 +19,7 @@ use move_binary_format::{ }; use move_core_types::{ account_address::AccountAddress, + function::ClosureMask, gas_algebra::{ AbstractMemorySize, GasQuantity, InternalGas, InternalGasPerAbstractMemoryUnit, InternalGasUnit, NumArgs, NumBytes, NumTypeNodes, ToUnit, diff --git a/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs b/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs index d96d01a23161a..a2c077274fd1e 100644 --- a/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs +++ b/third_party/move/move-vm/types/src/loaded_data/runtime_types.rs @@ -9,13 +9,13 @@ use itertools::Itertools; use move_binary_format::{ errors::{Location, PartialVMError, PartialVMResult, VMResult}, file_format::{ - Ability, AbilitySet, SignatureToken, StructHandle, StructTypeParameter, TypeParameterIndex, - VariantIndex, + SignatureToken, StructHandle, StructTypeParameter, TypeParameterIndex, VariantIndex, }, }; #[cfg(test)] use move_core_types::account_address::AccountAddress; use move_core_types::{ + ability::{Ability, AbilitySet}, identifier::Identifier, language_storage::{ModuleId, StructTag, TypeTag}, vm_status::{sub_status::unknown_invariant_violation::EPARANOID_FAILURE, StatusCode}, @@ -625,6 +625,10 @@ impl Type { AbilitySet::polymorphic_abilities(AbilitySet::VECTOR, vec![false], vec![ ty.abilities()? ]) + .map_err(|e| { + PartialVMError::new(StatusCode::VERIFIER_INVARIANT_VIOLATION) + .with_message(e.to_string()) + }) }, Type::Struct { ability, .. } => Ok(ability.base_ability_set), Type::StructInstantiation { @@ -645,6 +649,10 @@ impl Type { phantom_ty_args_mask.iter(), type_argument_abilities, ) + .map_err(|e| { + PartialVMError::new(StatusCode::VERIFIER_INVARIANT_VIOLATION) + .with_message(e.to_string()) + }) }, } } diff --git a/third_party/move/move-vm/types/src/values/values_impl.rs b/third_party/move/move-vm/types/src/values/values_impl.rs index df677ccf59d01..122c232dc6a81 100644 --- a/third_party/move/move-vm/types/src/values/values_impl.rs +++ b/third_party/move/move-vm/types/src/values/values_impl.rs @@ -35,7 +35,6 @@ use std::{ iter, mem, rc::Rc, }; - /*************************************************************************************** * * Internal Types diff --git a/third_party/move/tools/move-disassembler/src/disassembler.rs b/third_party/move/tools/move-disassembler/src/disassembler.rs index eee4338aa9459..867b795bf35a3 100644 --- a/third_party/move/tools/move-disassembler/src/disassembler.rs +++ b/third_party/move/tools/move-disassembler/src/disassembler.rs @@ -9,10 +9,10 @@ use move_binary_format::{ binary_views::BinaryIndexedView, control_flow_graph::{ControlFlowGraph, VMControlFlowGraph}, file_format::{ - Ability, AbilitySet, Bytecode, CodeUnit, FieldDefinition, FunctionDefinition, - FunctionDefinitionIndex, FunctionHandle, ModuleHandle, Signature, SignatureIndex, - SignatureToken, StructDefinition, StructDefinitionIndex, StructFieldInformation, - StructTypeParameter, StructVariantHandleIndex, TableIndex, VariantIndex, Visibility, + Bytecode, CodeUnit, FieldDefinition, FunctionDefinition, FunctionDefinitionIndex, + FunctionHandle, ModuleHandle, Signature, SignatureIndex, SignatureToken, StructDefinition, + StructDefinitionIndex, StructFieldInformation, StructTypeParameter, + StructVariantHandleIndex, TableIndex, VariantIndex, Visibility, }, views::FieldOrVariantIndex, }; @@ -21,7 +21,12 @@ use move_bytecode_source_map::{ source_map::{FunctionSourceMap, SourceName, StructSourceMap}, }; use move_compiler::compiled_unit::{CompiledUnit, NamedCompiledModule, NamedCompiledScript}; -use move_core_types::{ident_str, identifier::IdentStr, language_storage::ModuleId}; +use move_core_types::{ + ability::{Ability, AbilitySet}, + ident_str, + identifier::IdentStr, + language_storage::ModuleId, +}; use move_coverage::coverage_map::{ExecCoverageMap, FunctionCoverage}; use move_ir_types::location::Loc; use std::collections::HashMap; diff --git a/third_party/move/tools/move-resource-viewer/src/fat_type.rs b/third_party/move/tools/move-resource-viewer/src/fat_type.rs index d5c832ce94aa9..d4f8097a4f178 100644 --- a/third_party/move/tools/move-resource-viewer/src/fat_type.rs +++ b/third_party/move/tools/move-resource-viewer/src/fat_type.rs @@ -4,11 +4,9 @@ //! Loaded representation for runtime types. use crate::limit::Limiter; -use move_binary_format::{ - errors::{PartialVMError, PartialVMResult}, - file_format::AbilitySet, -}; +use move_binary_format::errors::{PartialVMError, PartialVMResult}; use move_core_types::{ + ability::AbilitySet, account_address::AccountAddress, identifier::Identifier, language_storage::{StructTag, TypeTag}, diff --git a/third_party/move/tools/move-resource-viewer/src/lib.rs b/third_party/move/tools/move-resource-viewer/src/lib.rs index ba6d7f3eca515..6dd335429d400 100644 --- a/third_party/move/tools/move-resource-viewer/src/lib.rs +++ b/third_party/move/tools/move-resource-viewer/src/lib.rs @@ -10,14 +10,15 @@ use move_binary_format::{ binary_views::BinaryIndexedView, errors::{Location, PartialVMError}, file_format::{ - Ability, AbilitySet, CompiledScript, FieldDefinition, SignatureToken, - StructDefinitionIndex, StructFieldInformation, StructHandleIndex, + CompiledScript, FieldDefinition, SignatureToken, StructDefinitionIndex, + StructFieldInformation, StructHandleIndex, }, views::FunctionHandleView, CompiledModule, }; use move_bytecode_utils::{compiled_module_viewer::CompiledModuleView, layout::TypeLayoutBuilder}; use move_core_types::{ + ability::{Ability, AbilitySet}, account_address::AccountAddress, identifier::{IdentStr, Identifier}, language_storage::{ModuleId, StructTag, TypeTag},