Skip to content

Commit b720555

Browse files
committed
add attributes for struct api
1 parent 6eb2d64 commit b720555

File tree

9 files changed

+154
-18
lines changed

9 files changed

+154
-18
lines changed

aptos-move/aptos-release-builder/src/components/feature_flags.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ pub enum FeatureFlag {
156156
VMBinaryFormatV9,
157157
EnableFrameworkForOption,
158158
SessionContinuation,
159+
VMBinaryFormatV10,
159160
}
160161

161162
fn generate_features_blob(writer: &CodeWriter, data: &[u64]) {
@@ -411,6 +412,7 @@ impl From<FeatureFlag> for AptosFeatureFlag {
411412
FeatureFlag::VMBinaryFormatV9 => AptosFeatureFlag::VM_BINARY_FORMAT_V9,
412413
FeatureFlag::EnableFrameworkForOption => AptosFeatureFlag::ENABLE_FRAMEWORK_FOR_OPTION,
413414
FeatureFlag::SessionContinuation => AptosFeatureFlag::SESSION_CONTINUATION,
415+
FeatureFlag::VMBinaryFormatV10 => AptosFeatureFlag::VM_BINARY_FORMAT_V10,
414416
}
415417
}
416418
}
@@ -593,6 +595,7 @@ impl From<AptosFeatureFlag> for FeatureFlag {
593595
AptosFeatureFlag::VM_BINARY_FORMAT_V9 => FeatureFlag::VMBinaryFormatV9,
594596
AptosFeatureFlag::ENABLE_FRAMEWORK_FOR_OPTION => FeatureFlag::EnableFrameworkForOption,
595597
AptosFeatureFlag::SESSION_CONTINUATION => FeatureFlag::SessionContinuation,
598+
AptosFeatureFlag::VM_BINARY_FORMAT_V10 => FeatureFlag::VMBinaryFormatV10,
596599
}
597600
}
598601
}

third_party/move/move-binary-format/src/deserializer.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,7 @@ fn load_function_handle(
938938
};
939939

940940
let attributes = if version >= VERSION_8 {
941-
load_function_attributes(cursor)?
941+
load_function_attributes(cursor, version)?
942942
} else {
943943
vec![]
944944
};
@@ -1061,23 +1061,46 @@ fn load_signature_tokens(cursor: &mut VersionedCursor) -> BinaryLoaderResult<Vec
10611061

10621062
fn load_function_attributes(
10631063
cursor: &mut VersionedCursor,
1064+
bytecode_version: u32,
10641065
) -> BinaryLoaderResult<Vec<FunctionAttribute>> {
10651066
let count = read_uleb_internal(cursor, ATTRIBUTE_COUNT_MAX)?;
10661067
let mut attributes = Vec::with_capacity(count);
10671068
for _ in 0..count {
1068-
attributes.push(load_attribute(cursor)?);
1069+
attributes.push(load_attribute(cursor, bytecode_version)?);
10691070
}
10701071
Ok(attributes)
10711072
}
10721073

1073-
fn load_attribute(cursor: &mut VersionedCursor) -> BinaryLoaderResult<FunctionAttribute> {
1074+
fn load_attribute(
1075+
cursor: &mut VersionedCursor,
1076+
bytecode_version: u32,
1077+
) -> BinaryLoaderResult<FunctionAttribute> {
10741078
use SerializedFunctionAttribute::*;
1075-
Ok(
1076-
match SerializedFunctionAttribute::from_u8(load_u8(cursor)?)? {
1077-
PERSISTENT => FunctionAttribute::Persistent,
1078-
MODULE_LOCK => FunctionAttribute::ModuleLock,
1079+
match SerializedFunctionAttribute::from_u8(load_u8(cursor)?)? {
1080+
PERSISTENT => Ok(FunctionAttribute::Persistent),
1081+
MODULE_LOCK => Ok(FunctionAttribute::ModuleLock),
1082+
PACK => {
1083+
if bytecode_version < VERSION_10 {
1084+
Err(PartialVMError::new(StatusCode::MALFORMED)
1085+
.with_message("Unexpected EOF".to_string()))?
1086+
} else {
1087+
Ok(FunctionAttribute::Pack(load_struct_def_index(cursor)?))
1088+
}
10791089
},
1080-
)
1090+
PACK_VARIANT => {
1091+
if bytecode_version < VERSION_10 {
1092+
Err(PartialVMError::new(StatusCode::MALFORMED)
1093+
.with_message("Unexpected EOF".to_string()))?
1094+
} else {
1095+
let definition_index = load_struct_def_index(cursor)?;
1096+
let variant_index = load_bytecode_index(cursor)?;
1097+
Ok(FunctionAttribute::PackVariant(
1098+
definition_index,
1099+
variant_index,
1100+
))
1101+
}
1102+
},
1103+
}
10811104
}
10821105

10831106
fn load_access_specifiers(
@@ -2249,8 +2272,10 @@ impl SerializedFunctionAttribute {
22492272
match value {
22502273
0x1 => Ok(PERSISTENT),
22512274
0x2 => Ok(MODULE_LOCK),
2275+
0x3 => Ok(PACK),
2276+
0x4 => Ok(PACK_VARIANT),
22522277
_ => Err(PartialVMError::new(StatusCode::MALFORMED)
2253-
.with_message("malformed attribute".to_owned())),
2278+
.with_message(format!("malformed attribute: {}", value))),
22542279
}
22552280
}
22562281
}

third_party/move/move-binary-format/src/file_format.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ pub enum FunctionAttribute {
368368
Persistent,
369369
/// During execution of the function, a module reentrancy lock is established.
370370
ModuleLock,
371+
Pack(StructDefinitionIndex),
372+
PackVariant(StructDefinitionIndex, VariantIndex),
371373
}
372374

373375
impl FunctionAttribute {
@@ -389,6 +391,16 @@ impl fmt::Display for FunctionAttribute {
389391
match self {
390392
FunctionAttribute::Persistent => write!(f, "persistent"),
391393
FunctionAttribute::ModuleLock => write!(f, "module_lock"),
394+
FunctionAttribute::Pack(struct_definition_index) => {
395+
write!(f, "pack({})", struct_definition_index)
396+
},
397+
FunctionAttribute::PackVariant(struct_definition_index, variant_index) => {
398+
write!(
399+
f,
400+
"pack_variant({},{})",
401+
struct_definition_index, variant_index
402+
)
403+
},
392404
}
393405
}
394406
}

third_party/move/move-binary-format/src/file_format_common.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ pub enum SerializedNativeStructFlag {
222222
pub enum SerializedFunctionAttribute {
223223
PERSISTENT = 0x1,
224224
MODULE_LOCK = 0x2,
225+
PACK = 0x3,
226+
PACK_VARIANT = 0x4,
225227
}
226228

227229
/// List of opcodes constants.
@@ -552,8 +554,12 @@ pub const VERSION_8: u32 = 8;
552554
/// + allow `$` in identifiers
553555
pub const VERSION_9: u32 = 9;
554556

557+
/// Version 10: changes compared to version 9
558+
/// + new attributes for structs api
559+
pub const VERSION_10: u32 = 10;
560+
555561
/// Mark which version is the latest version.
556-
pub const VERSION_MAX: u32 = VERSION_9;
562+
pub const VERSION_MAX: u32 = VERSION_10;
557563

558564
/// Mark which version is the default version. This is the version used by default by tools like
559565
/// the compiler. Notice that this version might be different from the one supported on nodes.
@@ -566,6 +572,9 @@ pub const VERSION_DEFAULT_LANG_V2: u32 = VERSION_8;
566572
/// Mark which version is the default version if compiling with language version 2.3
567573
pub const VERSION_DEFAULT_LANG_V2_3: u32 = VERSION_9;
568574

575+
/// Mark which version is the default version if compiling with language version 2.4
576+
pub const VERSION_DEFAULT_LANG_V2_4: u32 = VERSION_10;
577+
569578
// Mark which oldest version is supported.
570579
pub const VERSION_MIN: u32 = VERSION_5;
571580

third_party/move/move-binary-format/src/serializer.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ fn serialize_function_handle(
549549
));
550550
}
551551
if major_version >= VERSION_8 {
552-
serialize_function_attributes(binary, &function_handle.attributes)
552+
serialize_function_attributes(binary, &function_handle.attributes, major_version)
553553
} else if !function_handle.attributes.is_empty() {
554554
Err(anyhow!(
555555
"Function attributes not supported in bytecode version {}",
@@ -867,22 +867,45 @@ fn serialize_ability_sets(binary: &mut BinaryData, sets: &[AbilitySet]) -> Resul
867867
fn serialize_function_attributes(
868868
binary: &mut BinaryData,
869869
attributes: &[FunctionAttribute],
870+
version: u32,
870871
) -> Result<()> {
871872
write_as_uleb128(binary, attributes.len() as u64, ATTRIBUTE_COUNT_MAX)?;
872873
for attr in attributes {
873-
serialize_function_attribute(binary, attr)?;
874+
serialize_function_attribute(binary, attr, version)?;
874875
}
875876
Ok(())
876877
}
877878

878879
fn serialize_function_attribute(
879880
binary: &mut BinaryData,
880881
attribute: &FunctionAttribute,
882+
version: u32,
881883
) -> Result<()> {
882884
use FunctionAttribute::*;
883885
match attribute {
884886
Persistent => binary.push(SerializedFunctionAttribute::PERSISTENT as u8),
885887
ModuleLock => binary.push(SerializedFunctionAttribute::MODULE_LOCK as u8),
888+
Pack(struct_definition_index) => {
889+
if version < VERSION_10 {
890+
return Err(anyhow!(
891+
"Pack attribute not supported in bytecode version {}",
892+
version
893+
));
894+
}
895+
binary.push(SerializedFunctionAttribute::PACK as u8)?;
896+
serialize_struct_def_index(binary, struct_definition_index)
897+
},
898+
PackVariant(struct_definition_index, variant_index) => {
899+
if version < VERSION_10 {
900+
return Err(anyhow!(
901+
"PackVariant attribute not supported in bytecode version {}",
902+
version
903+
));
904+
}
905+
binary.push(SerializedFunctionAttribute::PACK_VARIANT as u8)?;
906+
serialize_struct_def_index(binary, struct_definition_index)?;
907+
write_as_uleb128(binary, *variant_index, BYTECODE_INDEX_MAX)
908+
},
886909
}
887910
}
888911

third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,8 @@ impl ModuleGenerator {
681681

682682
let name_sym = struct_env.env().symbol_pool().make(&name);
683683
let name_idx = self.name_index(ctx, loc, name_sym);
684+
// TODO: add function attribute
685+
// let function_attribute = FunctionAttribute::Pack(struct_env.get_definition_index());
684686

685687
let handle = FF::FunctionHandle {
686688
module,

third_party/move/move-model/src/builder/binary_module_loader.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use move_binary_format::{
2727
AccessKind as FFAccessKind, AddressSpecifier as FFAddressSpecifier, FunctionAttribute,
2828
FunctionDefinitionIndex, FunctionHandleIndex, MemberCount,
2929
ResourceSpecifier as FFResourceSpecifier, SignatureToken, StructDefinitionIndex,
30-
StructHandleIndex, TableIndex, VariantIndex, Visibility,
30+
StructFieldInformation, StructHandleIndex, TableIndex, VariantIndex, Visibility,
3131
},
3232
internals::ModuleIndex,
3333
views::{
@@ -479,6 +479,64 @@ impl<'a> BinaryModuleLoader<'a> {
479479
.make(well_known::MODULE_LOCK_ATTRIBUTE);
480480
attributes.push(Attribute::Apply(node_id, sym, vec![]));
481481
},
482+
FunctionAttribute::Pack(struct_definition_index) => {
483+
let node_id = self.env.new_node(Loc::default(), Type::Tuple(vec![]));
484+
let struct_def = handle_view.module().struct_def_at(*struct_definition_index);
485+
let struct_handle = handle_view
486+
.module()
487+
.struct_handle_at(struct_def.struct_handle);
488+
let struct_name = handle_view.module().identifier_at(struct_handle.name);
489+
let module_handle = handle_view.module().module_handle_at(struct_handle.module);
490+
let module_id = handle_view.module().module_id_for_handle(module_handle);
491+
let module_name = module_id.name().as_str();
492+
let addr = module_id.address;
493+
let sym = self.env.symbol_pool().make(&format!(
494+
"pack{}{}{}{}{}{}",
495+
well_known::PUBLIC_STRUCT_DELIMITER,
496+
addr,
497+
well_known::PUBLIC_STRUCT_DELIMITER,
498+
module_name,
499+
well_known::PUBLIC_STRUCT_DELIMITER,
500+
struct_name.as_str()
501+
));
502+
attributes.push(Attribute::Apply(node_id, sym, vec![]));
503+
},
504+
FunctionAttribute::PackVariant(struct_definition_index, variant_index) => {
505+
let node_id = self.env.new_node(Loc::default(), Type::Tuple(vec![]));
506+
let struct_def = handle_view.module().struct_def_at(*struct_definition_index);
507+
if let StructFieldInformation::DeclaredVariants(variants) =
508+
&struct_def.field_information
509+
{
510+
if let Some(variant) = variants.get(*variant_index as usize) {
511+
let struct_handle = handle_view
512+
.module()
513+
.struct_handle_at(struct_def.struct_handle);
514+
let struct_name =
515+
handle_view.module().identifier_at(struct_handle.name);
516+
let module_handle =
517+
handle_view.module().module_handle_at(struct_handle.module);
518+
let module_id =
519+
handle_view.module().module_id_for_handle(module_handle);
520+
let module_name = module_id.name().as_str();
521+
let addr = module_id.address;
522+
let variant_name = variant.name;
523+
let variant_name_str =
524+
handle_view.module().identifier_at(variant_name).as_str();
525+
let sym = self.env.symbol_pool().make(&format!(
526+
"pack{}{}{}{}{}{}{}{}",
527+
well_known::PUBLIC_STRUCT_DELIMITER,
528+
addr,
529+
well_known::PUBLIC_STRUCT_DELIMITER,
530+
module_name,
531+
well_known::PUBLIC_STRUCT_DELIMITER,
532+
struct_name.as_str(),
533+
well_known::PUBLIC_STRUCT_DELIMITER,
534+
variant_name_str
535+
));
536+
attributes.push(Attribute::Apply(node_id, sym, vec![]));
537+
}
538+
}
539+
},
482540
}
483541
}
484542

third_party/move/move-model/src/metadata.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use anyhow::bail;
55
use legacy_move_compiler::shared::LanguageVersion as CompilerLanguageVersion;
66
use move_binary_format::file_format_common::{
7-
VERSION_DEFAULT, VERSION_DEFAULT_LANG_V2, VERSION_DEFAULT_LANG_V2_3,
7+
VERSION_DEFAULT, VERSION_DEFAULT_LANG_V2, VERSION_DEFAULT_LANG_V2_3, VERSION_DEFAULT_LANG_V2_4,
88
};
99
use move_command_line_common::env;
1010
use serde::{Deserialize, Serialize};
@@ -315,9 +315,8 @@ impl LanguageVersion {
315315
LanguageVersion::V2_0 | LanguageVersion::V2_1 | LanguageVersion::V2_2 => {
316316
VERSION_DEFAULT_LANG_V2
317317
},
318-
LanguageVersion::V2_3 | LanguageVersion::V2_4 | LanguageVersion::V2_5 => {
319-
VERSION_DEFAULT_LANG_V2_3
320-
},
318+
LanguageVersion::V2_3 => VERSION_DEFAULT_LANG_V2_3,
319+
LanguageVersion::V2_4 | LanguageVersion::V2_5 => VERSION_DEFAULT_LANG_V2_4,
321320
})
322321
}
323322

types/src/on_chain_config/aptos_features.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ pub enum FeatureFlag {
154154
/// If enabled, new single session is used by the VM to avoid squashing write-sets and cache
155155
/// reads between sessions (e.g., between transaction prologue, user session and epilogue).
156156
SESSION_CONTINUATION = 104,
157+
/// Enables bytecode version v9
158+
VM_BINARY_FORMAT_V10 = 105,
157159
}
158160

159161
impl FeatureFlag {
@@ -259,6 +261,7 @@ impl FeatureFlag {
259261
FeatureFlag::ENABLE_ENUM_OPTION,
260262
FeatureFlag::VM_BINARY_FORMAT_V9,
261263
FeatureFlag::ENABLE_FRAMEWORK_FOR_OPTION,
264+
FeatureFlag::VM_BINARY_FORMAT_V10,
262265
]
263266
}
264267
}
@@ -473,7 +476,9 @@ impl Features {
473476
}
474477

475478
pub fn get_max_binary_format_version(&self) -> u32 {
476-
if self.is_enabled(FeatureFlag::VM_BINARY_FORMAT_V9) {
479+
if self.is_enabled(FeatureFlag::VM_BINARY_FORMAT_V10) {
480+
file_format_common::VERSION_10
481+
} else if self.is_enabled(FeatureFlag::VM_BINARY_FORMAT_V9) {
477482
file_format_common::VERSION_9
478483
} else if self.is_enabled(FeatureFlag::VM_BINARY_FORMAT_V8) {
479484
file_format_common::VERSION_8

0 commit comments

Comments
 (0)