From 83fcf007bfdf9c9c8b595369c0542d45943ee095 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 26 Feb 2018 18:25:36 +0100 Subject: Do not retain any gas in external calls (except if EVM version is set to homestead). --- Changelog.md | 1 + libsolidity/codegen/ExpressionCompiler.cpp | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Changelog.md b/Changelog.md index 04a45f7d..529fb181 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ Features: * C99/C++-style scoping rules (instead of JavaScript function scoping) take effect as experimental v0.5.0 feature. * Code Generator: Assert that ``k != 0`` for ``molmod(a, b, k)`` and ``addmod(a, b, k)`` as experimental 0.5.0 feature. + * Code Generator: Do not retain any gas in calls (except if EVM version is set to homestead). * Interface: Provide ability to select target EVM version (homestead or byzantium, with byzantium being the default). * Standard JSON: Reject badly formatted invalid JSON inputs. * Type Checker: Disallow uninitialized storage pointers as experimental 0.5.0 feature. diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 12881d63..441e4429 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1671,16 +1671,19 @@ void ExpressionCompiler::appendExternalFunctionCall( utils().storeFreeMemoryPointer(); } - // Touch the end of the output area so that we do not pay for memory resize during the call - // (which we would have to subtract from the gas left) - // We could also just use MLOAD; POP right before the gas calculation, but the optimizer - // would remove that, so we use MSTORE here. - if (!_functionType.gasSet() && retSize > 0) + if (!m_context.evmVersion().canOverchargeGasForCall()) { - m_context << u256(0); - utils().fetchFreeMemoryPointer(); - // This touches too much, but that way we save some rounding arithmetics - m_context << u256(retSize) << Instruction::ADD << Instruction::MSTORE; + // Touch the end of the output area so that we do not pay for memory resize during the call + // (which we would have to subtract from the gas left) + // We could also just use MLOAD; POP right before the gas calculation, but the optimizer + // would remove that, so we use MSTORE here. + if (!_functionType.gasSet() && retSize > 0) + { + m_context << u256(0); + utils().fetchFreeMemoryPointer(); + // This touches too much, but that way we save some rounding arithmetics + m_context << u256(retSize) << Instruction::ADD << Instruction::MSTORE; + } } // Copy function identifier to memory. @@ -1749,7 +1752,7 @@ void ExpressionCompiler::appendExternalFunctionCall( if (_functionType.gasSet()) m_context << dupInstruction(m_context.baseToCurrentStackOffset(gasStackPos)); - else if (m_context.experimentalFeatureActive(ExperimentalFeature::V050)) + else if (m_context.evmVersion().canOverchargeGasForCall()) // Send all gas (requires tangerine whistle EVM) m_context << Instruction::GAS; else -- cgit