mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
More flexible access to stack during external function call.
This commit is contained in:
parent
d1e05ac416
commit
1ba38c9c02
@ -95,6 +95,11 @@ unsigned CompilerContext::baseToCurrentStackOffset(unsigned _baseOffset) const
|
||||
return _baseOffset + m_asm.deposit();
|
||||
}
|
||||
|
||||
unsigned CompilerContext::currentToBaseStackOffset(unsigned _offset) const
|
||||
{
|
||||
return -baseToCurrentStackOffset(-_offset);
|
||||
}
|
||||
|
||||
u256 CompilerContext::getStorageLocationOfVariable(const Declaration& _declaration) const
|
||||
{
|
||||
auto it = m_stateVariables.find(&_declaration);
|
||||
|
@ -62,6 +62,9 @@ public:
|
||||
/// If supplied by a value returned by @ref getBaseStackOffsetOfVariable(variable), returns
|
||||
/// the distance of that variable from the current top of the stack.
|
||||
unsigned baseToCurrentStackOffset(unsigned _baseOffset) const;
|
||||
/// Converts an offset relative to the current stack height to a value that can be used later
|
||||
/// with baseToCurrentStackOffset to point to the same stack element.
|
||||
unsigned currentToBaseStackOffset(unsigned _offset) const;
|
||||
u256 getStorageLocationOfVariable(Declaration const& _declaration) const;
|
||||
|
||||
/// Appends a JUMPI instruction to a new tag and @returns the tag
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user