diff --git a/Cargo.lock b/Cargo.lock index eb295ea68b219..20f5443612682 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8741,6 +8741,7 @@ name = "move-compiler-v2" version = "0.1.0" dependencies = [ "anyhow", + "bcs 0.1.4", "clap 3.2.23", "codespan", "codespan-reporting", @@ -8748,7 +8749,10 @@ dependencies = [ "ethnum", "itertools", "move-binary-format", + "move-command-line-common", "move-core-types", + "move-disassembler", + "move-ir-types", "move-model", "move-prover-test-utils", "move-stackless-bytecode", @@ -8758,6 +8762,14 @@ dependencies = [ "serde 1.0.149", ] +[[package]] +name = "move-compiler-v2-transactional-tests" +version = "0.1.0" +dependencies = [ + "datatest-stable", + "move-transactional-test-runner", +] + [[package]] name = "move-core-types" version = "0.0.4" @@ -9253,6 +9265,7 @@ dependencies = [ "move-cli", "move-command-line-common", "move-compiler", + "move-compiler-v2", "move-core-types", "move-disassembler", "move-ir-compiler", @@ -9267,6 +9280,7 @@ dependencies = [ "rayon", "regex", "tempfile", + "termcolor", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 3126081ea8cd9..528a412598b84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -181,6 +181,7 @@ members = [ "third_party/move/move-command-line-common", "third_party/move/move-compiler", "third_party/move/move-compiler-v2", + "third_party/move/move-compiler-v2/transactional-tests", "third_party/move/move-compiler/transactional-tests", "third_party/move/move-core/types", "third_party/move/move-ir-compiler", diff --git a/aptos-move/aptos-transactional-test-harness/src/aptos_test_harness.rs b/aptos-move/aptos-transactional-test-harness/src/aptos_test_harness.rs index 656023ca498da..17582020a415f 100644 --- a/aptos-move/aptos-transactional-test-harness/src/aptos_test_harness.rs +++ b/aptos-move/aptos-transactional-test-harness/src/aptos_test_harness.rs @@ -46,7 +46,7 @@ use move_resource_viewer::{AnnotatedMoveValue, MoveValueAnnotator}; use move_transactional_test_runner::{ framework::{run_test_impl, CompiledState, MoveTestAdapter}, tasks::{InitCommand, SyntaxChoice, TaskInput}, - vm_test_harness::view_resource_in_move_storage, + vm_test_harness::{view_resource_in_move_storage, TestRunConfig}, }; use move_vm_runtime::session::SerializedReturnValues; use once_cell::sync::Lazy; @@ -553,6 +553,8 @@ impl<'a> MoveTestAdapter<'a> for AptosTestAdapter<'a> { fn init( default_syntax: SyntaxChoice, + _comparison_mode: bool, + _run_config: TestRunConfig, pre_compiled_deps: Option<&'a FullyCompiledProgram>, task_opt: Option>, ) -> (Self, Option) { @@ -959,5 +961,9 @@ fn render_events(events: &[ContractEvent]) -> Option { pub fn run_aptos_test(path: &Path) -> Result<(), Box> { // TODO: remove once bundles removed aptos_vm::aptos_vm::allow_module_bundle_for_test(); - run_test_impl::(path, Some(&*PRECOMPILED_APTOS_FRAMEWORK)) + run_test_impl::( + TestRunConfig::CompilerV1, + path, + Some(&*PRECOMPILED_APTOS_FRAMEWORK), + ) } diff --git a/third_party/move/move-command-line-common/src/testing.rs b/third_party/move/move-command-line-common/src/testing.rs index 44ad8d2328075..4f0f0f47f8713 100644 --- a/third_party/move/move-command-line-common/src/testing.rs +++ b/third_party/move/move-command-line-common/src/testing.rs @@ -63,3 +63,29 @@ pub fn format_diff(expected: impl AsRef, actual: impl AsRef) -> String } ret } + +pub fn format_diff_no_color(expected: impl AsRef, actual: impl AsRef) -> String { + use difference::*; + + let changeset = Changeset::new(expected.as_ref(), actual.as_ref(), "\n"); + + let mut ret = String::new(); + + for seq in changeset.diffs { + match &seq { + Difference::Same(x) => { + ret.push_str(&format!("= {}", x.replace('\n', "\n= "))); + ret.push('\n'); + }, + Difference::Add(x) => { + ret.push_str(&format!("+ {}", x.replace('\n', "\n+ "))); + ret.push('\n'); + }, + Difference::Rem(x) => { + ret.push_str(&format!("- {}", x.replace('\n', "\n- "))); + ret.push('\n'); + }, + } + } + ret +} diff --git a/third_party/move/move-compiler-v2/Cargo.toml b/third_party/move/move-compiler-v2/Cargo.toml index c5a0a1ecf606b..95818d809d4b8 100644 --- a/third_party/move/move-compiler-v2/Cargo.toml +++ b/third_party/move/move-compiler-v2/Cargo.toml @@ -10,12 +10,13 @@ publish = false edition = "2021" [dependencies] +anyhow = "1.0.62" move-binary-format = { path = "../move-binary-format" } move-core-types = { path = "../move-core/types" } move-model = { path = "../move-model" } move-stackless-bytecode = { path = "../move-prover/bytecode" } -anyhow = "1.0.62" +bcs = { workspace = true } clap = { version = "3.2.23", features = ["derive", "env"] } codespan = "0.11.1" codespan-reporting = { version = "0.11.1", features = ["serde", "serialization"] } @@ -32,6 +33,9 @@ serde = { version = "1.0.124", features = ["derive"] } [dev-dependencies] anyhow = "1.0.52" datatest-stable = "0.1.1" +move-command-line-common = { path = "../move-command-line-common" } +move-disassembler = { path = "../tools/move-disassembler" } +move-ir-types = { path = "../move-ir/types" } move-prover-test-utils = { path = "../move-prover/test-utils" } move-stdlib = { path = "../move-stdlib" } 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 f69931faabcde..e7eff285c27bd 100644 --- a/third_party/move/move-compiler-v2/src/bytecode_generator.rs +++ b/third_party/move/move-compiler-v2/src/bytecode_generator.rs @@ -38,6 +38,7 @@ pub fn generate_bytecode(env: &GlobalEnv, fid: QualifiedId) -> FunctionDa loops: vec![], reference_mode_counter: 0, reference_mode_kind: ReferenceKind::Immutable, + results: vec![], code: vec![], }; let mut scope = BTreeMap::new(); @@ -45,13 +46,13 @@ pub fn generate_bytecode(env: &GlobalEnv, fid: QualifiedId) -> FunctionDa let temp = gen.new_temp(ty); scope.insert(name, temp); } - let mut results = vec![]; for ty in gen.func_env.get_result_type().flatten() { let temp = gen.new_temp(ty); - results.push(temp) + gen.results.push(temp) } gen.scopes.push(scope); if let Some(def) = gen.func_env.get_def().cloned() { + let results = gen.results.clone(); // Need to clone expression if present because of sharing issues with `gen`. However, because // of interning, clone is cheap. gen.gen(results.clone(), &def); @@ -66,6 +67,7 @@ pub fn generate_bytecode(env: &GlobalEnv, fid: QualifiedId) -> FunctionDa loops: _, reference_mode_counter: _, reference_mode_kind: _, + results: _, code, } = gen; FunctionData::new( @@ -107,6 +109,8 @@ struct Generator<'env> { reference_mode_counter: usize, /// The kind of the reference mode. reference_mode_kind: ReferenceKind, + /// The list of temporaries where to store function return result. + results: Vec, /// The bytecode, as generated so far. code: Vec, // TODO: location_table, @@ -327,6 +331,7 @@ impl<'env> Generator<'env> { self.scopes.pop(); }, ExpData::Mutate(id, lhs, rhs) => { + let rhs_temp = self.gen_arg(rhs); let lhs_temp = self.gen_auto_ref_arg(lhs, ReferenceKind::Mutable); if !self.temp_type(lhs_temp).is_mutable_reference() { self.error( @@ -338,13 +343,16 @@ impl<'env> Generator<'env> { ), ); } - let rhs_temp = self.gen_arg(rhs); self.emit_call(*id, targets, BytecodeOperation::WriteRef, vec![ lhs_temp, rhs_temp, ]) }, ExpData::Assign(id, lhs, rhs) => self.gen_assign(*id, lhs, rhs, None), - ExpData::Return(_, exp) => self.gen(targets, exp), + ExpData::Return(id, exp) => { + let results = self.results.clone(); + self.gen(results.clone(), exp); + self.emit_with(*id, |attr| Bytecode::Ret(attr, results)) + }, ExpData::IfElse(id, cond, then_exp, else_exp) => { let cond_temp = self.gen_arg(cond); let then_label = self.new_label(*id); @@ -574,8 +582,8 @@ impl<'env> Generator<'env> { Operation::Xor => self.gen_op_call(targets, id, BytecodeOperation::Xor, args), Operation::Shl => self.gen_op_call(targets, id, BytecodeOperation::Shl, args), Operation::Shr => self.gen_op_call(targets, id, BytecodeOperation::Shr, args), - Operation::And => self.gen_op_call(targets, id, BytecodeOperation::And, args), - Operation::Or => self.gen_op_call(targets, id, BytecodeOperation::Or, args), + Operation::And => self.gen_logical_shortcut(true, targets, id, args), + Operation::Or => self.gen_logical_shortcut(false, targets, id, args), Operation::Eq => self.gen_op_call(targets, id, BytecodeOperation::Eq, args), Operation::Neq => self.gen_op_call(targets, id, BytecodeOperation::Neq, args), Operation::Lt => self.gen_op_call(targets, id, BytecodeOperation::Lt, args), @@ -666,6 +674,41 @@ impl<'env> Generator<'env> { }) } + fn gen_logical_shortcut( + &mut self, + is_and: bool, + targets: Vec, + id: NodeId, + args: &[Exp], + ) { + let target = self.require_unary_target(id, targets); + let arg1 = self.gen_arg(&args[0]); + let true_label = self.new_label(id); + let false_label = self.new_label(id); + let done_label = self.new_label(id); + self.emit_with(id, |attr| { + Bytecode::Branch(attr, true_label, false_label, arg1) + }); + self.emit_with(id, |attr| Bytecode::Label(attr, true_label)); + if is_and { + self.gen(vec![target], &args[1]); + } else { + self.emit_with(id, |attr| { + Bytecode::Load(attr, target, Constant::Bool(true)) + }) + } + self.emit_with(id, |attr| Bytecode::Jump(attr, done_label)); + self.emit_with(id, |attr| Bytecode::Label(attr, false_label)); + if is_and { + self.emit_with(id, |attr| { + Bytecode::Load(attr, target, Constant::Bool(false)) + }) + } else { + self.gen(vec![target], &args[1]); + } + self.emit_with(id, |attr| Bytecode::Label(attr, done_label)); + } + fn gen_function_call( &mut self, targets: Vec, diff --git a/third_party/move/move-compiler-v2/src/bytecode_pipeline.rs b/third_party/move/move-compiler-v2/src/bytecode_pipeline.rs deleted file mode 100644 index 8cf4e525d4bb5..0000000000000 --- a/third_party/move/move-compiler-v2/src/bytecode_pipeline.rs +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright © Aptos Foundation -// Parts of the project are originally copyright © Meta Platforms, Inc. -// SPDX-License-Identifier: Apache-2.0 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 new file mode 100644 index 0000000000000..1e7b0de4ea083 --- /dev/null +++ b/third_party/move/move-compiler-v2/src/file_format_generator/function_generator.rs @@ -0,0 +1,720 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::file_format_generator::{ + module_generator::{ModuleContext, ModuleGenerator}, + MAX_FUNCTION_DEF_COUNT, MAX_LOCAL_COUNT, +}; +use move_binary_format::file_format as FF; +use move_model::{ + ast::TempIndex, + model::{FunId, FunctionEnv, Loc, QualifiedId, StructId, TypeParameter}, + ty::{PrimitiveType, Type}, +}; +use move_stackless_bytecode::{ + function_target::FunctionTarget, + function_target_pipeline::FunctionVariant, + stackless_bytecode::{Bytecode, Label, Operation}, +}; +use std::collections::{BTreeMap, BTreeSet}; + +pub struct FunctionGenerator<'a> { + /// The underlying module generator. + gen: &'a mut ModuleGenerator, + /// The set of temporaries which need to be pinned to locals because references are taken for + /// them. + pinned: BTreeSet, + /// A map from a temporary to information associated with it. + temps: BTreeMap, + /// The value stack, represented by the temporaries which are located on it. + stack: Vec, + /// The locals which have been used so far. This contains the parameters of the function. + locals: Vec, + /// A map from branching labels to information about them. + label_info: BTreeMap, + /// The generated code + code: Vec, +} + +/// Immutable context for a function, seperated from the mutable generator state, to reduce +/// borrow conflicts. +#[derive(Clone)] +pub struct FunctionContext<'env> { + /// The module context + pub module: ModuleContext<'env>, + /// Function target we are generating code for. + pub fun: FunctionTarget<'env>, + /// Location of the function for error messages. + pub loc: Loc, + /// Type parameters, cached here. + type_parameters: Vec, +} + +#[derive(Debug, Copy, Clone)] +/// Represents the location of a temporary if it is not only on the stack. +struct TempInfo { + /// The temp is stored in a local of given index. + local: FF::LocalIndex, +} + +impl TempInfo { + fn new(local: FF::LocalIndex) -> Self { + Self { local } + } +} + +/// Represents information about a label. +#[derive(Debug, Default)] +struct LabelInfo { + /// The references to this label, as seen so far, in terms of the code offset of the + /// instruction. The instruction pointed to will be any of `Branch`, `BrTrue`, or `BrFalse`. + references: BTreeSet, + /// The resolution of linking the label to a code offset. + resolution: Option, +} + +impl<'a> FunctionGenerator<'a> { + /// Runs the function generator for the given function. + pub fn run<'b>(gen: &'a mut ModuleGenerator, ctx: &'b ModuleContext, fun_env: FunctionEnv<'b>) { + let loc = fun_env.get_loc(); + let function = gen.function_index(ctx, &loc, &fun_env); + let visibility = fun_env.visibility(); + let fun_count = gen.module.function_defs.len(); + let (gen, code) = if !fun_env.is_native() { + let mut fun_gen = Self { + gen, + pinned: Default::default(), + temps: Default::default(), + stack: vec![], + locals: vec![], + label_info: Default::default(), + code: vec![], + }; + let target = ctx.targets.get_target(&fun_env, &FunctionVariant::Baseline); + let code = fun_gen.gen_code(&FunctionContext { + module: ctx.clone(), + fun: target, + loc: loc.clone(), + type_parameters: fun_env.get_type_parameters(), + }); + (fun_gen.gen, Some(code)) + } else { + (gen, None) + }; + let def = FF::FunctionDefinition { + function, + visibility, + is_entry: fun_env.is_entry(), + acquires_global_resources: vec![], + code, + }; + ctx.checked_bound( + loc, + fun_count, // gen.module.function_defs.len(), + MAX_FUNCTION_DEF_COUNT, + "defined function", + ); + gen.module.function_defs.push(def) + } + + /// Generates code for a function. + fn gen_code(&mut self, ctx: &FunctionContext<'_>) -> FF::CodeUnit { + // Initialize the abstract virtual machine + self.pinned = Self::referenced_temps(ctx); + self.temps = (0..ctx.fun.get_parameter_count()) + .map(|temp| (temp, TempInfo::new(self.temp_to_local(ctx, temp)))) + .collect(); + self.locals = (0..ctx.fun.get_parameter_count()) + .map(|temp| ctx.temp_type(temp).to_owned()) + .collect(); + + // Walk the bytecode + let bytecode = ctx.fun.get_bytecode(); + for i in 0..bytecode.len() { + if i + 1 < bytecode.len() { + let bc = &bytecode[i]; + let next_bc = &bytecode[i + 1]; + self.gen_bytecode(ctx, &bytecode[i], Some(next_bc)); + if !bc.is_branch() && matches!(next_bc, Bytecode::Label(..)) { + // At block boundaries without a preceding branch, need to flush stack + // TODO: to avoid this, we should use the CFG for code generation. + self.abstract_flush_stack(ctx, 0); + } + } else { + self.gen_bytecode(ctx, &bytecode[i], None) + } + } + + // At this point, all labels should be resolved, so link them. + for info in self.label_info.values() { + if let Some(label_offs) = info.resolution { + for ref_offs in &info.references { + let ref_offs = *ref_offs; + let code_ref = &mut self.code[ref_offs as usize]; + match code_ref { + FF::Bytecode::Branch(_) => *code_ref = FF::Bytecode::Branch(label_offs), + FF::Bytecode::BrTrue(_) => *code_ref = FF::Bytecode::BrTrue(label_offs), + FF::Bytecode::BrFalse(_) => *code_ref = FF::Bytecode::BrFalse(label_offs), + _ => {}, + } + } + } else { + ctx.internal_error("inconsistent bytecode label info") + } + } + + // Deliver result + let locals = self.gen.signature( + &ctx.module, + &ctx.loc, + self.locals[ctx.fun.get_parameter_count()..].to_vec(), + ); + FF::CodeUnit { + locals, + code: std::mem::take(&mut self.code), + } + } + + /// Compute the set of temporaries which are referenced in borrow instructions. + fn referenced_temps(ctx: &FunctionContext) -> BTreeSet { + let mut result = BTreeSet::new(); + for bc in ctx.fun.get_bytecode() { + if let Bytecode::Call(_, _, Operation::BorrowLoc, args, _) = bc { + result.insert(args[0]); + } + } + result + } + + /// Generate file-format bytecode from a stackless bytecode and an optional next bytecode + /// for peephole optimizations. + fn gen_bytecode(&mut self, ctx: &FunctionContext, bc: &Bytecode, next_bc: Option<&Bytecode>) { + match bc { + Bytecode::Assign(_, dest, source, _mode) => { + self.abstract_push_args(ctx, vec![*source]); + let local = self.temp_to_local(ctx, *dest); + self.emit(FF::Bytecode::StLoc(local)); + self.abstract_pop(ctx) + }, + Bytecode::Ret(_, result) => { + self.balance_stack_end_of_block(ctx, result); + self.emit(FF::Bytecode::Ret); + self.abstract_pop_n(ctx, result.len()); + }, + Bytecode::Call(_, dest, oper, source, None) => { + self.gen_operation(ctx, dest, oper, source) + }, + Bytecode::Load(_, dest, cons) => { + let cons = self.gen.constant_index( + &ctx.module, + &ctx.loc, + cons, + ctx.fun.get_local_type(*dest), + ); + self.emit(FF::Bytecode::LdConst(cons)); + self.abstract_push_result(ctx, vec![*dest]); + }, + Bytecode::Label(_, label) => self.define_label(*label), + Bytecode::Branch(_, if_true, if_false, cond) => { + // Ensure only `cond` is on the stack before branch. + self.balance_stack_end_of_block(ctx, vec![*cond]); + // Attempt to detect fallthrough, such that for + // ``` + // branch l1, l2, cond + // l1: ... + // ``` + // .. we generate adequate code. + let successor_label_opt = next_bc.and_then(|bc| { + if let Bytecode::Label(_, l) = bc { + Some(*l) + } else { + None + } + }); + if successor_label_opt == Some(*if_true) { + self.add_label_reference(*if_false); + self.emit(FF::Bytecode::BrFalse(0)) + } else if successor_label_opt == Some(*if_false) { + self.add_label_reference(*if_true); + self.emit(FF::Bytecode::BrTrue(0)) + } else { + // No fallthrough + self.add_label_reference(*if_false); + self.emit(FF::Bytecode::BrFalse(0)); + self.add_label_reference(*if_true); + self.emit(FF::Bytecode::Branch(0)) + } + self.abstract_pop(ctx); + }, + Bytecode::Jump(_, label) => { + self.abstract_flush_stack(ctx, 0); + self.add_label_reference(*label); + self.emit(FF::Bytecode::Branch(0)); + }, + Bytecode::Abort(_, temp) => { + self.balance_stack_end_of_block(ctx, &vec![*temp]); + self.emit(FF::Bytecode::Abort); + self.abstract_pop(ctx) + }, + Bytecode::Nop(_) => { + // do nothing -- labels are relative + }, + Bytecode::SaveMem(_, _, _) + | Bytecode::Call(_, _, _, _, Some(_)) + | Bytecode::SaveSpecVar(_, _, _) + | Bytecode::Prop(_, _, _) => ctx.internal_error("unexpected specification bytecode"), + } + } + + /// Balance the stack such that it exactly contains the `result` temps and nothing else. This + /// is used for instructions like `return` or `abort` which terminate a block und must leave + /// the stack empty at end. + fn balance_stack_end_of_block( + &mut self, + ctx: &FunctionContext, + result: impl AsRef<[TempIndex]>, + ) { + let result = result.as_ref(); + // First ensure the arguments are on the stack. + self.abstract_push_args(ctx, result); + if self.stack.len() != result.len() { + // Unfortunately, there is more on the stack than needed. + // Need to flush and push again so the stack is empty after return. + self.abstract_flush_stack(ctx, 0); + self.abstract_push_args(ctx, result.as_ref()); + assert_eq!(self.stack.len(), result.len()) + } + } + + /// Adds a reference to a label to the LabelInfo. This is used to link the labels final + /// value at the current code offset once it is resolved. + fn add_label_reference(&mut self, label: Label) { + let offset = self.code.len() as FF::CodeOffset; + self.label_info + .entry(label) + .or_default() + .references + .insert(offset); + } + + /// Sets the resolution of a lable to the current code offset. + fn define_label(&mut self, label: Label) { + let offset = self.code.len() as FF::CodeOffset; + self.label_info.entry(label).or_default().resolution = Some(offset) + } + + /// Generates code for an operation. + fn gen_operation( + &mut self, + ctx: &FunctionContext, + dest: &[TempIndex], + oper: &Operation, + source: &[TempIndex], + ) { + match oper { + Operation::Function(mid, fid, inst) => { + self.gen_call(ctx, dest, mid.qualified(*fid), inst, source); + }, + Operation::Pack(mid, sid, inst) => { + self.gen_struct_oper( + ctx, + dest, + mid.qualified(*sid), + inst, + source, + FF::Bytecode::Pack, + FF::Bytecode::PackGeneric, + ); + }, + Operation::Unpack(mid, sid, inst) => { + self.gen_struct_oper( + ctx, + dest, + mid.qualified(*sid), + inst, + source, + FF::Bytecode::Unpack, + FF::Bytecode::UnpackGeneric, + ); + }, + Operation::MoveTo(mid, sid, inst) => { + self.gen_struct_oper( + ctx, + dest, + mid.qualified(*sid), + inst, + source, + FF::Bytecode::MoveTo, + FF::Bytecode::MoveToGeneric, + ); + }, + Operation::MoveFrom(mid, sid, inst) => { + self.gen_struct_oper( + ctx, + dest, + mid.qualified(*sid), + inst, + source, + FF::Bytecode::MoveFrom, + FF::Bytecode::MoveFromGeneric, + ); + }, + Operation::Exists(mid, sid, inst) => { + self.gen_struct_oper( + ctx, + dest, + mid.qualified(*sid), + inst, + source, + FF::Bytecode::Exists, + FF::Bytecode::ExistsGeneric, + ); + }, + Operation::BorrowLoc => { + let local = self.temp_to_local(ctx, source[0]); + if ctx.fun.get_local_type(dest[0]).is_mutable_reference() { + self.emit(FF::Bytecode::MutBorrowLoc(local)) + } else { + self.emit(FF::Bytecode::ImmBorrowLoc(local)) + } + self.abstract_push_result(ctx, dest) + }, + Operation::BorrowField(mid, sid, inst, offset) => { + self.gen_borrow_field( + ctx, + dest, + mid.qualified(*sid), + inst.clone(), + *offset, + source, + ); + }, + Operation::BorrowGlobal(mid, sid, inst) => { + let is_mut = ctx.fun.get_local_type(dest[0]).is_mutable_reference(); + self.gen_struct_oper( + ctx, + dest, + mid.qualified(*sid), + inst, + source, + if is_mut { + FF::Bytecode::MutBorrowGlobal + } else { + FF::Bytecode::ImmBorrowGlobal + }, + if is_mut { + FF::Bytecode::MutBorrowGlobalGeneric + } else { + FF::Bytecode::ImmBorrowGlobalGeneric + }, + ) + }, + Operation::Vector => { + let elem_type = if let Type::Vector(el) = ctx.fun.get_local_type(dest[0]) { + el.as_ref().clone() + } else { + ctx.internal_error("expected vector type"); + Type::new_prim(PrimitiveType::Bool) + }; + let sign = self.gen.signature(&ctx.module, &ctx.loc, vec![elem_type]); + self.gen_builtin( + ctx, + dest, + FF::Bytecode::VecPack(sign, source.len() as u64), + source, + ) + }, + Operation::ReadRef => self.gen_builtin(ctx, dest, FF::Bytecode::ReadRef, source), + Operation::WriteRef => { + // TODO: WriteRef in FF bytecode and in stackless bytecode use different operand + // order, perhaps we should fix this. + self.gen_builtin(ctx, dest, FF::Bytecode::WriteRef, &[source[1], source[0]]) + }, + Operation::FreezeRef => self.gen_builtin(ctx, dest, FF::Bytecode::FreezeRef, source), + Operation::CastU8 => self.gen_builtin(ctx, dest, FF::Bytecode::CastU8, source), + Operation::CastU16 => self.gen_builtin(ctx, dest, FF::Bytecode::CastU16, source), + Operation::CastU32 => self.gen_builtin(ctx, dest, FF::Bytecode::CastU32, source), + Operation::CastU64 => self.gen_builtin(ctx, dest, FF::Bytecode::CastU64, source), + Operation::CastU128 => self.gen_builtin(ctx, dest, FF::Bytecode::CastU128, source), + Operation::CastU256 => self.gen_builtin(ctx, dest, FF::Bytecode::CastU256, source), + Operation::Not => self.gen_builtin(ctx, dest, FF::Bytecode::Not, source), + Operation::Add => self.gen_builtin(ctx, dest, FF::Bytecode::Add, source), + Operation::Sub => self.gen_builtin(ctx, dest, FF::Bytecode::Sub, source), + Operation::Mul => self.gen_builtin(ctx, dest, FF::Bytecode::Mul, source), + Operation::Div => self.gen_builtin(ctx, dest, FF::Bytecode::Div, source), + Operation::Mod => self.gen_builtin(ctx, dest, FF::Bytecode::Mod, source), + Operation::BitOr => self.gen_builtin(ctx, dest, FF::Bytecode::BitOr, source), + Operation::BitAnd => self.gen_builtin(ctx, dest, FF::Bytecode::BitAnd, source), + Operation::Xor => self.gen_builtin(ctx, dest, FF::Bytecode::Xor, source), + Operation::Shl => self.gen_builtin(ctx, dest, FF::Bytecode::Shl, source), + Operation::Shr => self.gen_builtin(ctx, dest, FF::Bytecode::Shr, source), + Operation::Lt => self.gen_builtin(ctx, dest, FF::Bytecode::Lt, source), + Operation::Gt => self.gen_builtin(ctx, dest, FF::Bytecode::Gt, source), + Operation::Le => self.gen_builtin(ctx, dest, FF::Bytecode::Le, source), + Operation::Ge => self.gen_builtin(ctx, dest, FF::Bytecode::Ge, source), + Operation::Or => self.gen_builtin(ctx, dest, FF::Bytecode::Or, source), + Operation::And => self.gen_builtin(ctx, dest, FF::Bytecode::And, source), + Operation::Eq => self.gen_builtin(ctx, dest, FF::Bytecode::Eq, source), + Operation::Neq => self.gen_builtin(ctx, dest, FF::Bytecode::Neq, source), + + Operation::TraceLocal(_) + | Operation::TraceReturn(_) + | Operation::TraceAbort + | Operation::TraceExp(_, _) + | Operation::TraceGlobalMem(_) + | Operation::EmitEvent + | Operation::EventStoreDiverge + | Operation::OpaqueCallBegin(_, _, _) + | Operation::OpaqueCallEnd(_, _, _) + | Operation::GetField(_, _, _, _) + | Operation::GetGlobal(_, _, _) + | Operation::Uninit + | Operation::Destroy + | Operation::Havoc(_) + | Operation::Stop + | Operation::IsParent(_, _) + | Operation::WriteBack(_, _) + | Operation::UnpackRef + | Operation::PackRef + | Operation::UnpackRefDeep + | Operation::PackRefDeep => ctx.internal_error("unexpected specification opcode"), + } + } + + /// Generates code for a function call. + fn gen_call( + &mut self, + ctx: &FunctionContext, + dest: &[TempIndex], + id: QualifiedId, + inst: &[Type], + source: &[TempIndex], + ) { + self.abstract_push_args(ctx, source); + if inst.is_empty() { + let idx = + self.gen + .function_index(&ctx.module, &ctx.loc, &ctx.module.env.get_function(id)); + self.emit(FF::Bytecode::Call(idx)) + } else { + let idx = self.gen.function_instantiation_index( + &ctx.module, + &ctx.loc, + ctx.fun.func_env, + inst.to_vec(), + ); + self.emit(FF::Bytecode::CallGeneric(idx)) + } + self.abstract_pop_n(ctx, source.len()); + self.abstract_push_result(ctx, dest); + } + + /// Generates code for an operation working on a structure. This can be a structure with or + /// without generics: the two passed functions allow the caller to determine which bytecode + /// to create for each case. + fn gen_struct_oper( + &mut self, + ctx: &FunctionContext, + dest: &[TempIndex], + id: QualifiedId, + inst: &[Type], + source: &[TempIndex], + mk_simple: impl FnOnce(FF::StructDefinitionIndex) -> FF::Bytecode, + mk_generic: impl FnOnce(FF::StructDefInstantiationIndex) -> FF::Bytecode, + ) { + self.abstract_push_args(ctx, source); + let struct_env = &ctx.module.env.get_struct(id); + if inst.is_empty() { + let idx = self.gen.struct_def_index(&ctx.module, &ctx.loc, struct_env); + self.emit(mk_simple(idx)) + } else { + let idx = self.gen.struct_def_instantiation_index( + &ctx.module, + &ctx.loc, + struct_env, + inst.to_vec(), + ); + self.emit(mk_generic(idx)) + } + self.abstract_pop_n(ctx, source.len()); + self.abstract_push_result(ctx, dest); + } + + /// Generate code for the borrow-field instruction. + fn gen_borrow_field( + &mut self, + ctx: &FunctionContext, + dest: &[TempIndex], + id: QualifiedId, + inst: Vec, + offset: usize, + source: &[TempIndex], + ) { + self.abstract_push_args(ctx, source); + let struct_env = &ctx.module.env.get_struct(id); + let field_env = &struct_env.get_field_by_offset(offset); + let is_mut = ctx.fun.get_local_type(dest[0]).is_mutable_reference(); + if inst.is_empty() { + let idx = self.gen.field_index(&ctx.module, &ctx.loc, field_env); + if is_mut { + self.emit(FF::Bytecode::MutBorrowField(idx)) + } else { + self.emit(FF::Bytecode::ImmBorrowField(idx)) + } + } else { + let idx = self + .gen + .field_inst_index(&ctx.module, &ctx.loc, field_env, inst); + if is_mut { + self.emit(FF::Bytecode::MutBorrowFieldGeneric(idx)) + } else { + self.emit(FF::Bytecode::ImmBorrowFieldGeneric(idx)) + } + } + self.abstract_pop_n(ctx, source.len()); + self.abstract_push_result(ctx, dest); + } + + /// Generate code for a general builtin instruction. + fn gen_builtin( + &mut self, + ctx: &FunctionContext, + dest: &[TempIndex], + bc: FF::Bytecode, + source: &[TempIndex], + ) { + self.abstract_push_args(ctx, source); + self.emit(bc); + self.abstract_pop_n(ctx, source.len()); + self.abstract_push_result(ctx, dest) + } + + /// Emits a file-format bytecode. + fn emit(&mut self, bc: FF::Bytecode) { + self.code.push(bc) + } + + /// Ensure that on the abstract stack of the generator, the given temporaries are ready, + /// in order, to be consumed. Ideally those are already on the stack, but if they are not, + /// they will be made available. + fn abstract_push_args(&mut self, ctx: &FunctionContext, temps: impl AsRef<[TempIndex]>) { + // Compute the maximal prefix of `temps` which are already on the stack. + let temps = temps.as_ref(); + let mut temps_to_push = temps; + for i in 0..temps.len() { + let end = temps.len() - i; + if end > self.stack.len() || end == 0 { + continue; + } + if self.stack.ends_with(&temps[0..end]) { + temps_to_push = &temps[end..temps.len()]; + break; + } + } + // However, the remaining temps in temps_to_push need to be stored in locals and not on the + // stack. Otherwise we need to flush the stack to reach them. + let mut stack_to_flush = self.stack.len(); + for temp in temps_to_push { + if let Some(offs) = self.stack.iter().position(|t| t == temp) { + // The lowest point in the stack we need to flush. + stack_to_flush = std::cmp::min(offs, stack_to_flush); + // Unfortunately, whatever is on the stack already, needs to be flushed out and + // pushed again. (We really should introduce a ROTATE opcode to the Move VM) + temps_to_push = temps; + } + } + self.abstract_flush_stack(ctx, stack_to_flush); + // Finally, push `temps_to_push` onto the stack. + for temp in temps_to_push { + let local = self.temp_to_local(ctx, *temp); + if ctx.is_copyable(*temp) { + self.emit(FF::Bytecode::CopyLoc(local)) + } else { + self.emit(FF::Bytecode::MoveLoc(local)); + } + self.stack.push(*temp) + } + } + + /// Flush the abstract stack, ensuring that all values on the stack are stored in locals. + fn abstract_flush_stack(&mut self, ctx: &FunctionContext, top: usize) { + while self.stack.len() > top { + let temp = self.stack.pop().unwrap(); + let local = self.temp_to_local(ctx, temp); + self.emit(FF::Bytecode::StLoc(local)); + } + } + + /// Push the result of an operation to the abstract stack. + fn abstract_push_result(&mut self, ctx: &FunctionContext, result: impl AsRef<[TempIndex]>) { + let mut flush_mark = usize::MAX; + for temp in result.as_ref() { + if self.pinned.contains(temp) { + // need to flush this right away and maintain a local for it + flush_mark = flush_mark.min(self.stack.len()) + } + self.stack.push(*temp); + } + if flush_mark != usize::MAX { + self.abstract_flush_stack(ctx, flush_mark) + } + } + + /// Pop a value from the abstract stack. + fn abstract_pop(&mut self, ctx: &FunctionContext) { + if self.stack.pop().is_none() { + ctx.internal_error("unbalanced abstract stack") + } + } + + /// Pop a number of values from the abstract stack. + fn abstract_pop_n(&mut self, ctx: &FunctionContext, cnt: usize) { + for _ in 0..cnt { + self.abstract_pop(ctx) + } + } + + /// Creates a new local of type. + fn new_local(&mut self, ctx: &FunctionContext, ty: Type) -> FF::LocalIndex { + let local = ctx + .module + .checked_bound(&ctx.loc, self.locals.len(), MAX_LOCAL_COUNT, "local") + as FF::LocalIndex; + self.locals.push(ty); + local + } + + /// Allocates a local for the given temporary + fn temp_to_local(&mut self, ctx: &FunctionContext, temp: TempIndex) -> FF::LocalIndex { + if let Some(TempInfo { local }) = self.temps.get(&temp) { + *local + } else { + let idx = self.new_local(ctx, ctx.temp_type(temp).to_owned()); + self.temps.insert(temp, TempInfo::new(idx)); + idx + } + } +} + +impl<'env> FunctionContext<'env> { + /// Emits an internal error for this function. + pub fn internal_error(&self, msg: impl AsRef) { + self.module.internal_error(&self.loc, msg) + } + + /// Gets the type of the temporary. + pub fn temp_type(&self, temp: TempIndex) -> &Type { + self.fun.get_local_type(temp) + } + + /// Returns true of the given temporary can/should be copied when it is loaded onto the stack. + /// Currently, this is using the `Copy` ability, but in the future it may also use lifetime + /// analysis results to check whether the variable is still accessed. + pub fn is_copyable(&self, temp: TempIndex) -> bool { + self.module + .env + .type_abilities(self.temp_type(temp), &self.type_parameters) + .has_ability(FF::Ability::Copy) + } +} diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs b/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs new file mode 100644 index 0000000000000..a555596e00ad3 --- /dev/null +++ b/third_party/move/move-compiler-v2/src/file_format_generator/mod.rs @@ -0,0 +1,92 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +mod function_generator; +mod module_generator; + +use crate::file_format_generator::module_generator::ModuleContext; +use module_generator::ModuleGenerator; +use move_binary_format::{ + file_format as FF, + file_format::{CompiledScript, FunctionDefinition, FunctionHandle}, + CompiledModule, +}; +use move_model::model::GlobalEnv; +use move_stackless_bytecode::function_target_pipeline::FunctionTargetsHolder; + +pub fn generate_file_format( + env: &GlobalEnv, + targets: &FunctionTargetsHolder, +) -> (Vec, Vec) { + let ctx = ModuleContext { env, targets }; + let mut modules = vec![]; + let mut scripts = vec![]; + for module_env in ctx.env.get_modules() { + if !module_env.is_target() { + continue; + } + let (ff_module, main_handle) = ModuleGenerator::run(&ctx, &module_env); + if module_env.is_script_module() { + let CompiledModule { + version, + module_handles, + struct_handles, + function_handles, + mut function_defs, + function_instantiations, + signatures, + identifiers, + address_identifiers, + constant_pool, + metadata, + .. + } = ff_module; + if let Some(FunctionDefinition { + code: Some(code), .. + }) = function_defs.pop() + { + let FunctionHandle { + parameters, + type_parameters, + .. + } = main_handle.expect("main handle defined"); + scripts.push(CompiledScript { + version, + module_handles, + struct_handles, + function_handles, + function_instantiations, + signatures, + identifiers, + address_identifiers, + constant_pool, + metadata, + code, + type_parameters, + parameters, + }) + } else { + ctx.internal_error(module_env.get_loc(), "inconsistent script module"); + } + } else { + modules.push(ff_module) + } + } + (modules, scripts) +} + +const MAX_MODULE_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_IDENTIFIER_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_ADDRESS_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_CONST_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_STRUCT_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_SIGNATURE_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_STRUCT_DEF_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_STRUCT_DEF_INST_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_FIELD_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_FIELD_INST_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_FUNCTION_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_FUNCTION_INST_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_FUNCTION_DEF_COUNT: usize = FF::TableIndex::MAX as usize; +const MAX_LOCAL_COUNT: usize = FF::LocalIndex::MAX as usize; diff --git a/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs b/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs new file mode 100644 index 0000000000000..b0a1671a4d1ab --- /dev/null +++ b/third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs @@ -0,0 +1,626 @@ +// Copyright © Aptos Foundation +// Parts of the project are originally copyright © Meta Platforms, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use crate::file_format_generator::{ + function_generator::FunctionGenerator, MAX_ADDRESS_COUNT, MAX_CONST_COUNT, MAX_FIELD_COUNT, + MAX_FIELD_INST_COUNT, MAX_FUNCTION_COUNT, MAX_FUNCTION_INST_COUNT, MAX_IDENTIFIER_COUNT, + MAX_MODULE_COUNT, MAX_SIGNATURE_COUNT, MAX_STRUCT_COUNT, MAX_STRUCT_DEF_COUNT, + MAX_STRUCT_DEF_INST_COUNT, +}; +use codespan_reporting::diagnostic::Severity; +use move_binary_format::{ + file_format as FF, + file_format::{FunctionHandle, ModuleHandle, TableIndex}, + file_format_common, +}; +use move_core_types::{account_address::AccountAddress, identifier::Identifier}; +use move_model::{ + model::{ + FieldEnv, FunId, FunctionEnv, GlobalEnv, Loc, ModuleEnv, ModuleId, Parameter, QualifiedId, + StructEnv, StructId, TypeParameter, TypeParameterKind, + }, + symbol::Symbol, + ty::{PrimitiveType, ReferenceKind, Type}, +}; +use move_stackless_bytecode::{ + function_target_pipeline::FunctionTargetsHolder, stackless_bytecode::Constant, +}; +use std::collections::BTreeMap; + +/// Internal state of the module code generator +#[derive(Debug)] +pub struct ModuleGenerator { + /// The module index for which we generate code. + #[allow(unused)] + module_idx: FF::ModuleHandleIndex, + /// A mapping from modules to indices. + module_to_idx: BTreeMap, + /// A mapping from symbols to indices. + name_to_idx: BTreeMap, + /// A mapping from addresses to indices. + address_to_idx: BTreeMap, + /// A mapping from functions to indices. + fun_to_idx: BTreeMap, FF::FunctionHandleIndex>, + /// The special function handle of the `main` function of a script. This is not stored + /// in `module.function_handles` because the file format does not maintain a handle + /// for this function. + main_handle: Option, + /// The special module handle for a script, see also `main_handle`. + script_handle: Option, + /// A mapping from function instantiations to indices. + fun_inst_to_idx: + BTreeMap<(QualifiedId, FF::SignatureIndex), FF::FunctionInstantiationIndex>, + /// A mapping from structs to indices. + struct_to_idx: BTreeMap, FF::StructHandleIndex>, + /// A mapping from function instantiations to indices. + struct_def_inst_to_idx: + BTreeMap<(QualifiedId, FF::SignatureIndex), FF::StructDefInstantiationIndex>, + /// A mapping from fields to indices. + field_to_idx: BTreeMap<(QualifiedId, usize), FF::FieldHandleIndex>, + /// A mapping from fields to indices. + field_inst_to_idx: + BTreeMap<(QualifiedId, usize, FF::SignatureIndex), FF::FieldInstantiationIndex>, + /// A mapping from type sequences to signature indices. + types_to_signature: BTreeMap, FF::SignatureIndex>, + /// A mapping from constants sequences to pool indices. + cons_to_idx: BTreeMap, + /// The file-format module we are building. + pub module: move_binary_format::CompiledModule, +} + +/// Immutable context for a module code generation, seperated from the mutable generator +/// state to reduce borrow conflicts. +#[derive(Debug, Clone)] +pub struct ModuleContext<'env> { + pub env: &'env GlobalEnv, + pub targets: &'env FunctionTargetsHolder, +} + +impl ModuleGenerator { + /// Runs generation of `CompiledModule`. + pub fn run( + ctx: &ModuleContext, + module_env: &ModuleEnv, + ) -> (FF::CompiledModule, Option) { + let module = move_binary_format::CompiledModule { + version: file_format_common::VERSION_6, + self_module_handle_idx: FF::ModuleHandleIndex(0), + ..Default::default() + }; + let mut gen = Self { + module_idx: FF::ModuleHandleIndex(0), + module_to_idx: Default::default(), + name_to_idx: Default::default(), + address_to_idx: Default::default(), + fun_to_idx: Default::default(), + struct_to_idx: Default::default(), + struct_def_inst_to_idx: Default::default(), + field_to_idx: Default::default(), + field_inst_to_idx: Default::default(), + types_to_signature: Default::default(), + cons_to_idx: Default::default(), + fun_inst_to_idx: Default::default(), + main_handle: None, + script_handle: None, + module, + }; + gen.gen_module(ctx, module_env); + (gen.module, gen.main_handle) + } + + /// Generates a module, visiting all of its members. + fn gen_module(&mut self, ctx: &ModuleContext, module_env: &ModuleEnv<'_>) { + // Create the self module handle, at well known handle index 0, but only if this is not + // a script module. + if !module_env.is_script_module() { + let loc = &module_env.get_loc(); + self.module_index(ctx, loc, module_env); + } + + for struct_env in module_env.get_structs() { + self.gen_struct(ctx, &struct_env) + } + for fun_env in module_env.get_functions() { + FunctionGenerator::run(self, ctx, fun_env); + } + } + + /// Generate information for a struct. + fn gen_struct(&mut self, ctx: &ModuleContext, struct_env: &StructEnv<'_>) { + let loc = &struct_env.get_loc(); + let struct_handle = self.struct_index(ctx, loc, struct_env); + let field_information = FF::StructFieldInformation::Declared( + struct_env + .get_fields() + .map(|f| { + let name = self.name_index(ctx, loc, f.get_name()); + let signature = + FF::TypeSignature(self.signature_token(ctx, loc, &f.get_type())); + FF::FieldDefinition { name, signature } + }) + .collect(), + ); + let def = FF::StructDefinition { + struct_handle, + field_information, + }; + ctx.checked_bound( + loc, + self.module.struct_defs.len(), + MAX_STRUCT_DEF_COUNT, + "struct", + ); + self.module.struct_defs.push(def); + } + + /// Obtains or creates an index for a signature, a sequence of types. + pub fn signature( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + tys: Vec, + ) -> FF::SignatureIndex { + if let Some(idx) = self.types_to_signature.get(&tys) { + return *idx; + } + let tokens = tys + .iter() + .map(|ty| self.signature_token(ctx, loc, ty)) + .collect::>(); + let idx = FF::SignatureIndex(ctx.checked_bound( + loc, + self.module.signatures.len(), + MAX_SIGNATURE_COUNT, + "signature", + )); + self.module.signatures.push(FF::Signature(tokens)); + self.types_to_signature.insert(tys, idx); + idx + } + + /// Creates a signature token from a Move model type. + pub fn signature_token( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + ty: &Type, + ) -> FF::SignatureToken { + use PrimitiveType::*; + use Type::*; + match ty { + Primitive(kind) => match kind { + Bool => FF::SignatureToken::Bool, + U8 => FF::SignatureToken::U8, + U16 => FF::SignatureToken::U16, + U32 => FF::SignatureToken::U32, + U64 => FF::SignatureToken::U64, + U128 => FF::SignatureToken::U128, + U256 => FF::SignatureToken::U256, + Address => FF::SignatureToken::Address, + Signer => FF::SignatureToken::Signer, + Num | Range | EventStore => { + ctx.internal_error(loc, "unexpected specification type"); + FF::SignatureToken::Bool + }, + }, + Tuple(_) => { + ctx.internal_error(loc, "unexpected tuple type"); + FF::SignatureToken::Bool + }, + Vector(ty) => FF::SignatureToken::Vector(Box::new(self.signature_token(ctx, loc, ty))), + Struct(mid, sid, inst) => { + let handle = self.struct_index(ctx, loc, &ctx.env.get_struct(mid.qualified(*sid))); + if inst.is_empty() { + FF::SignatureToken::Struct(handle) + } else { + FF::SignatureToken::StructInstantiation( + handle, + inst.iter() + .map(|t| self.signature_token(ctx, loc, t)) + .collect(), + ) + } + }, + TypeParameter(p) => FF::SignatureToken::TypeParameter(*p), + Reference(kind, target_ty) => { + let target_ty = Box::new(self.signature_token(ctx, loc, target_ty)); + match kind { + ReferenceKind::Immutable => FF::SignatureToken::Reference(target_ty), + ReferenceKind::Mutable => FF::SignatureToken::MutableReference(target_ty), + } + }, + Fun(_, _) | TypeDomain(_) | ResourceDomain(_, _, _) | Error | Var(_) => { + ctx.internal_error( + loc, + format!( + "unexpected type: {}", + ty.display(&ctx.env.get_type_display_ctx()) + ), + ); + FF::SignatureToken::Bool + }, + } + } + + /// Obtains or generates an identifier index for the given symbol. + pub fn name_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + name: Symbol, + ) -> FF::IdentifierIndex { + if let Some(idx) = self.name_to_idx.get(&name) { + return *idx; + } + let ident = + if let Ok(ident) = Identifier::new(name.display(ctx.env.symbol_pool()).to_string()) { + ident + } else { + ctx.internal_error( + loc, + format!("invalid identifier {}", name.display(ctx.env.symbol_pool())), + ); + Identifier::new("error").unwrap() + }; + let idx = FF::IdentifierIndex(ctx.checked_bound( + loc, + self.module.identifiers.len(), + MAX_IDENTIFIER_COUNT, + "identifier", + )); + self.module.identifiers.push(ident); + self.name_to_idx.insert(name, idx); + idx + } + + /// Obtains or generates an identifier index for the given symbol. + pub fn address_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + addr: AccountAddress, + ) -> FF::AddressIdentifierIndex { + if let Some(idx) = self.address_to_idx.get(&addr) { + return *idx; + } + let idx = FF::AddressIdentifierIndex(ctx.checked_bound( + loc, + self.module.address_identifiers.len(), + MAX_ADDRESS_COUNT, + "address", + )); + self.module.address_identifiers.push(addr); + self.address_to_idx.insert(addr, idx); + idx + } + + // Obtains or generates a module index. + pub fn module_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + module_env: &ModuleEnv, + ) -> FF::ModuleHandleIndex { + let id = module_env.get_id(); + if let Some(idx) = self.module_to_idx.get(&id) { + return *idx; + } + let name = module_env.get_name(); + let address = self.address_index(ctx, loc, name.addr().expect_numerical()); + let name = self.name_index(ctx, loc, name.name()); + let handle = FF::ModuleHandle { address, name }; + let idx = if module_env.is_script_module() { + self.script_handle = Some(handle); + FF::ModuleHandleIndex(TableIndex::MAX) + } else { + let idx = FF::ModuleHandleIndex(ctx.checked_bound( + loc, + self.module.module_handles.len(), + MAX_MODULE_COUNT, + "used module", + )); + self.module.module_handles.push(handle); + idx + }; + self.module_to_idx.insert(id, idx); + idx + } + + /// Obtains or generates a function index. + pub fn function_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + fun_env: &FunctionEnv, + ) -> FF::FunctionHandleIndex { + if let Some(idx) = self.fun_to_idx.get(&fun_env.get_qualified_id()) { + return *idx; + } + let module = self.module_index(ctx, loc, &fun_env.module_env); + let name = self.name_index(ctx, loc, fun_env.get_name()); + let type_parameters = fun_env + .get_type_parameters() + .into_iter() + .map(|TypeParameter(_, TypeParameterKind { abilities, .. })| abilities) + .collect::>(); + let parameters = self.signature( + ctx, + loc, + fun_env + .get_parameters() + .iter() + .map(|Parameter(_, ty)| ty.to_owned()) + .collect(), + ); + let return_ = self.signature( + ctx, + loc, + fun_env.get_result_type().flatten().into_iter().collect(), + ); + let handle = FF::FunctionHandle { + module, + name, + type_parameters, + parameters, + return_, + }; + let idx = if fun_env.module_env.is_script_module() { + self.main_handle = Some(handle); + FF::FunctionHandleIndex(TableIndex::MAX) + } else { + let idx = FF::FunctionHandleIndex(ctx.checked_bound( + loc, + self.module.function_handles.len(), + MAX_FUNCTION_COUNT, + "used function", + )); + self.module.function_handles.push(handle); + idx + }; + self.fun_to_idx.insert(fun_env.get_qualified_id(), idx); + idx + } + + pub fn function_instantiation_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + fun_env: &FunctionEnv<'_>, + inst: Vec, + ) -> FF::FunctionInstantiationIndex { + let type_parameters = self.signature(ctx, loc, inst); + let cache_key = (fun_env.get_qualified_id(), type_parameters); + if let Some(idx) = self.fun_inst_to_idx.get(&cache_key) { + return *idx; + } + let handle = self.function_index(ctx, loc, fun_env); + let fun_inst = FF::FunctionInstantiation { + handle, + type_parameters, + }; + let idx = FF::FunctionInstantiationIndex(ctx.checked_bound( + loc, + self.module.function_instantiations.len(), + MAX_FUNCTION_INST_COUNT, + "function instantiation", + )); + self.module.function_instantiations.push(fun_inst); + self.fun_inst_to_idx.insert(cache_key, idx); + idx + } + + /// Obtains or generates a struct index. + pub fn struct_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + struct_env: &StructEnv<'_>, + ) -> FF::StructHandleIndex { + if let Some(idx) = self.struct_to_idx.get(&struct_env.get_qualified_id()) { + return *idx; + } + let name = self.name_index(ctx, loc, struct_env.get_name()); + let module = self.module_index(ctx, loc, &struct_env.module_env); + let handle = FF::StructHandle { + module, + name, + abilities: struct_env.get_abilities(), + type_parameters: struct_env + .get_type_parameters() + .iter() + .map( + |TypeParameter( + _sym, + TypeParameterKind { + abilities, + is_phantom, + }, + )| FF::StructTypeParameter { + constraints: *abilities, + is_phantom: *is_phantom, + }, + ) + .collect(), + }; + let idx = FF::StructHandleIndex(ctx.checked_bound( + loc, + self.module.struct_handles.len(), + MAX_STRUCT_COUNT, + "used structs", + )); + self.module.struct_handles.push(handle); + self.struct_to_idx + .insert(struct_env.get_qualified_id(), idx); + idx + } + + /// Obtains a struct definition index. + pub fn struct_def_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + struct_env: &StructEnv, + ) -> FF::StructDefinitionIndex { + let struct_idx = self.struct_index(ctx, loc, struct_env); + for (i, def) in self.module.struct_defs.iter().enumerate() { + if def.struct_handle == struct_idx { + return FF::StructDefinitionIndex::new(i as FF::TableIndex); + } + } + ctx.internal_error(loc, "struct not defined"); + FF::StructDefinitionIndex(0) + } + + /// Obtains or constructs a struct definition instantiation index. + pub fn struct_def_instantiation_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + struct_env: &StructEnv, + inst: Vec, + ) -> FF::StructDefInstantiationIndex { + let type_parameters = self.signature(ctx, loc, inst); + let cache_key = (struct_env.get_qualified_id(), type_parameters); + if let Some(idx) = self.struct_def_inst_to_idx.get(&cache_key) { + return *idx; + } + let def = self.struct_def_index(ctx, loc, struct_env); + let struct_inst = FF::StructDefInstantiation { + def, + type_parameters, + }; + let idx = FF::StructDefInstantiationIndex(ctx.checked_bound( + loc, + self.module.struct_def_instantiations.len(), + MAX_STRUCT_DEF_INST_COUNT, + "struct instantiation", + )); + self.module.struct_def_instantiations.push(struct_inst); + self.struct_def_inst_to_idx.insert(cache_key, idx); + idx + } + + /// Obtains or creates a field handle index. + pub fn field_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + field_env: &FieldEnv, + ) -> FF::FieldHandleIndex { + let key = ( + field_env.struct_env.get_qualified_id(), + field_env.get_offset(), + ); + if let Some(idx) = self.field_to_idx.get(&key) { + return *idx; + } + let field_idx = FF::FieldHandleIndex(ctx.checked_bound( + loc, + self.module.field_handles.len(), + MAX_FIELD_COUNT, + "field", + )); + let owner = self.struct_def_index(ctx, loc, &field_env.struct_env); + self.module.field_handles.push(FF::FieldHandle { + owner, + field: field_env.get_offset() as FF::MemberCount, + }); + self.field_to_idx.insert(key, field_idx); + field_idx + } + + /// Obtains or creates a field instantiation handle index. + pub fn field_inst_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + field_env: &FieldEnv, + inst: Vec, + ) -> FF::FieldInstantiationIndex { + let type_parameters = self.signature(ctx, loc, inst); + let key = ( + field_env.struct_env.get_qualified_id(), + field_env.get_offset(), + type_parameters, + ); + if let Some(idx) = self.field_inst_to_idx.get(&key) { + return *idx; + } + let field_inst_idx = FF::FieldInstantiationIndex(ctx.checked_bound( + loc, + self.module.field_instantiations.len(), + MAX_FIELD_INST_COUNT, + "field instantiation", + )); + let handle = self.field_index(ctx, loc, field_env); + self.module + .field_instantiations + .push(FF::FieldInstantiation { + handle, + type_parameters, + }); + self.field_inst_to_idx.insert(key, field_inst_idx); + field_inst_idx + } + + /// Obtains or generates a constant index. + pub fn constant_index( + &mut self, + ctx: &ModuleContext, + loc: &Loc, + cons: &Constant, + ty: &Type, + ) -> FF::ConstantPoolIndex { + if let Some(idx) = self.cons_to_idx.get(cons) { + return *idx; + } + let data = cons + .to_move_value() + .simple_serialize() + .expect("serialization succeeds"); + let ff_cons = FF::Constant { + type_: self.signature_token(ctx, loc, ty), + data, + }; + let idx = FF::ConstantPoolIndex(ctx.checked_bound( + loc, + self.module.constant_pool.len(), + MAX_CONST_COUNT, + "constant", + )); + self.module.constant_pool.push(ff_cons); + self.cons_to_idx.insert(cons.clone(), idx); + idx + } +} + +impl<'env> ModuleContext<'env> { + /// Emits an error at the location. + pub fn error(&self, loc: impl AsRef, msg: impl AsRef) { + self.env.diag(Severity::Error, loc.as_ref(), msg.as_ref()) + } + + /// Emits an internal error at the location. + pub fn internal_error(&self, loc: impl AsRef, msg: impl AsRef) { + self.env.diag(Severity::Bug, loc.as_ref(), msg.as_ref()) + } + + /// Check for a bound table index and report an error if its out of bound. All bounds + /// should be handled by this generator in a graceful and giving the user detail + /// information of the location. + pub fn checked_bound( + &self, + loc: impl AsRef, + value: usize, + max: usize, + msg: &str, + ) -> FF::TableIndex { + if value >= max { + self.error(loc, format!("exceeded maximal {} count: {}", msg, max)); + 0 + } else { + value as FF::TableIndex + } + } +} diff --git a/third_party/move/move-compiler-v2/src/lib.rs b/third_party/move/move-compiler-v2/src/lib.rs index 8799138b005ff..af5026ce70716 100644 --- a/third_party/move/move-compiler-v2/src/lib.rs +++ b/third_party/move/move-compiler-v2/src/lib.rs @@ -3,22 +3,25 @@ // SPDX-License-Identifier: Apache-2.0 mod bytecode_generator; -mod bytecode_pipeline; mod experiments; +mod file_format_generator; mod options; -use anyhow::{anyhow, bail}; +use anyhow::anyhow; use codespan_reporting::term::termcolor::{ColorChoice, StandardStream, WriteColor}; pub use experiments::*; +use move_binary_format::{file_format as FF, file_format::CompiledScript, CompiledModule}; use move_model::{model::GlobalEnv, PackageInfo}; use move_stackless_bytecode::function_target_pipeline::{ FunctionTargetPipeline, FunctionTargetsHolder, FunctionVariant, }; pub use options::*; -use std::path::Path; +use std::{collections::BTreeSet, path::Path}; /// Run Move compiler and print errors to stderr. -pub fn run_move_compiler_to_stderr(options: Options) -> anyhow::Result<()> { +pub fn run_move_compiler_to_stderr( + options: Options, +) -> anyhow::Result<(Vec, Vec)> { let mut error_writer = StandardStream::stderr(ColorChoice::Auto); run_move_compiler(&mut error_writer, options) } @@ -27,7 +30,7 @@ pub fn run_move_compiler_to_stderr(options: Options) -> anyhow::Result<()> { pub fn run_move_compiler( error_writer: &mut impl WriteColor, options: Options, -) -> anyhow::Result<()> { +) -> anyhow::Result<(Vec, Vec)> { // Run context check. let env = run_checker(options.clone())?; check_errors(&env, error_writer, "checking errors")?; @@ -52,7 +55,9 @@ pub fn run_move_compiler( } else { pipeline.run(&env, &mut targets) } - bail!("bytecode lowering not implemented") + let modules_and_scripts = run_file_format_gen(&env, &targets); + check_errors(&env, error_writer, "assembling errors")?; + Ok(modules_and_scripts) } /// Run the type checker and return the global env (with errors if encountered). The result @@ -80,18 +85,40 @@ pub fn run_checker(options: Options) -> anyhow::Result { // like the generated bytecode. pub fn run_bytecode_gen(env: &GlobalEnv) -> FunctionTargetsHolder { let mut targets = FunctionTargetsHolder::default(); + let mut todo = BTreeSet::new(); + let mut done = BTreeSet::new(); for module in env.get_modules() { if module.is_target() { for fun in module.get_functions() { let id = fun.get_qualified_id(); - let data = bytecode_generator::generate_bytecode(env, id); - targets.insert_target_data(&id, FunctionVariant::Baseline, data) + todo.insert(id); + } + } + } + while let Some(id) = todo.pop_first() { + done.insert(id); + let data = bytecode_generator::generate_bytecode(env, id); + targets.insert_target_data(&id, FunctionVariant::Baseline, data); + for callee in env + .get_function(id) + .get_called_functions() + .expect("called functions available") + { + if !done.contains(callee) { + todo.insert(*callee); } } } targets } +pub fn run_file_format_gen( + env: &GlobalEnv, + targets: &FunctionTargetsHolder, +) -> (Vec, Vec) { + file_format_generator::generate_file_format(env, targets) +} + /// Returns the bytecode processing pipeline. pub fn bytecode_pipeline(_env: &GlobalEnv) -> FunctionTargetPipeline { // TODO: insert processors here as we proceed. diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/fields.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/fields.exp index c08a4bfaf34ac..caa2b3ac07020 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/fields.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/fields.exp @@ -76,20 +76,20 @@ fun fields::write_local_direct(): fields::S { var $t3: u64 var $t4: fields::T var $t5: u64 - var $t6: &mut u64 - var $t7: &mut fields::T - var $t8: &mut fields::S - var $t9: u64 + var $t6: u64 + var $t7: &mut u64 + var $t8: &mut fields::T + var $t9: &mut fields::S 0: $t3 := 0 1: $t5 := 0 2: $t4 := pack fields::T($t5) 3: $t2 := pack fields::S($t3, $t4) 4: $t1 := move($t2) - 5: $t8 := borrow_local($t1) - 6: $t7 := borrow_field.g($t8) - 7: $t6 := borrow_field.h($t7) - 8: $t9 := 42 - 9: write_ref($t6, $t9) + 5: $t6 := 42 + 6: $t9 := borrow_local($t1) + 7: $t8 := borrow_field.g($t9) + 8: $t7 := borrow_field.h($t8) + 9: write_ref($t7, $t6) 10: $t0 := move($t1) 11: return $t0 } @@ -105,9 +105,9 @@ fun fields::write_local_via_ref(): fields::S { var $t5: u64 var $t6: &mut fields::S var $t7: &mut fields::S - var $t8: &mut u64 - var $t9: &mut fields::T - var $t10: u64 + var $t8: u64 + var $t9: &mut u64 + var $t10: &mut fields::T 0: $t3 := 0 1: $t5 := 0 2: $t4 := pack fields::T($t5) @@ -115,10 +115,10 @@ fun fields::write_local_via_ref(): fields::S { 4: $t1 := move($t2) 5: $t7 := borrow_local($t1) 6: $t6 := move($t7) - 7: $t9 := borrow_field.g($t6) - 8: $t8 := borrow_field.h($t9) - 9: $t10 := 42 - 10: write_ref($t8, $t10) + 7: $t8 := 42 + 8: $t10 := borrow_field.g($t6) + 9: $t9 := borrow_field.h($t10) + 10: write_ref($t9, $t8) 11: $t0 := move($t1) 12: return $t0 } @@ -126,13 +126,13 @@ fun fields::write_local_via_ref(): fields::S { [variant baseline] fun fields::write_param($t0: &mut fields::S) { - var $t1: &mut u64 - var $t2: &mut fields::T - var $t3: u64 - 0: $t2 := borrow_field.g($t0) - 1: $t1 := borrow_field.h($t2) - 2: $t3 := 42 - 3: write_ref($t1, $t3) + var $t1: u64 + var $t2: &mut u64 + var $t3: &mut fields::T + 0: $t1 := 42 + 1: $t3 := borrow_field.g($t0) + 2: $t2 := borrow_field.h($t3) + 3: write_ref($t2, $t1) 4: return () } @@ -140,15 +140,15 @@ fun fields::write_param($t0: &mut fields::S) { [variant baseline] fun fields::write_val($t0: fields::S): fields::S { var $t1: fields::S - var $t2: &mut u64 - var $t3: &mut fields::T - var $t4: &mut fields::S - var $t5: u64 - 0: $t4 := borrow_local($t0) - 1: $t3 := borrow_field.g($t4) - 2: $t2 := borrow_field.h($t3) - 3: $t5 := 42 - 4: write_ref($t2, $t5) + var $t2: u64 + var $t3: &mut u64 + var $t4: &mut fields::T + var $t5: &mut fields::S + 0: $t2 := 42 + 1: $t5 := borrow_local($t0) + 2: $t4 := borrow_field.g($t5) + 3: $t3 := borrow_field.h($t4) + 4: write_ref($t3, $t2) 5: $t1 := move($t0) 6: return $t1 } diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp index f55e4cc3be215..24936dde07656 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/globals.exp @@ -65,13 +65,13 @@ fun globals::write($t0: address, $t1: u64): u64 { var $t2: u64 var $t3: &mut globals::R var $t4: &mut globals::R - var $t5: &mut u64 - var $t6: u64 + var $t5: u64 + var $t6: &mut u64 0: $t4 := borrow_global($t0) 1: $t3 := move($t4) - 2: $t5 := borrow_field.f($t3) - 3: $t6 := 2 - 4: write_ref($t5, $t6) + 2: $t5 := 2 + 3: $t6 := borrow_field.f($t3) + 4: write_ref($t6, $t5) 5: $t2 := 9 6: return $t2 } diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.exp b/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.exp index 588ffa560cddb..1fec9e325c643 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.exp +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.exp @@ -3,8 +3,8 @@ module 0x42::operators { private fun arithm(x: u64,y: u64) { Add(x, Mod(Mul(Div(y, Sub(x, y)), y), x)) } - private fun bits(x: u64,y: u64) { - BitOr(BitAnd(Shl(x, y), x), Xor(Shr(y, x), y)) + private fun bits(x: u64,y: u8) { + BitAnd(Shl(x, y), x) } private fun bools(x: bool,y: bool) { Or(Or(Or(And(x, y), And(x, Not(y))), And(Not(x), y)), And(Not(x), Not(y))) @@ -39,18 +39,12 @@ fun operators::arithm($t0: u64, $t1: u64): u64 { [variant baseline] -fun operators::bits($t0: u64, $t1: u64): u64 { +fun operators::bits($t0: u64, $t1: u8): u64 { var $t2: u64 var $t3: u64 - var $t4: u64 - var $t5: u64 - var $t6: u64 - 0: $t4 := <<($t0, $t1) - 1: $t3 := &($t4, $t0) - 2: $t6 := >>($t1, $t0) - 3: $t5 := ^($t6, $t1) - 4: $t2 := |($t3, $t5) - 5: return $t2 + 0: $t3 := <<($t0, $t1) + 1: $t2 := &($t3, $t0) + 2: return $t2 } @@ -62,23 +56,55 @@ fun operators::bools($t0: bool, $t1: bool): bool { var $t5: bool var $t6: bool var $t7: bool - var $t8: bool - var $t9: bool - var $t10: bool - var $t11: bool - var $t12: bool - 0: $t5 := &&($t0, $t1) - 1: $t7 := !($t1) - 2: $t6 := &&($t0, $t7) - 3: $t4 := ||($t5, $t6) - 4: $t9 := !($t0) - 5: $t8 := &&($t9, $t1) - 6: $t3 := ||($t4, $t8) - 7: $t11 := !($t0) - 8: $t12 := !($t1) - 9: $t10 := &&($t11, $t12) - 10: $t2 := ||($t3, $t10) - 11: return $t2 + 0: if ($t0) goto 1 else goto 4 + 1: label L0 + 2: $t5 := move($t1) + 3: goto 6 + 4: label L1 + 5: $t5 := false + 6: label L2 + 7: if ($t5) goto 8 else goto 11 + 8: label L3 + 9: $t4 := true + 10: goto 19 + 11: label L4 + 12: if ($t0) goto 13 else goto 16 + 13: label L6 + 14: $t4 := !($t1) + 15: goto 18 + 16: label L7 + 17: $t4 := false + 18: label L8 + 19: label L5 + 20: if ($t4) goto 21 else goto 24 + 21: label L9 + 22: $t3 := true + 23: goto 33 + 24: label L10 + 25: $t6 := !($t0) + 26: if ($t6) goto 27 else goto 30 + 27: label L12 + 28: $t3 := move($t1) + 29: goto 32 + 30: label L13 + 31: $t3 := false + 32: label L14 + 33: label L11 + 34: if ($t3) goto 35 else goto 38 + 35: label L15 + 36: $t2 := true + 37: goto 47 + 38: label L16 + 39: $t7 := !($t0) + 40: if ($t7) goto 41 else goto 44 + 41: label L18 + 42: $t2 := !($t1) + 43: goto 46 + 44: label L19 + 45: $t2 := false + 46: label L20 + 47: label L17 + 48: return $t2 } @@ -106,17 +132,29 @@ fun operators::order($t0: u64, $t1: u64): bool { var $t5: bool var $t6: bool var $t7: bool - var $t8: bool - var $t9: bool - var $t10: bool 0: $t5 := <($t0, $t1) - 1: $t6 := <=($t0, $t1) - 2: $t4 := &&($t5, $t6) - 3: $t8 := >($t0, $t1) - 4: $t7 := !($t8) - 5: $t3 := &&($t4, $t7) - 6: $t10 := >=($t0, $t1) - 7: $t9 := !($t10) - 8: $t2 := &&($t3, $t9) - 9: return $t2 + 1: if ($t5) goto 2 else goto 5 + 2: label L0 + 3: $t4 := <=($t0, $t1) + 4: goto 7 + 5: label L1 + 6: $t4 := false + 7: label L2 + 8: if ($t4) goto 9 else goto 13 + 9: label L3 + 10: $t6 := >($t0, $t1) + 11: $t3 := !($t6) + 12: goto 15 + 13: label L4 + 14: $t3 := false + 15: label L5 + 16: if ($t3) goto 17 else goto 21 + 17: label L6 + 18: $t7 := >=($t0, $t1) + 19: $t2 := !($t7) + 20: goto 23 + 21: label L7 + 22: $t2 := false + 23: label L8 + 24: return $t2 } diff --git a/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.move b/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.move index 831bc2b6835fe..84b7e474d18a5 100644 --- a/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.move +++ b/third_party/move/move-compiler-v2/tests/bytecode-generator/operators.move @@ -3,8 +3,8 @@ module 0x42::operators { x + y / (x - y) * y % x } - fun bits(x: u64, y: u64): u64 { - x << y & x | y >> x ^ y + fun bits(x: u64, y: u8): u64 { + x << y & x } fun bools(x: bool, y: bool): bool { diff --git a/third_party/move/move-compiler-v2/tests/checking/specs/assert_skipped_for_spec.exp b/third_party/move/move-compiler-v2/tests/checking/specs/assert_skipped_for_spec.exp index 803712bf84eb4..3972e3333a093 100644 --- a/third_party/move/move-compiler-v2/tests/checking/specs/assert_skipped_for_spec.exp +++ b/third_party/move/move-compiler-v2/tests/checking/specs/assert_skipped_for_spec.exp @@ -2,9 +2,9 @@ module 0x42::M { private fun bar(x: u64) { if Gt(x, 0) { - Abort(1) - } else { Tuple() + } else { + Abort(1) }; Sub(x, 1) } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl.exp index 42df35ef2197d..cba5c27bb6bae 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl.exp @@ -1,27 +1,20 @@ - -Diagnostics: -error: no matching declaration of `<<` - ┌─ tests/checking/typing/binary_shl.move:15:9 - │ -15 │ copy x << copy b; - │ ^^^^^^^^^^^^^^^^ - │ - = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `u64` for argument 1) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `u64` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `u64` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `u8` for argument 2) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `u64` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `u64` for argument 1) - -error: no matching declaration of `<<` - ┌─ tests/checking/typing/binary_shl.move:16:9 - │ -16 │ r.f << r.b; - │ ^^^^^^^^^^ - │ - = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `u64` for argument 1) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `u64` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `u64` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `u8` for argument 2) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `u64` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `u64` for argument 1) +// ---- Model Dump +module 0x8675309::M { + struct R { + f: u64, + b: u8, + } + private fun t0(x: u64,b: u8,r: M::R) { + Shl(0, 0); + Shl(1, 0); + Shl(0, 1); + Shl(0, 1); + Add(0, 1); + Shl(0, 1); + Shl(0, 1); + Shl(x, b); + Shl(select M::R.f(r), select M::R.b(r)); + Shl(Shl(Shl(1, select M::R.b(r)), select M::R.b(r)), 0); + M::R{ f: _, b: _ } = r + } +} // end 0x8675309::M diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl_invalid.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl_invalid.exp index 2350b0305793d..4936be7e2552c 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shl_invalid.exp @@ -7,11 +7,11 @@ error: no matching declaration of `<<` │ ^^^^^^^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `bool` for argument 1) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `bool` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `bool` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `bool` for argument 1) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `bool` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `bool` for argument 1) + = outruled candidate `<<(u16, u8): u16` (expected `u16` but found `bool` for argument 1) + = outruled candidate `<<(u32, u8): u32` (expected `u32` but found `bool` for argument 1) + = outruled candidate `<<(u64, u8): u64` (expected `u64` but found `bool` for argument 1) + = outruled candidate `<<(u128, u8): u128` (expected `u128` but found `bool` for argument 1) + = outruled candidate `<<(u256, u8): u256` (expected `u256` but found `bool` for argument 1) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:9:9 @@ -20,11 +20,11 @@ error: no matching declaration of `<<` │ ^^^^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `bool` for argument 2) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `bool` for argument 2) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `bool` for argument 2) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `bool` for argument 2) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `bool` for argument 2) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `bool` for argument 2) + = outruled candidate `<<(u16, u8): u16` (expected `u8` but found `bool` for argument 2) + = outruled candidate `<<(u32, u8): u32` (expected `u8` but found `bool` for argument 2) + = outruled candidate `<<(u64, u8): u64` (expected `u8` but found `bool` for argument 2) + = outruled candidate `<<(u128, u8): u128` (expected `u8` but found `bool` for argument 2) + = outruled candidate `<<(u256, u8): u256` (expected `u8` but found `bool` for argument 2) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:10:9 @@ -33,11 +33,11 @@ error: no matching declaration of `<<` │ ^^^^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `bool` for argument 1) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `bool` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `bool` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `bool` for argument 1) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `bool` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `bool` for argument 1) + = outruled candidate `<<(u16, u8): u16` (expected `u16` but found `bool` for argument 1) + = outruled candidate `<<(u32, u8): u32` (expected `u32` but found `bool` for argument 1) + = outruled candidate `<<(u64, u8): u64` (expected `u64` but found `bool` for argument 1) + = outruled candidate `<<(u128, u8): u128` (expected `u128` but found `bool` for argument 1) + = outruled candidate `<<(u256, u8): u256` (expected `u256` but found `bool` for argument 1) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:11:9 @@ -46,11 +46,11 @@ error: no matching declaration of `<<` │ ^^^^^^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `address` for argument 1) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `address` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `address` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `address` for argument 1) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `address` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `address` for argument 1) + = outruled candidate `<<(u16, u8): u16` (expected `u16` but found `address` for argument 1) + = outruled candidate `<<(u32, u8): u32` (expected `u32` but found `address` for argument 1) + = outruled candidate `<<(u64, u8): u64` (expected `u64` but found `address` for argument 1) + = outruled candidate `<<(u128, u8): u128` (expected `u128` but found `address` for argument 1) + = outruled candidate `<<(u256, u8): u256` (expected `u256` but found `address` for argument 1) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:12:9 @@ -59,11 +59,11 @@ error: no matching declaration of `<<` │ ^^^^^^^^^^^^^^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `u128` for argument 2) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `u8` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `u8` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `u8` for argument 1) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `u8` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `u8` for argument 1) + = outruled candidate `<<(u16, u8): u16` (expected `u16` but found `u8` for argument 1) + = outruled candidate `<<(u32, u8): u32` (expected `u32` but found `u8` for argument 1) + = outruled candidate `<<(u64, u8): u64` (expected `u64` but found `u8` for argument 1) + = outruled candidate `<<(u128, u8): u128` (expected `u128` but found `u8` for argument 1) + = outruled candidate `<<(u256, u8): u256` (expected `u256` but found `u8` for argument 1) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:13:9 @@ -72,11 +72,11 @@ error: no matching declaration of `<<` │ ^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `M::R` for argument 1) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `M::R` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `M::R` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `M::R` for argument 1) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `M::R` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `M::R` for argument 1) + = outruled candidate `<<(u16, u8): u16` (expected `u16` but found `M::R` for argument 1) + = outruled candidate `<<(u32, u8): u32` (expected `u32` but found `M::R` for argument 1) + = outruled candidate `<<(u64, u8): u64` (expected `u64` but found `M::R` for argument 1) + = outruled candidate `<<(u128, u8): u128` (expected `u128` but found `M::R` for argument 1) + = outruled candidate `<<(u256, u8): u256` (expected `u256` but found `M::R` for argument 1) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:14:9 @@ -85,11 +85,11 @@ error: no matching declaration of `<<` │ ^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `M::S` for argument 1) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `M::S` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `M::S` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `M::S` for argument 1) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `M::S` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `M::S` for argument 1) + = outruled candidate `<<(u16, u8): u16` (expected `u16` but found `M::S` for argument 1) + = outruled candidate `<<(u32, u8): u32` (expected `u32` but found `M::S` for argument 1) + = outruled candidate `<<(u64, u8): u64` (expected `u64` but found `M::S` for argument 1) + = outruled candidate `<<(u128, u8): u128` (expected `u128` but found `M::S` for argument 1) + = outruled candidate `<<(u256, u8): u256` (expected `u256` but found `M::S` for argument 1) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:15:9 @@ -98,11 +98,11 @@ error: no matching declaration of `<<` │ ^^^^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `bool` for argument 2) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `bool` for argument 2) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `bool` for argument 2) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `bool` for argument 2) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `bool` for argument 2) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `bool` for argument 2) + = outruled candidate `<<(u16, u8): u16` (expected `u8` but found `bool` for argument 2) + = outruled candidate `<<(u32, u8): u32` (expected `u8` but found `bool` for argument 2) + = outruled candidate `<<(u64, u8): u64` (expected `u8` but found `bool` for argument 2) + = outruled candidate `<<(u128, u8): u128` (expected `u8` but found `bool` for argument 2) + = outruled candidate `<<(u256, u8): u256` (expected `u8` but found `bool` for argument 2) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:15:9 @@ -111,11 +111,11 @@ error: no matching declaration of `<<` │ ^^^^^^^^^^^^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `address` for argument 2) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `address` for argument 2) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `address` for argument 2) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `address` for argument 2) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `address` for argument 2) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `address` for argument 2) + = outruled candidate `<<(u16, u8): u16` (expected `u8` but found `address` for argument 2) + = outruled candidate `<<(u32, u8): u32` (expected `u8` but found `address` for argument 2) + = outruled candidate `<<(u64, u8): u64` (expected `u8` but found `address` for argument 2) + = outruled candidate `<<(u128, u8): u128` (expected `u8` but found `address` for argument 2) + = outruled candidate `<<(u256, u8): u256` (expected `u8` but found `address` for argument 2) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:16:9 @@ -124,11 +124,11 @@ error: no matching declaration of `<<` │ ^^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `()` for argument 1) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `()` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `()` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `()` for argument 1) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `()` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `()` for argument 1) + = outruled candidate `<<(u16, u8): u16` (expected `u16` but found `()` for argument 1) + = outruled candidate `<<(u32, u8): u32` (expected `u32` but found `()` for argument 1) + = outruled candidate `<<(u64, u8): u64` (expected `u64` but found `()` for argument 1) + = outruled candidate `<<(u128, u8): u128` (expected `u128` but found `()` for argument 1) + = outruled candidate `<<(u256, u8): u256` (expected `u256` but found `()` for argument 1) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:17:9 @@ -137,11 +137,11 @@ error: no matching declaration of `<<` │ ^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `()` for argument 2) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `()` for argument 2) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `()` for argument 2) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `()` for argument 2) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `()` for argument 2) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `()` for argument 2) + = outruled candidate `<<(u16, u8): u16` (expected `u8` but found `()` for argument 2) + = outruled candidate `<<(u32, u8): u32` (expected `u8` but found `()` for argument 2) + = outruled candidate `<<(u64, u8): u64` (expected `u8` but found `()` for argument 2) + = outruled candidate `<<(u128, u8): u128` (expected `u8` but found `()` for argument 2) + = outruled candidate `<<(u256, u8): u256` (expected `u8` but found `()` for argument 2) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:18:9 @@ -150,11 +150,11 @@ error: no matching declaration of `<<` │ ^^^^^^^^^^^^^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `(integer, integer)` for argument 1) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `(integer, integer)` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `(integer, integer)` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `(integer, integer)` for argument 1) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `(integer, integer)` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `(integer, integer)` for argument 1) + = outruled candidate `<<(u16, u8): u16` (expected `u16` but found `(integer, integer)` for argument 1) + = outruled candidate `<<(u32, u8): u32` (expected `u32` but found `(integer, integer)` for argument 1) + = outruled candidate `<<(u64, u8): u64` (expected `u64` but found `(integer, integer)` for argument 1) + = outruled candidate `<<(u128, u8): u128` (expected `u128` but found `(integer, integer)` for argument 1) + = outruled candidate `<<(u256, u8): u256` (expected `u256` but found `(integer, integer)` for argument 1) error: no matching declaration of `<<` ┌─ tests/checking/typing/binary_shl_invalid.move:19:9 @@ -163,8 +163,8 @@ error: no matching declaration of `<<` │ ^^^^^^^^^^^^^^^^ │ = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `(integer, integer)` for argument 1) - = outruled candidate `<<(u16, u16): u16` (expected `u16` but found `(integer, integer)` for argument 1) - = outruled candidate `<<(u32, u32): u32` (expected `u32` but found `(integer, integer)` for argument 1) - = outruled candidate `<<(u64, u64): u64` (expected `u64` but found `(integer, integer)` for argument 1) - = outruled candidate `<<(u128, u128): u128` (expected `u128` but found `(integer, integer)` for argument 1) - = outruled candidate `<<(u256, u256): u256` (expected `u256` but found `(integer, integer)` for argument 1) + = outruled candidate `<<(u16, u8): u16` (expected `u16` but found `(integer, integer)` for argument 1) + = outruled candidate `<<(u32, u8): u32` (expected `u32` but found `(integer, integer)` for argument 1) + = outruled candidate `<<(u64, u8): u64` (expected `u64` but found `(integer, integer)` for argument 1) + = outruled candidate `<<(u128, u8): u128` (expected `u128` but found `(integer, integer)` for argument 1) + = outruled candidate `<<(u256, u8): u256` (expected `u256` but found `(integer, integer)` for argument 1) diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr.exp index 78798eb1228d8..440e47c084a18 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr.exp @@ -1,27 +1,20 @@ - -Diagnostics: -error: no matching declaration of `>>` - ┌─ tests/checking/typing/binary_shr.move:15:9 - │ -15 │ copy x >> copy b; - │ ^^^^^^^^^^^^^^^^ - │ - = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `u64` for argument 1) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `u64` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `u64` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `u8` for argument 2) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `u64` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `u64` for argument 1) - -error: no matching declaration of `>>` - ┌─ tests/checking/typing/binary_shr.move:16:9 - │ -16 │ r.f >> r.b; - │ ^^^^^^^^^^ - │ - = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `u64` for argument 1) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `u64` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `u64` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `u8` for argument 2) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `u64` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `u64` for argument 1) +// ---- Model Dump +module 0x8675309::M { + struct R { + f: u64, + b: u8, + } + private fun t0(x: u64,b: u8,r: M::R) { + Shr(0, 0); + Shr(1, 0); + Shr(0, 1); + Shr(0, 1); + Add(0, 1); + Shr(0, 1); + Shr(0, 1); + Shr(x, b); + Shr(select M::R.f(r), select M::R.b(r)); + Shr(Shr(Shr(1, select M::R.b(r)), select M::R.b(r)), 0); + M::R{ f: _, b: _ } = r + } +} // end 0x8675309::M diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr_invalid.exp b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr_invalid.exp index dcb53c65aa75d..c9ab598cb050a 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr_invalid.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/binary_shr_invalid.exp @@ -7,11 +7,11 @@ error: no matching declaration of `>>` │ ^^^^^^^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `bool` for argument 1) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `bool` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `bool` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `bool` for argument 1) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `bool` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `bool` for argument 1) + = outruled candidate `>>(u16, u8): u16` (expected `u16` but found `bool` for argument 1) + = outruled candidate `>>(u32, u8): u32` (expected `u32` but found `bool` for argument 1) + = outruled candidate `>>(u64, u8): u64` (expected `u64` but found `bool` for argument 1) + = outruled candidate `>>(u128, u8): u128` (expected `u128` but found `bool` for argument 1) + = outruled candidate `>>(u256, u8): u256` (expected `u256` but found `bool` for argument 1) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:9:9 @@ -20,11 +20,11 @@ error: no matching declaration of `>>` │ ^^^^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `bool` for argument 2) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `bool` for argument 2) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `bool` for argument 2) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `bool` for argument 2) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `bool` for argument 2) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `bool` for argument 2) + = outruled candidate `>>(u16, u8): u16` (expected `u8` but found `bool` for argument 2) + = outruled candidate `>>(u32, u8): u32` (expected `u8` but found `bool` for argument 2) + = outruled candidate `>>(u64, u8): u64` (expected `u8` but found `bool` for argument 2) + = outruled candidate `>>(u128, u8): u128` (expected `u8` but found `bool` for argument 2) + = outruled candidate `>>(u256, u8): u256` (expected `u8` but found `bool` for argument 2) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:10:9 @@ -33,11 +33,11 @@ error: no matching declaration of `>>` │ ^^^^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `bool` for argument 1) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `bool` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `bool` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `bool` for argument 1) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `bool` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `bool` for argument 1) + = outruled candidate `>>(u16, u8): u16` (expected `u16` but found `bool` for argument 1) + = outruled candidate `>>(u32, u8): u32` (expected `u32` but found `bool` for argument 1) + = outruled candidate `>>(u64, u8): u64` (expected `u64` but found `bool` for argument 1) + = outruled candidate `>>(u128, u8): u128` (expected `u128` but found `bool` for argument 1) + = outruled candidate `>>(u256, u8): u256` (expected `u256` but found `bool` for argument 1) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:11:9 @@ -46,11 +46,11 @@ error: no matching declaration of `>>` │ ^^^^^^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `address` for argument 1) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `address` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `address` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `address` for argument 1) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `address` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `address` for argument 1) + = outruled candidate `>>(u16, u8): u16` (expected `u16` but found `address` for argument 1) + = outruled candidate `>>(u32, u8): u32` (expected `u32` but found `address` for argument 1) + = outruled candidate `>>(u64, u8): u64` (expected `u64` but found `address` for argument 1) + = outruled candidate `>>(u128, u8): u128` (expected `u128` but found `address` for argument 1) + = outruled candidate `>>(u256, u8): u256` (expected `u256` but found `address` for argument 1) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:12:9 @@ -59,11 +59,11 @@ error: no matching declaration of `>>` │ ^^^^^^^^^^^^^^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `u128` for argument 2) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `u8` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `u8` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `u8` for argument 1) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `u8` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `u8` for argument 1) + = outruled candidate `>>(u16, u8): u16` (expected `u16` but found `u8` for argument 1) + = outruled candidate `>>(u32, u8): u32` (expected `u32` but found `u8` for argument 1) + = outruled candidate `>>(u64, u8): u64` (expected `u64` but found `u8` for argument 1) + = outruled candidate `>>(u128, u8): u128` (expected `u128` but found `u8` for argument 1) + = outruled candidate `>>(u256, u8): u256` (expected `u256` but found `u8` for argument 1) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:13:9 @@ -72,11 +72,11 @@ error: no matching declaration of `>>` │ ^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `M::R` for argument 1) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `M::R` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `M::R` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `M::R` for argument 1) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `M::R` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `M::R` for argument 1) + = outruled candidate `>>(u16, u8): u16` (expected `u16` but found `M::R` for argument 1) + = outruled candidate `>>(u32, u8): u32` (expected `u32` but found `M::R` for argument 1) + = outruled candidate `>>(u64, u8): u64` (expected `u64` but found `M::R` for argument 1) + = outruled candidate `>>(u128, u8): u128` (expected `u128` but found `M::R` for argument 1) + = outruled candidate `>>(u256, u8): u256` (expected `u256` but found `M::R` for argument 1) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:14:9 @@ -85,11 +85,11 @@ error: no matching declaration of `>>` │ ^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `M::S` for argument 1) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `M::S` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `M::S` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `M::S` for argument 1) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `M::S` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `M::S` for argument 1) + = outruled candidate `>>(u16, u8): u16` (expected `u16` but found `M::S` for argument 1) + = outruled candidate `>>(u32, u8): u32` (expected `u32` but found `M::S` for argument 1) + = outruled candidate `>>(u64, u8): u64` (expected `u64` but found `M::S` for argument 1) + = outruled candidate `>>(u128, u8): u128` (expected `u128` but found `M::S` for argument 1) + = outruled candidate `>>(u256, u8): u256` (expected `u256` but found `M::S` for argument 1) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:15:9 @@ -98,11 +98,11 @@ error: no matching declaration of `>>` │ ^^^^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `bool` for argument 2) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `bool` for argument 2) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `bool` for argument 2) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `bool` for argument 2) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `bool` for argument 2) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `bool` for argument 2) + = outruled candidate `>>(u16, u8): u16` (expected `u8` but found `bool` for argument 2) + = outruled candidate `>>(u32, u8): u32` (expected `u8` but found `bool` for argument 2) + = outruled candidate `>>(u64, u8): u64` (expected `u8` but found `bool` for argument 2) + = outruled candidate `>>(u128, u8): u128` (expected `u8` but found `bool` for argument 2) + = outruled candidate `>>(u256, u8): u256` (expected `u8` but found `bool` for argument 2) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:15:9 @@ -111,11 +111,11 @@ error: no matching declaration of `>>` │ ^^^^^^^^^^^^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `address` for argument 2) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `address` for argument 2) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `address` for argument 2) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `address` for argument 2) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `address` for argument 2) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `address` for argument 2) + = outruled candidate `>>(u16, u8): u16` (expected `u8` but found `address` for argument 2) + = outruled candidate `>>(u32, u8): u32` (expected `u8` but found `address` for argument 2) + = outruled candidate `>>(u64, u8): u64` (expected `u8` but found `address` for argument 2) + = outruled candidate `>>(u128, u8): u128` (expected `u8` but found `address` for argument 2) + = outruled candidate `>>(u256, u8): u256` (expected `u8` but found `address` for argument 2) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:16:9 @@ -124,11 +124,11 @@ error: no matching declaration of `>>` │ ^^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `()` for argument 1) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `()` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `()` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `()` for argument 1) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `()` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `()` for argument 1) + = outruled candidate `>>(u16, u8): u16` (expected `u16` but found `()` for argument 1) + = outruled candidate `>>(u32, u8): u32` (expected `u32` but found `()` for argument 1) + = outruled candidate `>>(u64, u8): u64` (expected `u64` but found `()` for argument 1) + = outruled candidate `>>(u128, u8): u128` (expected `u128` but found `()` for argument 1) + = outruled candidate `>>(u256, u8): u256` (expected `u256` but found `()` for argument 1) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:17:9 @@ -137,11 +137,11 @@ error: no matching declaration of `>>` │ ^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `()` for argument 2) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `()` for argument 2) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `()` for argument 2) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `()` for argument 2) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `()` for argument 2) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `()` for argument 2) + = outruled candidate `>>(u16, u8): u16` (expected `u8` but found `()` for argument 2) + = outruled candidate `>>(u32, u8): u32` (expected `u8` but found `()` for argument 2) + = outruled candidate `>>(u64, u8): u64` (expected `u8` but found `()` for argument 2) + = outruled candidate `>>(u128, u8): u128` (expected `u8` but found `()` for argument 2) + = outruled candidate `>>(u256, u8): u256` (expected `u8` but found `()` for argument 2) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:18:9 @@ -150,11 +150,11 @@ error: no matching declaration of `>>` │ ^^^^^^^^^^^^^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `(integer, integer)` for argument 1) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `(integer, integer)` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `(integer, integer)` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `(integer, integer)` for argument 1) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `(integer, integer)` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `(integer, integer)` for argument 1) + = outruled candidate `>>(u16, u8): u16` (expected `u16` but found `(integer, integer)` for argument 1) + = outruled candidate `>>(u32, u8): u32` (expected `u32` but found `(integer, integer)` for argument 1) + = outruled candidate `>>(u64, u8): u64` (expected `u64` but found `(integer, integer)` for argument 1) + = outruled candidate `>>(u128, u8): u128` (expected `u128` but found `(integer, integer)` for argument 1) + = outruled candidate `>>(u256, u8): u256` (expected `u256` but found `(integer, integer)` for argument 1) error: no matching declaration of `>>` ┌─ tests/checking/typing/binary_shr_invalid.move:19:9 @@ -163,8 +163,8 @@ error: no matching declaration of `>>` │ ^^^^^^^^^^^^^^^^ │ = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `(integer, integer)` for argument 1) - = outruled candidate `>>(u16, u16): u16` (expected `u16` but found `(integer, integer)` for argument 1) - = outruled candidate `>>(u32, u32): u32` (expected `u32` but found `(integer, integer)` for argument 1) - = outruled candidate `>>(u64, u64): u64` (expected `u64` but found `(integer, integer)` for argument 1) - = outruled candidate `>>(u128, u128): u128` (expected `u128` but found `(integer, integer)` for argument 1) - = outruled candidate `>>(u256, u256): u256` (expected `u256` but found `(integer, integer)` for argument 1) + = outruled candidate `>>(u16, u8): u16` (expected `u16` but found `(integer, integer)` for argument 1) + = outruled candidate `>>(u32, u8): u32` (expected `u32` but found `(integer, integer)` for argument 1) + = outruled candidate `>>(u64, u8): u64` (expected `u64` but found `(integer, integer)` for argument 1) + = outruled candidate `>>(u128, u8): u128` (expected `u128` but found `(integer, integer)` for argument 1) + = outruled candidate `>>(u256, u8): u256` (expected `u256` but found `(integer, integer)` for argument 1) diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/constant_all_valid_types.exp b/third_party/move/move-compiler-v2/tests/checking/typing/constant_all_valid_types.exp index 099f6616a0e63..e2eb3f04d31fe 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/constant_all_valid_types.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/constant_all_valid_types.exp @@ -22,3 +22,15 @@ module 0x42::M { [97, 98, 99, 100] } } // end 0x42::M +module { + private fun t() { + 0; + 0; + 0; + false; + 0x0; + [1, 35]; + [97, 98, 99, 100]; + Tuple() + } +} // end diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins_script.exp b/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins_script.exp index 7685f36b32f53..86c36bfd527f8 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins_script.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/global_builtins_script.exp @@ -7,3 +7,13 @@ module 0x42::M { pack M::R(false) } } // end 0x42::M +module { + private fun test(account: signer) { + { + let r: M::R = M::new(); + BorrowGlobal(Immutable)(0x1); + MoveTo(Borrow(Immutable)(account), r); + Tuple() + } + } +} // end diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/hex_and_decimal_address.exp b/third_party/move/move-compiler-v2/tests/checking/typing/hex_and_decimal_address.exp index e721755bea456..3cc5b9d0f50f8 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/hex_and_decimal_address.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/hex_and_decimal_address.exp @@ -10,3 +10,12 @@ module 0x7b::M { Tuple() } } // end 0x7b::M +module { + private fun main() { + M::take(M::s()); + M::take(M::s()); + M::take(M::s()); + M::take(M::s()); + Tuple() + } +} // end diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/if_default_else.exp b/third_party/move/move-compiler-v2/tests/checking/typing/if_default_else.exp index a32bd60de90ec..be4b1cb265d3e 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/if_default_else.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/if_default_else.exp @@ -15,7 +15,7 @@ module 0x8675309::M { { let () = if cond { { - let x: () = 0; + let x: u64 = 0; x; Tuple() } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/large_binop.exp b/third_party/move/move-compiler-v2/tests/checking/typing/large_binop.exp index 799554d4c017a..f127994b5ff64 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/large_binop.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/large_binop.exp @@ -1 +1,7 @@ // ---- Model Dump +module { + private fun main() { + Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(Or(And(And(true, true), Not(false)), And(Eq(Shl(1, 7), 128), Eq(Shr(128, 7), 1))), And(Eq(Div(255, 2), 127), Eq(Mod(255, 2), 1))), And(Eq(Add(254, 1), 255), Eq(Sub(255, 255), 0))), And(Eq(BitAnd(255, 255), 255), Eq(BitOr(255, 255), 255))), And(Eq(Xor(255, 255), 0), Eq>([66], [66]))), And(And(Neq>([104, 101, 108, 108, 111], [98, 121, 101]), And(true, true)), Not(false))), And(Eq(Shl(1, 7), 128), Eq(Shr(128, 7), 1))), And(Eq(Div(255, 2), 127), Eq(Mod(255, 2), 1))), And(Eq(Add(254, 1), 255), Eq(Sub(255, 255), 0))), And(Eq(BitAnd(255, 255), 255), Eq(BitOr(255, 255), 255))), And(Eq(Xor(255, 255), 0), Eq>([66], [66]))), And(And(Neq>([104, 101, 108, 108, 111], [98, 121, 101]), And(true, true)), Not(false))), And(Eq(Shl(1, 7), 128), Eq(Shr(128, 7), 1))), And(Eq(Div(255, 2), 127), Eq(Mod(255, 2), 1))), And(Eq(Add(254, 1), 255), Eq(Sub(255, 255), 0))), And(Eq(BitAnd(255, 255), 255), Eq(BitOr(255, 255), 255))), And(Eq(Xor(255, 255), 0), Eq>([66], [66]))), And(And(Neq>([104, 101, 108, 108, 111], [98, 121, 101]), And(true, true)), Not(false))), And(Eq(Shl(1, 7), 128), Eq(Shr(128, 7), 1))), And(Eq(Div(255, 2), 127), Eq(Mod(255, 2), 1))), And(Eq(Add(254, 1), 255), Eq(Sub(255, 255), 0))), And(Eq(BitAnd(255, 255), 255), Eq(BitOr(255, 255), 255))), And(Eq(Xor(255, 255), 0), Eq>([66], [66]))), And(And(Neq>([104, 101, 108, 108, 111], [98, 121, 101]), And(true, true)), Not(false))), And(Eq(Shl(1, 7), 128), Eq(Shr(128, 7), 1))), And(Eq(Div(255, 2), 127), Eq(Mod(255, 2), 1))), And(Eq(Add(254, 1), 255), Eq(Sub(255, 255), 0))), And(Eq(BitAnd(255, 255), 255), Eq(BitOr(255, 255), 255))), And(Eq(Xor(255, 255), 0), Eq>([66], [66]))), And(And(Neq>([104, 101, 108, 108, 111], [98, 121, 101]), And(true, true)), Not(false))), And(Eq(Shl(1, 7), 128), Eq(Shr(128, 7), 1))), And(Eq(Div(255, 2), 127), Eq(Mod(255, 2), 1))), And(Eq(Add(254, 1), 255), Eq(Sub(255, 255), 0))), And(Eq(BitAnd(255, 255), 255), Eq(BitOr(255, 255), 255))), And(Eq(Xor(255, 255), 0), Eq>([66], [66]))), And(And(Neq>([104, 101, 108, 108, 111], [98, 121, 101]), And(true, true)), Not(false))), And(Eq(Shl(1, 7), 128), Eq(Shr(128, 7), 1))), And(Eq(Div(255, 2), 127), Eq(Mod(255, 2), 1))), And(Eq(Add(254, 1), 255), Eq(Sub(255, 255), 0))), And(Eq(BitAnd(255, 255), 255), Eq(BitOr(255, 255), 255))), And(Eq(Xor(255, 255), 0), Eq>([66], [66]))), And(And(Neq>([104, 101, 108, 108, 111], [98, 121, 101]), And(true, true)), Not(false))), And(Eq(Shl(1, 7), 128), Eq(Shr(128, 7), 1))), And(Eq(Div(255, 2), 127), Eq(Mod(255, 2), 1))), And(Eq(Add(254, 1), 255), Eq(Sub(255, 255), 0))), And(Eq(BitAnd(255, 255), 255), Eq(BitOr(255, 255), 255))), And(Eq(Xor(255, 255), 0), Eq>([66], [66]))), And(And(Neq>([104, 101, 108, 108, 111], [98, 121, 101]), And(true, true)), Not(false))), And(Eq(Shl(1, 7), 128), Eq(Shr(128, 7), 1))), And(Eq(Div(255, 2), 127), Eq(Mod(255, 2), 1))), And(Eq(Add(254, 1), 255), Eq(Sub(255, 255), 0))), And(Eq(BitAnd(255, 255), 255), Eq(BitOr(255, 255), 255))), And(Eq(Xor(255, 255), 0), Eq>([66], [66]))), And(And(Neq>([104, 101, 108, 108, 111], [98, 121, 101]), And(true, true)), Not(false))), And(Eq(Shl(1, 7), 128), Eq(Shr(128, 7), 1))), And(Eq(Div(255, 2), 127), Eq(Mod(255, 2), 1))), And(Eq(Add(254, 1), 255), Eq(Sub(255, 255), 0))), And(Eq(BitAnd(255, 255), 255), Eq(BitOr(255, 255), 255))), And(Eq(Xor(255, 255), 0), Eq>([66], [66]))); + Tuple() + } +} // end diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/loop_body.exp b/third_party/move/move-compiler-v2/tests/checking/typing/loop_body.exp index 3a8ef45d33b21..9d6bff1408a64 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/loop_body.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/loop_body.exp @@ -18,7 +18,7 @@ module 0x8675309::M { private fun t3() { loop { { - let x: () = 0; + let x: u64 = 0; x; Tuple() } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/loop_result_type.exp b/third_party/move/move-compiler-v2/tests/checking/typing/loop_result_type.exp index d5ec570b0513b..c1574179967be 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/loop_result_type.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/loop_result_type.exp @@ -16,7 +16,7 @@ module 0x2::M { private fun t1() { loop { { - let x: () = 0; + let x: u64 = 0; x; Tuple() } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/main_arguments.exp b/third_party/move/move-compiler-v2/tests/checking/typing/main_arguments.exp index 799554d4c017a..a128e66c13086 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/main_arguments.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/main_arguments.exp @@ -1 +1,6 @@ // ---- Model Dump +module { + private fun main(_sender: signer,_a: address,_x8: u8,_x64: u64,_x128: u128,_b: bool,_v8: vector,_va: vector
,_v64: vector,_v128: vector,_vb: vector,_vv8: vector>,_vva: vector>,_vv64: vector>,_vv128: vector>,_vvb: vector>,_vvv8: vector>>,_vvva: vector>>,_vvv64: vector>>,_vvv128: vector>>,_vvvb: vector>>,_vvvv8: vector>>>,_vvvva: vector>>>,_vvvv64: vector>>>,_vvvv128: vector>>>,_vvvvb: vector>>>) { + Tuple() + } +} // end diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/main_arguments_various_caes.exp b/third_party/move/move-compiler-v2/tests/checking/typing/main_arguments_various_caes.exp index 60ed9be808cd1..21d87ac430554 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/main_arguments_various_caes.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/main_arguments_various_caes.exp @@ -13,3 +13,8 @@ module 0x42::M { M::R{ dummy_field: _ } = r } } // end 0x42::M +module { + private fun main(_s: &signer,_a0: T,_a1: vector,_a2: vector>,_a3: M::S,_a4: M::R,_a5: M::Cup,_a6: M::Cup,_a7: vector) { + Abort(0) + } +} // end diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/main_call_entry.exp b/third_party/move/move-compiler-v2/tests/checking/typing/main_call_entry.exp index e33be57f3245e..4fa729e730333 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/main_call_entry.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/main_call_entry.exp @@ -4,3 +4,8 @@ module 0x2::X { Tuple() } } // end 0x2::X +module { + private fun main() { + X::foo() + } +} // end diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/main_with_type_parameters.exp b/third_party/move/move-compiler-v2/tests/checking/typing/main_with_type_parameters.exp index 799554d4c017a..6ab4b5d61fc9c 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/main_with_type_parameters.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/main_with_type_parameters.exp @@ -1 +1,6 @@ // ---- Model Dump +module { + private fun main() { + Tuple() + } +} // end diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/other_builtins.exp b/third_party/move/move-compiler-v2/tests/checking/typing/other_builtins.exp index d3987e0fe1e88..666525567ad5e 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/other_builtins.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/other_builtins.exp @@ -7,14 +7,14 @@ module 0x8675309::M { Freeze(x); Freeze>(Borrow(Mutable)(M::any>())); if And(true, false) { - Abort(Deref(x)) - } else { Tuple() + } else { + Abort(Deref(x)) }; if Or(true, false) { - Abort(Cast(0)) - } else { Tuple() + } else { + Abort(Cast(0)) }; Tuple() } diff --git a/third_party/move/move-compiler-v2/tests/checking/typing/while_body.exp b/third_party/move/move-compiler-v2/tests/checking/typing/while_body.exp index 2be683625c4c5..3f606f1f729f3 100644 --- a/third_party/move/move-compiler-v2/tests/checking/typing/while_body.exp +++ b/third_party/move/move-compiler-v2/tests/checking/typing/while_body.exp @@ -25,7 +25,7 @@ module 0x8675309::M { loop { if cond { { - let x: () = 0; + let x: u64 = 0; x; Tuple() } diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/assign.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/assign.exp new file mode 100644 index 0000000000000..0ebc48e81c396 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/assign.exp @@ -0,0 +1,93 @@ +============ initial bytecode ================ + +[variant baseline] +fun assign::assign_field($t0: &mut assign::S, $t1: u64) { + var $t2: &mut u64 + 0: $t2 := borrow_field.f($t0) + 1: write_ref($t2, $t1) + 2: return () +} + + +[variant baseline] +fun assign::assign_int($t0: &mut u64) { + var $t1: u64 + 0: $t1 := 42 + 1: write_ref($t0, $t1) + 2: return () +} + + +[variant baseline] +fun assign::assign_pattern($t0: assign::S, $t1: u64, $t2: u64): u64 { + var $t3: u64 + var $t4: assign::T + 0: ($t1, $t4) := unpack assign::S($t0) + 1: $t2 := unpack assign::T($t4) + 2: $t3 := +($t1, $t2) + 3: return $t3 +} + + +[variant baseline] +fun assign::assign_struct($t0: &mut assign::S) { + var $t1: assign::S + var $t2: u64 + var $t3: assign::T + var $t4: u64 + 0: $t2 := 42 + 1: $t4 := 42 + 2: $t3 := pack assign::T($t4) + 3: $t1 := pack assign::S($t2, $t3) + 4: write_ref($t0, $t1) + 5: return () +} + + +============ disassembled file-format ================== +// Move bytecode v6 +module 42.assign { +struct T { + h: u64 +} +struct S { + f: u64, + g: T +} + +assign_field(Arg0: &mut S, Arg1: u64) { +B0: + 0: CopyLoc[0](Arg0: &mut S) + 1: MutBorrowField[0](S.f: u64) + 2: StLoc[2](loc0: &mut u64) + 3: CopyLoc[1](Arg1: u64) + 4: CopyLoc[2](loc0: &mut u64) + 5: WriteRef + 6: Ret +} +assign_int(Arg0: &mut u64) { +B0: + 0: LdConst[0](U64: [42, 0, 0, 0, 0, 0, 0, 0]) + 1: CopyLoc[0](Arg0: &mut u64) + 2: WriteRef + 3: Ret +} +assign_pattern(Arg0: S, Arg1: u64, Arg2: u64): u64 { +B0: + 0: MoveLoc[0](Arg0: S) + 1: Unpack[1](S) + 2: Unpack[0](T) + 3: Add + 4: Ret +} +assign_struct(Arg0: &mut S) { +B0: + 0: LdConst[0](U64: [42, 0, 0, 0, 0, 0, 0, 0]) + 1: LdConst[0](U64: [42, 0, 0, 0, 0, 0, 0, 0]) + 2: Pack[0](T) + 3: Pack[1](S) + 4: CopyLoc[0](Arg0: &mut S) + 5: WriteRef + 6: Ret +} +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/assign.move b/third_party/move/move-compiler-v2/tests/file-format-generator/assign.move new file mode 100644 index 0000000000000..2ea2fe8d33721 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/assign.move @@ -0,0 +1,28 @@ +module 0x42::assign { + + struct S { + f: u64, + g: T + } + + struct T { + h: u64 + } + + fun assign_int(x: &mut u64) { + *x = 42; + } + + fun assign_struct(s: &mut S) { + *s = S { f: 42, g: T { h: 42 } }; + } + + fun assign_pattern(s: S, f: u64, h: u64): u64 { + S { f, g: T { h } } = s; + f + h + } + + fun assign_field(s: &mut S, f: u64) { + s.f = f; + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.exp new file mode 100644 index 0000000000000..41caecaea2cc3 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.exp @@ -0,0 +1,164 @@ +============ initial bytecode ================ + +[variant baseline] +fun borrow::field($t0: &borrow::S): u64 { + var $t1: u64 + var $t2: &u64 + var $t3: &u64 + 0: $t3 := borrow_field.f($t0) + 1: $t2 := move($t3) + 2: $t1 := read_ref($t2) + 3: return $t1 +} + + +[variant baseline] +fun borrow::local($t0: u64): u64 { + var $t1: u64 + var $t2: u64 + var $t3: u64 + var $t4: &u64 + var $t5: &u64 + 0: $t3 := 33 + 1: $t2 := move($t3) + 2: $t5 := borrow_local($t2) + 3: $t4 := move($t5) + 4: $t1 := read_ref($t4) + 5: return $t1 +} + + +[variant baseline] +fun borrow::param($t0: u64): u64 { + var $t1: u64 + var $t2: &u64 + var $t3: &u64 + 0: $t3 := borrow_local($t0) + 1: $t2 := move($t3) + 2: $t1 := read_ref($t2) + 3: return $t1 +} + + +[variant baseline] +fun borrow::mut_field($t0: &mut borrow::S): u64 { + var $t1: u64 + var $t2: &mut u64 + var $t3: &mut u64 + var $t4: u64 + 0: $t3 := borrow_field.f($t0) + 1: $t2 := move($t3) + 2: $t4 := 22 + 3: write_ref($t2, $t4) + 4: $t1 := read_ref($t2) + 5: return $t1 +} + + +[variant baseline] +fun borrow::mut_local($t0: u64): u64 { + var $t1: u64 + var $t2: u64 + var $t3: u64 + var $t4: &mut u64 + var $t5: &mut u64 + var $t6: u64 + 0: $t3 := 33 + 1: $t2 := move($t3) + 2: $t5 := borrow_local($t2) + 3: $t4 := move($t5) + 4: $t6 := 22 + 5: write_ref($t4, $t6) + 6: $t1 := read_ref($t4) + 7: return $t1 +} + + +[variant baseline] +fun borrow::mut_param($t0: u64): u64 { + var $t1: u64 + var $t2: &mut u64 + var $t3: &mut u64 + var $t4: u64 + 0: $t3 := borrow_local($t0) + 1: $t2 := move($t3) + 2: $t4 := 22 + 3: write_ref($t2, $t4) + 4: $t1 := read_ref($t2) + 5: return $t1 +} + + +============ disassembled file-format ================== +// Move bytecode v6 +module 42.borrow { +struct S { + f: u64 +} + +field(Arg0: &S): u64 { +B0: + 0: CopyLoc[0](Arg0: &S) + 1: ImmBorrowField[0](S.f: u64) + 2: StLoc[1](loc0: &u64) + 3: CopyLoc[1](loc0: &u64) + 4: ReadRef + 5: Ret +} +local(Arg0: u64): u64 { +L0: loc1: &u64 +B0: + 0: LdConst[0](U64: [33, 0, 0, 0, 0, 0, 0, 0]) + 1: StLoc[1](loc0: u64) + 2: ImmBorrowLoc[1](loc0: u64) + 3: StLoc[2](loc1: &u64) + 4: CopyLoc[2](loc1: &u64) + 5: ReadRef + 6: Ret +} +param(Arg0: u64): u64 { +B0: + 0: ImmBorrowLoc[0](Arg0: u64) + 1: StLoc[1](loc0: &u64) + 2: CopyLoc[1](loc0: &u64) + 3: ReadRef + 4: Ret +} +mut_field(Arg0: &mut S): u64 { +B0: + 0: CopyLoc[0](Arg0: &mut S) + 1: MutBorrowField[0](S.f: u64) + 2: StLoc[1](loc0: &mut u64) + 3: LdConst[1](U64: [22, 0, 0, 0, 0, 0, 0, 0]) + 4: CopyLoc[1](loc0: &mut u64) + 5: WriteRef + 6: CopyLoc[1](loc0: &mut u64) + 7: ReadRef + 8: Ret +} +mut_local(Arg0: u64): u64 { +L0: loc1: &mut u64 +B0: + 0: LdConst[0](U64: [33, 0, 0, 0, 0, 0, 0, 0]) + 1: StLoc[1](loc0: u64) + 2: MutBorrowLoc[1](loc0: u64) + 3: StLoc[2](loc1: &mut u64) + 4: LdConst[1](U64: [22, 0, 0, 0, 0, 0, 0, 0]) + 5: CopyLoc[2](loc1: &mut u64) + 6: WriteRef + 7: CopyLoc[2](loc1: &mut u64) + 8: ReadRef + 9: Ret +} +mut_param(Arg0: u64): u64 { +B0: + 0: MutBorrowLoc[0](Arg0: u64) + 1: StLoc[1](loc0: &mut u64) + 2: LdConst[1](U64: [22, 0, 0, 0, 0, 0, 0, 0]) + 3: CopyLoc[1](loc0: &mut u64) + 4: WriteRef + 5: CopyLoc[1](loc0: &mut u64) + 6: ReadRef + 7: Ret +} +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.move b/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.move new file mode 100644 index 0000000000000..847c60a0e6704 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/borrow.move @@ -0,0 +1,41 @@ +module 0x42::borrow { + + struct S { + f: u64 + } + + fun param(param: u64): u64 { + let r = ¶m; + *r + } + + fun local(param: u64): u64 { + let local: u64 = 33; + let r = &local; + *r + } + + fun field(s: &S): u64 { + let r = &s.f; + *r + } + + fun mut_param(param: u64): u64 { + let r = &mut param; + *r = 22; + *r + } + + fun mut_local(param: u64): u64 { + let local: u64 = 33; + let r = &mut local; + *r = 22; + *r + } + + fun mut_field(s: &mut S): u64 { + let r = &mut s.f; + *r = 22; + *r + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/fields.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/fields.exp new file mode 100644 index 0000000000000..68c3894490319 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/fields.exp @@ -0,0 +1,204 @@ +============ initial bytecode ================ + +[variant baseline] +fun fields::read_ref($t0: &fields::S): u64 { + var $t1: u64 + var $t2: &fields::T + var $t3: &u64 + 0: $t2 := borrow_field.g($t0) + 1: $t3 := borrow_field.h($t2) + 2: $t1 := read_ref($t3) + 3: return $t1 +} + + +[variant baseline] +fun fields::read_val($t0: fields::S): u64 { + var $t1: u64 + var $t2: &fields::T + var $t3: &fields::S + var $t4: &u64 + 0: $t3 := borrow_local($t0) + 1: $t2 := borrow_field.g($t3) + 2: $t4 := borrow_field.h($t2) + 3: $t1 := read_ref($t4) + 4: return $t1 +} + + +[variant baseline] +fun fields::write_local_direct(): fields::S { + var $t0: fields::S + var $t1: fields::S + var $t2: fields::S + var $t3: u64 + var $t4: fields::T + var $t5: u64 + var $t6: u64 + var $t7: &mut u64 + var $t8: &mut fields::T + var $t9: &mut fields::S + 0: $t3 := 0 + 1: $t5 := 0 + 2: $t4 := pack fields::T($t5) + 3: $t2 := pack fields::S($t3, $t4) + 4: $t1 := move($t2) + 5: $t6 := 42 + 6: $t9 := borrow_local($t1) + 7: $t8 := borrow_field.g($t9) + 8: $t7 := borrow_field.h($t8) + 9: write_ref($t7, $t6) + 10: $t0 := move($t1) + 11: return $t0 +} + + +[variant baseline] +fun fields::write_local_via_ref(): fields::S { + var $t0: fields::S + var $t1: fields::S + var $t2: fields::S + var $t3: u64 + var $t4: fields::T + var $t5: u64 + var $t6: &mut fields::S + var $t7: &mut fields::S + var $t8: u64 + var $t9: &mut u64 + var $t10: &mut fields::T + 0: $t3 := 0 + 1: $t5 := 0 + 2: $t4 := pack fields::T($t5) + 3: $t2 := pack fields::S($t3, $t4) + 4: $t1 := move($t2) + 5: $t7 := borrow_local($t1) + 6: $t6 := move($t7) + 7: $t8 := 42 + 8: $t10 := borrow_field.g($t6) + 9: $t9 := borrow_field.h($t10) + 10: write_ref($t9, $t8) + 11: $t0 := move($t1) + 12: return $t0 +} + + +[variant baseline] +fun fields::write_param($t0: &mut fields::S) { + var $t1: u64 + var $t2: &mut u64 + var $t3: &mut fields::T + 0: $t1 := 42 + 1: $t3 := borrow_field.g($t0) + 2: $t2 := borrow_field.h($t3) + 3: write_ref($t2, $t1) + 4: return () +} + + +[variant baseline] +fun fields::write_val($t0: fields::S): fields::S { + var $t1: fields::S + var $t2: u64 + var $t3: &mut u64 + var $t4: &mut fields::T + var $t5: &mut fields::S + 0: $t2 := 42 + 1: $t5 := borrow_local($t0) + 2: $t4 := borrow_field.g($t5) + 3: $t3 := borrow_field.h($t4) + 4: write_ref($t3, $t2) + 5: $t1 := move($t0) + 6: return $t1 +} + + +============ disassembled file-format ================== +// Move bytecode v6 +module 42.fields { +struct T { + h: u64 +} +struct S { + f: u64, + g: T +} + +read_ref(Arg0: &S): u64 { +B0: + 0: CopyLoc[0](Arg0: &S) + 1: ImmBorrowField[0](S.g: T) + 2: ImmBorrowField[1](T.h: u64) + 3: ReadRef + 4: Ret +} +read_val(Arg0: S): u64 { +B0: + 0: ImmBorrowLoc[0](Arg0: S) + 1: ImmBorrowField[0](S.g: T) + 2: ImmBorrowField[1](T.h: u64) + 3: ReadRef + 4: Ret +} +write_local_direct(): S { +L0: loc0: S +L1: loc1: S +B0: + 0: LdConst[0](U64: [0, 0, 0, 0, 0, 0, 0, 0]) + 1: LdConst[0](U64: [0, 0, 0, 0, 0, 0, 0, 0]) + 2: Pack[0](T) + 3: Pack[1](S) + 4: StLoc[0](loc0: S) + 5: LdConst[1](U64: [42, 0, 0, 0, 0, 0, 0, 0]) + 6: MutBorrowLoc[0](loc0: S) + 7: MutBorrowField[0](S.g: T) + 8: MutBorrowField[1](T.h: u64) + 9: WriteRef + 10: MoveLoc[0](loc0: S) + 11: StLoc[1](loc1: S) + 12: MoveLoc[1](loc1: S) + 13: Ret +} +write_local_via_ref(): S { +L0: loc0: S +L1: loc1: &mut S +L2: loc2: S +B0: + 0: LdConst[0](U64: [0, 0, 0, 0, 0, 0, 0, 0]) + 1: LdConst[0](U64: [0, 0, 0, 0, 0, 0, 0, 0]) + 2: Pack[0](T) + 3: Pack[1](S) + 4: StLoc[0](loc0: S) + 5: MutBorrowLoc[0](loc0: S) + 6: StLoc[1](loc1: &mut S) + 7: LdConst[1](U64: [42, 0, 0, 0, 0, 0, 0, 0]) + 8: CopyLoc[1](loc1: &mut S) + 9: MutBorrowField[0](S.g: T) + 10: MutBorrowField[1](T.h: u64) + 11: WriteRef + 12: MoveLoc[0](loc0: S) + 13: StLoc[2](loc2: S) + 14: MoveLoc[2](loc2: S) + 15: Ret +} +write_param(Arg0: &mut S) { +B0: + 0: LdConst[1](U64: [42, 0, 0, 0, 0, 0, 0, 0]) + 1: CopyLoc[0](Arg0: &mut S) + 2: MutBorrowField[0](S.g: T) + 3: MutBorrowField[1](T.h: u64) + 4: WriteRef + 5: Ret +} +write_val(Arg0: S): S { +B0: + 0: LdConst[1](U64: [42, 0, 0, 0, 0, 0, 0, 0]) + 1: MutBorrowLoc[0](Arg0: S) + 2: MutBorrowField[0](S.g: T) + 3: MutBorrowField[1](T.h: u64) + 4: WriteRef + 5: MoveLoc[0](Arg0: S) + 6: StLoc[1](loc0: S) + 7: MoveLoc[1](loc0: S) + 8: Ret +} +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/fields.move b/third_party/move/move-compiler-v2/tests/file-format-generator/fields.move new file mode 100644 index 0000000000000..da6bea9d1d449 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/fields.move @@ -0,0 +1,41 @@ +module 0x42::fields { + + struct S { + f: u64, + g: T + } + + struct T { + h: u64 + } + + fun read_val(x: S): u64 { + x.g.h + } + + fun read_ref(x: &S): u64 { + x.g.h + } + + fun write_val(x: S): S { + x.g.h = 42; + x + } + + fun write_param(x: &mut S) { + x.g.h = 42; + } + + fun write_local_via_ref(): S { + let x = S { f: 0, g: T { h: 0 } }; + let r = &mut x; + r.g.h = 42; + x + } + + fun write_local_direct(): S { + let x = S { f: 0, g: T { h: 0 } }; + x.g.h = 42; + x + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/globals.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/globals.exp new file mode 100644 index 0000000000000..10b0382ef49d1 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/globals.exp @@ -0,0 +1,98 @@ +============ initial bytecode ================ + +[variant baseline] +fun globals::check($t0: address): bool { + var $t1: bool + 0: $t1 := exists($t0) + 1: return $t1 +} + + +[variant baseline] +fun globals::publish($t0: &signer) { + var $t1: globals::R + var $t2: u64 + 0: $t2 := 1 + 1: $t1 := pack globals::R($t2) + 2: move_to($t0, $t1) + 3: return () +} + + +[variant baseline] +fun globals::read($t0: address): u64 { + var $t1: u64 + var $t2: &globals::R + var $t3: &globals::R + var $t4: &u64 + 0: $t3 := borrow_global($t0) + 1: $t2 := move($t3) + 2: $t4 := borrow_field.f($t2) + 3: $t1 := read_ref($t4) + 4: return $t1 +} + + +[variant baseline] +fun globals::write($t0: address, $t1: u64): u64 { + var $t2: u64 + var $t3: &mut globals::R + var $t4: &mut globals::R + var $t5: u64 + var $t6: &mut u64 + 0: $t4 := borrow_global($t0) + 1: $t3 := move($t4) + 2: $t5 := 2 + 3: $t6 := borrow_field.f($t3) + 4: write_ref($t6, $t5) + 5: $t2 := 9 + 6: return $t2 +} + + +============ disassembled file-format ================== +// Move bytecode v6 +module 42.globals { +struct R has store { + f: u64 +} + +check(Arg0: address): bool { +B0: + 0: CopyLoc[0](Arg0: address) + 1: Exists[0](R) + 2: Ret +} +publish(Arg0: &signer) { +B0: + 0: LdConst[0](U64: [1, 0, 0, 0, 0, 0, 0, 0]) + 1: Pack[0](R) + 2: StLoc[1](loc0: R) + 3: CopyLoc[0](Arg0: &signer) + 4: MoveLoc[1](loc0: R) + 5: MoveTo[0](R) + 6: Ret +} +read(Arg0: address): u64 { +B0: + 0: CopyLoc[0](Arg0: address) + 1: ImmBorrowGlobal[0](R) + 2: StLoc[1](loc0: &R) + 3: CopyLoc[1](loc0: &R) + 4: ImmBorrowField[0](R.f: u64) + 5: ReadRef + 6: Ret +} +write(Arg0: address, Arg1: u64): u64 { +B0: + 0: CopyLoc[0](Arg0: address) + 1: MutBorrowGlobal[0](R) + 2: StLoc[2](loc0: &mut R) + 3: LdConst[1](U64: [2, 0, 0, 0, 0, 0, 0, 0]) + 4: CopyLoc[2](loc0: &mut R) + 5: MutBorrowField[0](R.f: u64) + 6: WriteRef + 7: LdConst[2](U64: [9, 0, 0, 0, 0, 0, 0, 0]) + 8: Ret +} +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/globals.move b/third_party/move/move-compiler-v2/tests/file-format-generator/globals.move new file mode 100644 index 0000000000000..e2da286af777a --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/globals.move @@ -0,0 +1,23 @@ +module 0x42::globals { + + struct R has store { f: u64 } + + fun publish(s: &signer) { + move_to(s, R{f: 1}); + } + + fun check(a: address): bool { + exists(a) + } + + fun read(a: address): u64 { + let r = borrow_global(a); + r.f + } + + fun write(a: address, x: u64): u64 { + let r = borrow_global_mut(a); + r.f = 2; + 9 + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.exp new file mode 100644 index 0000000000000..6ca94d4797a51 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.exp @@ -0,0 +1,134 @@ +============ initial bytecode ================ + +[variant baseline] +fun if_else::if_else($t0: bool, $t1: u64): u64 { + var $t2: u64 + var $t3: u64 + var $t4: u64 + 0: if ($t0) goto 1 else goto 5 + 1: label L0 + 2: $t3 := 1 + 3: $t2 := +($t1, $t3) + 4: goto 8 + 5: label L1 + 6: $t4 := 1 + 7: $t2 := -($t1, $t4) + 8: label L2 + 9: return $t2 +} + + +[variant baseline] +fun if_else::if_else_nested($t0: bool, $t1: u64): u64 { + var $t2: u64 + var $t3: bool + var $t4: u64 + var $t5: u64 + var $t6: u64 + var $t7: u64 + var $t8: u64 + var $t9: u64 + 0: if ($t0) goto 1 else goto 5 + 1: label L0 + 2: $t5 := 1 + 3: $t4 := +($t1, $t5) + 4: goto 8 + 5: label L1 + 6: $t6 := 1 + 7: $t4 := -($t1, $t6) + 8: label L2 + 9: $t7 := 10 + 10: $t3 := >($t4, $t7) + 11: if ($t3) goto 12 else goto 16 + 12: label L3 + 13: $t8 := 2 + 14: $t2 := *($t1, $t8) + 15: goto 19 + 16: label L4 + 17: $t9 := 2 + 18: $t2 := /($t1, $t9) + 19: label L5 + 20: return $t2 +} + + +============ disassembled file-format ================== +// Move bytecode v6 +module 42.if_else { + + +if_else(Arg0: bool, Arg1: u64): u64 { +L0: loc2: u64 +B0: + 0: CopyLoc[0](Arg0: bool) + 1: BrFalse(9) +B1: + 2: LdConst[0](U64: [1, 0, 0, 0, 0, 0, 0, 0]) + 3: StLoc[2](loc0: u64) + 4: CopyLoc[1](Arg1: u64) + 5: CopyLoc[2](loc0: u64) + 6: Add + 7: StLoc[3](loc1: u64) + 8: Branch(15) +B2: + 9: LdConst[0](U64: [1, 0, 0, 0, 0, 0, 0, 0]) + 10: StLoc[4](loc2: u64) + 11: CopyLoc[1](Arg1: u64) + 12: CopyLoc[4](loc2: u64) + 13: Sub + 14: StLoc[3](loc1: u64) +B3: + 15: CopyLoc[3](loc1: u64) + 16: Ret +} +if_else_nested(Arg0: bool, Arg1: u64): u64 { +L0: loc2: u64 +L1: loc3: u64 +L2: loc4: u64 +L3: loc5: u64 +L4: loc6: u64 +B0: + 0: CopyLoc[0](Arg0: bool) + 1: BrFalse(9) +B1: + 2: LdConst[0](U64: [1, 0, 0, 0, 0, 0, 0, 0]) + 3: StLoc[2](loc0: u64) + 4: CopyLoc[1](Arg1: u64) + 5: CopyLoc[2](loc0: u64) + 6: Add + 7: StLoc[3](loc1: u64) + 8: Branch(15) +B2: + 9: LdConst[0](U64: [1, 0, 0, 0, 0, 0, 0, 0]) + 10: StLoc[4](loc2: u64) + 11: CopyLoc[1](Arg1: u64) + 12: CopyLoc[4](loc2: u64) + 13: Sub + 14: StLoc[3](loc1: u64) +B3: + 15: LdConst[1](U64: [10, 0, 0, 0, 0, 0, 0, 0]) + 16: StLoc[5](loc3: u64) + 17: CopyLoc[3](loc1: u64) + 18: CopyLoc[5](loc3: u64) + 19: Gt + 20: BrFalse(28) +B4: + 21: LdConst[2](U64: [2, 0, 0, 0, 0, 0, 0, 0]) + 22: StLoc[6](loc4: u64) + 23: CopyLoc[1](Arg1: u64) + 24: CopyLoc[6](loc4: u64) + 25: Mul + 26: StLoc[7](loc5: u64) + 27: Branch(34) +B5: + 28: LdConst[2](U64: [2, 0, 0, 0, 0, 0, 0, 0]) + 29: StLoc[8](loc6: u64) + 30: CopyLoc[1](Arg1: u64) + 31: CopyLoc[8](loc6: u64) + 32: Div + 33: StLoc[7](loc5: u64) +B6: + 34: CopyLoc[7](loc5: u64) + 35: Ret +} +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.move b/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.move new file mode 100644 index 0000000000000..22ea0d1eb7e42 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/if_else.move @@ -0,0 +1,10 @@ +module 0x42::if_else { + + fun if_else(cond: bool, x: u64): u64 { + if (cond) x + 1 else x - 1 + } + + fun if_else_nested(cond: bool, x: u64): u64 { + if ((if (cond) x + 1 else x - 1) > 10) x * 2 else x / 2 + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/loop.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/loop.exp new file mode 100644 index 0000000000000..b1f56c601e389 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/loop.exp @@ -0,0 +1,259 @@ +============ initial bytecode ================ + +[variant baseline] +fun loops::nested_loop($t0: u64): u64 { + var $t1: u64 + var $t2: bool + var $t3: u64 + var $t4: bool + var $t5: u64 + var $t6: u64 + var $t7: u64 + var $t8: u64 + var $t9: u64 + 0: label L0 + 1: $t3 := 0 + 2: $t2 := >($t0, $t3) + 3: if ($t2) goto 4 else goto 25 + 4: label L2 + 5: label L5 + 6: $t5 := 10 + 7: $t4 := >($t0, $t5) + 8: if ($t4) goto 9 else goto 15 + 9: label L7 + 10: $t7 := 1 + 11: $t6 := -($t0, $t7) + 12: $t0 := move($t6) + 13: goto 19 + 14: goto 17 + 15: label L8 + 16: goto 19 + 17: label L9 + 18: goto 5 + 19: label L6 + 20: $t9 := 1 + 21: $t8 := -($t0, $t9) + 22: $t0 := move($t8) + 23: goto 0 + 24: goto 27 + 25: label L3 + 26: goto 29 + 27: label L4 + 28: goto 0 + 29: label L1 + 30: $t1 := move($t0) + 31: return $t1 +} + + +[variant baseline] +fun loops::while_loop($t0: u64): u64 { + var $t1: u64 + var $t2: bool + var $t3: u64 + var $t4: u64 + var $t5: u64 + 0: label L0 + 1: $t3 := 0 + 2: $t2 := >($t0, $t3) + 3: if ($t2) goto 4 else goto 9 + 4: label L2 + 5: $t5 := 1 + 6: $t4 := -($t0, $t5) + 7: $t0 := move($t4) + 8: goto 11 + 9: label L3 + 10: goto 13 + 11: label L4 + 12: goto 0 + 13: label L1 + 14: $t1 := move($t0) + 15: return $t1 +} + + +[variant baseline] +fun loops::while_loop_with_break_and_continue($t0: u64): u64 { + var $t1: u64 + var $t2: bool + var $t3: u64 + var $t4: bool + var $t5: u64 + var $t6: bool + var $t7: u64 + var $t8: u64 + var $t9: u64 + 0: label L0 + 1: $t3 := 0 + 2: $t2 := >($t0, $t3) + 3: if ($t2) goto 4 else goto 25 + 4: label L2 + 5: $t5 := 42 + 6: $t4 := ==($t0, $t5) + 7: if ($t4) goto 8 else goto 11 + 8: label L5 + 9: goto 29 + 10: goto 12 + 11: label L6 + 12: label L7 + 13: $t7 := 21 + 14: $t6 := ==($t0, $t7) + 15: if ($t6) goto 16 else goto 19 + 16: label L8 + 17: goto 0 + 18: goto 20 + 19: label L9 + 20: label L10 + 21: $t9 := 1 + 22: $t8 := -($t0, $t9) + 23: $t0 := move($t8) + 24: goto 27 + 25: label L3 + 26: goto 29 + 27: label L4 + 28: goto 0 + 29: label L1 + 30: $t1 := move($t0) + 31: return $t1 +} + + +============ disassembled file-format ================== +// Move bytecode v6 +module 42.loops { + + +nested_loop(Arg0: u64): u64 { +L0: loc1: u64 +L1: loc2: u64 +L2: loc3: u64 +L3: loc4: u64 +B0: + 0: LdConst[0](U64: [0, 0, 0, 0, 0, 0, 0, 0]) + 1: StLoc[1](loc0: u64) + 2: CopyLoc[0](Arg0: u64) + 3: CopyLoc[1](loc0: u64) + 4: Gt + 5: BrFalse(30) +B1: + 6: LdConst[1](U64: [10, 0, 0, 0, 0, 0, 0, 0]) + 7: StLoc[2](loc1: u64) + 8: CopyLoc[0](Arg0: u64) + 9: CopyLoc[2](loc1: u64) + 10: Gt + 11: BrFalse(20) +B2: + 12: LdConst[2](U64: [1, 0, 0, 0, 0, 0, 0, 0]) + 13: StLoc[3](loc2: u64) + 14: CopyLoc[0](Arg0: u64) + 15: CopyLoc[3](loc2: u64) + 16: Sub + 17: StLoc[0](Arg0: u64) + 18: Branch(22) +B3: + 19: Branch(21) +B4: + 20: Branch(22) +B5: + 21: Branch(6) +B6: + 22: LdConst[2](U64: [1, 0, 0, 0, 0, 0, 0, 0]) + 23: StLoc[4](loc3: u64) + 24: CopyLoc[0](Arg0: u64) + 25: CopyLoc[4](loc3: u64) + 26: Sub + 27: StLoc[0](Arg0: u64) + 28: Branch(0) +B7: + 29: Branch(31) +B8: + 30: Branch(32) +B9: + 31: Branch(0) +B10: + 32: CopyLoc[0](Arg0: u64) + 33: StLoc[5](loc4: u64) + 34: CopyLoc[5](loc4: u64) + 35: Ret +} +while_loop(Arg0: u64): u64 { +L0: loc1: u64 +L1: loc2: u64 +B0: + 0: LdConst[0](U64: [0, 0, 0, 0, 0, 0, 0, 0]) + 1: StLoc[1](loc0: u64) + 2: CopyLoc[0](Arg0: u64) + 3: CopyLoc[1](loc0: u64) + 4: Gt + 5: BrFalse(13) +B1: + 6: LdConst[2](U64: [1, 0, 0, 0, 0, 0, 0, 0]) + 7: StLoc[2](loc1: u64) + 8: CopyLoc[0](Arg0: u64) + 9: CopyLoc[2](loc1: u64) + 10: Sub + 11: StLoc[0](Arg0: u64) + 12: Branch(14) +B2: + 13: Branch(15) +B3: + 14: Branch(0) +B4: + 15: CopyLoc[0](Arg0: u64) + 16: StLoc[3](loc2: u64) + 17: CopyLoc[3](loc2: u64) + 18: Ret +} +while_loop_with_break_and_continue(Arg0: u64): u64 { +L0: loc1: u64 +L1: loc2: u64 +L2: loc3: u64 +L3: loc4: u64 +B0: + 0: LdConst[0](U64: [0, 0, 0, 0, 0, 0, 0, 0]) + 1: StLoc[1](loc0: u64) + 2: CopyLoc[0](Arg0: u64) + 3: CopyLoc[1](loc0: u64) + 4: Gt + 5: BrFalse(29) +B1: + 6: LdConst[3](U64: [42, 0, 0, 0, 0, 0, 0, 0]) + 7: StLoc[2](loc1: u64) + 8: CopyLoc[0](Arg0: u64) + 9: CopyLoc[2](loc1: u64) + 10: Eq + 11: BrFalse(14) +B2: + 12: Branch(31) +B3: + 13: Branch(14) +B4: + 14: LdConst[4](U64: [21, 0, 0, 0, 0, 0, 0, 0]) + 15: StLoc[3](loc2: u64) + 16: CopyLoc[0](Arg0: u64) + 17: CopyLoc[3](loc2: u64) + 18: Eq + 19: BrFalse(22) +B5: + 20: Branch(0) +B6: + 21: Branch(22) +B7: + 22: LdConst[2](U64: [1, 0, 0, 0, 0, 0, 0, 0]) + 23: StLoc[4](loc3: u64) + 24: CopyLoc[0](Arg0: u64) + 25: CopyLoc[4](loc3: u64) + 26: Sub + 27: StLoc[0](Arg0: u64) + 28: Branch(30) +B8: + 29: Branch(31) +B9: + 30: Branch(0) +B10: + 31: CopyLoc[0](Arg0: u64) + 32: StLoc[5](loc4: u64) + 33: CopyLoc[5](loc4: u64) + 34: Ret +} +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/loop.move b/third_party/move/move-compiler-v2/tests/file-format-generator/loop.move new file mode 100644 index 0000000000000..75dcafbc54814 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/loop.move @@ -0,0 +1,32 @@ +module 0x42::loops { + + fun while_loop(x: u64): u64 { + while (x > 0) { + x = x - 1; + }; + x + } + + fun while_loop_with_break_and_continue(x: u64): u64 { + while (x > 0) { + if (x == 42) + break; + if (x == 21) + continue; + x = x - 1; + }; + x + } + + fun nested_loop(x: u64): u64 { + while (x > 0) { + while (x > 10) { + x = x - 1; + break; + }; + x = x - 1; + continue; + }; + x + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/operators.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/operators.exp new file mode 100644 index 0000000000000..9eab27dca498f --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/operators.exp @@ -0,0 +1,27 @@ + +Diagnostics: +error: no matching declaration of `<<` + ┌─ tests/file-format-generator/operators.move:7:9 + │ +7 │ x << y & x | y >> x ^ y + │ ^^^^^^ + │ + = outruled candidate `<<(u8, u8): u8` (expected `u8` but found `u64` for argument 1) + = outruled candidate `<<(u16, u8): u16` (expected `u16` but found `u64` for argument 1) + = outruled candidate `<<(u32, u8): u32` (expected `u32` but found `u64` for argument 1) + = outruled candidate `<<(u64, u8): u64` (expected `u8` but found `u64` for argument 2) + = outruled candidate `<<(u128, u8): u128` (expected `u128` but found `u64` for argument 1) + = outruled candidate `<<(u256, u8): u256` (expected `u256` but found `u64` for argument 1) + +error: no matching declaration of `>>` + ┌─ tests/file-format-generator/operators.move:7:22 + │ +7 │ x << y & x | y >> x ^ y + │ ^^^^^^ + │ + = outruled candidate `>>(u8, u8): u8` (expected `u8` but found `u64` for argument 1) + = outruled candidate `>>(u16, u8): u16` (expected `u16` but found `u64` for argument 1) + = outruled candidate `>>(u32, u8): u32` (expected `u32` but found `u64` for argument 1) + = outruled candidate `>>(u64, u8): u64` (expected `u8` but found `u64` for argument 2) + = outruled candidate `>>(u128, u8): u128` (expected `u128` but found `u64` for argument 1) + = outruled candidate `>>(u256, u8): u256` (expected `u256` but found `u64` for argument 1) diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/operators.move b/third_party/move/move-compiler-v2/tests/file-format-generator/operators.move new file mode 100644 index 0000000000000..831bc2b6835fe --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/operators.move @@ -0,0 +1,25 @@ +module 0x42::operators { + fun arithm(x: u64, y: u64): u64 { + x + y / (x - y) * y % x + } + + fun bits(x: u64, y: u64): u64 { + x << y & x | y >> x ^ y + } + + fun bools(x: bool, y: bool): bool { + x && y || x && !y || !x && y || !x && !y + } + + fun equality(x: T, y: T): bool { + x == y + } + + fun inequality(x: T, y: T): bool { + x != y + } + + fun order(x: u64, y: u64): bool { + x < y && x <= y && !(x > y) && !(x >= y) + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.exp new file mode 100644 index 0000000000000..23f5758a17b4c --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.exp @@ -0,0 +1,67 @@ +============ initial bytecode ================ + +[variant baseline] +fun pack_unpack::pack($t0: u64, $t1: u64): pack_unpack::S { + var $t2: pack_unpack::S + var $t3: pack_unpack::T + 0: $t3 := pack pack_unpack::T($t1) + 1: $t2 := pack pack_unpack::S($t0, $t3) + 2: return $t2 +} + + +[variant baseline] +fun pack_unpack::unpack($t0: pack_unpack::S): (u64, u64) { + var $t1: u64 + var $t2: u64 + var $t3: u64 + var $t4: u64 + var $t5: pack_unpack::T + 0: ($t3, $t5) := unpack pack_unpack::S($t0) + 1: $t4 := unpack pack_unpack::T($t5) + 2: $t1 := move($t3) + 3: $t2 := move($t4) + 4: return ($t1, $t2) +} + + +============ disassembled file-format ================== +// Move bytecode v6 +module 42.pack_unpack { +struct T { + h: u64 +} +struct S { + f: u64, + g: T +} + +pack(Arg0: u64, Arg1: u64): S { +B0: + 0: CopyLoc[1](Arg1: u64) + 1: Pack[0](T) + 2: StLoc[2](loc0: T) + 3: CopyLoc[0](Arg0: u64) + 4: MoveLoc[2](loc0: T) + 5: Pack[1](S) + 6: Ret +} +unpack(Arg0: S): u64 * u64 { +L0: loc1: u64 +L1: loc2: u64 +L2: loc3: u64 +B0: + 0: MoveLoc[0](Arg0: S) + 1: Unpack[1](S) + 2: Unpack[0](T) + 3: StLoc[1](loc0: u64) + 4: StLoc[2](loc1: u64) + 5: CopyLoc[2](loc1: u64) + 6: StLoc[3](loc2: u64) + 7: CopyLoc[1](loc0: u64) + 8: StLoc[4](loc3: u64) + 9: CopyLoc[3](loc2: u64) + 10: CopyLoc[4](loc3: u64) + 11: Ret +} +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.move b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.move new file mode 100644 index 0000000000000..66118cf1194db --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.move @@ -0,0 +1,21 @@ +module 0x42::pack_unpack { + + struct S { + f: u64, + g: T + } + + struct T { + h: u64 + } + + + fun pack(x: u64, y: u64): S { + S{f: x, g: T{h: y}} + } + + fun unpack(s: S): (u64, u64) { + let S{f, g: T{h}} = s; + (f, h) + } +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/vector.exp b/third_party/move/move-compiler-v2/tests/file-format-generator/vector.exp new file mode 100644 index 0000000000000..ea04db9c64c65 --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/vector.exp @@ -0,0 +1,30 @@ +============ initial bytecode ================ + +[variant baseline] +fun vector::create(): vector { + var $t0: vector + var $t1: u64 + var $t2: u64 + var $t3: u64 + 0: $t1 := 1 + 1: $t2 := 2 + 2: $t3 := 3 + 3: $t0 := vector($t1, $t2, $t3) + 4: return $t0 +} + + +============ disassembled file-format ================== +// Move bytecode v6 +module 42.vector { + + +create(): vector { +B0: + 0: LdConst[0](U64: [1, 0, 0, 0, 0, 0, 0, 0]) + 1: LdConst[1](U64: [2, 0, 0, 0, 0, 0, 0, 0]) + 2: LdConst[2](U64: [3, 0, 0, 0, 0, 0, 0, 0]) + 3: VecPack(2, 3) + 4: Ret +} +} diff --git a/third_party/move/move-compiler-v2/tests/file-format-generator/vector.move b/third_party/move/move-compiler-v2/tests/file-format-generator/vector.move new file mode 100644 index 0000000000000..c6dbf488f56eb --- /dev/null +++ b/third_party/move/move-compiler-v2/tests/file-format-generator/vector.move @@ -0,0 +1,5 @@ +module 0x42::vector { + fun create(): vector { + vector[1, 2, 3] + } +} diff --git a/third_party/move/move-compiler-v2/tests/testsuite.rs b/third_party/move/move-compiler-v2/tests/testsuite.rs index 4e8cee0c302cc..1dae4b9d16d92 100644 --- a/third_party/move/move-compiler-v2/tests/testsuite.rs +++ b/third_party/move/move-compiler-v2/tests/testsuite.rs @@ -3,7 +3,11 @@ // SPDX-License-Identifier: Apache-2.0 use codespan_reporting::{diagnostic::Severity, term::termcolor::Buffer}; -use move_compiler_v2::Options; +use move_binary_format::{binary_views::BinaryIndexedView, file_format as FF}; +use move_command_line_common::files::FileHash; +use move_compiler_v2::{run_file_format_gen, Options}; +use move_disassembler::disassembler::Disassembler; +use move_ir_types::location; use move_model::model::GlobalEnv; use move_prover_test_utils::{baseline_test, extract_test_directives}; use move_stackless_bytecode::function_target_pipeline::FunctionTargetPipeline; @@ -24,6 +28,8 @@ struct TestConfig { dump_ast: bool, /// A sequence of bytecode processors to run for this test. pipeline: FunctionTargetPipeline, + /// Whether we should generate file format from resulting bytecode + generate_file_format: bool, } fn path_from_crate_root(path: &str) -> String { @@ -65,12 +71,21 @@ impl TestConfig { check_only: true, dump_ast: true, pipeline: FunctionTargetPipeline::default(), + generate_file_format: false, } } else if path.contains("/bytecode-generator/") { Self { check_only: false, dump_ast: true, pipeline: FunctionTargetPipeline::default(), + generate_file_format: false, + } + } else if path.contains("/file-format-generator/") { + Self { + check_only: false, + dump_ast: false, + pipeline: FunctionTargetPipeline::default(), + generate_file_format: true, } } else { panic!( @@ -134,6 +149,17 @@ impl TestConfig { )); }, ); + let ok = Self::check_diags(&mut test_output.borrow_mut(), &env); + if ok && self.generate_file_format { + let (mods, _) = run_file_format_gen(&env, &targets); + let out = &mut test_output.borrow_mut(); + out.push_str("\n============ disassembled file-format ==================\n"); + Self::check_diags(out, &env); + for compiled_mod in mods { + let cont = Self::disassemble(&compiled_mod)?; + out.push_str(&cont) + } + } } } @@ -155,6 +181,14 @@ impl TestConfig { env.clear_diag(); ok } + + fn disassemble(module: &FF::CompiledModule) -> anyhow::Result { + let diss = Disassembler::from_view( + BinaryIndexedView::Module(module), + location::Loc::new(FileHash::empty(), 0, 0), + )?; + diss.disassemble() + } } datatest_stable::harness!(test_runner, "tests", r".*\.move$"); diff --git a/third_party/move/move-compiler-v2/transactional-tests/Cargo.toml b/third_party/move/move-compiler-v2/transactional-tests/Cargo.toml new file mode 100644 index 0000000000000..89189c98dd341 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "move-compiler-v2-transactional-tests" +version = "0.1.0" +authors = ["Diem Association "] +publish = false +edition = "2021" +license = "Apache-2.0" + +[dev-dependencies] +datatest-stable = "0.1.1" +move-transactional-test-runner = { path = "../../testing-infra/transactional-test-runner" } + +[[test]] +name = "tests" +harness = false diff --git a/third_party/move/move-compiler-v2/transactional-tests/src/lib.rs b/third_party/move/move-compiler-v2/transactional-tests/src/lib.rs new file mode 100644 index 0000000000000..0cd3c22c1b783 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/src/lib.rs @@ -0,0 +1,7 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +#![forbid(unsafe_code)] + +// Empty src/lib.rs to get rusty-tags working. diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.exp new file mode 100644 index 0000000000000..a6db107b3b9ca --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.exp @@ -0,0 +1,3 @@ +processed 2 tasks + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.move new file mode 100644 index 0000000000000..fc85094c71c7c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.move @@ -0,0 +1,35 @@ +//# publish +module 0x42::Test { + struct Tester has drop { + f: u64 + } + + public fun new(): Tester { + Tester { f: 10 } + } + + public fun len(t: &Tester): u64 { + t.f + } + + public fun modify(t: &mut Tester): u64 { + t.f = t.f - 1; + 9 - t.f + } +} + +//# run +script { +use 0x42::Test; +fun main() { + let x = Test::new(); + assert!(Test::len(&x) == 10, 70002); + + let i = 0; + while (i < Test::len(&x)) { + // if inline blocks skips relabelling this will cause a bytecode verifier error + assert!(Test::modify(&mut x) == i, 70003); + i = i + 1 + } +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.move new file mode 100644 index 0000000000000..1ed144ce31d9b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.move @@ -0,0 +1,16 @@ +//# run +script { +fun main() { + let x; + let y; + if (true) { + x = 1; + y = move x; + x = 5; + y; + } else { + x = 0; + }; + assert!(copy x == 5, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.move new file mode 100644 index 0000000000000..ecca0906c4caf --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + let x = 0; + while (true) { + if (x >= 5) break; + x = x + 1; + }; + assert!(x == 5, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.move new file mode 100644 index 0000000000000..3cbd68091b5ed --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.move @@ -0,0 +1,12 @@ +//# run +script { +fun main() { + let x = 0; + while (true) { + if (x >= 5) break; + x = x + 1; + continue + }; + assert!(move x == 5, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.move new file mode 100644 index 0000000000000..4d491716cf885 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.move @@ -0,0 +1,17 @@ +//# run +script { +fun main() { + let x = 0; + let y = 0; + loop { + if (x < 10) { + x = x + 1; + if (x % 2 == 0) continue; + y = y + x + } else { + break + } + }; + assert!(y == 25, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.move new file mode 100644 index 0000000000000..490507ae9fca5 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.move @@ -0,0 +1,17 @@ +//# run +script { +fun main() { + let x = 0; + let y = 0; + while (true) { + loop { + y = 5; + break + }; + x = 3; + break + }; + assert!(x == 3, 42); + assert!(y == 5, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.move new file mode 100644 index 0000000000000..3d041a50dcb66 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + let x = 0; + while (true) { + x = x + 1; + break + }; + assert!(x == 1, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.move new file mode 100644 index 0000000000000..14471d002cd95 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.move @@ -0,0 +1,12 @@ +//# run +script { +fun main() { + let x; + if (true) { + if (false) return () else return () + } else { + x = 0; + }; + assert!(x == 5, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.exp new file mode 100644 index 0000000000000..a6db107b3b9ca --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.exp @@ -0,0 +1,3 @@ +processed 2 tasks + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.move new file mode 100644 index 0000000000000..bbd2cddfa29a9 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.move @@ -0,0 +1,19 @@ +//# publish +address 0x42 { +module ReassignCond { + public fun reassign_cond(a: address, b: bool): address { + if (b) { + a = @0x2; + }; + a + } +} +} + +//# run +script { + use 0x42::ReassignCond::reassign_cond; + fun main() { + assert!(reassign_cond(@0x1, false) == @0x1, 42); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.move new file mode 100644 index 0000000000000..d57ede2bffbd1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.move @@ -0,0 +1,10 @@ +//# run +script { +fun main() { + if (true) { + return () + } else { + return () + } +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.move new file mode 100644 index 0000000000000..7107694b53350 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + if (true) { + loop return () + } else { + assert!(false, 42); + return () + } +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.move new file mode 100644 index 0000000000000..bc71fc7bc1b85 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.move @@ -0,0 +1,7 @@ +//# run +script { +fun main() { + if (true) return (); + assert!(false, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.move new file mode 100644 index 0000000000000..4740e60e3c342 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + if (true) { + return () + } else { + assert!(false, 42); + }; + assert!(false, 43); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.move new file mode 100644 index 0000000000000..5bb473588775b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + if (true) { + if (true) return () else return () + } else { + assert!(false, 42); + return () + } +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.move new file mode 100644 index 0000000000000..cf53544d745a6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + if (true) { + loop break + } else { + assert!(false, 42); + return () + } +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.move new file mode 100644 index 0000000000000..7e74e494e4981 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + if (true) { + loop { if (true) return () else break } + } else { + assert!(false, 42); + return () + } +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.move new file mode 100644 index 0000000000000..ca6b74e88f27d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + if (true) { + loop { if (true) return () else continue } + } else { + assert!(false, 42); + return () + } +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.move new file mode 100644 index 0000000000000..ac1ffab64cfd8 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + if (true) { + loop { break } + } else { + assert!(false, 42); + return () + } +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.move new file mode 100644 index 0000000000000..78bc7bcfdd8aa --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.move @@ -0,0 +1,10 @@ +//# run +script { +fun main() { + let b = false; + loop { + if (b) { if (b) continue } + else break; + }; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.move new file mode 100644 index 0000000000000..58cd17b090119 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + let x; + if (true) + x = 3 + else + x = 5; + x; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.move new file mode 100644 index 0000000000000..947a7b0ef73f1 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.move @@ -0,0 +1,12 @@ +//# run +script { +fun main() { + let x; + if (true) { + x = 3; + } + else + x = 5; + x; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.move new file mode 100644 index 0000000000000..4c08dcd692083 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.move @@ -0,0 +1,12 @@ +//# run +script { +fun main() { + let x; + if (true) + x = 3 + else { + x = 5 + }; + x; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.move new file mode 100644 index 0000000000000..ec23bc36f713c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.move @@ -0,0 +1,8 @@ +//# run +script { +fun main() { + let x = 0; + if (true) x = 3; + x; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.move new file mode 100644 index 0000000000000..8dc1523ca3298 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.move @@ -0,0 +1,6 @@ +//# run +script { +fun main() { + loop break; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.move new file mode 100644 index 0000000000000..d1e2e036e1598 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.move @@ -0,0 +1,30 @@ +//# run +script { +fun main() { + let x = 5; + let y = 2; + let x_ref; + let y_ref; + + x_ref = &x; + y_ref = &y; + y_ref; + x_ref; + + x_ref = &x; + y_ref = x_ref; + + if (true) { + _ = y_ref; + x_ref = &y; + y_ref = &x; + } else { + _ = y_ref; + x_ref = &x; + y_ref = &y; + }; + + assert!(*x_ref == 2, 42); + y_ref; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.move new file mode 100644 index 0000000000000..05efc97bc500c --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.move @@ -0,0 +1,10 @@ +//# run +script { +fun main() { + loop { + loop break; + break + }; + if (true) () else () +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.move new file mode 100644 index 0000000000000..80c522d9ab228 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.move @@ -0,0 +1,6 @@ +//# run +script { +fun main() { + loop return () +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.move new file mode 100644 index 0000000000000..b57492b992f0e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + let x = 0; + loop { + x = x + 1; + break + }; + assert!(x == 1, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.exp new file mode 100644 index 0000000000000..a6db107b3b9ca --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.exp @@ -0,0 +1,3 @@ +processed 2 tasks + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.move new file mode 100644 index 0000000000000..cc050a95019d4 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.move @@ -0,0 +1,20 @@ +//# publish +module 0x42::M { + public fun foobar(cond: bool) { + loop { + loop { + if (cond) break + }; + if (cond) break + } + } +} + +//# run +script { +use 0x42::M; + +fun main() { + M::foobar(true) +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.move new file mode 100644 index 0000000000000..a51faa05d435d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.move @@ -0,0 +1,12 @@ +//# run +script { +fun main() { + let x; + if (true) { + return () + } else { + x = 0 + }; + assert!(x == 5, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.move new file mode 100644 index 0000000000000..25cda679d5f79 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.move @@ -0,0 +1,15 @@ +//# run +script { +fun main() { + let x = 0; + let y = 1; + if (false) { + y = move x; + y; + return () + }; + y; + + assert!(x == 0, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.exp new file mode 100644 index 0000000000000..a6db107b3b9ca --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.exp @@ -0,0 +1,3 @@ +processed 2 tasks + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.move new file mode 100644 index 0000000000000..66744dc3b4f7a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.move @@ -0,0 +1,21 @@ +//# publish +module 0x42::Test { + public fun t(): u64 { + let x; + if (true) { + return 100 + } else { + x = 0; + }; + x + } +} + +//# run +script { +use 0x42::Test; + +fun main() { + assert!(Test::t() == 100, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.move new file mode 100644 index 0000000000000..ee9b46ebe6486 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.move @@ -0,0 +1,12 @@ +//# run +script { +fun main() { + let x; + if (true) { + return () + } else { + x = 0 + }; + assert!(x == 0, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.exp new file mode 100644 index 0000000000000..a6db107b3b9ca --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.exp @@ -0,0 +1,3 @@ +processed 2 tasks + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.move new file mode 100644 index 0000000000000..ef08a6a0f4a10 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.move @@ -0,0 +1,16 @@ +//# publish +module 0x42::Test { + public fun t(): u64 { + if (true) return 100; + 0 + } +} + +//# run +script { +use 0x42::Test; + +fun main() { + assert!(Test::t() == 100, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.exp new file mode 100644 index 0000000000000..1674857b1cce0 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.exp @@ -0,0 +1,12 @@ +processed 1 task + +task 0 'run'. lines 1-7: +Error: Script execution failed with VMError: { + major_status: OUT_OF_GAS, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.move new file mode 100644 index 0000000000000..37969fa9099c3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.move @@ -0,0 +1,7 @@ +//# run --gas-budget 700 --signers 0x1 +script { + fun main(_s: signer) { + // out of gas + loop () + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.move new file mode 100644 index 0000000000000..6747cea05d060 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.move @@ -0,0 +1,8 @@ +//# run +script { +fun main() { + let x = 0; + while (false) x = 1; + assert!(x == 0, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.move new file mode 100644 index 0000000000000..989d653e4fc34 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.move @@ -0,0 +1,17 @@ +//# run +script { +fun main() { + let x = 0; + let z = 0; + let y; + while (x < 3) { + x = x + 1; + y = 0; + while (y < 7) { + y = y + 1; + z = z + 1; + } + }; + assert!(z == 21, 42) +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.move new file mode 100644 index 0000000000000..e60a63dbf95b7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.move @@ -0,0 +1,10 @@ +//# run +script { +fun main() { + while (true) { + while (true) return (); + assert!(false, 42); + }; + assert!(false, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.move new file mode 100644 index 0000000000000..ad9e7a313723f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.move @@ -0,0 +1,7 @@ +//# run +script { +fun main() { + while (true) return (); + assert!(false, 42) +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.move b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.move new file mode 100644 index 0000000000000..b7f5d9d3e1bb3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.move @@ -0,0 +1,8 @@ +//# run +script { +fun main() { + let x = 0; + while (x < 5) x = x + 1; + assert!(x == 5, 42); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.exp new file mode 100644 index 0000000000000..15b4a3261910f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.exp @@ -0,0 +1,3 @@ +processed 3 tasks + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.move b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.move new file mode 100644 index 0000000000000..213896bd5a456 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.move @@ -0,0 +1,29 @@ +//# publish +module 0x42::C { + struct T {} + public fun foo(): T { + T{} + } +} + +//# publish +// names used to try to force an ordering of depedencies +module 0x42::B { + public fun foo(): 0x42::C::T { + 0x42::C::foo() + } +} + +//# publish +module 0x42::A { + struct T { + t_b: 0x42::C::T, + t_c: 0x42::C::T, + } + public fun foo(): T { + T { + t_c: 0x42::C::foo(), + t_b: 0x42::B::foo() + } + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.exp new file mode 100644 index 0000000000000..15b4a3261910f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.exp @@ -0,0 +1,3 @@ +processed 3 tasks + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.move b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.move new file mode 100644 index 0000000000000..f20950b817970 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.move @@ -0,0 +1,25 @@ +//# publish +module 0x42::X { + struct T has drop {} + public fun new(): T { + T {} + } +} + +//# publish +module 0x42::Y { + use 0x42::X; + public fun foo(): X::T { + X::new() + } +} + + +//# run +script { +use 0x42::Y; + +fun main() { + Y::foo(); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.exp new file mode 100644 index 0000000000000..ab071bbb64a07 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.exp @@ -0,0 +1,12 @@ +processed 3 tasks + +task 1 'run'. lines 9-15: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.move b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.move new file mode 100644 index 0000000000000..7b169dc3b7a26 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.move @@ -0,0 +1,23 @@ +//# run +script { + fun main() { + // does not abort + assert!(true, 1 / 0); + } +} + +//# run +script { + fun main() { + // does abort + assert!(false, 1 / 0); + } +} + +//# run +script { + fun main() { + // does abort, will be deprecated + assert!(true, 1 / 0); + } +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.exp new file mode 100644 index 0000000000000..a6db107b3b9ca --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.exp @@ -0,0 +1,3 @@ +processed 2 tasks + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.move b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.move new file mode 100644 index 0000000000000..06c32ed094616 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.move @@ -0,0 +1,27 @@ +//# publish +module 0x42::X { + public fun error(): bool { + abort 42 + } +} + +//# run +script { +use 0x42::X; +fun main() { + let vtrue = true; + let vfalse = false; + + true || X::error(); + vtrue || X::error(); + vtrue || { let r = X::error(); r }; + { let x = vtrue; x} || X::error(); + + false && X::error(); + vfalse && X::error(); + vfalse && { let r = X::error(); r }; + { let x = vfalse; x} && X::error(); + true || { abort 0 }; + { true } || (abort 0); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.exp new file mode 100644 index 0000000000000..6c14fc6226823 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.exp @@ -0,0 +1,48 @@ +processed 6 tasks + +task 1 'run'. lines 10-16: +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: redacted, + offsets: redacted, +} + +task 2 'run'. lines 19-25: +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: redacted, + offsets: redacted, +} + +task 3 'run'. lines 27-33: +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: redacted, + offsets: redacted, +} + +task 4 'run'. lines 35-41: +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(42), + location: 0x42::X, + indices: redacted, + offsets: redacted, +} + +task 5 'run'. lines 43-48: +Error: Script execution failed with VMError: { + major_status: ABORTED, + sub_status: Some(0), + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.move b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.move new file mode 100644 index 0000000000000..6bac1a6a64659 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.move @@ -0,0 +1,48 @@ +//# publish +module 0x42::X { + public fun error(): bool { + abort 42 + } +} + +// all should abort + +//# run +script { +use 0x42::X; +fun main() { + false || X::error(); +} +} + + +//# run +script { +use 0x42::X; +fun main() { + true && X::error(); +} +} + +//# run +script { +use 0x42::X; +fun main() { + X::error() && false; +} +} + +//# run +script { +use 0x42::X; +fun main() { + X::error() || true; +} +} + +//# run +script { +fun main() { + false || { abort 0 }; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.exp new file mode 100644 index 0000000000000..e2293ece03138 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.exp @@ -0,0 +1,69 @@ +comparison between v1 and v2 failed: += processed 7 tasks += += task 1 'run'. lines 57-64: += Error: Script execution failed with VMError: { +- major_status: ARITHMETIC_ERROR, +- sub_status: None, ++ major_status: ABORTED, ++ sub_status: Some(0), += location: 0x42::M, += indices: redacted, += offsets: redacted, += } += += task 2 'run'. lines 66-73: += Error: Script execution failed with VMError: { +- major_status: ARITHMETIC_ERROR, +- sub_status: None, ++ major_status: ABORTED, ++ sub_status: Some(0), += location: 0x42::M, += indices: redacted, += offsets: redacted, += } += += task 3 'run'. lines 75-82: += Error: Script execution failed with VMError: { +- major_status: ARITHMETIC_ERROR, +- sub_status: None, ++ major_status: ABORTED, ++ sub_status: Some(0), += location: 0x42::M, += indices: redacted, += offsets: redacted, += } += += task 4 'run'. lines 84-91: += Error: Script execution failed with VMError: { +- major_status: ARITHMETIC_ERROR, +- sub_status: None, ++ major_status: ABORTED, ++ sub_status: Some(0), += location: 0x42::M, += indices: redacted, += offsets: redacted, += } += += task 5 'run'. lines 93-110: += Error: Script execution failed with VMError: { +- major_status: ARITHMETIC_ERROR, +- sub_status: None, ++ major_status: ABORTED, ++ sub_status: Some(0), += location: 0x42::M, += indices: redacted, += offsets: redacted, += } += += task 6 'run'. lines 112-119: += Error: Script execution failed with VMError: { +- major_status: RESOURCE_ALREADY_EXISTS, +- sub_status: None, ++ major_status: ABORTED, ++ sub_status: Some(0), += location: 0x42::M, += indices: redacted, += offsets: redacted, += } += diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.move b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.move new file mode 100644 index 0000000000000..851d6b67cf713 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.move @@ -0,0 +1,119 @@ +// TODO: this currently does not work as expected; see +// # +//# publish +module 0x42::M { + struct S has drop { + a: u64, + b: u64, + } + + struct R has key, store {} + struct Cup has key { + a: u64, + b: R, + } + + public fun t0() { + S { b: 1 / 0, a: fail(0) }; + } + + public fun t1() { + S { b: 18446744073709551615 + 18446744073709551615, a: fail(0) }; + } + + public fun t2() { + S { b: 0 - 1, a: fail(0) }; + } + + public fun t3() { + S { b: 1 % 0, a: fail(0) }; + } + + public fun t4() { + S { b: 18446744073709551615 * 18446744073709551615, a: fail(0) }; + } + + /* TODO: activate once acquires is implemented + public fun t5(account: &signer) acquires R { + move_to(account, Cup { b: move_from(@0x0), a: fail(0) }); + } + */ + + public fun t6(account: &signer) { + move_to(account, Cup { b: R{}, a: 0 }); + S { b: mts(account), a: fail(0) }; + } + + fun fail(code: u64): u64 { + abort code + } + + fun mts(account: &signer): u64 { + move_to(account, Cup { b: R{}, a: 0 }); + 0 + } +} + +//# run +script { +use 0x42::M; +fun main() { + // arithmetic error + M::t0() +} +} + +//# run +script { +use 0x42::M; +fun main() { + // arithmetic error + M::t1() +} +} + +//# run +script { +use 0x42::M; +fun main() { + // arithmetic error + M::t2() +} +} + +//# run +script { +use 0x42::M; +fun main() { + // arithmetic error + M::t3() +} +} + +//# run +script { +use 0x42::M; +fun main() { + // arithmetic error + M::t4() +} +} + +// //# run --signers 0x1 +// script { +// use 0x42::M; +// fun main(account: signer) { +// // missing data +// M::t5(&account) +// } +// } +// + +//# run --signers 0x1 +script { +use 0x42::M; +fun main(account: signer) { + // resource already exists + M::t6(&account) +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.exp new file mode 100644 index 0000000000000..76ae614296663 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.exp @@ -0,0 +1,111 @@ +processed 17 tasks + +task 1 'run'. lines 17-23: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 2 'run'. lines 25-31: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 4 'run'. lines 50-56: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 5 'run'. lines 58-64: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 7 'run'. lines 80-86: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 8 'run'. lines 88-94: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 10 'run'. lines 113-119: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 11 'run'. lines 121-127: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 12 'run'. lines 131-137: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 14 'run'. lines 155-161: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 15 'run'. lines 163-169: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 16 'run'. lines 171-177: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.move new file mode 100644 index 0000000000000..599aed6209fb3 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.move @@ -0,0 +1,177 @@ +//# run +script { +fun main() { + assert!(0u128 + 0u128 == 0u128, 1000); + assert!(0u128 + 1u128 == 1u128, 1001); + assert!(1u128 + 1u128 == 2u128, 1002); + + assert!(13u128 + 67u128 == 80u128, 1100); + assert!(100u128 + 10u128 == 110u128, 1101); + + assert!(0u128 + 340282366920938463463374607431768211455u128 == 340282366920938463463374607431768211455u128, 1200); + assert!(1u128 + 340282366920938463463374607431768211454u128 == 340282366920938463463374607431768211455u128, 1201); + assert!(5u128 + 340282366920938463463374607431768211450u128 == 340282366920938463463374607431768211455u128, 1202); +} +} + +//# run +script { +fun main() { + // should fail + 1u128 + 340282366920938463463374607431768211455u128; +} +} + +//# run +script { +fun main() { + // should fail + 264235234643575437864589745863652363451u128 + 98731747836156137656137643716471364731u128; +} +} + + + +//# run +script { +fun main() { + assert!(0u128 - 0u128 == 0u128, 2000); + assert!(1u128 - 0u128 == 1u128, 2001); + assert!(1u128 - 1u128 == 0u128, 2002); + + assert!(52u128 - 13u128 == 39u128, 2100); + assert!(100u128 - 10u128 == 90u128, 2101); + + assert!(340282366920938463463374607431768211455u128 - 340282366920938463463374607431768211455u128 == 0u128, 2200); + assert!(5u128 - 1u128 - 4u128 == 0u128, 2201); +} +} + +//# run +script { +fun main() { + // should fail + 0u128 - 1u128; +} +} + +//# run +script { +fun main() { + // should fail + 54u128 - 100u128; +} +} + +//# run +script { +fun main() { + assert!(0u128 * 0u128 == 0u128, 3000); + assert!(1u128 * 0u128 == 0u128, 3001); + assert!(1u128 * 1u128 == 1u128, 3002); + + assert!(6u128 * 7u128 == 42u128, 3100); + assert!(10u128 * 10u128 == 100u128, 3101); + + assert!(170141183460469231731687303715884105727u128 * 2u128 == 340282366920938463463374607431768211454u128, 3200); +} +} + +//# run +script { +fun main() { + // should fail + 18446744073709551616u128 * 18446744073709551616u128; +} +} + +//# run +script { +fun main() { + // should fail + 170141183460469231731687303715884105728u128 * 2u128; +} +} + + + +//# run +script { +fun main() { + assert!(0u128 / 1u128 == 0u128, 4000); + assert!(1u128 / 1u128 == 1u128, 4001); + assert!(1u128 / 2u128 == 0u128, 4002); + + assert!(6u128 / 3u128 == 2u128, 4100); + assert!(340282366920938463463374607431768211455u128 / 4315342637u128 == 78854078469537403609736727246u128, 4101); + + assert!(340282366920938463463374607431768211454u128 / 340282366920938463463374607431768211455u128 == 0u128, 4200); + assert!(340282366920938463463374607431768211455u128 / 340282366920938463463374607431768211455u128 == 1u128, 4201); +} +} + +//# run +script { +fun main() { + // should fail + 0u128 / 0u128; +} +} + +//# run +script { +fun main() { + // should fail + 1u128 / 0u128; +} +} + + + +//# run +script { +fun main() { + // should fail + 340282366920938463463374607431768211455u128 / 0u128; +} +} + + +//# run +script { +fun main() { + assert!(0u128 % 1u128 == 0u128, 5000); + assert!(1u128 % 1u128 == 0u128, 5001); + assert!(1u128 % 2u128 == 1u128, 5002); + + assert!(8u128 % 3u128 == 2u128, 5100); + assert!(340282366920938463463374607431768211455u128 % 4315342637u128 == 2264823753u128, 5101); + + assert!(340282366920938463463374607431768211454u128 % 340282366920938463463374607431768211455u128 == 340282366920938463463374607431768211454u128, 5200); + assert!(340282366920938463463374607431768211455u128 % 340282366920938463463374607431768211455u128 == 0u128, 5201); +} +} + +//# run +script { +fun main() { + // should fail + 0u128 % 0u128; +} +} + +//# run +script { +fun main() { + // should fail + 1u128 % 0u128; +} +} + +//# run +script { +fun main() { + // should fail + 340282366920938463463374607431768211455u128 % 0u128; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.exp new file mode 100644 index 0000000000000..7afc624dc2c7b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.exp @@ -0,0 +1,111 @@ +processed 17 tasks + +task 1 'run'. lines 17-23: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 2 'run'. lines 25-31: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 4 'run'. lines 48-54: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 5 'run'. lines 56-62: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 7 'run'. lines 79-85: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 8 'run'. lines 87-93: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 10 'run'. lines 112-119: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 11 'run'. lines 121-126: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 12 'run'. lines 128-134: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 14 'run'. lines 152-158: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 15 'run'. lines 160-166: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 16 'run'. lines 168-174: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.move new file mode 100644 index 0000000000000..d0976630d990d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.move @@ -0,0 +1,174 @@ +//# run +script { +fun main() { + assert!(0u16 + 0u16 == 0u16, 1000); + assert!(0u16 + 1u16 == 1u16, 1001); + assert!(1u16 + 1u16 == 2u16, 1002); + + assert!(13u16 + 67u16 == 80u16, 1100); + assert!(100u16 + 10u16 == 110u16, 1101); + + assert!(0u16 + 65535u16 == 65535u16, 1200); + assert!(1u16 + 65534u16 == 65535u16, 1201); + assert!(5u16 + 65530u16 == 65535u16, 1202); +} +} + +//# run +script { +fun main() { + // should fail + 1u16 + 65535u16; +} +} + +//# run +script { +fun main() { + // should fail + 65135u16 + 6555u16; +} +} + +//# run +script { +fun main() { + assert!(0u16 - 0u16 == 0u16, 2000); + assert!(1u16 - 0u16 == 1u16, 2001); + assert!(1u16 - 1u16 == 0u16, 2002); + + assert!(52u16 - 13u16 == 39u16, 2100); + assert!(100u16 - 10u16 == 90u16, 2101); + + assert!(65535u16 - 65535u16 == 0u16, 2200); + assert!(5u16 - 1u16 - 4u16 == 0u16, 2201); +} +} + +//# run +script { +fun main() { + // should fail + 0u16 - 1u16; +} +} + +//# run +script { +fun main() { + // should fail + 54u16 - 100u16; +} +} + + +//# run +script { +fun main() { + assert!(0u16 * 0u16 == 0u16, 3000); + assert!(1u16 * 0u16 == 0u16, 3001); + assert!(1u16 * 1u16 == 1u16, 3002); + + assert!(6u16 * 7u16 == 42u16, 3100); + assert!(10u16 * 10u16 == 100u16, 3101); + + assert!(32767u16 * 2u16 == 65534u16, 3200); +} +} + +//# run +script { +fun main() { + // should fail + 32767u16 * 32767u16; +} +} + +//# run +script { +fun main() { + // should fail + 33767u16 * 2u16; +} +} + + + +//# run +script { +fun main() { + assert!(0u16 / 1u16 == 0u16, 4000); + assert!(1u16 / 1u16 == 1u16, 4001); + assert!(1u16 / 2u16 == 0u16, 4002); + + assert!(6u16 / 3u16 == 2u16, 4100); + assert!(65535u16 / 13u16 == 5041u16, 4101); + + assert!(65534u16 / 65535u16 == 0u16, 4200); + assert!(65535u16 / 65534u16 == 1u16, 4201); +} +} + +//# run +script { +fun main() { + // should fail + 0u16 / 0u16; +} +} +// check: ARITHMETIC_ERROR + +//# run +script { +fun main() { + 1u16 / 0u16; +} +} + +//# run +script { +fun main() { + // should fail + 65535u16 / 0u16; +} +} + + +//# run +script { +fun main() { + assert!(0u16 % 1u16 == 0u16, 5000); + assert!(1u16 % 1u16 == 0u16, 5001); + assert!(1u16 % 2u16 == 1u16, 5002); + + assert!(8u16 % 3u16 == 2u16, 5100); + assert!(65535u16 % 134u16 == 9u16, 5101); + + assert!(65534u16 % 65535u16 == 65534u16, 5200); + assert!(65535u16 % 65535u16 == 0u16, 5201); +} +} + +//# run +script { +fun main() { + // should fail + 0u16 % 0u16; +} +} + +//# run +script { +fun main() { + // should fail + 1u16 % 0u16; +} +} + +//# run +script { +fun main() { + // should fail + 65535u16 % 0u16; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.exp new file mode 100644 index 0000000000000..36939ee27d05b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.exp @@ -0,0 +1,102 @@ +processed 17 tasks + +task 1 'run'. lines 17-23: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 2 'run'. lines 25-31: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 4 'run'. lines 48-54: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 5 'run'. lines 56-62: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 7 'run'. lines 79-85: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 10 'run'. lines 112-119: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 11 'run'. lines 121-126: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 12 'run'. lines 128-134: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 14 'run'. lines 152-158: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 15 'run'. lines 160-166: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 16 'run'. lines 168-174: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.move new file mode 100644 index 0000000000000..1efaaaa5cfcce --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.move @@ -0,0 +1,174 @@ +//# run +script { +fun main() { + assert!(0u256 + 0u256 == 0u256, 1000); + assert!(0u256 + 1u256 == 1u256, 1001); + assert!(1u256 + 1u256 == 2u256, 1002); + + assert!(13u256 + 67u256 == 80u256, 1100); + assert!(100u256 + 10u256 == 110u256, 1101); + + assert!(0u256 + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 == 115792089237316195423570985008687907853269984665640564039457584007913129639935u256, 1200); + assert!(1u256 + 115792089237316195423570985008687907853269984665640564039457584007913129639934u256 == 115792089237316195423570985008687907853269984665640564039457584007913129639935u256, 1201); + assert!(5u256 + 115792089237316195423570985008687907853269984665640564039457584007913129639930u256 == 115792089237316195423570985008687907853269984665640564039457584007913129639935u256, 1202); +} +} + +//# run +script { +fun main() { + // should fail + 1u256 + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256; +} +} + +//# run +script { +fun main() { + // should fail + 105792089237316195423570985008687907853269984665640564039457584007913129639935u256 + 105792089237316195423570985008687907853269984665640564039457584007913129639935; +} +} + +//# run +script { +fun main() { + assert!(0u256 - 0u256 == 0u256, 2000); + assert!(1u256 - 0u256 == 1u256, 2001); + assert!(1u256 - 1u256 == 0u256, 2002); + + assert!(52u256 - 13u256 == 39u256, 2100); + assert!(100u256 - 10u256 == 90u256, 2101); + + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639935u256 - 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 == 0u256, 2200); + assert!(5u256 - 1u256 - 4u256 == 0u256, 2201); +} +} + +//# run +script { +fun main() { + // should fail + 0u256 - 1u256; +} +} + +//# run +script { +fun main() { + // should fail + 54u256 - 100u256; +} +} + + +//# run +script { +fun main() { + assert!(0u256 * 0u256 == 0u256, 3000); + assert!(1u256 * 0u256 == 0u256, 3001); + assert!(1u256 * 1u256 == 1u256, 3002); + + assert!(6u256 * 7u256 == 42u256, 3100); + assert!(10u256 * 10u256 == 100u256, 3101); + + assert!(57896044618658097711785492504343953926634992332820282019728792003956564819967u256 * 2u256 == 115792089237316195423570985008687907853269984665640564039457584007913129639934u256, 3200); +} +} + +//# run +script { +fun main() { + // should fail + 578960446186580977117853953926634992332820282019728792003956564819967u256 * 57896044618343953926634992332820282019728792003956564819967u256; +} +} + +//# run +script { +fun main() { + // should fail + 37896044618658097711785492504343953926634992332820282019728792003956564819967u256 * 2u256; +} +} + + + +//# run +script { +fun main() { + assert!(0u256 / 1u256 == 0u256, 4000); + assert!(1u256 / 1u256 == 1u256, 4001); + assert!(1u256 / 2u256 == 0u256, 4002); + + assert!(6u256 / 3u256 == 2u256, 4100); + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639935u256 / 1234567891234512345678912345u256 == 93791593041942242554519147120179023890934338607714u256, 4101); + + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639934u256 / 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 == 0u256, 4200); + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639935u256 / 115792089237316195423570985008687907853269984665640564039457584007913129639934u256 == 1u256, 4201); +} +} + +//# run +script { +fun main() { + // should fail + 0u256 / 0u256; +} +} +// check: ARITHMETIC_ERROR + +//# run +script { +fun main() { + 1u256 / 0u256; +} +} + +//# run +script { +fun main() { + // should fail + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 / 0u256; +} +} + + +//# run +script { +fun main() { + assert!(0u256 % 1u256 == 0u256, 5000); + assert!(1u256 % 1u256 == 0u256, 5001); + assert!(1u256 % 2u256 == 1u256, 5002); + + assert!(8u256 % 3u256 == 2u256, 5100); + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639935u256 % 1234567891234512345678912345u256 == 440810759282713395982810605u256, 5101); + + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639934u256 % 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 == 115792089237316195423570985008687907853269984665640564039457584007913129639934u256, 5200); + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639934u256 % 115792089237316195423570985008687907853269984665640564039457584007913129639934u256 == 0u256, 5201); +} +} + +//# run +script { +fun main() { + // should fail + 0u256 % 0u256; +} +} + +//# run +script { +fun main() { + // should fail + 1u256 % 0u256; +} +} + +//# run +script { +fun main() { + // should fail + 4294967294u256 % 0u256; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.exp new file mode 100644 index 0000000000000..36939ee27d05b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.exp @@ -0,0 +1,102 @@ +processed 17 tasks + +task 1 'run'. lines 17-23: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 2 'run'. lines 25-31: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 4 'run'. lines 48-54: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 5 'run'. lines 56-62: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 7 'run'. lines 79-85: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 10 'run'. lines 112-119: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 11 'run'. lines 121-126: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 12 'run'. lines 128-134: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 14 'run'. lines 152-158: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 15 'run'. lines 160-166: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 16 'run'. lines 168-174: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.move new file mode 100644 index 0000000000000..be2cf84cc85ba --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.move @@ -0,0 +1,174 @@ +//# run +script { +fun main() { + assert!(0u32 + 0u32 == 0u32, 1000); + assert!(0u32 + 1u32 == 1u32, 1001); + assert!(1u32 + 1u32 == 2u32, 1002); + + assert!(13u32 + 67u32 == 80u32, 1100); + assert!(100u32 + 10u32 == 110u32, 1101); + + assert!(0u32 + 4294967295u32 == 4294967295u32, 1200); + assert!(1u32 + 4294967294u32 == 4294967295u32, 1201); + assert!(5u32 + 4294967290u32 == 4294967295u32, 1202); +} +} + +//# run +script { +fun main() { + // should fail + 1u32 + 4294967295u32; +} +} + +//# run +script { +fun main() { + // should fail + 4294967295u32 + 4294967295u32; +} +} + +//# run +script { +fun main() { + assert!(0u32 - 0u32 == 0u32, 2000); + assert!(1u32 - 0u32 == 1u32, 2001); + assert!(1u32 - 1u32 == 0u32, 2002); + + assert!(52u32 - 13u32 == 39u32, 2100); + assert!(100u32 - 10u32 == 90u32, 2101); + + assert!(4294967295u32 - 4294967295u32 == 0u32, 2200); + assert!(5u32 - 1u32 - 4u32 == 0u32, 2201); +} +} + +//# run +script { +fun main() { + // should fail + 0u32 - 1u32; +} +} + +//# run +script { +fun main() { + // should fail + 54u32 - 100u32; +} +} + + +//# run +script { +fun main() { + assert!(0u32 * 0u32 == 0u32, 3000); + assert!(1u32 * 0u32 == 0u32, 3001); + assert!(1u32 * 1u32 == 1u32, 3002); + + assert!(6u32 * 7u32 == 42u32, 3100); + assert!(10u32 * 10u32 == 100u32, 3101); + + assert!(2147483647u32 * 2u32 == 4294967294u32, 3200); +} +} + +//# run +script { +fun main() { + // should fail + 1147483647u32 * 2147483647u32; +} +} + +//# run +script { +fun main() { + // should fail + 1147483647u32 * 2u32; +} +} + + + +//# run +script { +fun main() { + assert!(0u32 / 1u32 == 0u32, 4000); + assert!(1u32 / 1u32 == 1u32, 4001); + assert!(1u32 / 2u32 == 0u32, 4002); + + assert!(6u32 / 3u32 == 2u32, 4100); + assert!(4294967294u32 / 13u32 == 330382099u32, 4101); + + assert!(4294967294u32 / 4294967295u32 == 0u32, 4200); + assert!(4294967295u32 / 4294967294u32 == 1u32, 4201); +} +} + +//# run +script { +fun main() { + // should fail + 0u32 / 0u32; +} +} +// check: ARITHMETIC_ERROR + +//# run +script { +fun main() { + 1u32 / 0u32; +} +} + +//# run +script { +fun main() { + // should fail + 4294967294u32 / 0u32; +} +} + + +//# run +script { +fun main() { + assert!(0u32 % 1u32 == 0u32, 5000); + assert!(1u32 % 1u32 == 0u32, 5001); + assert!(1u32 % 2u32 == 1u32, 5002); + + assert!(8u32 % 3u32 == 2u32, 5100); + assert!(4294967294u32 % 1234u32 == 678u32, 5101); + + assert!(4294967294u32 % 4294967295u32 == 4294967294u32, 5200); + assert!(4294967294u32 % 4294967294u32 == 0u32, 5201); +} +} + +//# run +script { +fun main() { + // should fail + 0u32 % 0u32; +} +} + +//# run +script { +fun main() { + // should fail + 1u32 % 0u32; +} +} + +//# run +script { +fun main() { + // should fail + 4294967294u32 % 0u32; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.exp new file mode 100644 index 0000000000000..b295a500088a6 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.exp @@ -0,0 +1,111 @@ +processed 17 tasks + +task 1 'run'. lines 17-23: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 2 'run'. lines 25-31: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 4 'run'. lines 50-56: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 5 'run'. lines 58-64: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 7 'run'. lines 81-87: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 8 'run'. lines 89-95: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 10 'run'. lines 114-121: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 11 'run'. lines 123-128: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 12 'run'. lines 130-136: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 14 'run'. lines 154-160: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 15 'run'. lines 162-168: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 16 'run'. lines 170-176: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.move new file mode 100644 index 0000000000000..3f102aefa2904 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.move @@ -0,0 +1,176 @@ +//# run +script { +fun main() { + assert!(0u64 + 0u64 == 0u64, 1000); + assert!(0u64 + 1u64 == 1u64, 1001); + assert!(1u64 + 1u64 == 2u64, 1002); + + assert!(13u64 + 67u64 == 80u64, 1100); + assert!(100u64 + 10u64 == 110u64, 1101); + + assert!(0u64 + 18446744073709551615u64 == 18446744073709551615u64, 1200); + assert!(1u64 + 18446744073709551614u64 == 18446744073709551615u64, 1201); + assert!(5u64 + 18446744073709551610u64 == 18446744073709551615u64, 1202); +} +} + +//# run +script { +fun main() { + // should fail + 1u64 + 18446744073709551615u64; +} +} + +//# run +script { +fun main() { + // should fail + 12000000000000000000u64 + 10000000000000000000u64; +} +} + + + +//# run +script { +fun main() { + assert!(0u64 - 0u64 == 0u64, 2000); + assert!(1u64 - 0u64 == 1u64, 2001); + assert!(1u64 - 1u64 == 0u64, 2002); + + assert!(52u64 - 13u64 == 39u64, 2100); + assert!(100u64 - 10u64 == 90u64, 2101); + + assert!(18446744073709551615u64 - 18446744073709551615u64 == 0u64, 2200); + assert!(5u64 - 1u64 - 4u64 == 0u64, 2201); +} +} + +//# run +script { +fun main() { + // should fail + 0u64 - 1u64; +} +} + +//# run +script { +fun main() { + // should fail + 54u64 - 100u64; +} +} + + +//# run +script { +fun main() { + assert!(0u64 * 0u64 == 0u64, 3000); + assert!(1u64 * 0u64 == 0u64, 3001); + assert!(1u64 * 1u64 == 1u64, 3002); + + assert!(6u64 * 7u64 == 42u64, 3100); + assert!(10u64 * 10u64 == 100u64, 3101); + + assert!(9223372036854775807u64 * 2u64 == 18446744073709551614u64, 3200); +} +} + +//# run +script { +fun main() { + // should fail + 4294967296u64 * 4294967296u64; +} +} + +//# run +script { +fun main() { + // should fail + 9223372036854775808 * 2u64; +} +} + + + +//# run +script { +fun main() { + assert!(0u64 / 1u64 == 0u64, 4000); + assert!(1u64 / 1u64 == 1u64, 4001); + assert!(1u64 / 2u64 == 0u64, 4002); + + assert!(6u64 / 3u64 == 2u64, 4100); + assert!(18446744073709551615u64 / 13131u64 == 1404824009878116u64, 4101); + + assert!(18446744073709551614u64 / 18446744073709551615u64 == 0u64, 4200); + assert!(18446744073709551615u64 / 18446744073709551615u64 == 1u64, 4201); +} +} + +//# run +script { +fun main() { + // should fail + 0u64 / 0u64; +} +} +// check: ARITHMETIC_ERROR + +//# run +script { +fun main() { + 1u64 / 0u64; +} +} + +//# run +script { +fun main() { + // should fail + 18446744073709551615u64 / 0u64; +} +} + + +//# run +script { +fun main() { + assert!(0u64 % 1u64 == 0u64, 5000); + assert!(1u64 % 1u64 == 0u64, 5001); + assert!(1u64 % 2u64 == 1u64, 5002); + + assert!(8u64 % 3u64 == 2u64, 5100); + assert!(18446744073709551615u64 % 13131u64 == 10419u64, 5101); + + assert!(18446744073709551614u64 % 18446744073709551615u64 == 18446744073709551614u64, 5200); + assert!(18446744073709551615u64 % 18446744073709551615u64 == 0u64, 5201); +} +} + +//# run +script { +fun main() { + // should fail + 0u64 % 0u64; +} +} + +//# run +script { +fun main() { + // should fail + 1u64 % 0u64; +} +} + +//# run +script { +fun main() { + // should fail + 18446744073709551615u64 % 0u64; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.exp new file mode 100644 index 0000000000000..91d11847eab3a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.exp @@ -0,0 +1,111 @@ +processed 17 tasks + +task 1 'run'. lines 17-23: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 2 'run'. lines 25-31: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 4 'run'. lines 48-54: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 5 'run'. lines 56-62: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 7 'run'. lines 79-85: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 8 'run'. lines 87-93: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 10 'run'. lines 111-117: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 11 'run'. lines 119-125: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 12 'run'. lines 127-133: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 14 'run'. lines 152-158: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 15 'run'. lines 160-166: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 16 'run'. lines 168-174: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.move new file mode 100644 index 0000000000000..6da84c61ca26b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.move @@ -0,0 +1,174 @@ +//# run +script { +fun main() { + assert!(0u8 + 0u8 == 0u8, 1000); + assert!(0u8 + 1u8 == 1u8, 1001); + assert!(1u8 + 1u8 == 2u8, 1002); + + assert!(13u8 + 67u8 == 80u8, 1100); + assert!(100u8 + 10u8 == 110u8, 1101); + + assert!(0u8 + 255u8 == 255u8, 1200); + assert!(1u8 + 254u8 == 255u8, 1201); + assert!(5u8 + 250u8 == 255u8, 1202); +} +} + +//# run +script { +fun main() { + // should fail + 1u8 + 255u8; +} +} + +//# run +script { +fun main() { + // should fail + 215u8 + 156u8; +} +} + +//# run +script { +fun main() { + assert!(0u8 - 0u8 == 0u8, 2000); + assert!(1u8 - 0u8 == 1u8, 2001); + assert!(1u8 - 1u8 == 0u8, 2002); + + assert!(52u8 - 13u8 == 39u8, 2100); + assert!(100u8 - 10u8 == 90u8, 2101); + + assert!(255u8 - 255u8 == 0u8, 2200); + assert!(5u8 - 1u8 - 4u8 == 0u8, 2201); +} +} + +//# run +script { +fun main() { + // should fail + 0u8 - 1u8; +} +} + +//# run +script { +fun main() { + // should fail + 54u8 - 100u8; +} +} + + +//# run +script { +fun main() { + assert!(0u8 * 0u8 == 0u8, 3000); + assert!(1u8 * 0u8 == 0u8, 3001); + assert!(1u8 * 1u8 == 1u8, 3002); + + assert!(6u8 * 7u8 == 42u8, 3100); + assert!(10u8 * 10u8 == 100u8, 3101); + + assert!(127u8 * 2u8 == 254u8, 3200); +} +} + +//# run +script { +fun main() { + // should fail + 16u8 * 16u8; +} +} + +//# run +script { +fun main() { + // should fail + 128u8 * 2u8; +} +} + + +//# run +script { +fun main() { + assert!(0u8 / 1u8 == 0u8, 4000); + assert!(1u8 / 1u8 == 1u8, 4001); + assert!(1u8 / 2u8 == 0u8, 4002); + + assert!(6u8 / 3u8 == 2u8, 4100); + assert!(255u8 / 7u8 == 36u8, 4101); + + assert!(254u8 / 255u8 == 0u8, 4200); + assert!(255u8 / 255u8 == 1u8, 4201); +} +} + +//# run +script { +fun main() { + // should fail + 0u8 / 0u8; +} +} + +//# run +script { +fun main() { + // should fail + 1u8 / 0u8; +} +} + +//# run +script { +fun main() { + // should fail + 255u8 / 0u8; +} +} + + + +//# run +script { +fun main() { + assert!(0u8 % 1u8 == 0u8, 5000); + assert!(1u8 % 1u8 == 0u8, 5001); + assert!(1u8 % 2u8 == 1u8, 5002); + + assert!(8u8 % 3u8 == 2u8, 5100); + assert!(255u8 % 7u8 == 3u8, 5101); + + assert!(254u8 % 255u8 == 254u8, 5200); + assert!(255u8 % 255u8 == 0u8, 5201); +} +} + +//# run +script { +fun main() { + // should fail + 0u8 % 0u8; +} +} + +//# run +script { +fun main() { + // should fail + 1u8 % 0u8; +} +} + +//# run +script { +fun main() { + // should fail + 255u8 % 0u8; +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.exp new file mode 100644 index 0000000000000..15b4a3261910f --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.exp @@ -0,0 +1,3 @@ +processed 3 tasks + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.move new file mode 100644 index 0000000000000..247b401c0fd1e --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.move @@ -0,0 +1,156 @@ +//# run +script { +fun main() { + assert!(0u8 & 0u8 == 0u8, 1000); + assert!(0u64 & 0u64 == 0u64, 1001); + assert!(0u128 & 0u128 == 0u128, 1002); + assert!(0u8 & 42u8 == 0u8, 1003); + assert!(0u64 & 42u64 == 0u64, 1004); + assert!(0u128 & 42u128 == 0u128, 1005); + assert!(0u16 & 0u16 == 0u16, 1000); + assert!(0u32 & 0u32 == 0u32, 1001); + assert!(0u256 & 0u256 == 0u256, 1002); + assert!(0u16 & 42u16 == 0u16, 1003); + assert!(0u32 & 42u32 == 0u32, 1004); + assert!(0u256 & 42u256 == 0u256, 1005); + + assert!(43u8 & 43u8 == 43u8, 1100); + assert!(856776467654u64 & 856776467654u64 == 856776467654u64, 1101); + assert!(4125423653474658754976595u128 & 4125423653474658754976595u128 == 4125423653474658754976595u128, 1102); + assert!(43u16 & 43u16 == 43u16, 1100); + assert!(856744u32 & 856744u32 == 856744u32, 1101); + assert!(41254236534746587549765954658754976595u256 & 41254236534746587549765954658754976595u256 == 41254236534746587549765954658754976595u256, 1102); + + assert!(255u8 & 255u8 == 255u8, 1200); + assert!(18446744073709551615u64 & 18446744073709551615u64 == 18446744073709551615u64, 1201); + assert!( + 340282366920938463463374607431768211455u128 & + 340282366920938463463374607431768211455u128 == + 340282366920938463463374607431768211455u128, + 1202 + ); + assert!(65535u16 & 65535u16 == 65535u16, 1200); + assert!(4294967295u32 & 4294967295u32 == 4294967295u32, 1201); + assert!( + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 & + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 == + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256, + 1202 + ); + + assert!(101u8 & 77u8 == 69u8, 1300); + assert!(675437u64 & 14235u64 == 1545u64, 1301); + assert!(534263574563786485434889u128 & 3141524387653489576893u128 == 632665710869872675337u128, 1302); + assert!(10186u16 & 717u16 == 712u16, 1300); + assert!(675437u32 & 14235u32 == 1545u32, 1301); + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639u256 & 3141524387653489576893u256 == 2366182237060668637861u256, 1302); +} +} + + +//# run +script { +fun main() { + assert!(0u8 | 0u8 == 0u8, 2000); + assert!(0u64 | 0u64 == 0u64, 2001); + assert!(0u128 | 0u128 == 0u128, 2002); + assert!(42u8 | 0u8 == 42u8, 2003); + assert!(42u64 | 0u64 == 42u64, 2004); + assert!(42u128 | 0u128 == 42u128, 2005); + assert!(0u16 | 0u16 == 0u16, 1000); + assert!(0u32 | 0u32 == 0u32, 1001); + assert!(0u256 | 0u256 == 0u256, 1002); + assert!(0u16 | 42u16 == 42u16, 1003); + assert!(0u32 | 42u32 == 42u32, 1004); + assert!(0u256 | 42u256 == 42u256, 1005); + + + assert!(43u8 | 43u8 == 43u8, 2100); + assert!(856776467654u64 | 856776467654u64 == 856776467654u64, 2101); + assert!(4125423653474658754976595u128 | 4125423653474658754976595u128 == 4125423653474658754976595u128, 2102); + assert!(43u16 | 43u16 == 43u16, 1100); + assert!(856744u32 | 856744u32 == 856744u32, 1101); + assert!(41254236534746587549765954658754976595u256 | 41254236534746587549765954658754976595u256 == 41254236534746587549765954658754976595u256, 1102); + + assert!(255u8 | 255u8 == 255u8, 2200); + assert!(18446744073709551615u64 | 18446744073709551615u64 == 18446744073709551615u64, 2201); + assert!( + 340282366920938463463374607431768211455u128 | + 340282366920938463463374607431768211455u128 == + 340282366920938463463374607431768211455u128, + 2202 + ); + assert!(65535u16 | 65535u16 == 65535u16, 1200); + assert!(4294967295u32 | 4294967295u32 == 4294967295u32, 1201); + assert!( + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 | + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 == + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256, + 1202 + ); + + assert!(101u8 | 77u8 == 109u8, 2300); + assert!(675437u64 | 14235u64 == 688127u64, 2301); + assert!(534263574563786485434889u128 | 3141524387653489576893u128 == 536772433240570102336445u128, 2302); + assert!(10186u16 | 717u16 == 10191u16, 1300); + assert!(675437u32 | 14235u32 == 688127u32, 1301); + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639u256 | 3141524387653489576893u256 == 115792089237316195423570985008687907853269984665640564814799734600734068671u256, 1302); +} +} + + +//# run +script { +fun main() { + assert!(0u8 ^ 0u8 == 0u8, 3000); + assert!(0u64 ^ 0u64 == 0u64, 3001); + assert!(0u128 ^ 0u128 == 0u128, 3002); + assert!(13u8 ^ 0u8 == 13u8, 3003); + assert!(13u64 ^ 0u64 == 13u64, 3004); + assert!(13u128 ^ 0u128 == 13u128, 3005); + assert!(0u16 ^ 0u16 == 0u16, 3000); + assert!(0u32 ^ 0u32 == 0u32, 3001); + assert!(0u256 ^ 0u256 == 0u256, 3002); + assert!(13u16 ^ 0u16 == 13u16, 3003); + assert!(13u32 ^ 0u32 == 13u32, 3004); + assert!(13u256 ^ 0u256 == 13u256, 3005); + + assert!(43u8 ^ 43u8 == 0u8, 3100); + assert!(856776467654u64 ^ 856776467654u64 == 0u64, 3101); + assert!(4125423653474658754976595u128 ^ 4125423653474658754976595u128 == 0u128, 3102); + assert!(43u16 ^ 43u16 == 0u16, 1100); + assert!(856744u32 ^ 856744u32 == 0u32, 1101); + assert!(41254236534746587549765954658754976595u256 ^ 41254236534746587549765954658754976595u256 == 0u256, 1102); + + assert!(255u8 ^ 255u8 == 0u8, 3200); + assert!(18446744073709551615u64 ^ 18446744073709551615u64 == 0u64, 3201); + assert!( + 340282366920938463463374607431768211455u128 ^ + 340282366920938463463374607431768211455u128 == + 0u128, + 3202 + ); + assert!(65535u16 ^ 65535u16 == 0u16, 1200); + assert!(4294967295u32 ^ 4294967295u32 == 0u32, 1201); + assert!( + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 ^ + 115792089237316195423570985008687907853269984665640564039457584007913129639935u256 == + 0u256, + 1202 + ); + + assert!(101u8 ^ 77u8 == 40u8, 3300); + assert!(675437u64 ^ 14235u64 == 686582u64, 3301); + assert!(534263574563786485434889u128 ^ 3141524387653489576893u128 == 536139767529700229661108u128, 3302); + assert!(10186u16 ^ 717u16 == 9479u16, 1300); + assert!(675437u32 ^ 14235u32 == 686582u32, 1301); + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639u256 ^ 3141524387653489576893u256 == 115792089237316195423570985008687907853269984665640562448617497540065430810u256, 1302); + + assert!(13u8 ^ 1u8 == 12u8, 3400); + assert!(13u64 ^ 1u64 == 12u64, 3401); + assert!(13u128 ^ 1u128 == 12u128, 3402); + assert!(13u16 ^ 1u16 == 12u16, 3400); + assert!(13u32 ^ 1u32 == 12u32, 3401); + assert!(13u256 ^ 1u256 == 12u256, 3402); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.move new file mode 100644 index 0000000000000..9b17315665d5d --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + assert!((true && false) == false, 99); + assert!((true || false) == true, 100); + assert!(!true == false, 101); + assert!(!false == true, 102); + assert!(!!true == true, 103); + assert!(!!false == false, 104); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.exp new file mode 100644 index 0000000000000..68b0fe9f2f525 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.exp @@ -0,0 +1,255 @@ +processed 35 tasks + +task 6 'run'. lines 182-188: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 7 'run'. lines 190-196: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 8 'run'. lines 198-204: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 9 'run'. lines 206-212: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 10 'run'. lines 214-220: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 11 'run'. lines 222-228: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 12 'run'. lines 230-236: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 13 'run'. lines 238-244: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 14 'run'. lines 246-252: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 15 'run'. lines 254-262: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 16 'run'. lines 263-269: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 17 'run'. lines 271-277: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 18 'run'. lines 279-285: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 19 'run'. lines 287-293: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 20 'run'. lines 295-301: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 21 'run'. lines 303-309: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 22 'run'. lines 311-317: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 23 'run'. lines 319-325: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 24 'run'. lines 327-335: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 25 'run'. lines 336-342: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 27 'run'. lines 352-358: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 28 'run'. lines 360-366: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 29 'run'. lines 368-374: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 30 'run'. lines 376-382: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 31 'run'. lines 384-392: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 32 'run'. lines 393-399: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 33 'run'. lines 401-407: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 34 'run'. lines 409-415: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.move new file mode 100644 index 0000000000000..929e8620d559b --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.move @@ -0,0 +1,415 @@ +// Casting to u8. +//# run +script { +fun main() { + // 0 remains unchanged. + assert!((0u8 as u8) == 0u8, 1000); + assert!((0u64 as u8) == 0u8, 1001); + assert!((0u128 as u8) == 0u8, 1002); + assert!((0u16 as u8) == 0u8, 1000); + assert!((0u32 as u8) == 0u8, 1001); + assert!((0u256 as u8) == 0u8, 1002); + + // Random small number unchanged. + assert!((21u8 as u8) == 21u8, 1100); + assert!((21u64 as u8) == 21u8, 1101); + assert!((21u128 as u8) == 21u8, 1102); + assert!((21u16 as u8) == 21u8, 1100); + assert!((21u32 as u8) == 21u8, 1101); + assert!((21u256 as u8) == 21u8, 1102); + + // Max representable values remain unchanged. + assert!((255u8 as u8) == 255u8, 1200); + assert!((255u64 as u8) == 255u8, 1201); + assert!((255u128 as u8) == 255u8, 1202); + assert!((255u16 as u8) == 255u8, 1200); + assert!((255u32 as u8) == 255u8, 1201); + assert!((255u256 as u8) == 255u8, 1202); +} +} + +// Casting to u16. +//# run +script { +fun main() { + // 0 remains unchanged. + assert!((0u8 as u16) == 0u16, 1000); + assert!((0u64 as u16) == 0u16, 1001); + assert!((0u128 as u16) == 0u16, 1002); + assert!((0u16 as u16) == 0u16, 1000); + assert!((0u32 as u16) == 0u16, 1001); + assert!((0u256 as u16) == 0u16, 1002); + + // Random small number unchanged. + assert!((21u8 as u16) == 21u16, 1100); + assert!((21u64 as u16) == 21u16, 1101); + assert!((21u128 as u16) == 21u16, 1102); + assert!((21u16 as u16) == 21u16, 1100); + assert!((21u32 as u16) == 21u16, 1101); + assert!((21u256 as u16) == 21u16, 1102); + + // Max representable values remain unchanged. + assert!((255u8 as u16) == 255u16, 1200); + assert!((65535u64 as u16) == 65535u16, 1201); + assert!((65535u128 as u16) == 65535u16, 1202); + assert!((65535u16 as u16) == 65535u16, 1200); + assert!((65535u32 as u16) == 65535u16, 1201); + assert!((65535u256 as u16) == 65535u16, 1202); +} +} + +// Casting to u32. +//# run +script { +fun main() { + // 0 remains unchanged. + assert!((0u8 as u32) == 0u32, 1000); + assert!((0u64 as u32) == 0u32, 1001); + assert!((0u128 as u32) == 0u32, 1002); + assert!((0u16 as u32) == 0u32, 1000); + assert!((0u32 as u32) == 0u32, 1001); + assert!((0u256 as u32) == 0u32, 1002); + + // Random small number unchanged. + assert!((21u8 as u32) == 21u32, 1100); + assert!((21u64 as u32) == 21u32, 1101); + assert!((21u128 as u32) == 21u32, 1102); + assert!((21u16 as u32) == 21u32, 1100); + assert!((21u32 as u32) == 21u32, 1101); + assert!((21u256 as u32) == 21u32, 1102); + + // Max representable values remain unchanged. + assert!((255u8 as u32) == 255u32, 1200); + assert!((4294967295u64 as u32) == 4294967295u32, 1201); + assert!((4294967295u128 as u32) == 4294967295u32, 1202); + assert!((65535u16 as u32) == 65535u32, 1200); + assert!((4294967295u32 as u32) == 4294967295u32, 1201); + assert!((4294967295u256 as u32) == 4294967295u32, 1202); +} +} + +// Casting to u64. +//# run +script { +fun main() { + // 0 remains unchanged. + assert!((0u8 as u64) == 0u64, 2000); + assert!((0u64 as u64) == 0u64, 2001); + assert!((0u128 as u64) == 0u64, 2002); + assert!((0u16 as u64) == 0u64, 2000); + assert!((0u32 as u64) == 0u64, 2001); + assert!((0u256 as u64) == 0u64, 2002); + + // Random small number unchanged. + assert!((21u8 as u64) == 21u64, 2100); + assert!((21u64 as u64) == 21u64, 2101); + assert!((21u128 as u64) == 21u64, 2102); + assert!((21u16 as u64) == 21u64, 2100); + assert!((21u32 as u64) == 21u64, 2101); + assert!((21u256 as u64) == 21u64, 2102); + + // Max representable values remain unchanged. + assert!((255u8 as u64) == 255u64, 2200); + assert!((18446744073709551615u64 as u64) == 18446744073709551615u64, 2201); + assert!((18446744073709551615u128 as u64) == 18446744073709551615u64, 2202); + assert!((65535u16 as u64) == 65535u64, 2200); + assert!((4294967295u32 as u64) == 4294967295u64, 2201); + assert!((18446744073709551615u256 as u64) == 18446744073709551615u64, 2202); +} +} + +// Casting to u128. +//# run +script { +fun main() { + // 0 remains unchanged. + assert!((0u8 as u128) == 0u128, 3000); + assert!((0u64 as u128) == 0u128, 3001); + assert!((0u128 as u128) == 0u128, 3002); + assert!((0u16 as u128) == 0u128, 3000); + assert!((0u32 as u128) == 0u128, 3001); + assert!((0u256 as u128) == 0u128, 3002); + + // Random small number unchanged. + assert!((21u8 as u128) == 21u128, 3100); + assert!((21u64 as u128) == 21u128, 3101); + assert!((21u128 as u128) == 21u128, 3102); + assert!((21u16 as u128) == 21u128, 3100); + assert!((21u32 as u128) == 21u128, 3101); + assert!((21u256 as u128) == 21u128, 3102); + + // Max representable values remain unchanged. + assert!((255u8 as u128) == 255u128, 3200); + assert!((18446744073709551615u64 as u128) == 18446744073709551615u128, 3201); + assert!((340282366920938463463374607431768211455u128 as u128) == 340282366920938463463374607431768211455u128, 3202); + assert!((65535u16 as u128) == 65535u128, 2200); + assert!((4294967295u32 as u128) == 4294967295u128, 2201); + assert!((340282366920938463463374607431768211455u256 as u128) == 340282366920938463463374607431768211455u128, 3202); +} +} + +// Casting to u256. +//# run +script { +fun main() { + // 0 remains unchanged. + assert!((0u8 as u256) == 0u256, 3000); + assert!((0u64 as u256) == 0u256, 3001); + assert!((0u128 as u256) == 0u256, 3002); + assert!((0u16 as u256) == 0u256, 3000); + assert!((0u32 as u256) == 0u256, 3001); + assert!((0u256 as u256) == 0u256, 3002); + + // Random small number unchanged. + assert!((21u8 as u256) == 21u256, 3100); + assert!((21u64 as u256) == 21u256, 3101); + assert!((21u128 as u256) == 21u256, 3102); + assert!((21u16 as u256) == 21u256, 3100); + assert!((21u32 as u256) == 21u256, 3101); + assert!((21u256 as u256) == 21u256, 3102); + + // Max representable values remain unchanged. + assert!((255u8 as u256) == 255u256, 3200); + assert!((18446744073709551615u64 as u256) == 18446744073709551615u256, 3201); + assert!((340282366920938463463374607431768211455u128 as u256) == 340282366920938463463374607431768211455u256, 3202); + assert!((65535u16 as u256) == 65535u256, 2200); + assert!((4294967295u32 as u256) == 4294967295u256, 2201); + assert!((115792089237316195423570985008687907853269984665640564039457584007913129639935u256 as u256) == 115792089237316195423570985008687907853269984665640564039457584007913129639935u256, 3202); +} +} + +// Casting to u8, overflowing. +//# run +script { +fun main() { + // should fail + (256u64 as u8); +} +} + +//# run +script { +fun main() { + // should fail + (303u64 as u8); +} +} + +//# run +script { +fun main() { + // should fail + (256u128 as u8); +} +} + +//# run +script { +fun main() { + // should fail + (56432u128 as u8); +} +} + +//# run +script { +fun main() { + // should fail + (18446744073709551615u64 as u8); +} +} + +//# run +script { +fun main() { + // should fail + (340282366920938463463374607431768211455u128 as u8); +} +} + +//# run +script { +fun main() { + // should fail + (2561u16 as u8); +} +} + +//# run +script { +fun main() { + // should fail + (65532u16 as u8); +} +} + +//# run +script { +fun main() { + // should fail + (256123u32 as u8); +} +} + +//# run +script { +fun main() { + // should fail + (11579208923731619542357098500868790785326998466564056403945758400791312963993u256 as u8); +} +} + +// Casting to u16, overflowing. +//# run +script { +fun main() { + // should fail + (256343532u64 as u16); +} +} + +//# run +script { +fun main() { + // should fail + (3564603u64 as u16); +} +} + +//# run +script { +fun main() { + // should fail + (256666765790535666u128 as u16); +} +} + +//# run +script { +fun main() { + // should fail + (256765735666u128 as u16); +} +} + +//# run +script { +fun main() { + // should fail + (18446744073709551615u64 as u16); +} +} + +//# run +script { +fun main() { + // should fail + (340282366920938463463374607431768211455u128 as u16); +} +} + +//# run +script { +fun main() { + // should fail + (429496729u32 as u16); +} +} + +//# run +script { +fun main() { + // should fail + (42949629u32 as u16); +} +} + +//# run +script { +fun main() { + // should fail + (115792089237316195423570985008687907853269984665640564039457584007913129639u256 as u16); +} +} + +// Casting to u32, overflowing. +//# run +script { +fun main() { + // should fail + (4294967295644u64 as u32); +} +} + +//# run +script { +fun main() { + // should fail + (3564699003u64 as u32); +} +} + +//# run +script { +fun main() { + // should fail + (256666765790535666u128 as u32); +} +} + +//# run +script { +fun main() { + // should fail + (25676573566896u128 as u32); +} +} + +//# run +script { +fun main() { + // should fail + (18446744073709551615u64 as u32); +} +} + +//# run +script { +fun main() { + // should fail + (340282366920938463463374607431768211455u128 as u32); +} +} + +//# run +script { +fun main() { + // should fail + (115792089237316195423570985008687907853269984665640564039457584007913129639u256 as u32); +} +} + +// Casting to u64, overflowing. +//# run +script { +fun main() { + // should fail + (18446744073709551616u128 as u64); +} +} + +//# run +script { +fun main() { + // should fail + (18446744073709551647u128 as u64); +} +} + +//# run +script { +fun main() { + // should fail + (340282366920938463463374607431768211455u128 as u64); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.exp new file mode 100644 index 0000000000000..09136e6698579 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.exp @@ -0,0 +1,3 @@ +processed 6 tasks + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.move new file mode 100644 index 0000000000000..54c6d6104bc0a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.move @@ -0,0 +1,171 @@ +//# run +script { +fun main() { + assert!(0u8 == 0u8, 1000); + assert!(0u64 == 0u64, 1001); + assert!(0u128 == 0u128, 1002); + assert!(0u16 == 0u16, 1003); + assert!(0u32 == 0u32, 1004); + assert!(0u256 == 0u256, 1005); + + assert!(!(0u8 == 1u8), 1100); + assert!(!(0u64 == 1u64), 1101); + assert!(!(0u128 == 1u128), 1102); + assert!(!(0u16 == 1u16), 1103); + assert!(!(0u32 == 1u32), 1104); + assert!(!(0u256 == 1u256), 1105); + + + assert!(!(1u8 == 0u8), 1200); + assert!(!(1u64 == 0u64), 1201); + assert!(!(1u128 == 0u128), 1202); + assert!(!(1u16 == 0u16), 1203); + assert!(!(1u32 == 0u32), 1204); + assert!(!(1u256 == 0u256), 1205); +} +} + +//# run +script { +fun main() { + assert!(0u8 != 1u8, 2000); + assert!(0u64 != 1u64, 2001); + assert!(0u128 != 1u128, 2001); + + assert!(1u8 != 0u8, 2100); + assert!(1u64 != 0u64, 2101); + assert!(1u128 != 0u128, 2101); + + assert!(!(0u8 != 0u8), 2200); + assert!(!(0u64 != 0u64), 2201); + assert!(!(0u128 != 0u128), 2201); + + assert!(0u16 != 1u16, 2000); + assert!(0u32 != 1u32, 2001); + assert!(0u256 != 1u256, 2001); + + assert!(1u16 != 0u16, 2100); + assert!(1u32 != 0u32, 2101); + assert!(1u256 != 0u256, 2101); + + assert!(!(0u16 != 0u16), 2200); + assert!(!(0u32 != 0u32), 2201); + assert!(!(0u256 != 0u256), 2201); +} +} + +//# run +script { +fun main() { + assert!(0u8 < 1u8, 3000); + assert!(0u64 < 1u64, 3001); + assert!(0u128 < 1u128, 3002); + + assert!(!(1u8 < 0u8), 3100); + assert!(!(1u64 < 0u64), 3101); + assert!(!(1u128 < 0u128), 3102); + + assert!(!(0u8 < 0u8), 3200); + assert!(!(0u64 < 0u64), 3201); + assert!(!(0u128 < 0u128), 3202); + + assert!(0u16 < 1u16, 3000); + assert!(0u32 < 1u32, 3001); + assert!(0u256 < 1u256, 3002); + + assert!(!(1u16 < 0u16), 3100); + assert!(!(1u32 < 0u32), 3101); + assert!(!(1u256 < 0u256), 3102); + + assert!(!(0u16 < 0u16), 3200); + assert!(!(0u32 < 0u32), 3201); + assert!(!(0u256 < 0u256), 3202); +} +} + +//# run +script { +fun main() { + assert!(1u8 > 0u8, 4000); + assert!(1u64 > 0u64, 4001); + assert!(1u128 > 0u128, 4002); + + assert!(!(0u8 > 1u8), 4100); + assert!(!(0u64 > 1u64), 4101); + assert!(!(0u128 > 1u128), 4102); + + assert!(!(0u8 > 0u8), 4200); + assert!(!(0u64 > 0u64), 4201); + assert!(!(0u128 > 0u128), 4202); + + assert!(1u16 > 0u16, 4000); + assert!(1u32 > 0u32, 4001); + assert!(1u256 > 0u256, 4002); + + assert!(!(0u16 > 1u16), 4100); + assert!(!(0u32 > 1u32), 4101); + assert!(!(0u256 > 1u256), 4102); + + assert!(!(0u16 > 0u16), 4200); + assert!(!(0u32 > 0u32), 4201); + assert!(!(0u256 > 0u256), 4202); +} +} + +//# run +script { +fun main() { + assert!(0u8 <= 1u8, 5000); + assert!(0u64 <= 1u64, 5001); + assert!(0u128 <= 1u128, 5002); + + assert!(!(1u8 <= 0u8), 5100); + assert!(!(1u64 <= 0u64), 5101); + assert!(!(1u128 <= 0u128), 5102); + + assert!(0u8 <= 0u8, 5200); + assert!(0u64 <= 0u64, 5201); + assert!(0u128 <= 0u128, 5202); + + assert!(0u16 <= 1u16, 5000); + assert!(0u32 <= 1u32, 5001); + assert!(0u256 <= 1u256, 5002); + + assert!(!(1u16 <= 0u16), 5100); + assert!(!(1u32 <= 0u32), 5101); + assert!(!(1u256 <= 0u256), 5102); + + assert!(0u16 <= 0u16, 5200); + assert!(0u32 <= 0u32, 5201); + assert!(0u256 <= 0u256, 5202); +} +} + +//# run +script { +fun main() { + assert!(1u8 >= 0u8, 6000); + assert!(1u64 >= 0u64, 6001); + assert!(1u128 >= 0u128, 6002); + + assert!(!(0u8 >= 1u8), 6100); + assert!(!(0u64 >= 1u64), 6101); + assert!(!(0u128 >= 1u128), 6102); + + assert!(0u8 >= 0u8, 6200); + assert!(0u64 >= 0u64, 6201); + assert!(0u128 >= 0u128, 6202); + + assert!(1u16 >= 0u16, 6000); + assert!(1u32 >= 0u32, 6001); + assert!(1u256 >= 0u256, 6002); + + assert!(!(0u16 >= 1u16), 6100); + assert!(!(0u32 >= 1u32), 6101); + assert!(!(0u256 >= 1u256), 6102); + + assert!(0u16 >= 0u16, 6200); + assert!(0u32 >= 0u32, 6201); + assert!(0u256 >= 0u256, 6202); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.exp new file mode 100644 index 0000000000000..274cdfcf1b008 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.exp @@ -0,0 +1,3 @@ +processed 1 task + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.move new file mode 100644 index 0000000000000..a3288b1d80328 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.move @@ -0,0 +1,11 @@ +//# run +script { +fun main() { + assert!(true || true && false, 99); // "&&" has precedence over "||" + assert!(true != false && false != true, 100); // "&&" has precedence over comparisons + assert!(1 | 3 ^ 1 == 3, 101); // binary XOR has precedence over OR + assert!(2 ^ 3 & 1 == 3, 102); // binary AND has precedence over XOR + assert!(3 & 3 + 1 == 0, 103); // addition has precedence over binary AND + assert!(1 + 2 * 3 == 7, 104); // multiplication has precedence over addition +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.exp b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.exp new file mode 100644 index 0000000000000..51fb74b588de7 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.exp @@ -0,0 +1,21 @@ +processed 8 tasks + +task 0 'run'. lines 1-8: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +task 1 'run'. lines 10-18: +Error: Script execution failed with VMError: { + major_status: ARITHMETIC_ERROR, + sub_status: None, + location: script, + indices: redacted, + offsets: redacted, +} + +==> Compiler v2 delivered same results! diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.move b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.move new file mode 100644 index 0000000000000..ab146bad2890a --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.move @@ -0,0 +1,131 @@ +//# run +// Number of bits shifted >= total number of bits in the number. +script { +fun main() { + // should fail + 0u8 << 8u8; +} +} + +//# run +script { +fun main() { + // should fail + 0u8 >> 8u8; +} +} + +// Shifting 0 results in 0. +//# run +script { +fun main() { + assert!(0u8 << 4u8 == 0u8, 1000); + assert!(0u8 >> 4u8 == 0u8, 1100); +} +} + +// Shifting by 0 bits results in the same number. +//# run +script { +fun main() { + assert!(100u8 << 0u8 == 100u8, 2000); + assert!(43u64 << 0u8 == 43u64, 2001); + assert!(57348765484584586725315342563424u128 << 0u8 == 57348765484584586725315342563424u128, 2002); + assert!(1000u16 << 0u8 == 1000u16, 2003); + assert!(10000u32 << 0u8 == 10000u32, 2004); + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639935u256 << 0u8 == 115792089237316195423570985008687907853269984665640564039457584007913129639935u256, 2005); + + assert!(100u8 >> 0u8 == 100u8, 2100); + assert!(43u64 >> 0u8 == 43u64, 2101); + assert!(1000u16 >> 0u8 == 1000u16, 2103); + assert!(10000u32 >> 0u8 == 10000u32, 2104); + assert!(115792089237316195423570985008687907853269984665640564039457584007913129639935u256 >> 0u8 == 115792089237316195423570985008687907853269984665640564039457584007913129639935u256, 2105); +} +} + + + +// shl/shr by 1 equivalent to mul/div by 2. +//# run +script { +fun main() { + assert!(1u8 << 1u8 == 2u8, 3000); + assert!(7u64 << 1u8 == 14u64, 3001); + assert!(1000u128 << 1u8 == 2000u128, 3002); + assert!(3u16 << 1u8 == 6u16, 3003); + assert!(7u32 << 1u8 == 14u32, 3004); + assert!(1000u256 << 1u8 == 2000u256, 3005); + + assert!(1u8 >>1u8 == 0u8, 3100); + assert!(7u64 >> 1u8 == 3u64, 3101); + assert!(1000u128 >> 1u8 == 500u128, 3102); + assert!(3u16 >> 1u8 == 1u16, 3103); + assert!(7u32 >> 1u8 == 3u32, 3104); + assert!(1000u256 >> 1u8 == 500u256, 3105); +} +} + + + +// Underflowing results in 0. +//# run +script { +fun main() { + assert!(1234u64 >> 63u8 == 0u64, 4000); + assert!(3u8 >> 5u8 == 0u8, 4001); + assert!(43152365326753472145312542634526753u128 >> 127u8 == 0u128, 4002); + assert!(1234u16 >> 15u8 == 0u16, 4003); + assert!(123456u32 >> 31u8 == 0u32, 4004); + assert!(11579208923731619542357098500868790785326998466564056403945758400791312963993u256 >> 255u8 == 0u256, 4005); +} +} + + + +// Overflowing results are truncated. +//# run +script { +fun main() { + assert!(7u8 << 7u8 == 128u8, 5000); + assert!(7u64 << 62u8 == 13835058055282163712u64, 5001); + assert!(2u128 << 127u8 == 0u128, 5002); + assert!(7u16 << 15u8 == 32768u16, 5003); + assert!(17u32 << 30u8 == 1073741824u32, 5004); + assert!(7u256 << 254u8 == 86844066927987146567678238756515930889952488499230423029593188005934847229952u256, 5005); +} +} + + + +// Some random tests. +//# run +script { +fun main() { + assert!(54u8 << 3u8 == 176u8, 6000); + assert!(5u8 << 2u8 == 20u8, 6001); + assert!(124u8 << 5u8 == 128u8, 6002); + + assert!(326348456u64 << 13u8 == 2673446551552u64, 6100); + assert!(218u64 << 30u8 == 234075717632u64, 6101); + assert!(345325745376476456u64 << 47u8 == 2203386117691015168u64, 6102); + + assert!(95712896789423756892376u128 << 4u8 == 1531406348630780110278016u128, 6200); + assert!(8629035907847368941279654523567912314u128 << 77u8 == 317056859699765342273530379836650946560u128, 6201); + assert!(5742389768935678297185789157531u128 << 10u8 == 5880207123390134576318248097311744u128, 6202); + assert!(295429678238907658936718926478967892769u128 << 83u8 == 78660438169199498567214234129963941888u128, 6203); + + assert!(12u16 << 4u8 == 192u16, 6300); + assert!(1234u16 << 12u8 == 8192u16, 6301); + assert!(6553u16 << 15u8 == 32768u16, 6302); + + assert!(1234567u32 << 12u8 == 761819136u32, 6400); + assert!(1234567u32 << 17u8 == 2903375872u32, 6401); + assert!(12345671u32 << 27u8 == 939524096u32, 6402); + + assert!(123u256 << 1u8 == 246u256, 6500); + assert!(123453u256 << 13u8 == 1011326976u256, 6501); + assert!(123453678909u256 << 76u8 == 9327896247469005265829994770202624u256, 6502); + assert!(1234536789093546757803u256 << 168u8 == 461895049882996264654333091841553462264195467433049741837793730775482368u256, 6503); + assert!(1234536789093546757803786604381691994985672142341299639418u256 << 202u8 == 33658913632735705985908889087832028406806276615240336691180752852867975479296u256, 6504); +} +} diff --git a/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs new file mode 100644 index 0000000000000..82369aa21b204 --- /dev/null +++ b/third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs @@ -0,0 +1,14 @@ +// Copyright (c) The Diem Core Contributors +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +pub const TEST_DIR: &str = "tests"; + +use move_transactional_test_runner::{vm_test_harness, vm_test_harness::TestRunConfig}; +use std::path::Path; + +datatest_stable::harness!(run, TEST_DIR, r".*\.move$"); + +fn run(path: &Path) -> Result<(), Box> { + vm_test_harness::run_test_with_config(TestRunConfig::ComparisonV1V2, path) +} diff --git a/third_party/move/move-model/src/ast.rs b/third_party/move/move-model/src/ast.rs index fb9295eb1e927..5f2cbf1e2c571 100644 --- a/third_party/move/move-model/src/ast.rs +++ b/third_party/move/move-model/src/ast.rs @@ -9,9 +9,9 @@ use crate::{ model::{ EnvDisplay, FieldId, FunId, FunctionEnv, GlobalEnv, GlobalId, Loc, ModuleId, NodeId, Parameter, QualifiedId, QualifiedInstId, SchemaId, SpecFunId, StructId, TypeParameter, - GHOST_MEMORY_PREFIX, + GHOST_MEMORY_PREFIX, SCRIPT_MODULE_NAME, }, - symbol::Symbol, + symbol::{Symbol, SymbolPool}, ty::{ReferenceKind, Type, TypeDisplayContext}, }; use internment::LocalIntern; @@ -1337,8 +1337,17 @@ impl ModuleName { self.1 } - /// Determine whether this is a script. The move-compiler infrastructure uses MAX_ADDR - /// for pseudo modules created from scripts, so use this address to check. + /// Return the pseudo module name used for scripts. The move-compiler infrastructure uses MAX_ADDR + /// for pseudo modules created from scripts. + pub fn pseudo_script_name(pool: &SymbolPool) -> ModuleName { + let name = pool.make(SCRIPT_MODULE_NAME); + ModuleName( + Address::Numerical(AccountAddress::new([0xFF; AccountAddress::LENGTH])), + name, + ) + } + + /// Determine whether this is a script. pub fn is_script(&self) -> bool { self.0 == Address::Numerical(AccountAddress::new([0xFF; AccountAddress::LENGTH])) } diff --git a/third_party/move/move-model/src/builder/builtins.rs b/third_party/move/move-model/src/builder/builtins.rs index b981b1ae2d658..92bb1d8b0e9f5 100644 --- a/third_party/move/move-model/src/builder/builtins.rs +++ b/third_party/move/move-model/src/builder/builtins.rs @@ -73,7 +73,8 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder<'_>) { // Binary operators. let mut declare_bin = |op: PA::BinOp_, oper: Operation, - param_type: &Type, + param_type1: &Type, + param_type2: &Type, result_type: &Type, visibility: EntryVisibility| { trans.define_spec_or_builtin_fun(trans.bin_op_symbol(&op), SpecOrBuiltinFunEntry { @@ -81,8 +82,8 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder<'_>) { oper, type_params: vec![], params: vec![ - mk_param(trans, 1, param_type.clone()), - mk_param(trans, 2, param_type.clone()), + mk_param(trans, 1, param_type1.clone()), + mk_param(trans, 2, param_type2.clone()), ], result_type: result_type.clone(), visibility, @@ -93,6 +94,7 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder<'_>) { // The spec language uses the unified arbitrary precision num type instead. use EntryVisibility::{Impl, Spec, SpecAndImpl}; use PA::BinOp_::*; + let u8_ty = Type::Primitive(PrimitiveType::U8); for prim_ty in [ PrimitiveType::U8, PrimitiveType::U16, @@ -108,28 +110,28 @@ pub(crate) fn declare_builtins(trans: &mut ModelBuilder<'_>) { Impl }; let ty = Type::new_prim(prim_ty); - declare_bin(Add, Operation::Add, &ty, &ty, visibility); - declare_bin(Sub, Operation::Sub, &ty, &ty, visibility); - declare_bin(Mul, Operation::Mul, &ty, &ty, visibility); - declare_bin(Mod, Operation::Mod, &ty, &ty, visibility); - declare_bin(Div, Operation::Div, &ty, &ty, visibility); - declare_bin(BitOr, Operation::BitOr, &ty, &ty, visibility); - declare_bin(BitAnd, Operation::BitAnd, &ty, &ty, visibility); - declare_bin(Xor, Operation::Xor, &ty, &ty, visibility); - declare_bin(Shl, Operation::Shl, &ty, &ty, visibility); - declare_bin(Shr, Operation::Shr, &ty, &ty, visibility); - declare_bin(Lt, Operation::Lt, &ty, bool_t, visibility); - declare_bin(Le, Operation::Le, &ty, bool_t, visibility); - declare_bin(Gt, Operation::Gt, &ty, bool_t, visibility); - declare_bin(Ge, Operation::Ge, &ty, bool_t, visibility); + declare_bin(Add, Operation::Add, &ty, &ty, &ty, visibility); + declare_bin(Sub, Operation::Sub, &ty, &ty, &ty, visibility); + declare_bin(Mul, Operation::Mul, &ty, &ty, &ty, visibility); + declare_bin(Mod, Operation::Mod, &ty, &ty, &ty, visibility); + declare_bin(Div, Operation::Div, &ty, &ty, &ty, visibility); + declare_bin(BitOr, Operation::BitOr, &ty, &ty, &ty, visibility); + declare_bin(BitAnd, Operation::BitAnd, &ty, &ty, &ty, visibility); + declare_bin(Xor, Operation::Xor, &ty, &ty, &ty, visibility); + declare_bin(Shl, Operation::Shl, &ty, &u8_ty, &ty, visibility); + declare_bin(Shr, Operation::Shr, &ty, &u8_ty, &ty, visibility); + declare_bin(Lt, Operation::Lt, &ty, &ty, bool_t, visibility); + declare_bin(Le, Operation::Le, &ty, &ty, bool_t, visibility); + declare_bin(Gt, Operation::Gt, &ty, &ty, bool_t, visibility); + declare_bin(Ge, Operation::Ge, &ty, &ty, bool_t, visibility); } - declare_bin(Range, Operation::Range, num_t, range_t, Spec); + declare_bin(Range, Operation::Range, num_t, num_t, range_t, Spec); - declare_bin(Implies, Operation::Implies, bool_t, bool_t, Spec); - declare_bin(Iff, Operation::Iff, bool_t, bool_t, Spec); - declare_bin(And, Operation::And, bool_t, bool_t, SpecAndImpl); - declare_bin(Or, Operation::Or, bool_t, bool_t, SpecAndImpl); + declare_bin(Implies, Operation::Implies, bool_t, bool_t, bool_t, Spec); + declare_bin(Iff, Operation::Iff, bool_t, bool_t, bool_t, Spec); + declare_bin(And, Operation::And, bool_t, bool_t, bool_t, SpecAndImpl); + declare_bin(Or, Operation::Or, bool_t, bool_t, bool_t, SpecAndImpl); // Eq and Neq have special treatment because they are generic. trans.define_spec_or_builtin_fun( 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 aedb0f1f7f90e..0262e1a0f068c 100644 --- a/third_party/move/move-model/src/builder/exp_builder.rs +++ b/third_party/move/move-model/src/builder/exp_builder.rs @@ -1757,13 +1757,20 @@ impl<'env, 'translator, 'module_translator> ExpTranslator<'env, 'translator, 'mo // type of the expression is `()`. let exp_loc = self.to_loc(&exp.loc); let var = self.fresh_type_var_idx(); - self.subs.add_constraint( - var, - exp_loc, - WideningOrder::LeftToRight, - Constraint::WithDefault(Type::unit()), - ); - let exp = self.translate_exp(exp, &Type::Var(var)); + + let item_type = Type::Var(var); + let exp = self.translate_exp(exp, &item_type); + let item_type = self.subs.specialize(&item_type); + if self.subs.is_free_var_without_constraints(&item_type) { + // If this is a totally unbound item, assign default unit type. + self.subs.add_constraint( + var, + exp_loc, + WideningOrder::LeftToRight, + Constraint::WithDefault(Type::unit()), + ); + } + if self.mode == ExpTranslationMode::TryImplAsSpec && matches!(exp, ExpData::Call(_, Operation::NoOp, _)) { diff --git a/third_party/move/move-model/src/builder/macros.rs b/third_party/move/move-model/src/builder/macros.rs index 8b16101692148..5f54ae60aef8f 100644 --- a/third_party/move/move-model/src/builder/macros.rs +++ b/third_party/move/move-model/src/builder/macros.rs @@ -34,8 +34,8 @@ impl<'env> ModelBuilder<'env> { let abort_code = args.value[1].clone(); EA::Exp_::IfElse( Box::new(cond), - Box::new(sp(loc, EA::Exp_::Abort(Box::new(abort_code)))), Box::new(sp(loc, EA::Exp_::Unit { trailing: false })), + Box::new(sp(loc, EA::Exp_::Abort(Box::new(abort_code)))), ) } } diff --git a/third_party/move/move-model/src/lib.rs b/third_party/move/move-model/src/lib.rs index 9b4a4aa136802..36fc33bb2a510 100644 --- a/third_party/move/move-model/src/lib.rs +++ b/third_party/move/move-model/src/lib.rs @@ -357,8 +357,6 @@ pub fn run_model_builder_with_options_and_compilation_flags< } fn run_move_checker(env: &mut GlobalEnv, program: E::Program) { - // TODO: verify that the expansion AST has modules in bottom-up dependency order, since this - // is a requirement for the builder. let mut builder = ModelBuilder::new(env); for (module_count, (module_id, module_def)) in program .modules @@ -380,6 +378,14 @@ fn run_move_checker(env: &mut GlobalEnv, program: E::Program) { let mut module_translator = ModuleBuilder::new(&mut builder, module_id, module_name); module_translator.translate(loc, module_def, None); } + for (_, script_def) in program.scripts.into_iter() { + let loc = builder.to_loc(&script_def.loc); + let module_name = ModuleName::pseudo_script_name(builder.env.symbol_pool()); + let module_id = ModuleId::new(builder.env.module_data.len()); + let mut module_translator = ModuleBuilder::new(&mut builder, module_id, module_name); + let module_def = expansion_script_to_module(script_def); + module_translator.translate(loc, module_def, None); + } // Compute information derived from AST (currently callgraph) for module in env.module_data.iter_mut() { diff --git a/third_party/move/move-model/src/model.rs b/third_party/move/move-model/src/model.rs index 667403aca4a0f..67dc1850046cd 100644 --- a/third_party/move/move-model/src/model.rs +++ b/third_party/move/move-model/src/model.rs @@ -94,6 +94,12 @@ pub struct Loc { span: Span, } +impl AsRef for Loc { + fn as_ref(&self) -> &Loc { + self + } +} + impl Loc { pub fn new(file_id: FileId, span: Span) -> Loc { Loc { file_id, span } @@ -1073,6 +1079,49 @@ impl GlobalEnv { } } + /// Computes the abilities associated with the given type. + pub fn type_abilities(&self, ty: &Type, ty_params: &[TypeParameter]) -> AbilitySet { + match ty { + Type::Primitive(p) => match p { + PrimitiveType::Bool + | PrimitiveType::U8 + | PrimitiveType::U16 + | PrimitiveType::U32 + | PrimitiveType::U64 + | PrimitiveType::U128 + | PrimitiveType::U256 + | PrimitiveType::Num + | PrimitiveType::Range + | PrimitiveType::EventStore + | PrimitiveType::Address => AbilitySet::PRIMITIVES, + PrimitiveType::Signer => AbilitySet::SIGNER, + }, + Type::Vector(et) => AbilitySet::VECTOR.intersect(self.type_abilities(et, ty_params)), + Type::Struct(mid, sid, inst) => { + let struct_env = self.get_struct(mid.qualified(*sid)); + let mut abilities = struct_env.get_abilities(); + for inst_ty in inst { + abilities = abilities.intersect(self.type_abilities(inst_ty, ty_params)) + } + abilities + }, + Type::TypeParameter(i) => { + if let Some(tp) = ty_params.get(*i as usize) { + tp.1.abilities + } else { + AbilitySet::EMPTY + } + }, + Type::Reference(_, _) => AbilitySet::REFERENCES, + Type::Fun(_, _) + | Type::Tuple(_) + | Type::TypeDomain(_) + | Type::ResourceDomain(_, _, _) + | Type::Error + | Type::Var(_) => AbilitySet::EMPTY, + } + } + /// Returns associated intrinsics. pub fn get_intrinsics(&self) -> &IntrinsicsAnnotation { &self.intrinsics diff --git a/third_party/move/move-model/src/ty.rs b/third_party/move/move-model/src/ty.rs index 7026afae14cce..e209f635ac212 100644 --- a/third_party/move/move-model/src/ty.rs +++ b/third_party/move/move-model/src/ty.rs @@ -789,7 +789,21 @@ impl Substitution { self.constraints .entry(var) .or_default() - .push((loc, order, c)) + .push((loc, order, c)); + } + + /// Returns true if this is a free variable without constraints. + pub fn is_free_var_without_constraints(&self, ty: &Type) -> bool { + if let Type::Var(idx) = ty { + self.is_free_var(&Type::Var(*idx)) + && self + .constraints + .get(idx) + .map(|cs| cs.is_empty()) + .unwrap_or(true) + } else { + false + } } /// Returns true if the type is a free variable. diff --git a/third_party/move/move-prover/bytecode/src/function_target_pipeline.rs b/third_party/move/move-prover/bytecode/src/function_target_pipeline.rs index 8faccfd9f1809..f76a0e439a776 100644 --- a/third_party/move/move-prover/bytecode/src/function_target_pipeline.rs +++ b/third_party/move/move-prover/bytecode/src/function_target_pipeline.rs @@ -337,6 +337,11 @@ impl FunctionTargetPipeline { let src_idx = nodes.get(&fun_id).unwrap(); let fun_env = env.get_function(fun_id); for callee in fun_env.get_called_functions().expect("called functions") { + assert!( + nodes.contains_key(callee), + "{}", + env.get_function(*callee).get_full_name_str() + ); let dst_idx = nodes .get(callee) .expect("callee is not in function targets"); diff --git a/third_party/move/move-prover/bytecode/src/stackless_bytecode.rs b/third_party/move/move-prover/bytecode/src/stackless_bytecode.rs index fef352a344459..57c034c12666b 100644 --- a/third_party/move/move-prover/bytecode/src/stackless_bytecode.rs +++ b/third_party/move/move-prover/bytecode/src/stackless_bytecode.rs @@ -6,7 +6,7 @@ use crate::function_target::FunctionTarget; use ethnum::U256; use itertools::Itertools; use move_binary_format::file_format::CodeOffset; -use move_core_types::u256; +use move_core_types::{u256, value::MoveValue}; use move_model::{ ast, ast::{Address, Exp, ExpData, MemoryLabel, TempIndex, TraceKind}, @@ -106,6 +106,34 @@ impl From<&u256::U256> for Constant { } } +impl Constant { + /// Converts a constant into a `MoveValue` in the core types which also the runtime shares. + /// TODO: we should use MoveValue right away in the bytecode + pub fn to_move_value(&self) -> MoveValue { + match self { + Constant::Bool(x) => MoveValue::Bool(*x), + Constant::U8(x) => MoveValue::U8(*x), + Constant::U16(x) => MoveValue::U16(*x), + Constant::U32(x) => MoveValue::U32(*x), + Constant::U64(x) => MoveValue::U64(*x), + Constant::U128(x) => MoveValue::U128(*x), + Constant::U256(x) => { + MoveValue::U256(move_core_types::u256::U256::from_le_bytes(&x.to_le_bytes())) + }, + Constant::Address(a) => MoveValue::Address(a.expect_numerical()), + Constant::ByteArray(v) => { + MoveValue::Vector(v.iter().map(|x| MoveValue::U8(*x)).collect()) + }, + Constant::AddressArray(v) => MoveValue::Vector( + v.iter() + .map(|x| MoveValue::Address(x.expect_numerical())) + .collect(), + ), + Constant::Vector(v) => MoveValue::Vector(v.iter().map(|x| x.to_move_value()).collect()), + } + } +} + /// An operation -- target of a call. This contains user functions, builtin functions, and /// operators. #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/third_party/move/testing-infra/transactional-test-runner/Cargo.toml b/third_party/move/testing-infra/transactional-test-runner/Cargo.toml index f0b7337347713..b1b11cf7cc520 100644 --- a/third_party/move/testing-infra/transactional-test-runner/Cargo.toml +++ b/third_party/move/testing-infra/transactional-test-runner/Cargo.toml @@ -20,6 +20,7 @@ move-bytecode-verifier = { path = "../../move-bytecode-verifier" } move-cli = { path = "../../tools/move-cli" } move-command-line-common = { path = "../../move-command-line-common" } move-compiler = { path = "../../move-compiler" } +move-compiler-v2 = { path = "../../move-compiler-v2" } move-core-types = { path = "../../move-core/types" } move-disassembler = { path = "../../tools/move-disassembler" } move-ir-compiler = { path = "../../move-ir-compiler" } @@ -29,6 +30,7 @@ once_cell = "1.7.2" rayon = "1.5.0" regex = "1.1.9" tempfile = "3.2.0" +termcolor = "1.1.3" move-stdlib = { path = "../../move-stdlib", features = ["testing"] } move-symbol-pool = { path = "../../move-symbol-pool" } diff --git a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs index 9b0982c68df0c..6001828b21949 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/framework.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/framework.rs @@ -4,9 +4,12 @@ #![forbid(unsafe_code)] -use crate::tasks::{ - taskify, InitCommand, PrintBytecodeCommand, PrintBytecodeInputChoice, PublishCommand, - RunCommand, SyntaxChoice, TaskCommand, TaskInput, ViewCommand, +use crate::{ + tasks::{ + taskify, InitCommand, PrintBytecodeCommand, PrintBytecodeInputChoice, PublishCommand, + RunCommand, SyntaxChoice, TaskCommand, TaskInput, ViewCommand, + }, + vm_test_harness::TestRunConfig, }; use anyhow::{anyhow, Result}; use clap::Parser; @@ -19,7 +22,10 @@ use move_command_line_common::{ address::ParsedAddress, env::read_bool_env_var, files::{MOVE_EXTENSION, MOVE_IR_EXTENSION}, - testing::{add_update_baseline_fix, format_diff, read_env_update_baseline, EXP_EXT}, + testing::{ + add_update_baseline_fix, format_diff, format_diff_no_color, read_env_update_baseline, + EXP_EXT, + }, types::ParsedType, values::{ParsableValue, ParsedValue}, }; @@ -117,8 +123,13 @@ pub trait MoveTestAdapter<'a>: Sized { fn compiled_state(&mut self) -> &mut CompiledState<'a>; fn default_syntax(&self) -> SyntaxChoice; + fn run_config(&self) -> TestRunConfig { + TestRunConfig::CompilerV1 + } fn init( default_syntax: SyntaxChoice, + comparison_mode: bool, + run_config: TestRunConfig, option: Option<&'a FullyCompiledProgram>, init_data: Option>, ) -> (Self, Option); @@ -225,8 +236,23 @@ pub trait MoveTestAdapter<'a>: Sized { ), }; let data_path = data.path().to_str().unwrap(); + let run_config = self.run_config(); let state = self.compiled_state(); let (named_addr_opt, module, warnings_opt) = match syntax { + // Run the V2 compiler if requested + SyntaxChoice::Source if run_config == TestRunConfig::CompilerV2 => { + let ((module, _), warning_opt) = compile_source_unit_v2( + state.named_address_mapping.clone(), + &state.source_files().cloned().collect::>(), + data_path.to_owned(), + )?; + if let Some(module) = module { + (None, module, warning_opt) + } else { + anyhow::bail!("expected a module but found a script") + } + }, + // In all other cases, run V1 SyntaxChoice::Source => { let (unit, warnings_opt) = compile_source_unit( state.pre_compiled_deps, @@ -294,8 +320,23 @@ pub trait MoveTestAdapter<'a>: Sized { ), }; let data_path = data.path().to_str().unwrap(); + let run_config = self.run_config(); let state = self.compiled_state(); let (script, warning_opt) = match syntax { + // Run the V2 compiler if requested. + SyntaxChoice::Source if run_config == TestRunConfig::CompilerV2 => { + let ((_, script), warning_opt) = compile_source_unit_v2( + state.named_address_mapping.clone(), + &state.source_files().cloned().collect::>(), + data_path.to_owned(), + )?; + if let Some(script) = script { + (script, warning_opt) + } else { + anyhow::bail!("expected a script but found a module") + } + }, + // In all other Source cases, run the V1 compiler SyntaxChoice::Source => { let (unit, warning_opt) = compile_source_unit( state.pre_compiled_deps, @@ -304,12 +345,12 @@ pub trait MoveTestAdapter<'a>: Sized { data_path.to_owned(), )?; match unit { - AnnotatedCompiledUnit::Script(annot_script) => (annot_script.named_script.script, warning_opt), - AnnotatedCompiledUnit::Module(_) => panic!( + AnnotatedCompiledUnit::Script(annot_script) => (annot_script.named_script.script, warning_opt), + AnnotatedCompiledUnit::Module(_) => panic!( "Expected a script text block, not a module, following 'run' starting on lines {}-{}", start_line, command_lines_stop - ), - } + ), + } }, SyntaxChoice::IR => (compile_ir_script(state.dep_modules(), data_path)?, None), }; @@ -561,6 +602,46 @@ impl<'a> CompiledState<'a> { } } +fn compile_source_unit_v2( + named_address_mapping: BTreeMap, + deps: &[String], + path: String, +) -> Result<( + (Option, Option), + Option, +)> { + let options = move_compiler_v2::Options { + sources: vec![path], + dependencies: deps.to_vec(), + named_address_mapping: named_address_mapping + .into_iter() + .map(|(alias, addr)| format!("{}={}", alias, addr)) + .collect(), + ..move_compiler_v2::Options::default() + }; + let mut error_writer = termcolor::Buffer::no_color(); + let result = move_compiler_v2::run_move_compiler(&mut error_writer, options); + let error_str = String::from_utf8_lossy(&error_writer.into_inner()).to_string(); + let (mut modules, mut scripts) = + result.map_err(|_| anyhow::anyhow!("compilation errors:\n {}", error_str))?; + let unit = if modules.is_empty() && scripts.len() == 1 { + (None, scripts.pop()) + } else if scripts.is_empty() && modules.len() == 1 { + (modules.pop(), None) + } else { + anyhow::bail!( + "expected either one script or one module: {} - {}", + modules.len(), + scripts.len() + ) + }; + if error_str.is_empty() { + Ok((unit, None)) + } else { + Ok((unit, Some(error_str))) + } +} + fn compile_source_unit( pre_compiled_deps: Option<&FullyCompiledProgram>, named_address_mapping: BTreeMap, @@ -634,6 +715,7 @@ fn compile_ir_script<'a>( } pub fn run_test_impl<'a, Adapter>( + config: TestRunConfig, path: &Path, fully_compiled_program_opt: Option<&'a FullyCompiledProgram>, ) -> Result<(), Box> @@ -652,48 +734,77 @@ where assert!(extension == MOVE_EXTENSION); SyntaxChoice::Source }; - let mut output = String::new(); - let mut tasks = taskify::< - TaskCommand< - Adapter::ExtraInitArgs, - Adapter::ExtraPublishArgs, - Adapter::ExtraValueArgs, - Adapter::ExtraRunArgs, - Adapter::Subcommand, - >, - >(path)? - .into_iter() - .collect::>(); - assert!(!tasks.is_empty()); - let num_tasks = tasks.len(); - writeln!( - &mut output, - "processed {} task{}", - num_tasks, - if num_tasks > 1 { "s" } else { "" } - ) - .unwrap(); - let first_task = tasks.pop_front().unwrap(); - let init_opt = match &first_task.command { - TaskCommand::Init(_, _) => Some(first_task.map(|known| match known { - TaskCommand::Init(command, extra_args) => (command, extra_args), - _ => unreachable!(), - })), - _ => { - tasks.push_front(first_task); - None - }, + // Construct a sequence of compiler runs based on the given config. + let (runs, comparison_mode) = if config == TestRunConfig::ComparisonV1V2 { + ( + vec![TestRunConfig::CompilerV1, TestRunConfig::CompilerV2], + true, + ) + } else { + (vec![config], false) // either V1 or V2 }; - let (mut adapter, result_opt) = - Adapter::init(default_syntax, fully_compiled_program_opt, init_opt); - if let Some(result) = result_opt { - writeln!(output, "\ninit:\n{}", result)?; + let mut last_output = String::new(); + for run_config in runs { + let mut output = String::new(); + let mut tasks = taskify::< + TaskCommand< + Adapter::ExtraInitArgs, + Adapter::ExtraPublishArgs, + Adapter::ExtraValueArgs, + Adapter::ExtraRunArgs, + Adapter::Subcommand, + >, + >(path)? + .into_iter() + .collect::>(); + assert!(!tasks.is_empty()); + let num_tasks = tasks.len(); + writeln!( + &mut output, + "processed {} task{}", + num_tasks, + if num_tasks > 1 { "s" } else { "" } + ) + .unwrap(); + let first_task = tasks.pop_front().unwrap(); + let init_opt = match &first_task.command { + TaskCommand::Init(_, _) => Some(first_task.map(|known| match known { + TaskCommand::Init(command, extra_args) => (command, extra_args), + _ => unreachable!(), + })), + _ => { + tasks.push_front(first_task); + None + }, + }; + let (mut adapter, result_opt) = Adapter::init( + default_syntax, + comparison_mode, + run_config, + fully_compiled_program_opt, + init_opt, + ); + if let Some(result) = result_opt { + writeln!(output, "\ninit:\n{}", result)?; + } + for task in tasks { + handle_known_task(&mut output, &mut adapter, task); + } + // If there is a previous output, compare to that one + if !last_output.is_empty() && last_output != output { + let diff = format_diff_no_color(&last_output, &output); + let output = format!("comparison between v1 and v2 failed:\n{}", diff); + handle_expected_output(path, output)?; + return Ok(()); + } + last_output = output } - for task in tasks { - handle_known_task(&mut output, &mut adapter, task); + if config == TestRunConfig::ComparisonV1V2 { + // Indicate in output that we passed comparison test + last_output += "\n==> Compiler v2 delivered same results!\n" } - handle_expected_output(path, output)?; + handle_expected_output(path, last_output)?; Ok(()) } diff --git a/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs b/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs index a20d879a1b4a9..b5ccf25c69b47 100644 --- a/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs +++ b/third_party/move/testing-infra/transactional-test-runner/src/vm_test_harness.rs @@ -45,6 +45,8 @@ struct SimpleVMTestAdapter<'a> { compiled_state: CompiledState<'a>, storage: InMemoryStorage, default_syntax: SyntaxChoice, + comparison_mode: bool, + run_config: TestRunConfig, } pub fn view_resource_in_move_storage( @@ -104,8 +106,14 @@ impl<'a> MoveTestAdapter<'a> for SimpleVMTestAdapter<'a> { self.default_syntax } + fn run_config(&self) -> TestRunConfig { + self.run_config + } + fn init( default_syntax: SyntaxChoice, + comparison_mode: bool, + run_config: TestRunConfig, pre_compiled_deps: Option<&'a FullyCompiledProgram>, task_opt: Option>, ) -> (Self, Option) { @@ -129,6 +137,8 @@ impl<'a> MoveTestAdapter<'a> for SimpleVMTestAdapter<'a> { let mut adapter = Self { compiled_state: CompiledState::new(named_address_mapping, pre_compiled_deps, None), default_syntax, + comparison_mode, + run_config, storage: InMemoryStorage::new(), }; @@ -202,7 +212,7 @@ impl<'a> MoveTestAdapter<'a> for SimpleVMTestAdapter<'a> { Err(e) => Err(anyhow!( "Unable to publish module '{}'. Got VMError: {}", module.self_id(), - format_vm_error(&e) + format_vm_error(&e, self.comparison_mode) )), } } @@ -245,7 +255,7 @@ impl<'a> MoveTestAdapter<'a> for SimpleVMTestAdapter<'a> { .map_err(|e| { anyhow!( "Script execution failed with VMError: {}", - format_vm_error(&e) + format_vm_error(&e, self.comparison_mode) ) })?; Ok((None, serialized_return_values)) @@ -289,7 +299,7 @@ impl<'a> MoveTestAdapter<'a> for SimpleVMTestAdapter<'a> { .map_err(|e| { anyhow!( "Function execution failed with VMError: {}", - format_vm_error(&e) + format_vm_error(&e, self.comparison_mode) ) })?; Ok((None, serialized_return_values)) @@ -310,7 +320,7 @@ impl<'a> MoveTestAdapter<'a> for SimpleVMTestAdapter<'a> { } } -pub fn format_vm_error(e: &VMError) -> String { +pub fn format_vm_error(e: &VMError, comparison_mode: bool) -> String { let location_string = match e.location() { Location::Undefined => "undefined".to_owned(), Location::Script => "script".to_owned(), @@ -321,15 +331,25 @@ pub fn format_vm_error(e: &VMError) -> String { major_status: {major_status:?}, sub_status: {sub_status:?}, location: {location_string}, - indices: {indices:?}, - offsets: {offsets:?}, + indices: {indices}, + offsets: {offsets}, }}", major_status = e.major_status(), sub_status = e.sub_status(), location_string = location_string, // TODO maybe include source map info? - indices = e.indices(), - offsets = e.offsets(), + indices = if comparison_mode { + // During comparison testing, abstract this data. + "redacted".to_string() + } else { + format!("{:?}", e.indices()) + }, + offsets = if comparison_mode { + // During comparison testing, abstract this data. + "redacted".to_string() + } else { + format!("{:?}", e.offsets()) + }, ) } @@ -420,8 +440,22 @@ static MOVE_STDLIB_COMPILED: Lazy> = Lazy::new(|| { } }); +#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)] +pub enum TestRunConfig { + CompilerV1, + CompilerV2, + ComparisonV1V2, +} + pub fn run_test(path: &Path) -> Result<(), Box> { - run_test_impl::(path, Some(&*PRECOMPILED_MOVE_STDLIB)) + run_test_with_config(TestRunConfig::CompilerV1, path) +} + +pub fn run_test_with_config( + config: TestRunConfig, + path: &Path, +) -> Result<(), Box> { + run_test_impl::(config, path, Some(&*PRECOMPILED_MOVE_STDLIB)) } impl From for VMConfig {