From 52f5def2f9df51a591fe80185dfae114f924800d Mon Sep 17 00:00:00 2001 From: Wolfgang Grieskamp Date: Mon, 31 Jul 2023 09:22:26 -0700 Subject: [PATCH] [move-compiler v2] Comparison testing for file-format generator (#9345) * [move-compiler v2] File-format generator first version This adds an initial version of the generation of the external representation of Move code, the so-called file format. - Compiles from the register machine of the compiler IR into the stack machine the VM uses. Some attempts are made to optimize usage of the stack, though more can/must be done to optimize the stack machine code. - Adds a set of basic tests, but more e2e execution tests should be added. (Subsequent PRs.) - The translation can benefit from analysis results like live-var which allows it make smarter use of `CopyLoc` vs `MoveLoc` (to be added in the future) * Addressing reviewer comments * More review fixes * [move-compiler v2] Comparison testing for file-format generator This extends the transactional-test-runner to support compiler V2 _and_ to do comparison testing between V1 and V2. It ports over most of the transactional tests of the V1 compiler into the V2 tree and runs comparison testing on them, fixing bugs throughout the compilation chain as needed. Closes #9334 --- Cargo.lock | 14 + Cargo.toml | 1 + .../src/aptos_test_harness.rs | 10 +- .../move-command-line-common/src/testing.rs | 26 + third_party/move/move-compiler-v2/Cargo.toml | 6 +- .../src/bytecode_generator.rs | 55 +- .../move-compiler-v2/src/bytecode_pipeline.rs | 3 - .../function_generator.rs | 720 ++++++++++++++++++ .../src/file_format_generator/mod.rs | 92 +++ .../file_format_generator/module_generator.rs | 626 +++++++++++++++ third_party/move/move-compiler-v2/src/lib.rs | 43 +- .../tests/bytecode-generator/fields.exp | 64 +- .../tests/bytecode-generator/globals.exp | 10 +- .../tests/bytecode-generator/operators.exp | 120 ++- .../tests/bytecode-generator/operators.move | 4 +- .../specs/assert_skipped_for_spec.exp | 4 +- .../tests/checking/typing/binary_shl.exp | 47 +- .../checking/typing/binary_shl_invalid.exp | 130 ++-- .../tests/checking/typing/binary_shr.exp | 47 +- .../checking/typing/binary_shr_invalid.exp | 130 ++-- .../typing/constant_all_valid_types.exp | 12 + .../typing/global_builtins_script.exp | 10 + .../typing/hex_and_decimal_address.exp | 9 + .../tests/checking/typing/if_default_else.exp | 2 +- .../tests/checking/typing/large_binop.exp | 6 + .../tests/checking/typing/loop_body.exp | 2 +- .../checking/typing/loop_result_type.exp | 2 +- .../tests/checking/typing/main_arguments.exp | 5 + .../typing/main_arguments_various_caes.exp | 5 + .../tests/checking/typing/main_call_entry.exp | 5 + .../typing/main_with_type_parameters.exp | 5 + .../tests/checking/typing/other_builtins.exp | 8 +- .../tests/checking/typing/while_body.exp | 2 +- .../tests/file-format-generator/assign.exp | 93 +++ .../tests/file-format-generator/assign.move | 28 + .../tests/file-format-generator/borrow.exp | 164 ++++ .../tests/file-format-generator/borrow.move | 41 + .../tests/file-format-generator/fields.exp | 204 +++++ .../tests/file-format-generator/fields.move | 41 + .../tests/file-format-generator/globals.exp | 98 +++ .../tests/file-format-generator/globals.move | 23 + .../tests/file-format-generator/if_else.exp | 134 ++++ .../tests/file-format-generator/if_else.move | 10 + .../tests/file-format-generator/loop.exp | 259 +++++++ .../tests/file-format-generator/loop.move | 32 + .../tests/file-format-generator/operators.exp | 27 + .../file-format-generator/operators.move | 25 + .../file-format-generator/pack_unpack.exp | 67 ++ .../file-format-generator/pack_unpack.move | 21 + .../tests/file-format-generator/vector.exp | 30 + .../tests/file-format-generator/vector.move | 5 + .../move/move-compiler-v2/tests/testsuite.rs | 36 +- .../transactional-tests/Cargo.toml | 15 + .../transactional-tests/src/lib.rs | 7 + .../tests/control_flow/assert_in_while.exp | 3 + .../tests/control_flow/assert_in_while.move | 35 + ...branch_assigns_then_moves_then_assigns.exp | 3 + ...ranch_assigns_then_moves_then_assigns.move | 16 + .../tests/control_flow/break_accumulator.exp | 3 + .../tests/control_flow/break_accumulator.move | 11 + .../control_flow/break_continue_simple.exp | 3 + .../control_flow/break_continue_simple.move | 12 + .../break_continue_sum_of_odds.exp | 3 + .../break_continue_sum_of_odds.move | 17 + .../tests/control_flow/break_nested.exp | 3 + .../tests/control_flow/break_nested.move | 17 + .../tests/control_flow/break_simple.exp | 3 + .../tests/control_flow/break_simple.move | 11 + .../deep_return_branch_doesnt_assign.exp | 3 + .../deep_return_branch_doesnt_assign.move | 12 + .../tests/control_flow/if_assignment.exp | 3 + .../tests/control_flow/if_assignment.move | 19 + .../control_flow/if_branch_diverges_1.exp | 3 + .../control_flow/if_branch_diverges_1.move | 10 + .../control_flow/if_branch_diverges_10.exp | 3 + .../control_flow/if_branch_diverges_10.move | 11 + .../control_flow/if_branch_diverges_2.exp | 3 + .../control_flow/if_branch_diverges_2.move | 7 + .../control_flow/if_branch_diverges_3.exp | 3 + .../control_flow/if_branch_diverges_3.move | 11 + .../control_flow/if_branch_diverges_4.exp | 3 + .../control_flow/if_branch_diverges_4.move | 11 + .../control_flow/if_branch_diverges_5.exp | 3 + .../control_flow/if_branch_diverges_5.move | 11 + .../control_flow/if_branch_diverges_6.exp | 3 + .../control_flow/if_branch_diverges_6.move | 11 + .../control_flow/if_branch_diverges_7.exp | 3 + .../control_flow/if_branch_diverges_7.move | 11 + .../control_flow/if_branch_diverges_8.exp | 3 + .../control_flow/if_branch_diverges_8.move | 11 + .../control_flow/if_branch_diverges_9.exp | 3 + .../control_flow/if_branch_diverges_9.move | 10 + .../control_flow/if_without_braces_1.exp | 3 + .../control_flow/if_without_braces_1.move | 11 + .../control_flow/if_without_braces_2.exp | 3 + .../control_flow/if_without_braces_2.move | 12 + .../control_flow/if_without_braces_3.exp | 3 + .../control_flow/if_without_braces_3.move | 12 + .../control_flow/if_without_braces_4.exp | 3 + .../control_flow/if_without_braces_4.move | 8 + .../tests/control_flow/immediate_break.exp | 3 + .../tests/control_flow/immediate_break.move | 6 + .../local_assigned_many_times.exp | 3 + .../local_assigned_many_times.move | 30 + .../tests/control_flow/loop_nested_breaks.exp | 3 + .../control_flow/loop_nested_breaks.move | 10 + .../tests/control_flow/loop_return.exp | 3 + .../tests/control_flow/loop_return.move | 6 + .../tests/control_flow/loop_simple.exp | 3 + .../tests/control_flow/loop_simple.move | 11 + .../tests/control_flow/nested_loops.exp | 3 + .../tests/control_flow/nested_loops.move | 20 + .../return_branch_doesnt_assign.exp | 3 + .../return_branch_doesnt_assign.move | 12 + .../control_flow/return_branch_moves.exp | 3 + .../control_flow/return_branch_moves.move | 15 + .../return_in_if_branch_taken.exp | 3 + .../return_in_if_branch_taken.move | 21 + .../return_in_if_branch_taken_local.exp | 3 + .../return_in_if_branch_taken_local.move | 12 + .../return_in_if_branch_taken_no_else.exp | 3 + .../return_in_if_branch_taken_no_else.move | 16 + .../unused_signer_infinite_loop.exp | 12 + .../unused_signer_infinite_loop.move | 7 + .../tests/control_flow/while_false.exp | 3 + .../tests/control_flow/while_false.move | 8 + .../tests/control_flow/while_nested.exp | 3 + .../tests/control_flow/while_nested.move | 17 + .../control_flow/while_nested_return.exp | 3 + .../control_flow/while_nested_return.move | 10 + .../tests/control_flow/while_return.exp | 3 + .../tests/control_flow/while_return.move | 7 + .../tests/control_flow/while_simple.exp | 3 + .../tests/control_flow/while_simple.move | 8 + .../tests/dependencies/dependency_order.exp | 3 + .../tests/dependencies/dependency_order.move | 29 + .../tests/dependencies/transitive_deps.exp | 3 + .../tests/dependencies/transitive_deps.move | 25 + .../tests/evaluation_order/lazy_assert.exp | 12 + .../tests/evaluation_order/lazy_assert.move | 23 + .../evaluation_order/short_circuiting.exp | 3 + .../evaluation_order/short_circuiting.move | 27 + .../short_circuiting_invalid.exp | 48 ++ .../short_circuiting_invalid.move | 48 ++ .../evaluation_order/struct_arguments.exp | 69 ++ .../evaluation_order/struct_arguments.move | 119 +++ .../operators/arithmetic_operators_u128.exp | 111 +++ .../operators/arithmetic_operators_u128.move | 177 +++++ .../operators/arithmetic_operators_u16.exp | 111 +++ .../operators/arithmetic_operators_u16.move | 174 +++++ .../operators/arithmetic_operators_u256.exp | 102 +++ .../operators/arithmetic_operators_u256.move | 174 +++++ .../operators/arithmetic_operators_u32.exp | 102 +++ .../operators/arithmetic_operators_u32.move | 174 +++++ .../operators/arithmetic_operators_u64.exp | 111 +++ .../operators/arithmetic_operators_u64.move | 176 +++++ .../operators/arithmetic_operators_u8.exp | 111 +++ .../operators/arithmetic_operators_u8.move | 174 +++++ .../tests/operators/bitwise_operators.exp | 3 + .../tests/operators/bitwise_operators.move | 156 ++++ .../tests/operators/boolean_operators.exp | 3 + .../tests/operators/boolean_operators.move | 11 + .../tests/operators/casting_operators.exp | 255 +++++++ .../tests/operators/casting_operators.move | 415 ++++++++++ .../tests/operators/comparison_operators.exp | 3 + .../tests/operators/comparison_operators.move | 171 +++++ .../tests/operators/precedence.exp | 3 + .../tests/operators/precedence.move | 11 + .../tests/operators/shift_operators.exp | 21 + .../tests/operators/shift_operators.move | 131 ++++ .../transactional-tests/tests/tests.rs | 14 + third_party/move/move-model/src/ast.rs | 17 +- .../move/move-model/src/builder/builtins.rs | 46 +- .../move-model/src/builder/exp_builder.rs | 21 +- .../move/move-model/src/builder/macros.rs | 2 +- third_party/move/move-model/src/lib.rs | 10 +- third_party/move/move-model/src/model.rs | 49 ++ third_party/move/move-model/src/ty.rs | 16 +- .../bytecode/src/function_target_pipeline.rs | 5 + .../bytecode/src/stackless_bytecode.rs | 30 +- .../transactional-test-runner/Cargo.toml | 2 + .../src/framework.rs | 203 +++-- .../src/vm_test_harness.rs | 52 +- 183 files changed, 7595 insertions(+), 388 deletions(-) delete mode 100644 third_party/move/move-compiler-v2/src/bytecode_pipeline.rs create mode 100644 third_party/move/move-compiler-v2/src/file_format_generator/function_generator.rs create mode 100644 third_party/move/move-compiler-v2/src/file_format_generator/mod.rs create mode 100644 third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/assign.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/assign.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/borrow.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/borrow.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/fields.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/fields.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/globals.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/globals.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/if_else.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/if_else.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/loop.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/loop.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/operators.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/operators.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/pack_unpack.move create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/vector.exp create mode 100644 third_party/move/move-compiler-v2/tests/file-format-generator/vector.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/Cargo.toml create mode 100644 third_party/move/move-compiler-v2/transactional-tests/src/lib.rs create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/assert_in_while.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/branch_assigns_then_moves_then_assigns.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_accumulator.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_simple.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_continue_sum_of_odds.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_nested.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/break_simple.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/deep_return_branch_doesnt_assign.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_assignment.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_1.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_10.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_2.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_3.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_4.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_5.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_6.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_7.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_8.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_branch_diverges_9.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_1.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_2.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_3.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/if_without_braces_4.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/immediate_break.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/local_assigned_many_times.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_nested_breaks.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_return.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/loop_simple.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/nested_loops.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_doesnt_assign.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_branch_moves.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_local.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/return_in_if_branch_taken_no_else.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/unused_signer_infinite_loop.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_false.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_nested_return.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_return.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/control_flow/while_simple.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/dependency_order.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/dependencies/transitive_deps.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/lazy_assert.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/short_circuiting_invalid.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/evaluation_order/struct_arguments.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u128.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u16.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u256.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u32.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u64.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/arithmetic_operators_u8.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/bitwise_operators.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/boolean_operators.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/casting_operators.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/comparison_operators.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/precedence.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.exp create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/operators/shift_operators.move create mode 100644 third_party/move/move-compiler-v2/transactional-tests/tests/tests.rs 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 {