diff options
author | chriseth <c@ethdev.com> | 2015-06-06 06:45:47 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-06 06:45:47 +0800 |
commit | b51ef4a357b4b60fc01038b0e97280fb9ecca01e (patch) | |
tree | 729b53241b687f435209b6f45d3aa3b0faf5dce9 /ExpressionCompiler.cpp | |
parent | 779e793d60f2076fbd35b34f0c2073e92c058eef (diff) | |
parent | 651d755e562dc8b5bc12e42b0b808ff1046f5d43 (diff) | |
download | dexon-solidity-b51ef4a357b4b60fc01038b0e97280fb9ecca01e.tar.gz dexon-solidity-b51ef4a357b4b60fc01038b0e97280fb9ecca01e.tar.zst dexon-solidity-b51ef4a357b4b60fc01038b0e97280fb9ecca01e.zip |
Merge pull request #2096 from chriseth/sol_constantFallback
Fallback takes constant amount of gas, and send no gas with send.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r-- | ExpressionCompiler.cpp | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index 62df9205..bac967d8 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -521,6 +521,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) break; case Location::Send: _functionCall.getExpression().accept(*this); + m_context << u256(0); // do not send gas (there still is the stipend) arguments.front()->accept(*this); appendTypeConversion(*arguments.front()->getType(), *function.getParameterTypes().front(), true); @@ -532,7 +533,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) strings(), Location::Bare, false, - false, + true, true ), {} @@ -1057,10 +1058,15 @@ void ExpressionCompiler::appendExternalFunctionCall( unsigned gasStackPos = m_context.currentToBaseStackOffset(gasValueSize); unsigned valueStackPos = m_context.currentToBaseStackOffset(1); + bool returnSuccessCondition = + _functionType.getLocation() == FunctionType::Location::Bare || + _functionType.getLocation() == FunctionType::Location::BareCallCode; //@todo only return the first return value for now Type const* firstType = _functionType.getReturnParameterTypes().empty() ? nullptr : _functionType.getReturnParameterTypes().front().get(); unsigned retSize = firstType ? firstType->getCalldataEncodedSize() : 0; + if (returnSuccessCondition) + retSize = 0; // return value actually is success condition m_context << u256(retSize) << u256(0); if (_functionType.isBareCall()) @@ -1111,19 +1117,28 @@ void ExpressionCompiler::appendExternalFunctionCall( else m_context << eth::Instruction::CALL; - //Propagate error condition (if CALL pushes 0 on stack). - m_context << eth::Instruction::ISZERO; - m_context.appendConditionalJumpTo(m_context.errorTag()); + unsigned remainsSize = + 1 + // contract address + _functionType.valueSet() + + _functionType.gasSet() + + !_functionType.isBareCall(); - if (_functionType.valueSet()) - m_context << eth::Instruction::POP; - if (_functionType.gasSet()) - m_context << eth::Instruction::POP; - if (!_functionType.isBareCall()) - m_context << eth::Instruction::POP; - m_context << eth::Instruction::POP; // pop contract address + if (returnSuccessCondition) + m_context << eth::swapInstruction(remainsSize); + else + { + //Propagate error condition (if CALL pushes 0 on stack). + m_context << eth::Instruction::ISZERO; + m_context.appendConditionalJumpTo(m_context.errorTag()); + } - if (_functionType.getLocation() == FunctionType::Location::RIPEMD160) + CompilerUtils(m_context).popStackSlots(remainsSize); + + if (returnSuccessCondition) + { + // already there + } + else if (_functionType.getLocation() == FunctionType::Location::RIPEMD160) { // fix: built-in contract returns right-aligned data CompilerUtils(m_context).loadFromMemory(0, IntegerType(160), false, true); |