|
@@ -2028,7 +2028,7 @@ pub fn assign_single(
|
|
|
/// Convert a function call expression to CFG in expression context
|
|
/// Convert a function call expression to CFG in expression context
|
|
|
pub fn emit_function_call(
|
|
pub fn emit_function_call(
|
|
|
expr: &ast::Expression,
|
|
expr: &ast::Expression,
|
|
|
- callee_contract_no: usize,
|
|
|
|
|
|
|
+ caller_contract_no: usize,
|
|
|
cfg: &mut ControlFlowGraph,
|
|
cfg: &mut ControlFlowGraph,
|
|
|
func: Option<&Function>,
|
|
func: Option<&Function>,
|
|
|
ns: &Namespace,
|
|
ns: &Namespace,
|
|
@@ -2045,11 +2045,11 @@ pub fn emit_function_call(
|
|
|
{
|
|
{
|
|
|
let args = args
|
|
let args = args
|
|
|
.iter()
|
|
.iter()
|
|
|
- .map(|a| expression(a, cfg, callee_contract_no, func, ns, vartab, opt))
|
|
|
|
|
|
|
+ .map(|a| expression(a, cfg, caller_contract_no, func, ns, vartab, opt))
|
|
|
.collect();
|
|
.collect();
|
|
|
|
|
|
|
|
let function_no = if let Some(signature) = signature {
|
|
let function_no = if let Some(signature) = signature {
|
|
|
- ns.contracts[callee_contract_no].virtual_functions[signature]
|
|
|
|
|
|
|
+ ns.contracts[caller_contract_no].virtual_functions[signature]
|
|
|
} else {
|
|
} else {
|
|
|
*function_no
|
|
*function_no
|
|
|
};
|
|
};
|
|
@@ -2061,9 +2061,9 @@ pub fn emit_function_call(
|
|
|
ast_func_no: function_no,
|
|
ast_func_no: function_no,
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- InternalCallTy::Static {
|
|
|
|
|
- cfg_no: ns.contracts[callee_contract_no].all_functions[&function_no],
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ let cfg_no = ns.contracts[caller_contract_no].all_functions[&function_no];
|
|
|
|
|
+
|
|
|
|
|
+ InternalCallTy::Static { cfg_no }
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
if !ftype.returns.is_empty() {
|
|
if !ftype.returns.is_empty() {
|
|
@@ -2108,11 +2108,11 @@ pub fn emit_function_call(
|
|
|
vec![Expression::Poison]
|
|
vec![Expression::Poison]
|
|
|
}
|
|
}
|
|
|
} else if let Type::InternalFunction { returns, .. } = function.ty().deref_any() {
|
|
} else if let Type::InternalFunction { returns, .. } = function.ty().deref_any() {
|
|
|
- let cfg_expr = expression(function, cfg, callee_contract_no, func, ns, vartab, opt);
|
|
|
|
|
|
|
+ let cfg_expr = expression(function, cfg, caller_contract_no, func, ns, vartab, opt);
|
|
|
|
|
|
|
|
let args = args
|
|
let args = args
|
|
|
.iter()
|
|
.iter()
|
|
|
- .map(|a| expression(a, cfg, callee_contract_no, func, ns, vartab, opt))
|
|
|
|
|
|
|
+ .map(|a| expression(a, cfg, caller_contract_no, func, ns, vartab, opt))
|
|
|
.collect();
|
|
.collect();
|
|
|
|
|
|
|
|
if !returns.is_empty() {
|
|
if !returns.is_empty() {
|
|
@@ -2167,26 +2167,26 @@ pub fn emit_function_call(
|
|
|
call_args,
|
|
call_args,
|
|
|
ty,
|
|
ty,
|
|
|
} => {
|
|
} => {
|
|
|
- let args = expression(args, cfg, callee_contract_no, func, ns, vartab, opt);
|
|
|
|
|
- let address = expression(address, cfg, callee_contract_no, func, ns, vartab, opt);
|
|
|
|
|
|
|
+ let args = expression(args, cfg, caller_contract_no, func, ns, vartab, opt);
|
|
|
|
|
+ let address = expression(address, cfg, caller_contract_no, func, ns, vartab, opt);
|
|
|
let gas = if let Some(gas) = &call_args.gas {
|
|
let gas = if let Some(gas) = &call_args.gas {
|
|
|
- expression(gas, cfg, callee_contract_no, func, ns, vartab, opt)
|
|
|
|
|
|
|
+ expression(gas, cfg, caller_contract_no, func, ns, vartab, opt)
|
|
|
} else {
|
|
} else {
|
|
|
default_gas(ns)
|
|
default_gas(ns)
|
|
|
};
|
|
};
|
|
|
let value = if let Some(value) = &call_args.value {
|
|
let value = if let Some(value) = &call_args.value {
|
|
|
- expression(value, cfg, callee_contract_no, func, ns, vartab, opt)
|
|
|
|
|
|
|
+ expression(value, cfg, caller_contract_no, func, ns, vartab, opt)
|
|
|
} else {
|
|
} else {
|
|
|
Expression::NumberLiteral(pt::Loc::Codegen, Type::Value, BigInt::zero())
|
|
Expression::NumberLiteral(pt::Loc::Codegen, Type::Value, BigInt::zero())
|
|
|
};
|
|
};
|
|
|
let accounts = call_args
|
|
let accounts = call_args
|
|
|
.accounts
|
|
.accounts
|
|
|
.as_ref()
|
|
.as_ref()
|
|
|
- .map(|expr| expression(expr, cfg, callee_contract_no, func, ns, vartab, opt));
|
|
|
|
|
|
|
+ .map(|expr| expression(expr, cfg, caller_contract_no, func, ns, vartab, opt));
|
|
|
let seeds = call_args
|
|
let seeds = call_args
|
|
|
.seeds
|
|
.seeds
|
|
|
.as_ref()
|
|
.as_ref()
|
|
|
- .map(|expr| expression(expr, cfg, callee_contract_no, func, ns, vartab, opt));
|
|
|
|
|
|
|
+ .map(|expr| expression(expr, cfg, caller_contract_no, func, ns, vartab, opt));
|
|
|
|
|
|
|
|
let success = vartab.temp_name("success", &Type::Bool);
|
|
let success = vartab.temp_name("success", &Type::Bool);
|
|
|
|
|
|
|
@@ -2228,30 +2228,30 @@ pub fn emit_function_call(
|
|
|
let mut tys: Vec<Type> = args.iter().map(|a| a.ty()).collect();
|
|
let mut tys: Vec<Type> = args.iter().map(|a| a.ty()).collect();
|
|
|
let mut args: Vec<Expression> = args
|
|
let mut args: Vec<Expression> = args
|
|
|
.iter()
|
|
.iter()
|
|
|
- .map(|a| expression(a, cfg, callee_contract_no, func, ns, vartab, opt))
|
|
|
|
|
|
|
+ .map(|a| expression(a, cfg, caller_contract_no, func, ns, vartab, opt))
|
|
|
.collect();
|
|
.collect();
|
|
|
- let address = expression(address, cfg, callee_contract_no, func, ns, vartab, opt);
|
|
|
|
|
|
|
+ let address = expression(address, cfg, caller_contract_no, func, ns, vartab, opt);
|
|
|
let gas = if let Some(gas) = &call_args.gas {
|
|
let gas = if let Some(gas) = &call_args.gas {
|
|
|
- expression(gas, cfg, callee_contract_no, func, ns, vartab, opt)
|
|
|
|
|
|
|
+ expression(gas, cfg, caller_contract_no, func, ns, vartab, opt)
|
|
|
} else {
|
|
} else {
|
|
|
default_gas(ns)
|
|
default_gas(ns)
|
|
|
};
|
|
};
|
|
|
let accounts = call_args
|
|
let accounts = call_args
|
|
|
.accounts
|
|
.accounts
|
|
|
.as_ref()
|
|
.as_ref()
|
|
|
- .map(|expr| expression(expr, cfg, callee_contract_no, func, ns, vartab, opt));
|
|
|
|
|
|
|
+ .map(|expr| expression(expr, cfg, caller_contract_no, func, ns, vartab, opt));
|
|
|
let seeds = call_args
|
|
let seeds = call_args
|
|
|
.seeds
|
|
.seeds
|
|
|
.as_ref()
|
|
.as_ref()
|
|
|
- .map(|expr| expression(expr, cfg, callee_contract_no, func, ns, vartab, opt));
|
|
|
|
|
|
|
+ .map(|expr| expression(expr, cfg, caller_contract_no, func, ns, vartab, opt));
|
|
|
|
|
|
|
|
let value = if let Some(value) = &call_args.value {
|
|
let value = if let Some(value) = &call_args.value {
|
|
|
- expression(value, cfg, callee_contract_no, func, ns, vartab, opt)
|
|
|
|
|
|
|
+ expression(value, cfg, caller_contract_no, func, ns, vartab, opt)
|
|
|
} else {
|
|
} else {
|
|
|
Expression::NumberLiteral(pt::Loc::Codegen, Type::Value, BigInt::zero())
|
|
Expression::NumberLiteral(pt::Loc::Codegen, Type::Value, BigInt::zero())
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- let selector = dest_func.selector(ns, &callee_contract_no);
|
|
|
|
|
|
|
+ let selector = dest_func.selector(ns, &caller_contract_no);
|
|
|
|
|
|
|
|
tys.insert(0, Type::Bytes(selector.len() as u8));
|
|
tys.insert(0, Type::Bytes(selector.len() as u8));
|
|
|
|
|
|
|
@@ -2305,16 +2305,16 @@ pub fn emit_function_call(
|
|
|
let mut tys: Vec<Type> = args.iter().map(|a| a.ty()).collect();
|
|
let mut tys: Vec<Type> = args.iter().map(|a| a.ty()).collect();
|
|
|
let mut args = args
|
|
let mut args = args
|
|
|
.iter()
|
|
.iter()
|
|
|
- .map(|a| expression(a, cfg, callee_contract_no, func, ns, vartab, opt))
|
|
|
|
|
|
|
+ .map(|a| expression(a, cfg, caller_contract_no, func, ns, vartab, opt))
|
|
|
.collect::<Vec<Expression>>();
|
|
.collect::<Vec<Expression>>();
|
|
|
- let function = expression(function, cfg, callee_contract_no, func, ns, vartab, opt);
|
|
|
|
|
|
|
+ let function = expression(function, cfg, caller_contract_no, func, ns, vartab, opt);
|
|
|
let gas = if let Some(gas) = &call_args.gas {
|
|
let gas = if let Some(gas) = &call_args.gas {
|
|
|
- expression(gas, cfg, callee_contract_no, func, ns, vartab, opt)
|
|
|
|
|
|
|
+ expression(gas, cfg, caller_contract_no, func, ns, vartab, opt)
|
|
|
} else {
|
|
} else {
|
|
|
default_gas(ns)
|
|
default_gas(ns)
|
|
|
};
|
|
};
|
|
|
let value = if let Some(value) = &call_args.value {
|
|
let value = if let Some(value) = &call_args.value {
|
|
|
- expression(value, cfg, callee_contract_no, func, ns, vartab, opt)
|
|
|
|
|
|
|
+ expression(value, cfg, caller_contract_no, func, ns, vartab, opt)
|
|
|
} else {
|
|
} else {
|
|
|
Expression::NumberLiteral(pt::Loc::Codegen, Type::Value, BigInt::zero())
|
|
Expression::NumberLiteral(pt::Loc::Codegen, Type::Value, BigInt::zero())
|
|
|
};
|
|
};
|
|
@@ -2361,7 +2361,7 @@ pub fn emit_function_call(
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
ast::Expression::Builtin(loc, tys, ast::Builtin::AbiDecode, args) => {
|
|
ast::Expression::Builtin(loc, tys, ast::Builtin::AbiDecode, args) => {
|
|
|
- let data = expression(&args[0], cfg, callee_contract_no, func, ns, vartab, opt);
|
|
|
|
|
|
|
+ let data = expression(&args[0], cfg, caller_contract_no, func, ns, vartab, opt);
|
|
|
let encoder = create_encoder(ns, false);
|
|
let encoder = create_encoder(ns, false);
|
|
|
encoder.abi_decode(loc, &data, tys, ns, vartab, cfg, None)
|
|
encoder.abi_decode(loc, &data, tys, ns, vartab, cfg, None)
|
|
|
}
|
|
}
|