Răsfoiți Sursa

FunctionArg should be an expression in the CFG, not instruction

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 5 ani în urmă
părinte
comite
1b54454158
4 a modificat fișierele cu 21 adăugiri și 120 ștergeri
  1. 1 3
      src/emit/mod.rs
  2. 7 107
      src/resolver/builtin.rs
  3. 8 8
      src/resolver/cfg.rs
  4. 5 2
      src/resolver/expression.rs

+ 1 - 3
src/emit/mod.rs

@@ -704,6 +704,7 @@ impl<'a> Contract<'a> {
         runtime: &dyn TargetRuntime,
     ) -> BasicValueEnum<'a> {
         match e {
+            Expression::FunctionArg(_, pos) => function.get_nth_param(*pos as u32).unwrap(),
             Expression::BoolLiteral(_, val) => self
                 .context
                 .bool_type()
@@ -2557,9 +2558,6 @@ impl<'a> Contract<'a> {
 
             for ins in &cfg.bb[w.bb_no].instr {
                 match ins {
-                    cfg::Instr::FuncArg { res, arg } => {
-                        w.vars[*res].value = function.get_nth_param(*arg as u32).unwrap();
-                    }
                     cfg::Instr::Return { value } if value.is_empty() => {
                         self.builder
                             .build_return(Some(&self.context.i32_type().const_zero()));

+ 7 - 107
src/resolver/builtin.rs

@@ -13,7 +13,6 @@ pub fn add_builtin_function(ns: &mut Namespace, contract_no: usize) {
 }
 
 fn add_assert(ns: &mut Namespace, contract_no: usize) {
-    let argty = resolver::Type::Bool;
     let id = ast::Identifier {
         loc: ast::Loc(0, 0),
         name: "assert".to_owned(),
@@ -42,22 +41,10 @@ fn add_assert(ns: &mut Namespace, contract_no: usize) {
     let true_ = cfg.new_basic_block("noassert".to_owned());
     let false_ = cfg.new_basic_block("doassert".to_owned());
 
-    let cond = vartab
-        .add(
-            &ast::Identifier {
-                loc: ast::Loc(0, 0),
-                name: "arg0".to_owned(),
-            },
-            argty,
-            &mut errors,
-        )
-        .unwrap();
-
-    cfg.add(&mut vartab, Instr::FuncArg { res: cond, arg: 0 });
     cfg.add(
         &mut vartab,
         Instr::BranchCond {
-            cond: Expression::Variable(ast::Loc(0, 0), cond),
+            cond: Expression::FunctionArg(ast::Loc(0, 0), 0),
             true_,
             false_,
         },
@@ -86,7 +73,6 @@ fn add_assert(ns: &mut Namespace, contract_no: usize) {
 }
 
 fn add_print(ns: &mut Namespace, contract_no: usize) {
-    let argty = resolver::Type::String;
     let id = ast::Identifier {
         loc: ast::Loc(0, 0),
         name: "print".to_owned(),
@@ -112,22 +98,10 @@ fn add_print(ns: &mut Namespace, contract_no: usize) {
     let mut vartab = Vartable::new();
     let mut cfg = ControlFlowGraph::new();
 
-    let cond = vartab
-        .add(
-            &ast::Identifier {
-                loc: ast::Loc(0, 0),
-                name: "arg0".to_owned(),
-            },
-            argty,
-            &mut errors,
-        )
-        .unwrap();
-
-    cfg.add(&mut vartab, Instr::FuncArg { res: cond, arg: 0 });
     cfg.add(
         &mut vartab,
         Instr::Print {
-            expr: Expression::Variable(ast::Loc(0, 0), cond),
+            expr: Expression::FunctionArg(ast::Loc(0, 0), 0),
         },
     );
     cfg.add(&mut vartab, Instr::Return { value: Vec::new() });
@@ -148,7 +122,6 @@ fn add_print(ns: &mut Namespace, contract_no: usize) {
 }
 
 fn add_require(ns: &mut Namespace, contract_no: usize) {
-    let argty = resolver::Type::Bool;
     let id = ast::Identifier {
         loc: ast::Loc(0, 0),
         name: "require".to_owned(),
@@ -176,42 +149,16 @@ fn add_require(ns: &mut Namespace, contract_no: usize) {
         ns,
     );
 
-    let mut errors = Vec::new();
     let mut vartab = Vartable::new();
     let mut cfg = ControlFlowGraph::new();
 
     let true_ = cfg.new_basic_block("noassert".to_owned());
     let false_ = cfg.new_basic_block("doassert".to_owned());
 
-    let error = vartab
-        .add(
-            &ast::Identifier {
-                loc: ast::Loc(0, 0),
-                name: "ReasonCode".to_owned(),
-            },
-            resolver::Type::String,
-            &mut errors,
-        )
-        .unwrap();
-
-    cfg.add(&mut vartab, Instr::FuncArg { res: error, arg: 1 });
-
-    let cond = vartab
-        .add(
-            &ast::Identifier {
-                loc: ast::Loc(0, 0),
-                name: "condition".to_owned(),
-            },
-            argty,
-            &mut errors,
-        )
-        .unwrap();
-
-    cfg.add(&mut vartab, Instr::FuncArg { res: cond, arg: 0 });
     cfg.add(
         &mut vartab,
         Instr::BranchCond {
-            cond: Expression::Variable(ast::Loc(0, 0), cond),
+            cond: Expression::FunctionArg(ast::Loc(0, 0), 0),
             true_,
             false_,
         },
@@ -224,7 +171,7 @@ fn add_require(ns: &mut Namespace, contract_no: usize) {
     cfg.add(
         &mut vartab,
         Instr::AssertFailure {
-            expr: Some(Expression::Variable(ast::Loc(0, 0), error)),
+            expr: Some(Expression::FunctionArg(ast::Loc(0, 0), 1)),
         },
     );
 
@@ -234,8 +181,6 @@ fn add_require(ns: &mut Namespace, contract_no: usize) {
 
     let pos_with_reason = ns.contracts[contract_no].functions.len();
 
-    let argty = resolver::Type::Bool;
-
     ns.contracts[contract_no].functions.push(require);
 
     let mut require = FunctionDecl::new(
@@ -261,22 +206,10 @@ fn add_require(ns: &mut Namespace, contract_no: usize) {
     let true_ = cfg.new_basic_block("noassert".to_owned());
     let false_ = cfg.new_basic_block("doassert".to_owned());
 
-    let cond = vartab
-        .add(
-            &ast::Identifier {
-                loc: ast::Loc(0, 0),
-                name: "condition".to_owned(),
-            },
-            argty,
-            &mut errors,
-        )
-        .unwrap();
-
-    cfg.add(&mut vartab, Instr::FuncArg { res: cond, arg: 0 });
     cfg.add(
         &mut vartab,
         Instr::BranchCond {
-            cond: Expression::Variable(ast::Loc(0, 0), cond),
+            cond: Expression::FunctionArg(ast::Loc(0, 0), 0),
             true_,
             false_,
         },
@@ -331,27 +264,13 @@ fn add_revert(ns: &mut Namespace, contract_no: usize) {
 
     revert.noreturn = true;
 
-    let mut errors = Vec::new();
     let mut vartab = Vartable::new();
     let mut cfg = ControlFlowGraph::new();
 
-    let error = vartab
-        .add(
-            &ast::Identifier {
-                loc: ast::Loc(0, 0),
-                name: "ReasonCode".to_owned(),
-            },
-            resolver::Type::String,
-            &mut errors,
-        )
-        .unwrap();
-
-    cfg.add(&mut vartab, Instr::FuncArg { res: error, arg: 0 });
-
     cfg.add(
         &mut vartab,
         Instr::AssertFailure {
-            expr: Some(Expression::Variable(ast::Loc(0, 0), error)),
+            expr: Some(Expression::FunctionArg(ast::Loc(0, 0), 0)),
         },
     );
 
@@ -402,7 +321,6 @@ fn add_revert(ns: &mut Namespace, contract_no: usize) {
 }
 
 fn add_selfdestruct(ns: &mut Namespace, contract_no: usize) {
-    let argty = resolver::Type::Address(true);
     let id = ast::Identifier {
         loc: ast::Loc(0, 0),
         name: "selfdestruct".to_owned(),
@@ -430,28 +348,10 @@ fn add_selfdestruct(ns: &mut Namespace, contract_no: usize) {
     let mut vartab = Vartable::new();
     let mut cfg = ControlFlowGraph::new();
 
-    let recipient = vartab
-        .add(
-            &ast::Identifier {
-                loc: ast::Loc(0, 0),
-                name: "recipient".to_owned(),
-            },
-            argty,
-            &mut errors,
-        )
-        .unwrap();
-
-    cfg.add(
-        &mut vartab,
-        Instr::FuncArg {
-            res: recipient,
-            arg: 0,
-        },
-    );
     cfg.add(
         &mut vartab,
         Instr::SelfDestruct {
-            recipient: Expression::Variable(ast::Loc(0, 0), recipient),
+            recipient: Expression::FunctionArg(ast::Loc(0, 0), 0),
         },
     );
     cfg.add(&mut vartab, Instr::Unreachable);

+ 8 - 8
src/resolver/cfg.rs

@@ -16,10 +16,6 @@ use resolver::expression::{
 
 #[allow(clippy::large_enum_variant)]
 pub enum Instr {
-    FuncArg {
-        res: usize,
-        arg: usize,
-    },
     ClearStorage {
         ty: resolver::Type,
         storage: Expression,
@@ -186,6 +182,7 @@ impl ControlFlowGraph {
         expr: &Expression,
     ) -> String {
         match expr {
+            Expression::FunctionArg(_, pos) => format!("(arg #{})", pos),
             Expression::BoolLiteral(_, false) => "false".to_string(),
             Expression::BoolLiteral(_, true) => "true".to_string(),
             Expression::BytesLiteral(_, s) => format!("hex\"{}\"", hex::encode(s)),
@@ -541,9 +538,6 @@ impl ControlFlowGraph {
                 true_,
                 false_
             ),
-            Instr::FuncArg { res, arg } => {
-                format!("%{} = funcarg({})", self.vars[*res].id.name, arg)
-            }
             Instr::ClearStorage { ty, storage } => format!(
                 "clear storage slot({}) ty:{}",
                 self.expr_to_string(contract, ns, storage),
@@ -752,7 +746,13 @@ pub fn generate_cfg(
             if let Some(pos) = vartab.add(name, resolve_f.params[i].ty.clone(), errors) {
                 ns.check_shadowing(contract_no, name, errors);
 
-                cfg.add(&mut vartab, Instr::FuncArg { res: pos, arg: i });
+                cfg.add(
+                    &mut vartab,
+                    Instr::Set {
+                        res: pos,
+                        expr: Expression::FunctionArg(name.loc, i),
+                    },
+                );
             }
         }
     }

+ 5 - 2
src/resolver/expression.rs

@@ -29,6 +29,7 @@ use resolver::storage::{
 
 #[derive(PartialEq, Clone, Debug)]
 pub enum Expression {
+    FunctionArg(Loc, usize),
     BoolLiteral(Loc, bool),
     BytesLiteral(Loc, Vec<u8>),
     CodeLiteral(Loc, usize, bool),
@@ -125,7 +126,8 @@ impl Expression {
     /// Return the location for this expression
     pub fn loc(&self) -> Loc {
         match self {
-            Expression::BoolLiteral(loc, _)
+            Expression::FunctionArg(loc, _)
+            | Expression::BoolLiteral(loc, _)
             | Expression::BytesLiteral(loc, _)
             | Expression::CodeLiteral(loc, _, _)
             | Expression::NumberLiteral(loc, _, _)
@@ -192,7 +194,8 @@ impl Expression {
     pub fn reads_contract_storage(&self) -> bool {
         match self {
             Expression::StorageLoad(_, _, _) => true,
-            Expression::BoolLiteral(_, _)
+            Expression::FunctionArg(_, _)
+            | Expression::BoolLiteral(_, _)
             | Expression::BytesLiteral(_, _)
             | Expression::CodeLiteral(_, _, _)
             | Expression::NumberLiteral(_, _, _) => false,