浏览代码

Remove Expression::DynamicArray{Push,Pop}

We already have Builtin::ArrayPush and Builtin::ArrayPop.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 3 年之前
父节点
当前提交
af01ec6bb2

+ 0 - 7
src/bin/languageserver/mod.rs

@@ -608,13 +608,6 @@ impl SolangServer {
                 SolangServer::construct_expr(expr1, lookup_tbl, symtab, fnc_map, ns);
                 SolangServer::construct_expr(expr2, lookup_tbl, symtab, fnc_map, ns);
             }
-            ast::Expression::DynamicArrayPush(_locs, expr1, _typ, expr2) => {
-                SolangServer::construct_expr(expr1, lookup_tbl, symtab, fnc_map, ns);
-                SolangServer::construct_expr(expr2, lookup_tbl, symtab, fnc_map, ns);
-            }
-            ast::Expression::DynamicArrayPop(_locs, expr1, _typ) => {
-                SolangServer::construct_expr(expr1, lookup_tbl, symtab, fnc_map, ns);
-            }
             ast::Expression::StorageBytesSubscript(_locs, expr1, expr2) => {
                 SolangServer::construct_expr(expr1, lookup_tbl, symtab, fnc_map, ns);
                 SolangServer::construct_expr(expr2, lookup_tbl, symtab, fnc_map, ns);

+ 56 - 57
src/codegen/expression.rs

@@ -478,45 +478,6 @@ pub fn expression(
             *loc,
             Box::new(expression(expr, cfg, contract_no, func, ns, vartab, opt)),
         ),
-        Expression::DynamicArrayPush(loc, array, ty, value) => memory_array_push(
-            ty,
-            vartab,
-            array,
-            cfg,
-            contract_no,
-            func,
-            ns,
-            value,
-            loc,
-            opt,
-        ),
-        Expression::DynamicArrayPop(loc, array, ty) => {
-            let elem_ty = match ty {
-                Type::Array(..) => match ty.array_elem() {
-                    elem @ Type::Struct(..) => Type::Ref(Box::new(elem)),
-                    elem => elem,
-                },
-                Type::DynamicBytes => Type::Uint(8),
-                _ => unreachable!(),
-            };
-            let address_res = vartab.temp_anonymous(&elem_ty);
-
-            let address_arr = match expression(array, cfg, contract_no, func, ns, vartab, opt) {
-                Expression::Variable(_, _, pos) => pos,
-                _ => unreachable!(),
-            };
-
-            cfg.add(
-                vartab,
-                Instr::PopMemory {
-                    res: address_res,
-                    ty: ty.clone(),
-                    array: address_arr,
-                },
-            );
-
-            Expression::Variable(*loc, elem_ty, address_res)
-        }
         Expression::Or(loc, left, right) => {
             expr_or(left, cfg, contract_no, func, ns, vartab, loc, right, opt)
         }
@@ -574,18 +535,64 @@ pub fn expression(
             Box::new(expression(e, cfg, contract_no, func, ns, vartab, opt)),
         ),
         // for some built-ins, we have to inline special case code
-        Expression::Builtin(loc, _, Builtin::ArrayPush, args) => {
-            if ns.target == Target::Solana || args[0].ty().is_storage_bytes() {
-                array_push(loc, args, cfg, contract_no, func, ns, vartab, opt)
+        Expression::Builtin(loc, ty, Builtin::ArrayPush, args) => {
+            if args[0].ty().is_contract_storage() {
+                if ns.target == Target::Solana || args[0].ty().is_storage_bytes() {
+                    array_push(loc, args, cfg, contract_no, func, ns, vartab, opt)
+                } else {
+                    storage_slots_array_push(loc, args, cfg, contract_no, func, ns, vartab, opt)
+                }
             } else {
-                storage_slots_array_push(loc, args, cfg, contract_no, func, ns, vartab, opt)
+                memory_array_push(
+                    &ty[0],
+                    vartab,
+                    &args[0],
+                    cfg,
+                    contract_no,
+                    func,
+                    ns,
+                    &args[1],
+                    loc,
+                    opt,
+                )
             }
         }
         Expression::Builtin(loc, ty, Builtin::ArrayPop, args) => {
-            if ns.target == Target::Solana || args[0].ty().is_storage_bytes() {
-                array_pop(loc, args, &ty[0], cfg, contract_no, func, ns, vartab, opt)
+            if args[0].ty().is_contract_storage() {
+                if ns.target == Target::Solana || args[0].ty().is_storage_bytes() {
+                    array_pop(loc, args, &ty[0], cfg, contract_no, func, ns, vartab, opt)
+                } else {
+                    storage_slots_array_pop(
+                        loc,
+                        args,
+                        &ty[0],
+                        cfg,
+                        contract_no,
+                        func,
+                        ns,
+                        vartab,
+                        opt,
+                    )
+                }
             } else {
-                storage_slots_array_pop(loc, args, &ty[0], cfg, contract_no, func, ns, vartab, opt)
+                let address_res = vartab.temp_anonymous(&ty[0]);
+
+                let address_arr =
+                    match expression(&args[0], cfg, contract_no, func, ns, vartab, opt) {
+                        Expression::Variable(_, _, pos) => pos,
+                        _ => unreachable!(),
+                    };
+
+                cfg.add(
+                    vartab,
+                    Instr::PopMemory {
+                        res: address_res,
+                        ty: args[0].ty(),
+                        array: address_arr,
+                    },
+                );
+
+                Expression::Variable(*loc, ty[0].clone(), address_res)
             }
         }
         Expression::Builtin(_, _, Builtin::Assert, args) => {
@@ -679,15 +686,7 @@ fn memory_array_push(
     loc: &pt::Loc,
     opt: &Options,
 ) -> Expression {
-    let elem_ty = match ty {
-        Type::Array(..) => match ty.array_elem() {
-            elem @ Type::Struct(..) => Type::Ref(Box::new(elem)),
-            elem => elem,
-        },
-        Type::DynamicBytes => Type::Uint(8),
-        _ => unreachable!(),
-    };
-    let address_res = vartab.temp_anonymous(&elem_ty);
+    let address_res = vartab.temp_anonymous(ty);
     let address_arr = match expression(array, cfg, contract_no, func, ns, vartab, opt) {
         Expression::Variable(_, _, pos) => pos,
         _ => unreachable!(),
@@ -697,12 +696,12 @@ fn memory_array_push(
         vartab,
         Instr::PushMemory {
             res: address_res,
-            ty: ty.clone(),
+            ty: array.ty(),
             array: address_arr,
             value: Box::new(value),
         },
     );
-    Expression::Variable(*loc, elem_ty, address_res)
+    Expression::Variable(*loc, ty.clone(), address_res)
 }
 
 fn post_incdec(

+ 1 - 3
src/codegen/statements.rs

@@ -1464,9 +1464,7 @@ pub fn process_side_effects_expressions(
         | Expression::ExternalFunctionCall { .. }
         | Expression::ExternalFunctionCallRaw { .. }
         | Expression::Constructor { .. }
-        | Expression::Assign(..)
-        | Expression::DynamicArrayPop(..)
-        | Expression::DynamicArrayPush(..) => {
+        | Expression::Assign(..) => {
             let _ = expression(
                 exp,
                 ctx.cfg,

+ 1 - 18
src/sema/ast.rs

@@ -549,8 +549,6 @@ pub enum Expression {
     AllocDynamicArray(pt::Loc, Type, Box<Expression>, Option<Vec<u8>>),
     DynamicArrayLength(pt::Loc, Box<Expression>),
     DynamicArraySubscript(pt::Loc, Type, Box<Expression>, Box<Expression>),
-    DynamicArrayPush(pt::Loc, Box<Expression>, Type, Box<Expression>),
-    DynamicArrayPop(pt::Loc, Box<Expression>, Type),
     StorageBytesSubscript(pt::Loc, Box<Expression>, Box<Expression>),
     StorageArrayLength {
         loc: pt::Loc,
@@ -846,17 +844,6 @@ impl Expression {
                         Box::new(filter(right, ctx)),
                     )
                 }
-                Expression::DynamicArrayPush(loc, array, ty, value) => {
-                    Expression::DynamicArrayPush(
-                        *loc,
-                        Box::new(filter(array, ctx)),
-                        ty.clone(),
-                        Box::new(filter(value, ctx)),
-                    )
-                }
-                Expression::DynamicArrayPop(loc, array, ty) => {
-                    Expression::DynamicArrayPop(*loc, Box::new(filter(array, ctx)), ty.clone())
-                }
                 Expression::StorageBytesSubscript(loc, storage, index) => {
                     Expression::StorageBytesSubscript(
                         *loc,
@@ -1089,12 +1076,10 @@ impl Expression {
                 Expression::AllocDynamicArray(_, _, expr, _)
                 | Expression::DynamicArrayLength(_, expr) => expr.recurse(cx, f),
                 Expression::DynamicArraySubscript(_, _, left, right)
-                | Expression::StorageBytesSubscript(_, left, right)
-                | Expression::DynamicArrayPush(_, left, _, right) => {
+                | Expression::StorageBytesSubscript(_, left, right) => {
                     left.recurse(cx, f);
                     right.recurse(cx, f);
                 }
-                Expression::DynamicArrayPop(_, expr, _) => expr.recurse(cx, f),
                 Expression::StorageArrayLength { array, .. } => array.recurse(cx, f),
                 Expression::StringCompare(_, left, right)
                 | Expression::StringConcat(_, _, left, right) => {
@@ -1242,8 +1227,6 @@ impl Expression {
             | Expression::AllocDynamicArray(loc, _, _, _)
             | Expression::DynamicArrayLength(loc, _)
             | Expression::DynamicArraySubscript(loc, _, _, _)
-            | Expression::DynamicArrayPush(loc, _, _, _)
-            | Expression::DynamicArrayPop(loc, _, _)
             | Expression::StorageBytesSubscript(loc, _, _)
             | Expression::StorageArrayLength { loc, .. }
             | Expression::StringCompare(loc, _, _)

+ 1 - 1
src/sema/builtin.rs

@@ -605,7 +605,7 @@ pub fn resolve_call(
 /// to handle the special case "abi.decode(foo, (int32, bool, address))" where the
 /// second argument is a type list. The generic expression resolver cannot deal with
 /// this. It is only used in for this specific call.
-pub fn resolve_method_call(
+pub fn resolve_namespace_call(
     loc: &pt::Loc,
     namespace: &str,
     name: &str,

+ 0 - 31
src/sema/dotgraphviz.rs

@@ -953,37 +953,6 @@ impl Dot {
                 self.add_expression(array, func, ns, node, String::from("array"));
                 self.add_expression(index, func, ns, node, String::from("index"));
             }
-            Expression::DynamicArrayPush(loc, array, ty, val) => {
-                let node = self.add_node(
-                    Node::new(
-                        "array_push",
-                        vec![
-                            format!("array push {}", ty.to_string(ns)),
-                            ns.files[loc.0].loc_to_string(loc),
-                        ],
-                    ),
-                    Some(parent),
-                    Some(parent_rel),
-                );
-
-                self.add_expression(array, func, ns, node, String::from("array"));
-                self.add_expression(val, func, ns, node, String::from("val"));
-            }
-            Expression::DynamicArrayPop(loc, array, ty) => {
-                let node = self.add_node(
-                    Node::new(
-                        "array_pop",
-                        vec![
-                            format!("array pop {}", ty.to_string(ns)),
-                            ns.files[loc.0].loc_to_string(loc),
-                        ],
-                    ),
-                    Some(parent),
-                    Some(parent_rel),
-                );
-
-                self.add_expression(array, func, ns, node, String::from("array"));
-            }
             Expression::StorageBytesSubscript(loc, array, index) => {
                 let node = self.add_node(
                     Node::new(

+ 15 - 15
src/sema/expression.rs

@@ -89,13 +89,6 @@ impl Expression {
             | Expression::PostDecrement(_, ty, ..)
             | Expression::Keccak256(_, ty, _)
             | Expression::Assign(_, ty, _, _) => ty.clone(),
-            Expression::DynamicArrayPush(_, _, ty, _) | Expression::DynamicArrayPop(_, _, ty) => {
-                match ty {
-                    Type::Array(..) => ty.array_elem(),
-                    Type::DynamicBytes => Type::Uint(8),
-                    _ => unreachable!(),
-                }
-            }
             Expression::Subscript(_, ty, _, _) if ty.is_contract_storage() => {
                 ty.storage_array_elem()
             }
@@ -5304,7 +5297,7 @@ fn method_call_pos_args(
                 return Err(());
             }
 
-            return builtin::resolve_method_call(
+            return builtin::resolve_namespace_call(
                 loc,
                 &namespace.name,
                 &func.name,
@@ -5677,11 +5670,11 @@ fn method_call_pos_args(
                 }
             };
 
-            return Ok(Expression::DynamicArrayPush(
+            return Ok(Expression::Builtin(
                 *loc,
-                Box::new(var_expr),
-                var_ty.clone(),
-                Box::new(val),
+                vec![elem_ty.clone()],
+                Builtin::ArrayPush,
+                vec![var_expr, val],
             ));
         }
         if func.name == "pop" {
@@ -5701,10 +5694,17 @@ fn method_call_pos_args(
                 return Err(());
             }
 
-            return Ok(Expression::DynamicArrayPop(
+            let elem_ty = match &var_ty {
+                Type::Array(ty, _) => ty,
+                Type::DynamicBytes => &Type::Uint(8),
+                _ => unreachable!(),
+            };
+
+            return Ok(Expression::Builtin(
                 *loc,
-                Box::new(var_expr),
-                var_ty,
+                vec![elem_ty.clone()],
+                Builtin::ArrayPop,
+                vec![var_expr],
             ));
         }
     }

+ 7 - 2
src/sema/mutability.rs

@@ -253,9 +253,14 @@ fn read_expression(expr: &Expression, state: &mut StateCheck) -> bool {
         | Expression::Builtin(loc, _, Builtin::Random, _) => state.read(loc),
         Expression::Builtin(loc, _, Builtin::PayableSend, _)
         | Expression::Builtin(loc, _, Builtin::PayableTransfer, _)
-        | Expression::Builtin(loc, _, Builtin::ArrayPush, _)
-        | Expression::Builtin(loc, _, Builtin::ArrayPop, _)
         | Expression::Builtin(loc, _, Builtin::SelfDestruct, _) => state.write(loc),
+        Expression::Builtin(loc, _, Builtin::ArrayPush, args)
+        | Expression::Builtin(loc, _, Builtin::ArrayPop, args)
+            if args[0].ty().is_contract_storage() =>
+        {
+            state.write(loc)
+        }
+
         Expression::Constructor { loc, .. } => {
             state.write(loc);
         }

+ 0 - 14
src/sema/printer.rs

@@ -467,20 +467,6 @@ fn print_expr(e: &Expression, func: Option<&Function>, ns: &Namespace) -> Tree {
                 Tree::Branch(String::from("index"), vec![print_expr(index, func, ns)]),
             ],
         ),
-        Expression::DynamicArrayPush(_, array, ty, value) => Tree::Branch(
-            format!("dynamic array push {}", ty.to_string(ns)),
-            vec![
-                Tree::Branch(String::from("array"), vec![print_expr(array, func, ns)]),
-                Tree::Branch(String::from("value"), vec![print_expr(value, func, ns)]),
-            ],
-        ),
-        Expression::DynamicArrayPop(_, array, ty) => Tree::Branch(
-            format!("dynamic array pop {}", ty.to_string(ns)),
-            vec![Tree::Branch(
-                String::from("array"),
-                vec![print_expr(array, func, ns)],
-            )],
-        ),
         Expression::StorageBytesSubscript(_, array, index) => Tree::Branch(
             String::from("storage bytes subscript"),
             vec![

+ 0 - 9
src/sema/unused_variable.rs

@@ -210,15 +210,6 @@ pub fn check_function_call(ns: &mut Namespace, exp: &Expression, symtable: &mut
             }
         },
 
-        Expression::DynamicArrayPush(_, array, _, arg) => {
-            assigned_variable(ns, array, symtable);
-            used_variable(ns, arg, symtable);
-        }
-
-        Expression::DynamicArrayPop(_, array, _) => {
-            used_variable(ns, array, symtable);
-        }
-
         Expression::FormatString(_, args) => {
             for (_, expr) in args {
                 used_variable(ns, expr, symtable);