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

Implement storage access via storage keyword #646

Merged
merged 41 commits into from
Mar 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
1065c1e
StorageDeclaration and StorageAccess
Mar 10, 2022
125ba7c
clippy and fmt
Mar 10, 2022
7a391f1
More decl stuff
Mar 10, 2022
f9293e6
ir codegen for srwq
Mar 11, 2022
bbfa042
new IR instruction
Mar 11, 2022
e72c4a9
many ir changes
Mar 12, 2022
c457bb5
start of reassignment
mohammadfawaz Mar 13, 2022
71f2939
merge with master
mohammadfawaz Mar 13, 2022
de39112
updated test
mohammadfawaz Mar 14, 2022
12be058
wip
mohammadfawaz Mar 14, 2022
9d81ec7
wip
mohammadfawaz Mar 14, 2022
cbb7e0b
wip
mohammadfawaz Mar 14, 2022
6d83509
merge with master
mohammadfawaz Mar 16, 2022
6392294
multi-access
mohammadfawaz Mar 17, 2022
2d68e2e
merging some functions
mohammadfawaz Mar 17, 2022
9d5c1bd
merge with master
mohammadfawaz Mar 18, 2022
284416e
unnecessary changes
mohammadfawaz Mar 18, 2022
1703041
test
mohammadfawaz Mar 18, 2022
337da5e
Initial commit
mohammadfawaz Mar 20, 2022
1e1e9fc
fixing a few things
mohammadfawaz Mar 20, 2022
4c91105
additional fixes
mohammadfawaz Mar 20, 2022
dbd0e80
adding tests
mohammadfawaz Mar 20, 2022
e02ab43
fixing default value for cgas
mohammadfawaz Mar 20, 2022
731a78a
merge with master
mohammadfawaz Mar 20, 2022
4c66aa9
did not mean to change this test
mohammadfawaz Mar 20, 2022
b8eb0f0
Switching the default value for gas in IR to std::u64::MAX
mohammadfawaz Mar 21, 2022
dc21d92
merge with master
mohammadfawaz Mar 21, 2022
295c8a2
Merge branch 'mohammadfawaz/contract_call_with_ir' into mohammadfawaz…
mohammadfawaz Mar 21, 2022
27c3f02
small fixes
mohammadfawaz Mar 21, 2022
2b9a7e5
storage access test
mohammadfawaz Mar 21, 2022
910a94a
remove unnecessary test
mohammadfawaz Mar 21, 2022
a9f2bd7
remove initalizers for now
mohammadfawaz Mar 21, 2022
01aabef
Missing error
mohammadfawaz Mar 21, 2022
c7e93d6
final touches
mohammadfawaz Mar 21, 2022
c3ed975
fixing tests
mohammadfawaz Mar 21, 2022
21ad7ce
Update Forc.toml format
mohammadfawaz Mar 21, 2022
1105f47
Update sway-core/src/semantic_analysis/namespace.rs
mohammadfawaz Mar 22, 2022
d2eb5fd
merge with master
mohammadfawaz Mar 23, 2022
40dd4e0
cargo.lock
mohammadfawaz Mar 23, 2022
07b5804
revert Cargo.lock
mohammadfawaz Mar 23, 2022
30fa5ed
Merge branch 'master' into sezna/storage-access
mohammadfawaz Mar 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sway-core/src/asm_generation/from_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,7 @@ impl<'ir> AsmBuilder<'ir> {
self.bytecode.push(Op {
opcode: Either::Left(match access_type {
StateAccessType::Read => VirtualOp::SRWQ(val_reg, key_reg),
StateAccessType::Write => VirtualOp::SWWQ(val_reg, key_reg),
StateAccessType::Write => VirtualOp::SWWQ(key_reg, val_reg),
}),
comment: "quad word state access".into(),
owning_span: instr_val.get_span(self.context),
Expand Down Expand Up @@ -1584,7 +1584,7 @@ impl<'ir> AsmBuilder<'ir> {
);

self.bytecode.push(Op {
opcode: Either::Left(VirtualOp::SWW(store_reg, key_reg)),
opcode: Either::Left(VirtualOp::SWW(key_reg, store_reg)),
comment: "single word state access".into(),
owning_span: instr_val.get_span(self.context),
});
Expand Down
3 changes: 3 additions & 0 deletions sway-core/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ pub const LANGUAGE_NAME: &str = "Sway";
/// The size, in bytes, of a single word in the FuelVM.
pub const VM_WORD_SIZE: u64 = 8;

// Keywords
pub const INVALID_NAMES: &[&str] = &["storage"];

pub const CONTRACT_CALL_GAS_PARAMETER_NAME: &str = "gas";

pub const CONTRACT_CALL_COINS_PARAMETER_NAME: &str = "coins";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ fn connect_declaration(
| AbiDeclaration(_)
| StructDeclaration(_)
| EnumDeclaration(_)
| StorageDeclaration(_)
| GenericTypeForFunctionScope { .. } => leaves.to_vec(),
VariableDeclaration(_) | ConstantDeclaration(_) => {
let entry_node = graph.add_node(node.into());
Expand Down
42 changes: 35 additions & 7 deletions sway-core/src/control_flow_analysis/dead_code_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use crate::{
};
use sway_types::span::Span;

use crate::semantic_analysis::TypedStorageDeclaration;

use petgraph::algo::has_path_connecting;
use petgraph::prelude::NodeIndex;

Expand Down Expand Up @@ -78,6 +80,10 @@ impl ControlFlowGraph {
span: span.clone(),
warning_content: Warning::StructFieldNeverRead,
}),
ControlFlowGraphNode::StorageField { field_name, .. } => Some(CompileWarning {
span: field_name.span().clone(),
warning_content: Warning::DeadStorageDeclaration,
}),
ControlFlowGraphNode::OrganizationalDominator(..) => None,
})
.collect::<Vec<_>>();
Expand Down Expand Up @@ -393,6 +399,10 @@ fn connect_declaration(
connect_impl_trait(trait_name, graph, methods, entry_node, tree_type)?;
Ok(leaves.to_vec())
}
StorageDeclaration(storage) => {
connect_storage_declaration(storage, graph, entry_node, tree_type);
Ok(leaves.to_vec())
}
ErrorRecovery | GenericTypeForFunctionScope { .. } => Ok(leaves.to_vec()),
}
}
Expand Down Expand Up @@ -983,17 +993,19 @@ fn connect_expression(
)?;
Ok(prefix_idx)
}
StorageAccess(_fields) => {
// Enable the code below once the storage declaration is added to the namespace
/*let storage_node = graph.namespace.storage.get(&fields.field_name()).cloned();
let this_ix =
graph.add_node(format!("storage field access: {}", fields.field_name()).into());
StorageAccess(fields) => {
let storage_node = graph
.namespace
.storage
.get(&fields.storage_field_name())
.cloned();
let this_ix = graph
.add_node(format!("storage field access: {}", fields.storage_field_name()).into());
for leaf in leaves {
storage_node.map(|x| graph.add_edge(*leaf, x, "".into()));
graph.add_edge(*leaf, this_ix, "".into());
}
Ok(vec![this_ix])*/
Ok(vec![])
Ok(vec![this_ix])
}
SizeOf { variant } => match variant {
SizeOfVariant::Type(_) => Ok(vec![]),
Expand Down Expand Up @@ -1159,3 +1171,19 @@ fn construct_dead_code_warning_from_node(node: &TypedAstNode) -> Option<CompileW
},
})
}

fn connect_storage_declaration(
decl: &TypedStorageDeclaration,
graph: &mut ControlFlowGraph,
_entry_node: NodeIndex,
_tree_type: &TreeType,
) {
let TypedStorageDeclaration { fields, .. } = decl;

let field_nodes = fields
.iter()
.map(|field| (field.clone(), graph.add_node(field.into())))
.collect::<Vec<_>>();

graph.namespace.insert_storage(field_nodes);
}
14 changes: 14 additions & 0 deletions sway-core/src/control_flow_analysis/flow_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use sway_types::span::Span;
use petgraph::{graph::EdgeIndex, prelude::NodeIndex};

mod namespace;
use crate::semantic_analysis::declaration::TypedStorageField;
use namespace::ControlFlowNamespace;
pub(crate) use namespace::FunctionNamespaceEntry;

Expand Down Expand Up @@ -63,6 +64,9 @@ pub enum ControlFlowGraphNode {
struct_field_name: Ident,
span: Span,
},
StorageField {
field_name: Ident,
},
}

impl std::fmt::Debug for ControlFlowGraphNode {
Expand All @@ -81,10 +85,20 @@ impl std::fmt::Debug for ControlFlowGraphNode {
} => {
format!("Struct field {}", struct_field_name.as_str())
}
ControlFlowGraphNode::StorageField { field_name } => {
format!("Storage field {}", field_name.as_str())
}
};
f.write_str(&text)
}
}
impl std::convert::From<&TypedStorageField> for ControlFlowGraphNode {
fn from(other: &TypedStorageField) -> Self {
ControlFlowGraphNode::StorageField {
field_name: other.name.clone(),
}
}
}

impl std::convert::From<&TypedAstNode> for ControlFlowGraphNode {
fn from(other: &TypedAstNode) -> Self {
Expand Down
8 changes: 8 additions & 0 deletions sway-core/src/control_flow_analysis/flow_graph/namespace.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{EntryPoint, ExitPoint};
use crate::parse_tree::CallPath;
use crate::semantic_analysis::declaration::TypedStorageField;
use crate::type_engine::TypeInfo;
use crate::Ident;
use petgraph::prelude::NodeIndex;
Expand Down Expand Up @@ -38,6 +39,7 @@ pub struct ControlFlowNamespace {
/// TODO this should be an Ident and not a String, switch when static spans are implemented
pub(crate) struct_namespace: HashMap<String, StructNamespaceEntry>,
pub(crate) const_namespace: HashMap<Ident, NodeIndex>,
pub(crate) storage: HashMap<Ident, NodeIndex>,
}

impl ControlFlowNamespace {
Expand Down Expand Up @@ -113,6 +115,12 @@ impl ControlFlowNamespace {
}
}

pub(crate) fn insert_storage(&mut self, field_nodes: Vec<(TypedStorageField, NodeIndex)>) {
for (field, node) in field_nodes {
self.storage.insert(field.name, node);
}
}

pub(crate) fn insert_struct(
&mut self,
struct_name: String,
Expand Down
15 changes: 15 additions & 0 deletions sway-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ pub enum Warning {
ShadowingReservedRegister {
reg_name: Ident,
},
DeadStorageDeclaration,
MatchExpressionUnreachableArm,
}

Expand Down Expand Up @@ -380,6 +381,8 @@ impl fmt::Display for Warning {
"This register declaration shadows the reserved register, \"{}\".",
reg_name
),
DeadStorageDeclaration => write!(f, "This storage declaration is never accessed and can be removed."
),
MatchExpressionUnreachableArm => write!(f, "This match arm is unreachable."),
}
}
Expand Down Expand Up @@ -891,6 +894,14 @@ pub enum CompileError {
UnrecognizedContractParam { param_name: String, span: Span },
#[error("Attempting to specify a contract method parameter for a non-contract function call")]
CallParamForNonContractCallMethod { span: Span },
#[error("Storage field {name} does not exist")]
StorageFieldDoesNotExist { name: String, span: Span },
#[error("No storage has been declared")]
NoDeclaredStorage { span: Span },
#[error("Multiple storage declarations were found")]
MultipleStorageDeclarations { span: Span },
#[error("Expected identifier, found keyword \"{name}\" ")]
InvalidVariableName { name: String, span: Span },
}

impl std::convert::From<TypeError> for CompileError {
Expand Down Expand Up @@ -1099,6 +1110,10 @@ impl CompileError {
ContractCallParamRepeated { span, .. } => span,
UnrecognizedContractParam { span, .. } => span,
CallParamForNonContractCallMethod { span, .. } => span,
StorageFieldDoesNotExist { span, .. } => span,
NoDeclaredStorage { span, .. } => span,
MultipleStorageDeclarations { span, .. } => span,
InvalidVariableName { span, .. } => span,
}
}

Expand Down
5 changes: 5 additions & 0 deletions sway-core/src/optimize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ fn compile_declarations(
| TypedDeclaration::StorageReassignment(_)
| TypedDeclaration::AbiDeclaration(_)
| TypedDeclaration::GenericTypeForFunctionScope { .. }
| TypedDeclaration::StorageDeclaration(_)
| TypedDeclaration::ErrorRecovery => (),
}
}
Expand Down Expand Up @@ -483,6 +484,9 @@ impl FnCompiler {
Err("gen ty for fn scope".into())
}
TypedDeclaration::ErrorRecovery { .. } => Err("error recovery".into()),
TypedDeclaration::StorageDeclaration(_) => {
Err("storage declaration".into())
}
},
TypedAstNodeContent::Expression(te) => {
// An expression with an ignored return value... I assume.
Expand Down Expand Up @@ -2256,6 +2260,7 @@ fn convert_resolved_type(context: &mut Context, ast_type: &TypeInfo) -> Result<T
TypeInfo::UnknownGeneric { .. } => return Err("unknowngeneric type found in AST..?".into()),
TypeInfo::Ref(_) => return Err("ref type found in AST..?".into()),
TypeInfo::ErrorRecovery => return Err("error recovery type found in AST..?".into()),
TypeInfo::Storage { .. } => return Err("storage type found in AST..?".into()),
})
}

Expand Down
Loading