Browse Source

Remove Expression::BytesPush and Expression::BytesPop

These are just specialized versions of Expression::ArrayPush and
Expression::ArrayPop.

Also do the same for Instr::PopStorageBytes / Instr::PushStorageBytes.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 years ago
parent
commit
747724f280

+ 4 - 4
src/codegen/cfg.rs

@@ -64,12 +64,12 @@ pub enum Instr {
         offset: Expression,
     },
     /// Push an element onto a bytes in storage
-    PushStorageBytes {
+    PushStorage {
         value: Expression,
         storage: Expression,
     },
     /// Pop an element from a bytes in storage
-    PopStorageBytes { res: usize, storage: Expression },
+    PopStorage { res: usize, storage: Expression },
     /// Push element on memory array
     PushMemory {
         res: usize,
@@ -693,14 +693,14 @@ impl ControlFlowGraph {
                 self.expr_to_string(contract, ns, offset),
                 self.expr_to_string(contract, ns, value),
             ),
-            Instr::PushStorageBytes { storage, value } => {
+            Instr::PushStorage { storage, value } => {
                 format!(
                     "push bytes slot({}) = {}",
                     self.expr_to_string(contract, ns, storage),
                     self.expr_to_string(contract, ns, value),
                 )
             }
-            Instr::PopStorageBytes { res, storage } => {
+            Instr::PopStorage { res, storage } => {
                 format!(
                     "%{} = pop bytes slot({})",
                     self.vars[res].id.name,

+ 4 - 6
src/codegen/constant_folding.rs

@@ -128,18 +128,16 @@ pub fn constant_folding(cfg: &mut ControlFlowGraph, ns: &mut Namespace) {
                         offset,
                     };
                 }
-                Instr::PushStorageBytes { storage, value } => {
+                Instr::PushStorage { storage, value } => {
                     let (storage, _) = expression(storage, Some(&vars), &cur, cfg, ns);
                     let (value, _) = expression(value, Some(&vars), &cur, cfg, ns);
 
-                    cfg.blocks[block_no].instr[instr_no] =
-                        Instr::PushStorageBytes { storage, value };
+                    cfg.blocks[block_no].instr[instr_no] = Instr::PushStorage { storage, value };
                 }
-                Instr::PopStorageBytes { res, storage } => {
+                Instr::PopStorage { res, storage } => {
                     let (storage, _) = expression(storage, Some(&vars), &cur, cfg, ns);
 
-                    cfg.blocks[block_no].instr[instr_no] =
-                        Instr::PopStorageBytes { res: *res, storage };
+                    cfg.blocks[block_no].instr[instr_no] = Instr::PopStorage { res: *res, storage };
                 }
                 Instr::PushMemory {
                     res,

+ 10 - 12
src/codegen/expression.rs

@@ -718,18 +718,16 @@ pub fn expression(
             Box::new(expression(e, cfg, contract_no, ns, vartab)),
         ),
         // for some built-ins, we have to inline special case code
-        Expression::Builtin(loc, _, Builtin::ArrayPush, args) => {
-            array_push(loc, args, cfg, contract_no, ns, vartab)
-        }
-        Expression::Builtin(loc, _, Builtin::ArrayPop, args) => {
-            array_pop(loc, args, cfg, contract_no, ns, vartab)
-        }
-        Expression::Builtin(loc, _, Builtin::BytesPush, args) => {
-            bytes_push(loc, args, cfg, contract_no, ns, vartab)
-        }
-        Expression::Builtin(loc, _, Builtin::BytesPop, args) => {
-            bytes_pop(loc, args, cfg, contract_no, ns, vartab)
-        }
+        Expression::Builtin(loc, _, Builtin::ArrayPush, args) => match args[0].ty().deref_any() {
+            Type::DynamicBytes => bytes_push(loc, args, cfg, contract_no, ns, vartab),
+            Type::Array(_, _) => array_push(loc, args, cfg, contract_no, ns, vartab),
+            _ => unreachable!(),
+        },
+        Expression::Builtin(loc, _, Builtin::ArrayPop, args) => match args[0].ty().deref_any() {
+            Type::DynamicBytes => bytes_pop(loc, args, cfg, contract_no, ns, vartab),
+            Type::Array(_, _) => array_pop(loc, args, cfg, contract_no, ns, vartab),
+            _ => unreachable!(),
+        },
         Expression::Builtin(_, _, Builtin::Assert, args) => {
             let true_ = cfg.new_basic_block("noassert".to_owned());
             let false_ = cfg.new_basic_block("doassert".to_owned());

+ 1 - 1
src/codegen/reaching_definitions.rs

@@ -120,7 +120,7 @@ fn instr_transfers(block_no: usize, block: &BasicBlock) -> Vec<Vec<Transfer>> {
             Instr::Set { res, .. } => set_var(&[*res]),
             Instr::Call { res, .. } => set_var(res),
             Instr::AbiDecode { res, .. } => set_var(res),
-            Instr::PopStorageBytes { res, .. } => set_var(&[*res]),
+            Instr::PopStorage { res, .. } => set_var(&[*res]),
             Instr::PushMemory { array, res, .. } => {
                 let mut v = set_var(&[*res]);
                 v.push(Transfer::Mod { var_no: *array });

+ 2 - 2
src/codegen/storage.rs

@@ -293,7 +293,7 @@ pub fn bytes_push(
     );
     cfg.add(
         vartab,
-        Instr::PushStorageBytes {
+        Instr::PushStorage {
             storage,
             value: Expression::Variable(*loc, ty.clone(), res),
         },
@@ -315,7 +315,7 @@ pub fn bytes_pop(
 
     let res = vartab.temp_anonymous(&Type::Bytes(1));
 
-    cfg.add(vartab, Instr::PopStorageBytes { res, storage });
+    cfg.add(vartab, Instr::PopStorage { res, storage });
 
     Expression::Variable(*loc, Type::Bytes(1), res)
 }

+ 3 - 3
src/codegen/strength_reduce.rs

@@ -129,11 +129,11 @@ fn block_reduce(
                 *storage = expression_reduce(storage, &vars, ns);
                 *offset = expression_reduce(offset, &vars, ns);
             }
-            Instr::PushStorageBytes { storage, value, .. } => {
+            Instr::PushStorage { storage, value, .. } => {
                 *value = expression_reduce(value, &vars, ns);
                 *storage = expression_reduce(storage, &vars, ns);
             }
-            Instr::PopStorageBytes { storage, .. } => {
+            Instr::PopStorage { storage, .. } => {
                 *storage = expression_reduce(storage, &vars, ns);
             }
             Instr::PushMemory { value, .. } => {
@@ -789,7 +789,7 @@ fn transfer(instr: &Instr, vars: &mut Variables, ns: &Namespace) {
                 }
             }
         }
-        Instr::PopStorageBytes { res, .. } => {
+        Instr::PopStorage { res, .. } => {
             let mut set = HashSet::new();
 
             set.insert(Value::unknown(8));

+ 2 - 2
src/codegen/vector_to_slice.rs

@@ -87,8 +87,8 @@ fn find_writable_vectors(
             | Instr::SetStorage { .. }
             | Instr::ClearStorage { .. }
             | Instr::SetStorageBytes { .. }
-            | Instr::PushStorageBytes { .. }
-            | Instr::PopStorageBytes { .. }
+            | Instr::PushStorage { .. }
+            | Instr::PopStorage { .. }
             | Instr::SelfDestruct { .. }
             | Instr::EmitEvent { .. }
             | Instr::AbiDecode { .. }

+ 2 - 2
src/emit/mod.rs

@@ -3236,7 +3236,7 @@ pub trait TargetRuntime<'a> {
                             value.into_int_value(),
                         );
                     }
-                    Instr::PushStorageBytes { storage, value } => {
+                    Instr::PushStorage { storage, value } => {
                         let val = self
                             .expression(contract, value, &w.vars, function)
                             .into_int_value();
@@ -3246,7 +3246,7 @@ pub trait TargetRuntime<'a> {
 
                         self.storage_bytes_push(&contract, function, slot, val);
                     }
-                    Instr::PopStorageBytes { res, storage } => {
+                    Instr::PopStorage { res, storage } => {
                         let slot = self
                             .expression(contract, storage, &w.vars, function)
                             .into_int_value();

+ 0 - 2
src/sema/ast.rs

@@ -1142,8 +1142,6 @@ pub enum Builtin {
     PayableTransfer,
     ArrayPush,
     ArrayPop,
-    BytesPush,
-    BytesPop,
     Assert,
     Print,
     Revert,

+ 4 - 3
src/sema/builtin.rs

@@ -401,10 +401,11 @@ pub fn is_reserved(fname: &str) -> bool {
         return true;
     }
 
-    if BUILTIN_FUNCTIONS
+    let is_builtin_function = BUILTIN_FUNCTIONS
         .iter()
-        .any(|p| (p.name == fname && p.namespace == None) || (p.namespace == Some(fname)))
-    {
+        .any(|p| (p.name == fname && p.namespace == None) || (p.namespace == Some(fname)));
+
+    if is_builtin_function {
         return true;
     }
 

+ 6 - 6
src/sema/expression.rs

@@ -5472,7 +5472,7 @@ fn method_call_pos_args(
                     };
 
                     return Ok(Expression::Builtin(
-                        *loc,
+                        func.loc,
                         vec![ret_ty],
                         Builtin::ArrayPush,
                         builtin_args,
@@ -5500,7 +5500,7 @@ fn method_call_pos_args(
                     let elem_ty = storage_elem.deref_any();
 
                     return Ok(Expression::Builtin(
-                        *loc,
+                        func.loc,
                         vec![elem_ty.clone()],
                         Builtin::ArrayPop,
                         vec![var_expr],
@@ -5556,9 +5556,9 @@ fn method_call_pos_args(
                     };
 
                     return Ok(Expression::Builtin(
-                        *loc,
+                        func.loc,
                         vec![ret_ty],
-                        Builtin::BytesPush,
+                        Builtin::ArrayPush,
                         builtin_args,
                     ));
                 }
@@ -5573,9 +5573,9 @@ fn method_call_pos_args(
                     }
 
                     return Ok(Expression::Builtin(
-                        *loc,
+                        func.loc,
                         vec![Type::Bytes(1)],
-                        Builtin::BytesPop,
+                        Builtin::ArrayPop,
                         vec![var_expr],
                     ));
                 }

+ 0 - 2
src/sema/mutability.rs

@@ -254,8 +254,6 @@ fn read_expression(expr: &Expression, state: &mut StateCheck) -> bool {
         | Expression::Builtin(loc, _, Builtin::PayableTransfer, _)
         | Expression::Builtin(loc, _, Builtin::ArrayPush, _)
         | Expression::Builtin(loc, _, Builtin::ArrayPop, _)
-        | Expression::Builtin(loc, _, Builtin::BytesPush, _)
-        | Expression::Builtin(loc, _, Builtin::BytesPop, _)
         | Expression::Builtin(loc, _, Builtin::SelfDestruct, _) => state.write(loc),
         Expression::Constructor { loc, .. } => {
             state.write(loc);

+ 0 - 3
tests/builtins.rs

@@ -8,7 +8,4 @@ fn builtin_prototype() {
     assert_eq!(p.namespace, Some("block"));
     assert_eq!(p.name, "timestamp");
     assert!(p.args.is_empty());
-
-    // there is no entry for some builtins
-    assert!(builtin::get_prototype(ast::Builtin::ArrayPush).is_none());
 }