Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[move-compiler-v2, VM] add bytecode generator for lambdas #15485

Draft
wants to merge 5 commits into
base: 11-23-vm_changes_merged_in
Choose a base branch
from

Conversation

brmataptos
Copy link
Contributor

@brmataptos brmataptos commented Dec 4, 2024

Description

Finish codegen for lambdas.

  • implement stackless bytecode generation for lambda operations
  • fix generated names in lambda_lifter to be acceptable in later passes
  • implement stackful bytecode generation for lambda operations and types in move-compiler-v2
  • add test generic_func.move test exercise function types as generic parameters
  • re-add type constraint NoFunction to disallow function types as generic parameters
  • add SignatureToken::is_subtype_of to be more flexible about function type abilities
  • clarify AbilitySet constants FUNCTION_* to make it easier to be consistent.
  • fix bytecode-verifier/src/type_safety.rs for lambda-related bytecodes, using is_subtype_of.

How Has This Been Tested?

Added a few more function tests (as noted above). Examined output of existing tests as well.

May need to remove some function type parameters used in tests now that we're removing it from MVP. A few tests that used to generate code are now just erroring out.

Key Areas to Review

What can we do about recognizing public functions in file_format.rs? (See Slack discussion.)

Double-check that no ungated functionality in VM is broken.

Type of Change

  • New feature
  • Bug fix
  • Breaking change
  • Performance improvement
  • Refactoring
  • Dependency update
  • Documentation update
  • Tests

Which Components or Systems Does This Change Impact?

  • Validator Node
  • Full Node (API, Indexer, etc.)
  • Move/Aptos Virtual Machine
  • Aptos Framework
  • Aptos CLI/SDK
  • Developer Infrastructure
  • Move Compiler
  • Other (specify)

Copy link

trunk-io bot commented Dec 4, 2024

⏱️ 1h 24m total CI duration on this PR
Slowest 15 Jobs Cumulative Duration Recent Runs
rust-cargo-deny 23m 🟩🟩🟩🟩🟩 (+8 more)
check-dynamic-deps 15m 🟩🟩🟩🟩🟩 (+8 more)
general-lints 6m 🟩🟩🟩🟩🟩 (+8 more)
semgrep/ci 5m 🟩🟩🟩🟩🟩 (+8 more)
rust-move-tests 3m 🟥
rust-move-tests 3m 🟥
rust-move-tests 3m 🟥
rust-move-tests 3m 🟥
rust-move-tests 3m 🟥
rust-move-tests 2m 🟥
rust-move-tests 2m 🟥
rust-move-tests 2m 🟥
rust-move-tests 2m 🟥
rust-move-tests 2m 🟥
rust-move-tests 2m 🟥

settingsfeedbackdocs ⋅ learn more about trunk.io

@brmataptos brmataptos changed the title add bytecode generator add bytecode generator for lambdas Dec 4, 2024
@brmataptos brmataptos force-pushed the 11-23-vm_changes_merged_in branch from 1d8a057 to d382ca0 Compare December 4, 2024 07:23
@brmataptos brmataptos force-pushed the 12-01-add_bytecode_generator branch from 6f9ec9e to 0d44068 Compare December 4, 2024 07:23
@brmataptos brmataptos force-pushed the 11-23-vm_changes_merged_in branch from d382ca0 to 2fa8bde Compare December 4, 2024 07:54
@brmataptos brmataptos force-pushed the 12-01-add_bytecode_generator branch from 0d44068 to 8e869be Compare December 4, 2024 07:54
@brmataptos brmataptos force-pushed the 11-23-vm_changes_merged_in branch from 2fa8bde to d7ded7a Compare December 4, 2024 22:50
@brmataptos brmataptos force-pushed the 12-01-add_bytecode_generator branch from 8e869be to 06110d7 Compare December 4, 2024 22:50
@brmataptos brmataptos force-pushed the 11-23-vm_changes_merged_in branch from d7ded7a to 844871b Compare December 6, 2024 03:39
@brmataptos brmataptos force-pushed the 12-01-add_bytecode_generator branch 2 times, most recently from 0982a66 to 128417e Compare December 7, 2024 10:27
@brmataptos brmataptos force-pushed the 11-23-vm_changes_merged_in branch from fdd0ca9 to e8107d7 Compare December 7, 2024 22:13
@brmataptos brmataptos force-pushed the 12-01-add_bytecode_generator branch 2 times, most recently from ba7ee0f to dcd5597 Compare December 7, 2024 22:15
@brmataptos brmataptos force-pushed the 12-01-add_bytecode_generator branch from a177bcc to f3e3fb3 Compare December 9, 2024 04:13
- debug function value operations in `move-compiler-v2/src/file_format_generator/function_generator.rs`
- complete codegen for function types in `module_generator`
- add function `SignatureToken::is_subtype_of` which allows for subsetting of function abilities
- carefully use subtype tests in `move-bytecode-verifier/src/type_safety.rs` for contexts where function types may show up
- fix `lambda_lifter::gen_closure_function_name` to use alpha-numerics for symbols to avoid errors
- add some tests for ENABLE_FUNCTION_VALUES feature gating using Move source code in `move_feature_gating.rs`
- example `doable_func.lambda.exp` still shows an error due to imported public functions not being storable
@brmataptos brmataptos force-pushed the 12-01-add_bytecode_generator branch from f3e3fb3 to c92a8a3 Compare December 9, 2024 04:25
@brmataptos brmataptos changed the title add bytecode generator for lambdas [move-compiler-v2, VM] add bytecode generator for lambdas Dec 9, 2024
@brmataptos brmataptos marked this pull request as ready for review December 13, 2024 03:26
Copy link
Contributor

@vineethk vineethk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there are some compilation failures (see failing CI checks).

Tok::LParen | Tok::Amp | Tok::AmpMut | Tok::Pipe | Tok::Identifier
)
match (context.tokens.peek(), context.tokens.content()) {
(Tok::Identifier, "with") => false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a test that showcases a corresponding parser error?

let global_access = ExpData::Call(global_id, Operation::Global(None), vec![
zero_addr.into_exp()
]);
let global_access = ExpData::Call(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many of these changes seem to be only formatting changes that seem to revert back when I run the formatter. Might be good to be run the rust formatter before the PR to minimize such changes.

@@ -2486,7 +2486,7 @@ pub enum Value {
Vector(Vec<Value>),
Tuple(Vec<Value>),
/// Represents a reference to a Move Function as a function value.
Function(ModuleId, FunId),
Function(ModuleId, FunId, Vec<Type>),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a brief note about the new field in the doc string above.

.get_name()
.display(env.symbol_pool())
.to_string();
let name = format!("{}__lambda_{}", basename, self.lifted.len() + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the switch from the previous basename$lambda${} to this?

Also, a brief comment on linear search below (and why it is restricted to up to 256) would be useful.

@@ -197,6 +216,10 @@ pub enum Operation {
UnpackVariant(ModuleId, StructId, Symbol, Vec<Type>),
BorrowVariantField(ModuleId, StructId, Vec<Symbol>, Vec<Type>, usize),

// Lambda
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we say a bit here about the arguments for these operations?

let arg = safe_unwrap!(verifier.stack.pop());
if (type_actuals.is_empty() && &arg != parameter)
if (type_actuals.is_empty() && !arg.is_subtype_of(parameter))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(1) It might be worth reasoning if the replacement of equality by is_subtype_of can result in exploitable increased verification cost, (2) Whether the new type representation, which is being optimized for equality, would have any unexpected blowup in time.

// On top of the stack is the closure, pop it.
let closure_ty = safe_unwrap!(verifier.stack.pop());
// Verify that the closure type matches the expected type
if &closure_ty != expected_ty {
if !closure_ty.is_subtype_of(expected_ty) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same note as before.

let arg_ty = safe_unwrap!(verifier.stack.pop());
if &arg_ty != param_ty {
return Err(verifier.error(StatusCode::CALL_TYPE_MISMATCH_ERROR, offset));
if !arg_ty.is_subtype_of(param_ty) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same note as before.

@@ -373,10 +366,13 @@ fn ld_function(
break;
}
}
if !type_actuals.is_empty() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a brief note about generic functions not being storable for now.

@@ -673,7 +662,7 @@ fn verify_instr(

Bytecode::StLoc(idx) => {
let operand = safe_unwrap!(verifier.stack.pop());
if &operand != verifier.local_at(*idx) {
if !operand.is_subtype_of(verifier.local_at(*idx)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should perhaps measure the performance implications of this change? Should such changes also be hidden behind a feature flag?

@wrwg wrwg marked this pull request as draft January 9, 2025 03:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants