Skip to content

Commit

Permalink
[4/n][vm-rewrite][Move] Add shared "old vm types" to move-execution, …
Browse files Browse the repository at this point in the history
…and update execution versions to use it

This gets the different execution versions working. It does this by
replicating old code and traits that are removed in the new VM into the
`move-execution/shared` location, and different move-execution and
sui-execution versioned code can access these things from there.

**NOTE:** This will be moved to a crate outside of `move-execution` in a
future PR. Changing the location of the new `shared` dir here will be
harder to do rather than making this change higher up.

NB: The code in the PR may not be working as future PRs will build on top of
this.
  • Loading branch information
tzakian committed Feb 3, 2025
1 parent a1a87a0 commit f255e3f
Show file tree
Hide file tree
Showing 65 changed files with 6,201 additions and 181 deletions.
1 change: 0 additions & 1 deletion external-crates/move/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ move-unit-test = { path = "crates/move-unit-test" }
move-vm-config = { path = "crates/move-vm-config" }
move-vm-profiler = { path = "crates/move-vm-profiler" }
move-vm-runtime = { path = "crates/move-vm-runtime" }
move-vm-types = { path = "crates/move-vm-types" }
prover_bytecode = { path = "crates/move-stackless-bytecode", package="move-stackless-bytecode" }

[profile.bench]
Expand Down
1 change: 0 additions & 1 deletion external-crates/move/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ The Move language directory consists of three distinct parts: the Move bytecode
- The Move bytecode language defines programs published to the blockchain. It has a static type system that guarantees the absence of certain critical errors, including the prevention of duplicating certain values. Relevant crates include:
- [move-binary-format](crates/move-binary-format/) defines the binary format for Move bytecode.
- [move-bytecode-verifier](crates/move-bytecode-verifier/) provides the static safety checks for Move bytecode.
- [move-vm-types](crates/move-vm-types/) provides a shared utility crate types used by the Move VM and adapting layers.
- [move-vm-runtime](crates/move-vm-runtime/) provides the runtime for the Move VM, used for executing Move programs.

- The Move IR is a low-level intermediate representation that closely mirrors Move bytecode. What mainly differentiates it from the bytecode is that names are used as opposed to indexes into pools/tables. Relevant crates include:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "move-vm-types"
version = "0.1.0"
authors = ["Diem Association <[email protected]>"]
description = "Types for Move VM"
repository = "https://github.com/diem/diem"
homepage = "https://diem.com"
license = "Apache-2.0"
publish = false
edition = "2021"

[dependencies]
proptest = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive", "rc"] }
smallvec.workspace = true

bcs.workspace = true

move-core-types.workspace = true
move-binary-format.workspace = true
move-vm-profiler.workspace = true

[dev-dependencies]
proptest.workspace = true

[features]
default = []
fuzzing = ["proptest", "move-binary-format/fuzzing"]

Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright (c) The Diem Core Contributors
// Copyright (c) The Move Contributors
// SPDX-License-Identifier: Apache-2.0

use move_binary_format::errors::{PartialVMResult, VMResult};
use move_core_types::{
account_address::AccountAddress, identifier::IdentStr, language_storage::ModuleId,
resolver::ModuleResolver,
};
use std::fmt::Debug;

/// Provide an implementation for bytecodes related to data with a given data store.
///
/// The `DataStore` is a generic concept that includes both data and events.
/// A default implementation of the `DataStore` is `TransactionDataCache` which provides
/// an in memory cache for a given transaction and the atomic transactional changes
/// proper of a script execution (transaction).
pub trait DataStore {
/// The link context identifies the mapping from runtime `ModuleId`s to the `ModuleId`s in
/// storage that they are loaded from as returned by `relocate`. Implementors of `DataStore`
/// are required to keep the link context stable for the duration of
/// `Interpreter::execute_main`.
fn link_context(&self) -> AccountAddress;

/// Translate the runtime `module_id` to the on-chain `ModuleId` that it should be loaded from.
fn relocate(&self, module_id: &ModuleId) -> PartialVMResult<ModuleId>;

/// Translate the runtime fully-qualified struct name to the on-chain `ModuleId` that originally
/// defined that type.
fn defining_module(
&self,
module_id: &ModuleId,
struct_: &IdentStr,
) -> PartialVMResult<ModuleId>;

/// Get the serialized format of a `CompiledModule` given a `ModuleId`.
fn load_module(&self, module_id: &ModuleId) -> VMResult<Vec<u8>>;

/// Publish a module.
fn publish_module(&mut self, module_id: &ModuleId, blob: Vec<u8>) -> VMResult<()>;
}

/// A persistent storage implementation that can resolve both resources and modules
pub trait MoveResolver:
LinkageResolver<Error = Self::Err> + ModuleResolver<Error = Self::Err>
{
type Err: Debug;
}

impl<E: Debug, T: LinkageResolver<Error = E> + ModuleResolver<Error = E> + ?Sized> MoveResolver
for T
{
type Err = E;
}

/// An execution context that remaps the modules referred to at runtime according to a linkage
/// table, allowing the same module in storage to be run against different dependencies.
///
/// Default implementation does no re-linking (Module IDs are unchanged by relocation and the
/// link context is a constant value).
pub trait LinkageResolver {
type Error: Debug;

/// The link context identifies the mapping from runtime `ModuleId`s to the `ModuleId`s in
/// storage that they are loaded from as returned by `relocate`.
fn link_context(&self) -> AccountAddress {
AccountAddress::ZERO
}

/// Translate the runtime `module_id` to the on-chain `ModuleId` that it should be loaded from.
fn relocate(&self, module_id: &ModuleId) -> Result<ModuleId, Self::Error> {
Ok(module_id.clone())
}

/// Translate the runtime fully-qualified struct name to the on-chain `ModuleId` that originally
/// defined that type.
fn defining_module(
&self,
module_id: &ModuleId,
_struct: &IdentStr,
) -> Result<ModuleId, Self::Error> {
Ok(module_id.clone())
}
}

impl<T: LinkageResolver + ?Sized> LinkageResolver for &T {
type Error = T::Error;

fn link_context(&self) -> AccountAddress {
(**self).link_context()
}

fn relocate(&self, module_id: &ModuleId) -> Result<ModuleId, Self::Error> {
(**self).relocate(module_id)
}

fn defining_module(
&self,
module_id: &ModuleId,
struct_: &IdentStr,
) -> Result<ModuleId, Self::Error> {
(**self).defining_module(module_id, struct_)
}
}
Loading

0 comments on commit f255e3f

Please sign in to comment.