diff options
author | Christian <c@ethdev.com> | 2015-01-14 18:57:22 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2015-01-14 18:57:22 +0800 |
commit | 1ba38c9c0266ef3bf2229a18dc1953c0a954e182 (patch) | |
tree | 88a1150adc400f16576b4a2407e66f11d701e862 /ExpressionCompiler.cpp | |
parent | d1e05ac416c68d65112e9dd1427b8b009802afef (diff) | |
download | dexon-solidity-1ba38c9c0266ef3bf2229a18dc1953c0a954e182.tar.gz dexon-solidity-1ba38c9c0266ef3bf2229a18dc1953c0a954e182.tar.zst dexon-solidity-1ba38c9c0266ef3bf2229a18dc1953c0a954e182.zip |
More flexible access to stack during external function call.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r-- | ExpressionCompiler.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index 93645187..5c81b7c2 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -669,17 +669,24 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio // <stack top> // value [if _functionType.valueSet()] // gas [if _functionType.gasSet()] - // function identifier [unless options.bare] + // function identifier [unless bare] // contract address unsigned gasValueSize = (_functionType.gasSet() ? 1 : 0) + (_functionType.valueSet() ? 1 : 0); + + unsigned contractStackPos = m_context.currentToBaseStackOffset(1 + gasValueSize + (bare ? 0 : 1)); + unsigned gasStackPos = m_context.currentToBaseStackOffset(gasValueSize); + unsigned valueStackPos = m_context.currentToBaseStackOffset(1); + if (!bare) { + // copy function identifier m_context << eth::dupInstruction(gasValueSize + 1); CompilerUtils(m_context).storeInMemory(0, CompilerUtils::dataStartOffset); } - unsigned dataOffset = bare ? 0 : CompilerUtils::dataStartOffset; // reserve 4 bytes for the function's hash identifier + // reserve space for the function identifier + unsigned dataOffset = bare ? 0 : CompilerUtils::dataStartOffset; dataOffset += appendArgumentCopyToMemory(_functionType.getParameterTypes(), _arguments, dataOffset); //@todo only return the first return value for now @@ -689,13 +696,13 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio // CALL arguments: outSize, outOff, inSize, inOff, value, addr, gas (stack top) m_context << u256(retSize) << u256(0) << u256(dataOffset) << u256(0); if (_functionType.valueSet()) - m_context << eth::dupInstruction(5); + m_context << eth::dupInstruction(m_context.baseToCurrentStackOffset(valueStackPos)); else m_context << u256(0); - m_context << eth::dupInstruction(6 + gasValueSize + (bare ? 0 : 1)); //copy contract address + m_context << eth::dupInstruction(m_context.baseToCurrentStackOffset(contractStackPos)); if (_functionType.gasSet()) - m_context << eth::dupInstruction(7 + (_functionType.valueSet() ? 1 : 0)); + m_context << eth::dupInstruction(m_context.baseToCurrentStackOffset(gasStackPos)); else // send all gas except for the 21 needed to execute "SUB" and "CALL" m_context << u256(21) << eth::Instruction::GAS << eth::Instruction::SUB; |