Skip to content

Commit

Permalink
[move-model] Represent Move attributes in the move-model.
Browse files Browse the repository at this point in the history
Attributes weren't yet represented in the move-model. This PR adds a representation and extends the model builder to translate them from the expansion AST.

Attributes in the model are needed for playing with EVM code generation, and possibly also Jazz.

Closes: aptos-labs#10109
  • Loading branch information
wrwg authored and bors-libra committed Jan 5, 2022
1 parent ebca3d5 commit c2688f9
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 7 deletions.
15 changes: 15 additions & 0 deletions language/move-model/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,21 @@ pub struct SpecFunDecl {
pub is_recursive: RefCell<Option<bool>>,
}

// =================================================================================================
/// # Attributes
#[derive(Debug, Clone)]
pub enum AttributeValue {
Value(NodeId, Value),
Name(NodeId, Option<ModuleName>, Symbol),
}

#[derive(Debug, Clone)]
pub enum Attribute {
Apply(NodeId, Symbol, Vec<Attribute>),
Assign(NodeId, Symbol, AttributeValue),
}

// =================================================================================================
/// # Conditions
Expand Down
8 changes: 7 additions & 1 deletion language/move-model/src/builder/model_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use move_compiler::{expansion::ast as EA, parser::ast as PA, shared::NumericalAd
use move_symbol_pool::Symbol as MoveStringSymbol;

use crate::{
ast::{ModuleName, Operation, QualifiedSymbol, Spec, Value},
ast::{Attribute, ModuleName, Operation, QualifiedSymbol, Spec, Value},
builder::spec_builtins,
model::{
FunId, FunctionVisibility, GlobalEnv, Loc, ModuleId, QualifiedId, SpecFunId, SpecVarId,
Expand Down Expand Up @@ -107,6 +107,7 @@ pub(crate) struct StructEntry {
pub is_resource: bool,
pub type_params: Vec<(Symbol, Type)>,
pub fields: Option<BTreeMap<Symbol, (usize, Type)>>,
pub attributes: Vec<Attribute>,
}

/// A declaration of a function.
Expand All @@ -120,6 +121,7 @@ pub(crate) struct FunEntry {
pub params: Vec<(Symbol, Type)>,
pub result_type: Type,
pub is_pure: bool,
pub attributes: Vec<Attribute>,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -237,6 +239,7 @@ impl<'env> ModelBuilder<'env> {
pub fn define_struct(
&mut self,
loc: Loc,
attributes: Vec<Attribute>,
name: QualifiedSymbol,
module_id: ModuleId,
struct_id: StructId,
Expand All @@ -246,6 +249,7 @@ impl<'env> ModelBuilder<'env> {
) {
let entry = StructEntry {
loc,
attributes,
module_id,
struct_id,
is_resource,
Expand All @@ -262,6 +266,7 @@ impl<'env> ModelBuilder<'env> {
pub fn define_fun(
&mut self,
loc: Loc,
attributes: Vec<Attribute>,
name: QualifiedSymbol,
module_id: ModuleId,
fun_id: FunId,
Expand All @@ -272,6 +277,7 @@ impl<'env> ModelBuilder<'env> {
) {
let entry = FunEntry {
loc,
attributes,
module_id,
fun_id,
visibility,
Expand Down
87 changes: 83 additions & 4 deletions language/move-model/src/builder/module_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ use move_ir_types::{ast::ConstantName, location::Spanned};

use crate::{
ast::{
Condition, ConditionKind, Exp, ExpData, GlobalInvariant, ModuleName, Operation,
PropertyBag, PropertyValue, QualifiedSymbol, Spec, SpecBlockInfo, SpecBlockTarget,
SpecFunDecl, SpecVarDecl, Value,
Attribute, AttributeValue, Condition, ConditionKind, Exp, ExpData, GlobalInvariant,
ModuleName, Operation, PropertyBag, PropertyValue, QualifiedSymbol, Spec, SpecBlockInfo,
SpecBlockTarget, SpecFunDecl, SpecVarDecl, Value,
},
builder::{
exp_translator::ExpTranslator,
Expand Down Expand Up @@ -157,7 +157,8 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
self.decl_ana(&module_def, &compiled_module, &source_map);
self.def_ana(&module_def, function_infos);
self.collect_spec_block_infos(&module_def);
self.populate_env_from_result(loc, compiled_module, source_map);
let attrs = self.translate_attributes(&module_def.attributes);
self.populate_env_from_result(loc, attrs, compiled_module, source_map);
}
}

Expand Down Expand Up @@ -244,6 +245,76 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
}
}

/// # Attribute Analysis
impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
pub fn translate_attributes(&mut self, attrs: &EA::Attributes) -> Vec<Attribute> {
attrs
.iter()
.map(|(_, _, attr)| self.translate_attribute(attr))
.collect()
}

pub fn translate_attribute(&mut self, attr: &EA::Attribute) -> Attribute {
let node_id = self
.parent
.env
.new_node(self.parent.to_loc(&attr.loc), Type::Tuple(vec![]));
match &attr.value {
EA::Attribute_::Name(n) => {
let sym = self.symbol_pool().make(n.value.as_str());
Attribute::Apply(node_id, sym, vec![])
}
EA::Attribute_::Parameterized(n, vs) => {
let sym = self.symbol_pool().make(n.value.as_str());
Attribute::Apply(node_id, sym, self.translate_attributes(vs))
}
EA::Attribute_::Assigned(n, v) => {
let value_node_id = self
.parent
.env
.new_node(self.parent.to_loc(&v.loc), Type::Tuple(vec![]));
let v = match &v.value {
EA::AttributeValue_::Value(val) => {
let val =
if let Some((val, _)) = ExpTranslator::new(self).translate_value(val) {
val
} else {
// Error reported
Value::Bool(false)
};
AttributeValue::Value(value_node_id, val)
}
EA::AttributeValue_::ModuleAccess(macc) => match macc.value {
EA::ModuleAccess_::Name(n) => AttributeValue::Name(
value_node_id,
None,
self.symbol_pool().make(n.value.as_str()),
),
EA::ModuleAccess_::ModuleAccess(mident, n) => {
let addr_bytes = self.parent.resolve_address(
&self.parent.to_loc(&macc.loc),
&mident.value.address,
);
let module_name = ModuleName::from_address_bytes_and_name(
addr_bytes,
self.symbol_pool()
.make(mident.value.module.0.value.as_str()),
);
AttributeValue::Name(
value_node_id,
Some(module_name),
self.symbol_pool().make(n.value.as_str()),
)
}
},
};
Attribute::Assign(node_id, self.symbol_pool().make(n.value.as_str()), v)
}
}
}
}

/// # Declaration Analysis
impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
Expand Down Expand Up @@ -296,6 +367,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
fn decl_ana_struct(&mut self, name: &PA::StructName, def: &EA::StructDefinition) {
let qsym = self.qualified_by_module_from_name(&name.0);
let struct_id = StructId::new(qsym.symbol);
let attrs = self.translate_attributes(&def.attributes);
let is_resource =
// TODO migrate to abilities
def.abilities.has_ability_(PA::Ability_::Key) || (
Expand All @@ -307,6 +379,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
et.analyze_and_add_type_params(def.type_parameters.iter().map(|param| &param.name));
et.parent.parent.define_struct(
et.to_loc(&def.loc),
attrs,
qsym,
et.parent.module_id,
struct_id,
Expand All @@ -319,6 +392,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
fn decl_ana_fun(&mut self, name: &PA::FunctionName, def: &EA::Function) {
let qsym = self.qualified_by_module_from_name(&name.0);
let fun_id = FunId::new(qsym.symbol);
let attrs = self.translate_attributes(&def.attributes);
let mut et = ExpTranslator::new(self);
et.enter_scope();
let type_params = et.analyze_and_add_type_params(
Expand All @@ -336,6 +410,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
let loc = et.to_loc(&def.loc);
et.parent.parent.define_fun(
loc.clone(),
attrs,
qsym.clone(),
et.parent.module_id,
fun_id,
Expand Down Expand Up @@ -2989,6 +3064,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
fn populate_env_from_result(
&mut self,
loc: Loc,
attributes: Vec<Attribute>,
module: CompiledModule,
source_map: SourceMap,
) {
Expand All @@ -3015,6 +3091,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
def_idx,
name,
entry.loc.clone(),
entry.attributes.clone(),
struct_spec,
),
))
Expand Down Expand Up @@ -3052,6 +3129,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
def_idx,
name,
entry.loc.clone(),
entry.attributes.clone(),
arg_names,
type_arg_names,
fun_spec,
Expand Down Expand Up @@ -3084,6 +3162,7 @@ impl<'env, 'translator> ModuleBuilder<'env, 'translator> {
.collect();
self.parent.env.add(
loc,
attributes,
module,
source_map,
named_constants,
Expand Down
10 changes: 8 additions & 2 deletions language/move-model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,14 @@ pub fn run_bytecode_model_builder<'a>(
let name = m.identifier_at(m.struct_handle_at(def.struct_handle).name);
let symbol = env.symbol_pool().make(name.as_str());
let struct_id = StructId::new(symbol);
let data =
env.create_move_struct_data(m, def_idx, symbol, Loc::default(), Spec::default());
let data = env.create_move_struct_data(
m,
def_idx,
symbol,
Loc::default(),
Vec::default(),
Spec::default(),
);
module_data.struct_data.insert(struct_id, data);
module_data.struct_idx_to_id.insert(def_idx, struct_id);
}
Expand Down
Loading

0 comments on commit c2688f9

Please sign in to comment.