aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-09-26 21:27:03 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2018-03-06 22:30:18 +0800
commitb467116ea85383d5c8492e7f21ea16ce7c70ebc9 (patch)
treeb0bd8c7482d2f8c7b3716b11830990bd8a6fa110
parent0df4c64884d1b8d3695dd59de5f828ba5298b313 (diff)
downloaddexon-solidity-b467116ea85383d5c8492e7f21ea16ce7c70ebc9.tar
dexon-solidity-b467116ea85383d5c8492e7f21ea16ce7c70ebc9.tar.gz
dexon-solidity-b467116ea85383d5c8492e7f21ea16ce7c70ebc9.tar.bz2
dexon-solidity-b467116ea85383d5c8492e7f21ea16ce7c70ebc9.tar.lz
dexon-solidity-b467116ea85383d5c8492e7f21ea16ce7c70ebc9.tar.xz
dexon-solidity-b467116ea85383d5c8492e7f21ea16ce7c70ebc9.tar.zst
dexon-solidity-b467116ea85383d5c8492e7f21ea16ce7c70ebc9.zip
Use STATICCALL for pure function calls if EVM version supports it and 0.5.0 is activated.
-rw-r--r--Changelog.md3
-rw-r--r--libsolidity/ast/ExperimentalFeatures.h4
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp9
3 files changed, 13 insertions, 3 deletions
diff --git a/Changelog.md b/Changelog.md
index bea9dd5b..4a9f7ff4 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,8 +2,9 @@
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: Assert that ``k != 0`` for ``mulmod(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).
+ * Code Generator: Use ``STATICCALL`` opcode for calling ``view`` and ``pure`` functions as experimenal 0.5.0 feature.
* 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/ast/ExperimentalFeatures.h b/libsolidity/ast/ExperimentalFeatures.h
index a17778b4..30ea7ec5 100644
--- a/libsolidity/ast/ExperimentalFeatures.h
+++ b/libsolidity/ast/ExperimentalFeatures.h
@@ -29,8 +29,8 @@ namespace solidity
enum class ExperimentalFeature
{
- SMTChecker,
ABIEncoderV2, // new ABI encoder that makes use of JULIA
+ SMTChecker,
V050, // v0.5.0 breaking changes
Test,
TestOnlyAnalysis
@@ -45,8 +45,8 @@ static const std::map<ExperimentalFeature, bool> ExperimentalFeatureOnlyAnalysis
static const std::map<std::string, ExperimentalFeature> ExperimentalFeatureNames =
{
- { "SMTChecker", ExperimentalFeature::SMTChecker },
{ "ABIEncoderV2", ExperimentalFeature::ABIEncoderV2 },
+ { "SMTChecker", ExperimentalFeature::SMTChecker },
{ "v0.5.0", ExperimentalFeature::V050 },
{ "__test", ExperimentalFeature::Test },
{ "__testOnlyAnalysis", ExperimentalFeature::TestOnlyAnalysis },
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index d27af7db..7162cb0d 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -1610,6 +1610,10 @@ void ExpressionCompiler::appendExternalFunctionCall(
bool returnSuccessCondition = funKind == FunctionType::Kind::BareCall || funKind == FunctionType::Kind::BareCallCode || funKind == FunctionType::Kind::BareDelegateCall;
bool isCallCode = funKind == FunctionType::Kind::BareCallCode || funKind == FunctionType::Kind::CallCode;
bool isDelegateCall = funKind == FunctionType::Kind::BareDelegateCall || funKind == FunctionType::Kind::DelegateCall;
+ bool useStaticCall =
+ _functionType.stateMutability() <= StateMutability::View &&
+ m_context.experimentalFeatureActive(ExperimentalFeature::V050) &&
+ m_context.evmVersion().hasStaticCall();
unsigned retSize = 0;
if (returnSuccessCondition)
@@ -1738,6 +1742,8 @@ void ExpressionCompiler::appendExternalFunctionCall(
// [value,] addr, gas (stack top)
if (isDelegateCall)
solAssert(!_functionType.valueSet(), "Value set for delegatecall");
+ else if (useStaticCall)
+ solAssert(!_functionType.valueSet(), "Value set for staticcall");
else if (_functionType.valueSet())
m_context << dupInstruction(m_context.baseToCurrentStackOffset(valueStackPos));
else
@@ -1769,10 +1775,13 @@ void ExpressionCompiler::appendExternalFunctionCall(
gasNeededByCaller += eth::GasCosts::callNewAccountGas; // we never know
m_context << gasNeededByCaller << Instruction::GAS << Instruction::SUB;
}
+ // Order is important here, STATICCALL might overlap with DELEGATECALL.
if (isDelegateCall)
m_context << Instruction::DELEGATECALL;
else if (isCallCode)
m_context << Instruction::CALLCODE;
+ else if (useStaticCall)
+ m_context << Instruction::STATICCALL;
else
m_context << Instruction::CALL;