aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-07-28 19:37:38 +0800
committerchriseth <c@ethdev.com>2015-07-28 19:37:46 +0800
commitac1a11634edaacfdbc198df4ed4078ac4c141af7 (patch)
treeb6d07f8bac5f804c927838f2a06ceca944ea4aa8 /ExpressionCompiler.cpp
parentf2f1e0300793ea5686a4ad1c5c46b9e454c01bdc (diff)
downloaddexon-solidity-ac1a11634edaacfdbc198df4ed4078ac4c141af7.tar
dexon-solidity-ac1a11634edaacfdbc198df4ed4078ac4c141af7.tar.gz
dexon-solidity-ac1a11634edaacfdbc198df4ed4078ac4c141af7.tar.bz2
dexon-solidity-ac1a11634edaacfdbc198df4ed4078ac4c141af7.tar.lz
dexon-solidity-ac1a11634edaacfdbc198df4ed4078ac4c141af7.tar.xz
dexon-solidity-ac1a11634edaacfdbc198df4ed4078ac4c141af7.tar.zst
dexon-solidity-ac1a11634edaacfdbc198df4ed4078ac4c141af7.zip
Improved gas computation for CALLCODE.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r--ExpressionCompiler.cpp12
1 files changed, 10 insertions, 2 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 470fd7c5..786d386d 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -1072,6 +1072,7 @@ void ExpressionCompiler::appendExternalFunctionCall(
using FunctionKind = FunctionType::Location;
FunctionKind funKind = _functionType.getLocation();
bool returnSuccessCondition = funKind == FunctionKind::Bare || funKind == FunctionKind::BareCallCode;
+ bool isCallCode = funKind == FunctionKind::BareCallCode || funKind == FunctionKind::CallCode;
//@todo only return the first return value for now
Type const* firstReturnType =
@@ -1158,13 +1159,20 @@ void ExpressionCompiler::appendExternalFunctionCall(
if (_functionType.gasSet())
m_context << eth::dupInstruction(m_context.baseToCurrentStackOffset(gasStackPos));
else
+ {
// send all gas except the amount needed to execute "SUB" and "CALL"
// @todo this retains too much gas for now, needs to be fine-tuned.
+ u256 gasNeededByCaller = eth::c_callGas + 10;
+ if (_functionType.valueSet())
+ gasNeededByCaller += eth::c_callValueTransferGas;
+ if (!isCallCode)
+ gasNeededByCaller += eth::c_callNewAccountGas; // we never know
m_context <<
- u256(eth::c_callGas + 10 + (_functionType.valueSet() ? eth::c_callValueTransferGas : 0) + eth::c_callNewAccountGas) <<
+ gasNeededByCaller <<
eth::Instruction::GAS <<
eth::Instruction::SUB;
- if (funKind == FunctionKind::CallCode || funKind == FunctionKind::BareCallCode)
+ }
+ if (isCallCode)
m_context << eth::Instruction::CALLCODE;
else
m_context << eth::Instruction::CALL;