Kaynağa Gözat

Merge pull request #17 from seanyoung/substrate

Allow multiple constructors for substrate
Sean Young 6 yıl önce
ebeveyn
işleme
63b0d86b3d
7 değiştirilmiş dosya ile 279 ekleme ve 158 silme
  1. 8 1
      Cargo.toml
  2. 1 1
      Dockerfile
  3. 38 33
      src/emit/mod.rs
  4. 15 2
      src/main.rs
  5. 1 4
      src/resolver/cfg.rs
  6. 209 110
      src/resolver/mod.rs
  7. 7 7
      src/test.rs

+ 8 - 1
Cargo.toml

@@ -13,7 +13,6 @@ lalrpop = "0.17.0"
 [dependencies]
 lalrpop-util = "0.17.0"
 regex = "0.2.1"
-inkwell = { git = "https://github.com/seanyoung/inkwell", branch = "llvm8-0" }
 num-bigint = "0.2"
 num-traits = "0.2.6"
 parity-wasm = "0.35"
@@ -27,3 +26,11 @@ serde_json = "1.0"
 serde = "1.0.90"
 ethabi = "7.0.0"
 ethereum-types = "0.5.2"
+
+[dependencies.inkwell]
+git = "https://github.com/TheDan64/inkwell"
+branch = "llvm8-0"
+features = ["target-webassembly", "llvm8-0"]
+
+[profile.release]
+lto = true

+ 1 - 1
Dockerfile

@@ -11,7 +11,7 @@
 FROM ubuntu:18.04 as builder
 MAINTAINER Sean Young <sean@mess.org>
 RUN apt-get update
-RUN apt-get install -y cargo llvm-8-dev clang-8 libz-dev
+RUN apt-get install -y cargo llvm-8-dev clang-8 libz-dev pkg-config
 
 COPY src src/src/
 COPY stdlib src/stdlib/

+ 38 - 33
src/emit/mod.rs

@@ -49,6 +49,7 @@ pub struct Contract<'a> {
     context: &'a Context,
     target: Target,
     ns: &'a resolver::Contract,
+    constructors: Vec<Function<'a>>,
     functions: Vec<Function<'a>>,
     externals: HashMap<String, FunctionValue<'a>>,
 }
@@ -103,6 +104,7 @@ impl<'a> Contract<'a> {
             target: target,
             context: context,
             ns: contract,
+            constructors: Vec::new(),
             functions: Vec::new(),
             externals: HashMap::new(),
         };
@@ -110,8 +112,19 @@ impl<'a> Contract<'a> {
         // externals
         e.declare_externals();
 
+        e.constructors = contract.constructors.iter()
+            .map(|func| e.emit_func(&format!("sol::constructor::{}", func.wasm_symbol(&contract)), func))
+            .collect();
+
         for func in &contract.functions {
-            e.emit_func(func);
+            let name = if func.name != "" {
+                format!("sol::function::{}", func.wasm_symbol(&contract))
+            } else {
+                "sol::fallback".to_owned()
+            };
+
+            let f = e.emit_func(&name, func);
+            e.functions.push(f);
         }
 
         e.emit_constructor_dispatch(contract);
@@ -243,7 +256,7 @@ impl<'a> Contract<'a> {
             &[],
             "");
 
-        if let Some(n) = contract.constructor_function() {
+        if let Some(con) = contract.constructors.get(0) {
             let mut args = Vec::new();
 
             let arg = function.get_first_param().unwrap().into_pointer_value();
@@ -262,10 +275,10 @@ impl<'a> Contract<'a> {
                 &mut args,
                 args_ptr,
                 length.into_int_value(),
-                &contract.functions[n],
+                con,
             );
 
-            self.builder.build_call(self.functions[n].value_ref, &args, "");
+            self.builder.build_call(self.constructors[0].value_ref, &args, "");
         }
 
         self.builder.build_return(None);
@@ -278,8 +291,8 @@ impl<'a> Contract<'a> {
         let function = self.module.add_function("function", ftype, None);
 
         let entry = self.context.append_basic_block(function, "entry");
-        let fallback = self.context.append_basic_block(function, "fallback");
-        let switch = self.context.append_basic_block(function, "switch");
+        let fallback_block = self.context.append_basic_block(function, "fallback");
+        let switch_block = self.context.append_basic_block(function, "switch");
 
         self.builder.position_at_end(&entry);
 
@@ -292,9 +305,9 @@ impl<'a> Contract<'a> {
             self.context.i32_type().const_int(4, false).into(),
             "");
 
-        self.builder.build_conditional_branch(not_fallback, &switch, &fallback);
+        self.builder.build_conditional_branch(not_fallback, &switch_block, &fallback_block);
 
-        self.builder.position_at_end(&switch);
+        self.builder.position_at_end(&switch_block);
 
         let fid_ptr = unsafe {
             self.builder.build_gep(
@@ -327,12 +340,9 @@ impl<'a> Contract<'a> {
 
         let mut cases = Vec::new();
 
-        for (i, f) in contract.functions.iter().enumerate() {
-            // ignore constructors and fallback
-            if f.name == None {
-                continue;
-            }
+        let mut fallback = None;
 
+        for (i, f) in contract.functions.iter().enumerate() {
             match &f.visibility {
                 ast::Visibility::Internal(_) | ast::Visibility::Private(_) => {
                     continue;
@@ -340,7 +350,12 @@ impl<'a> Contract<'a> {
                 _ => (),
             }
 
-            let res = keccak256(f.sig.as_bytes());
+            if f.name == "" {
+                fallback = Some(i);
+                continue;
+            }
+
+            let res = keccak256(f.signature.as_bytes());
 
             let bb = self.context.append_basic_block(function, "");
             let id = u32::from_le_bytes([res[0], res[1], res[2], res[3]]);
@@ -414,7 +429,7 @@ impl<'a> Contract<'a> {
             cases.push((self.context.i32_type().const_int(id as u64, false), bb));
         }
 
-        self.builder.position_at_end(&switch);
+        self.builder.position_at_end(&switch_block);
 
         let mut c = Vec::new();
 
@@ -431,12 +446,12 @@ impl<'a> Contract<'a> {
         // FIXME: emit code for public contract variables
 
         // emit fallback code
-        self.builder.position_at_end(&fallback);
+        self.builder.position_at_end(&fallback_block);
 
-        match contract.fallback_function() {
-            Some(n) => {
+        match fallback {
+            Some(f) => {
                 self.builder.build_call(
-                    self.functions[n].value_ref,
+                    self.functions[f].value_ref,
                     &[],
                     "");
 
@@ -664,12 +679,12 @@ impl<'a> Contract<'a> {
         self.builder.position_at_end(&decode_block);
     }
 
-    fn emit_func(&mut self, f: &resolver::FunctionDecl) {
+    fn emit_func(&self, fname: &str, f: &resolver::FunctionDecl) -> Function<'a> {
         let mut args: Vec<BasicTypeEnum> = Vec::new();
         let mut wasm_return = false;
 
         for p in &f.params {
-            let ty = p.ty.LLVMType(self.ns, &self.context);
+            let ty = p.ty.LLVMType(self.ns, self.context);
             args.push(if p.ty.stack_based() {
                 ty.ptr_type(AddressSpace::Generic).into()
             } else {
@@ -677,16 +692,6 @@ impl<'a> Contract<'a> {
             });
         }
 
-        // FIXME: Substrate can have multiple overloaded constructors
-        // FIXME: Solidity can have multiple overloaded functions by the same name
-        let fname = if f.constructor {
-            "sol::__constructor".to_string()
-        } else if let Some(ref name) = f.name {
-            format!("sol::{}", name)
-        } else {
-            "sol::__fallback".to_string()
-        };
-
         let ftype = if f.returns.len() == 1 && !f.returns[0].ty.stack_based() {
             wasm_return = true;
             f.returns[0].ty.LLVMType(self.ns, &self.context).fn_type(&args, false)
@@ -931,10 +936,10 @@ impl<'a> Contract<'a> {
             }
         }
 
-        self.functions.push(Function {
+        Function {
             value_ref: function,
             wasm_return,
-        });
+        }
     }
 }
 

+ 15 - 2
src/main.rs

@@ -70,6 +70,14 @@ fn main() {
                 .possible_values(&["none", "less", "default", "aggressive"])
                 .default_value("default"),
         )
+        .arg(
+            Arg::with_name("TARGET")
+                .help("Target to build for")
+                .long("target")
+                .takes_value(true)
+                .possible_values(&["substrate", "burrow"])
+                .default_value("substrate")
+        )
         .arg(
             Arg::with_name("STD-JSON")
                 .help("mimic solidity json output on stdout")
@@ -102,6 +110,11 @@ fn main() {
     };
 
     let context = inkwell::context::Context::create();
+    let target = match matches.value_of("TARGET") {
+        Some("substrate") => resolver::Target::Substrate,
+        Some("burrow") => resolver::Target::Burrow,
+        _ => unreachable!()
+    };
 
     for filename in matches.values_of("INPUT").unwrap() {
         let mut f = File::open(&filename).expect("file not found");
@@ -110,7 +123,7 @@ fn main() {
         f.read_to_string(&mut contents)
             .expect("something went wrong reading the file");
 
-        let past = match parser::parse(&contents) {
+        let ast = match parser::parse(&contents) {
             Ok(s) => s,
             Err(errors) => {
                 if matches.is_present("STD-JSON") {
@@ -130,7 +143,7 @@ fn main() {
         };
 
         // resolve phase
-        let (contracts, errors) = resolver::resolver(past);
+        let (contracts, errors) = resolver::resolver(ast, &target);
 
         if matches.is_present("STD-JSON") {
             let mut out = output::message_as_json(filename, &contents, &errors);

+ 1 - 4
src/resolver/cfg.rs

@@ -261,10 +261,7 @@ impl ControlFlowGraph {
 
                     s.join(", ")
                 },
-                match ns.functions[*func].name {
-                    Some(ref n) => n.to_owned(),
-                    None => "???".to_owned(),
-                },
+                ns.functions[*func].name.to_owned(),
                 {
                     let s: Vec<String> = args
                         .iter()

+ 209 - 110
src/resolver/mod.rs

@@ -6,6 +6,7 @@ use std::collections::HashMap;
 
 pub mod cfg;
 
+// FIXME: Burrow ABIs do not belong here
 #[derive(Serialize)]
 pub struct ABIParam {
     pub name: String,
@@ -26,6 +27,12 @@ pub struct ABI {
     pub mutability: &'static str,
 }
 
+#[derive(PartialEq, Clone)]
+pub enum Target {
+    Substrate,
+    Burrow
+}
+
 #[derive(PartialEq, Clone)]
 pub enum TypeName {
     Elementary(ast::ElementaryTypeName),
@@ -96,9 +103,8 @@ impl Parameter {
 
 pub struct FunctionDecl {
     pub loc: ast::Loc,
-    pub constructor: bool,
-    pub name: Option<String>,
-    pub sig: String,
+    pub name: String,
+    pub signature: String,
     pub ast_index: usize,
     pub mutability: Option<ast::StateMutability>,
     pub visibility: ast::Visibility,
@@ -107,6 +113,55 @@ pub struct FunctionDecl {
     pub cfg: Option<Box<cfg::ControlFlowGraph>>,
 }
 
+impl FunctionDecl {
+    fn new(loc: ast::Loc, name: String, ast_index: usize, mutability: Option<ast::StateMutability>,
+        visibility: ast::Visibility, params: Vec<Parameter>, returns: Vec<Parameter>, ns: &Contract) -> Self {
+        let mut signature = name.to_owned();
+
+        signature.push('(');
+    
+        for (i, p) in params.iter().enumerate() {
+            if i > 0 {
+                signature.push(',');
+            }
+    
+            signature.push_str(&match &p.ty {
+                TypeName::Elementary(e) => e.to_string(),
+                TypeName::Enum(i) => ns.enums[*i].ty.to_string(),
+                TypeName::Noreturn => unreachable!(),
+            });
+        }
+    
+        signature.push(')');
+
+        FunctionDecl{
+            loc, name, signature, ast_index, mutability, visibility, params, returns, cfg: None
+        }
+    }
+
+    pub fn wasm_symbol(&self, ns: &Contract) -> String {
+        let mut sig = self.name.to_owned();
+
+        if !self.params.is_empty() {
+            sig.push_str("__");
+
+            for (i, p) in self.params.iter().enumerate() {
+                if i > 0 {
+                    sig.push('_');
+                }
+
+                sig.push_str(&match &p.ty {
+                    TypeName::Elementary(e) => e.to_string(),
+                    TypeName::Enum(i) => ns.enums[*i].name.to_owned(),
+                    TypeName::Noreturn => unreachable!(),
+                });
+            }
+        }
+
+        sig
+    }
+}
+
 pub struct ContractVariable {
     pub name: String,
     pub ty: TypeName,
@@ -124,8 +179,10 @@ pub struct Contract {
     pub name: String,
     pub enums: Vec<EnumDecl>,
     // structs/events
+    pub constructors: Vec<FunctionDecl>,
     pub functions: Vec<FunctionDecl>,
     pub variables: Vec<ContractVariable>,
+    pub target: Target,
     top_of_contract_storage: usize,
     symbols: HashMap<String, Symbol>,
 }
@@ -293,16 +350,7 @@ impl Contract {
 
     pub fn fallback_function(&self) -> Option<usize> {
         for (i, f) in self.functions.iter().enumerate() {
-            if !f.constructor && None == f.name {
-                return Some(i);
-            }
-        }
-        return None;
-    }
-
-    pub fn constructor_function(&self) -> Option<usize> {
-        for (i, f) in self.functions.iter().enumerate() {
-            if f.constructor {
+            if f.name == "" {
                 return Some(i);
             }
         }
@@ -312,37 +360,48 @@ impl Contract {
     pub fn generate_abi(&self) -> Vec<ABI> {
         let mut abis = Vec::new();
 
-        for f in &self.functions {
-            let (ty, name) = if f.constructor {
-                ("constructor".to_string(), "".to_string())
-            } else {
-                match &f.name {
-                    Some(n) => ("function".to_string(), n.to_string()),
-                    None => ("fallback".to_string(), "".to_string()),
-                }
-            };
-
-            let constant = match &f.cfg {
-                Some(cfg) => !cfg.writes_contract_storage,
-                None => false,
-            };
-
-            let mutability = match &f.mutability {
-                Some(n) => n.to_string(),
-                None => "nonpayable",
-            };
+        for f in &self.constructors {
+            abis.push(ABI {
+                name: "".to_owned(),
+                constant: match &f.cfg {
+                    Some(cfg) => !cfg.writes_contract_storage,
+                    None => false,
+                },
+                mutability: match &f.mutability {
+                    Some(n) => n.to_string(),
+                    None => "nonpayable",
+                },
+                payable: match &f.mutability {
+                    Some(ast::StateMutability::Payable(_)) => true,
+                    _ => false,
+                },
+                ty: "constructor".to_owned(),
+                inputs: f.params.iter().map(|p| p.to_abi(&self)).collect(),
+                outputs: f.returns.iter().map(|p| p.to_abi(&self)).collect(),
+            })
 
-            let payable = match &f.mutability {
-                Some(ast::StateMutability::Payable(_)) => true,
-                _ => false,
-            };
+        }
 
+        for f in &self.functions {
             abis.push(ABI {
-                name,
-                constant,
-                mutability,
-                payable,
-                ty,
+                name: f.name.to_owned(),
+                constant: match &f.cfg {
+                    Some(cfg) => !cfg.writes_contract_storage,
+                    None => false,
+                },
+                mutability: match &f.mutability {
+                    Some(n) => n.to_string(),
+                    None => "nonpayable",
+                },
+                payable: match &f.mutability {
+                    Some(ast::StateMutability::Payable(_)) => true,
+                    _ => false,
+                },
+                ty: if f.name == "" {
+                    "fallback".to_owned()
+                } else {
+                    "function".to_owned()
+                },
                 inputs: f.params.iter().map(|p| p.to_abi(&self)).collect(),
                 outputs: f.returns.iter().map(|p| p.to_abi(&self)).collect(),
             })
@@ -354,11 +413,19 @@ impl Contract {
     pub fn to_string(&self) -> String {
         let mut s = format!("#\n# Contract: {}\n", self.name);
 
+        for f in &self.constructors {
+            s.push_str(&format!("# constructor {}\n", f.signature));
+
+            if let Some(ref cfg) = f.cfg {
+                s.push_str(&cfg.to_string(self));
+            }
+        }
+
         for f in &self.functions {
-            if let Some(ref name) = f.name {
-                s.push_str(&format!("# function {}\n", name));
+            if f.name != "" {
+                s.push_str(&format!("# function {}\n", f.signature));
             } else {
-                s.push_str(&format!("# constructor\n"));
+                s.push_str(&format!("# fallback\n"));
             }
 
             if let Some(ref cfg) = f.cfg {
@@ -370,13 +437,13 @@ impl Contract {
     }
 }
 
-pub fn resolver(s: ast::SourceUnit) -> (Vec<Contract>, Vec<Output>) {
+pub fn resolver(s: ast::SourceUnit, target: &Target) -> (Vec<Contract>, Vec<Output>) {
     let mut contracts = Vec::new();
     let mut errors = Vec::new();
 
     for part in s.0 {
         if let ast::SourceUnitPart::ContractDefinition(def) = part {
-            if let Some(c) = resolve_contract(def, &mut errors) {
+            if let Some(c) = resolve_contract(def, &target, &mut errors) {
                 contracts.push(c)
             }
         }
@@ -387,13 +454,16 @@ pub fn resolver(s: ast::SourceUnit) -> (Vec<Contract>, Vec<Output>) {
 
 fn resolve_contract(
     def: Box<ast::ContractDefinition>,
+    target: &Target,
     errors: &mut Vec<Output>,
 ) -> Option<Contract> {
     let mut ns = Contract {
         name: def.name.name.to_string(),
         enums: Vec::new(),
+        constructors: Vec::new(),
         functions: Vec::new(),
         variables: Vec::new(),
+        target: target.clone(),
         top_of_contract_storage: 0,
         symbols: HashMap::new(),
     };
@@ -438,6 +508,17 @@ fn resolve_contract(
         }
     }
 
+    // resolve constructor bodies
+    for f in 0..ns.constructors.len() {
+        let ast_index = ns.constructors[f].ast_index;
+        if let ast::ContractPart::FunctionDefinition(ref ast_f) = def.parts[ast_index] {
+            match cfg::generate_cfg(ast_f, &ns.constructors[f], &ns, errors) {
+                Ok(c) =>  ns.constructors[f].cfg = Some(c),
+                Err(_) => broken = true
+            }
+        }
+    }
+
     // resolve function bodies
     for f in 0..ns.functions.len() {
         let ast_index = ns.functions[f].ast_index;
@@ -495,7 +576,7 @@ fn resolve_contract(
                     }
                     ns.functions[f].cfg = Some(c);
                 }
-                Err(_) => broken = true,
+                Err(_) => broken = true
             }
         }
     }
@@ -717,6 +798,7 @@ fn func_decl(
     }
 
     for r in &f.returns {
+        // FIXME: these should be allowed
         if let Some(ref n) = r.name {
             errors.push(Output::warning(
                 n.loc,
@@ -772,6 +854,26 @@ fn func_decl(
         }
     }
 
+    if f.constructor {
+        match mutability {
+            Some(ast::StateMutability::Pure(loc)) => {
+                errors.push(Output::error(
+                    loc,
+                    format!("constructor cannot be declared pure"),
+                ));
+                success = false;
+            },
+            Some(ast::StateMutability::View(loc)) => {
+                errors.push(Output::error(
+                    loc,
+                    format!("constructor cannot be declared view"),
+                ));
+                success = false;
+            },
+            _ => ()
+        }
+    }
+
     if visibility == None {
         errors.push(Output::error(
             f.loc,
@@ -780,34 +882,21 @@ fn func_decl(
         success = false;
     }
 
-    // FIXME: check visibility of constructor.
-
     if !success {
         return false;
     }
 
     let name = match f.name {
-        Some(ref n) => Some(n.name.to_string()),
-        None => None,
+        Some(ref n) => n.name.to_owned(),
+        None => "".to_owned()
     };
 
-    let fdecl = FunctionDecl {
-        loc: f.loc,
-        sig: external_signature(&name, &params, &ns),
-        name: name,
-        mutability,
-        visibility: visibility.unwrap(),
-        constructor: f.constructor,
-        ast_index: i,
-        params,
-        returns,
-        cfg: None,
-    };
+    let fdecl = FunctionDecl::new(f.loc, name, i, mutability, visibility.unwrap(), params, returns, &ns);
 
     if f.constructor {
-        // fallback function
-        if let Some(i) = ns.constructor_function() {
-            let prev = &ns.functions[i];
+        // In the eth solidity, only one constructor is allowed
+        if ns.target == Target::Burrow && !ns.constructors.is_empty() {
+            let prev = &ns.constructors[i];
             errors.push(Output::error_with_note(
                 f.loc,
                 "constructor already defined".to_string(),
@@ -817,14 +906,39 @@ fn func_decl(
             return false;
         }
 
-        ns.functions.push(fdecl);
+        // FIXME: Internal visibility is allowed on inherented contract, but we don't support those yet
+        match fdecl.visibility {
+            ast::Visibility::Public(_) => (),
+            _ => {
+                errors.push(Output::error(
+                    f.loc,
+                    "constructor function must be declared public".to_owned()
+                ));
+                return false;
+            }
+        }
+
+        for v in ns.constructors.iter() {
+            if v.signature == fdecl.signature {
+                errors.push(Output::error_with_note(
+                    f.loc,
+                    "constructor with this signature already exists".to_string(),
+                    v.loc,
+                    "location of previous definition".to_string(),
+                ));
+
+                return false;
+            }
+        }
+
+        ns.constructors.push(fdecl);
 
         true
     } else if let Some(ref id) = f.name {
         if let Some(Symbol::Function(ref mut v)) = ns.symbols.get_mut(&id.name) {
             // check if signature already present
             for o in v.iter() {
-                if fdecl.sig == ns.functions[o.1].sig {
+                if ns.functions[o.1].signature == fdecl.signature {
                     errors.push(Output::error_with_note(
                         f.loc,
                         "overloaded function with this signature already exist".to_string(),
@@ -852,6 +966,7 @@ fn func_decl(
         // fallback function
         if let Some(i) = ns.fallback_function() {
             let prev = &ns.functions[i];
+            
             errors.push(Output::error_with_note(
                 f.loc,
                 "fallback function already defined".to_string(),
@@ -861,63 +976,47 @@ fn func_decl(
             return false;
         }
 
+        if let ast::Visibility::External(_) = fdecl.visibility {
+            // ok
+        } else {
+            errors.push(Output::error(
+                f.loc,
+                "fallback function must be declared external".to_owned()
+            ));
+            return false;
+        }
+        
         ns.functions.push(fdecl);
 
         true
     }
 }
 
-pub fn external_signature(name: &Option<String>, params: &Vec<Parameter>, ns: &Contract) -> String {
-    let mut sig = match name {
-        Some(ref n) => n.to_string(),
-        None => "".to_string(),
-    };
-
-    sig.push('(');
-
-    for (i, p) in params.iter().enumerate() {
-        if i > 0 {
-            sig.push(',');
-        }
-
-        sig.push_str(&match &p.ty {
-            TypeName::Elementary(e) => e.to_string(),
-            TypeName::Enum(i) => ns.enums[*i].ty.to_string(),
-            TypeName::Noreturn => unreachable!(),
-        });
-    }
-
-    sig.push(')');
-
-    sig
-}
-
 #[test]
 fn signatures() {
     let ns = Contract {
         name: String::from("foo"),
         enums: Vec::new(),
+        constructors: Vec::new(),
         functions: Vec::new(),
         variables: Vec::new(),
+        target: crate::resolver::Target::Burrow,
         top_of_contract_storage: 0,
         symbols: HashMap::new(),
     };
 
-    assert_eq!(
-        external_signature(
-            &Some("foo".to_string()),
-            &vec!(
-                Parameter {
-                    name: "".to_string(),
-                    ty: TypeName::Elementary(ast::ElementaryTypeName::Uint(8))
-                },
-                Parameter {
-                    name: "".to_string(),
-                    ty: TypeName::Elementary(ast::ElementaryTypeName::Address)
-                },
-            ),
-            &ns
-        ),
-        "foo(uint8,address)"
-    );
+    let fdecl = FunctionDecl::new(
+        ast::Loc(0, 0), "foo".to_owned(), 0, None, ast::Visibility::Public(ast::Loc(0, 0)),
+        vec!(
+            Parameter {
+                name: "".to_string(),
+                ty: TypeName::Elementary(ast::ElementaryTypeName::Uint(8))
+            },
+            Parameter {
+                name: "".to_string(),
+                ty: TypeName::Elementary(ast::ElementaryTypeName::Address)
+            },
+        ), Vec::new(), &ns);
+
+    assert_eq!(fdecl.signature, "foo(uint8,address)");
 }

+ 7 - 7
src/test.rs

@@ -91,7 +91,7 @@ mod tests {
         let s = parser::parse(src).expect("parse should succeed");
 
         // resolve
-        let (contracts, errors) = resolver::resolver(s);
+        let (contracts, errors) = resolver::resolver(s, &resolver::Target::Burrow);
 
         if contracts.is_empty() {
             output::print_messages("test.sol", src, &errors, false);
@@ -138,7 +138,7 @@ mod tests {
         );
 
         let ret = main
-            .invoke_export("sol::foo", &[], &mut NopExternals)
+            .invoke_export("sol::function::foo", &[], &mut NopExternals)
             .expect("failed to call function");
 
         assert_eq!(ret, Some(RuntimeValue::I32(2)));
@@ -195,7 +195,7 @@ contract test3 {
             let res = ((50 - i) * 100 + 5) + i * 1000;
 
             let ret = main
-                .invoke_export("sol::foo", &[RuntimeValue::I32(i)], &mut NopExternals)
+                .invoke_export("sol::function::foo__uint32", &[RuntimeValue::I32(i)], &mut NopExternals)
                 .expect("failed to call function");
 
             assert_eq!(ret, Some(RuntimeValue::I32(res)));
@@ -206,7 +206,7 @@ contract test3 {
 
             let ret = main
                 .invoke_export(
-                    "sol::bar",
+                    "sol::function::bar__uint32_bool",
                     &[RuntimeValue::I32(i), RuntimeValue::I32(1)],
                     &mut NopExternals,
                 )
@@ -224,7 +224,7 @@ contract test3 {
 
             let ret = main
                 .invoke_export(
-                    "sol::bar",
+                    "sol::function::bar__uint32_bool",
                     &[RuntimeValue::I32(i), RuntimeValue::I32(0)],
                     &mut NopExternals,
                 )
@@ -245,7 +245,7 @@ contract test3 {
             }
 
             let ret = main
-                .invoke_export("sol::baz", &[RuntimeValue::I32(i)], &mut NopExternals)
+                .invoke_export("sol::function::baz__uint32", &[RuntimeValue::I32(i)], &mut NopExternals)
                 .expect("failed to call function");
 
             assert_eq!(ret, Some(RuntimeValue::I32(res)));
@@ -269,7 +269,7 @@ contract test3 {
         );
 
         let ret = main
-            .invoke_export("sol::foo", &[], &mut NopExternals)
+            .invoke_export("sol::function::foo", &[], &mut NopExternals)
             .expect("failed to call function");
 
         assert_eq!(ret, Some(RuntimeValue::I32(1)));