aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--libevmasm/GasMeter.cpp1
-rw-r--r--libevmasm/Instruction.cpp2
-rw-r--r--libevmasm/Instruction.h1
-rw-r--r--libevmasm/SemanticInformation.cpp3
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp12
6 files changed, 19 insertions, 1 deletions
diff --git a/Changelog.md b/Changelog.md
index 15edb6d5..866cb860 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -90,6 +90,7 @@ Language Features:
Compiler Features:
* C API (``libsolc``): Export the ``solidity_license``, ``solidity_version`` and ``solidity_compile`` methods.
* Code Generator: ``CREATE2`` instruction has been updated to match EIP1014 (aka "Skinny CREATE2"). It also is accepted as part of Constantinople.
+ * Code Generator: ``EXTCODEHASH`` instruction has been added based on EIP1052.
* Type Checker: Nicer error message when trying to reference overloaded identifiers in inline assembly.
* Type Checker: Show named argument in case of error.
* Type System: IntegerType is split into IntegerType and AddressType internally.
diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp
index b40617c1..59afc4da 100644
--- a/libevmasm/GasMeter.cpp
+++ b/libevmasm/GasMeter.cpp
@@ -112,6 +112,7 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-2));
break;
case Instruction::EXTCODESIZE:
+ case Instruction::EXTCODEHASH:
gas = GasCosts::extCodeGas(m_evmVersion);
break;
case Instruction::EXTCODECOPY:
diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp
index d5b82e75..46f6c628 100644
--- a/libevmasm/Instruction.cpp
+++ b/libevmasm/Instruction.cpp
@@ -73,6 +73,7 @@ const std::map<std::string, Instruction> dev::solidity::c_instructions =
{ "EXTCODECOPY", Instruction::EXTCODECOPY },
{ "RETURNDATASIZE", Instruction::RETURNDATASIZE },
{ "RETURNDATACOPY", Instruction::RETURNDATACOPY },
+ { "EXTCODEHASH", Instruction::EXTCODEHASH },
{ "BLOCKHASH", Instruction::BLOCKHASH },
{ "COINBASE", Instruction::COINBASE },
{ "TIMESTAMP", Instruction::TIMESTAMP },
@@ -216,6 +217,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::ExtCode } },
{ Instruction::RETURNDATASIZE, {"RETURNDATASIZE", 0, 0, 1, false, Tier::Base } },
{ Instruction::RETURNDATACOPY, {"RETURNDATACOPY", 0, 3, 0, true, Tier::VeryLow } },
+ { Instruction::EXTCODEHASH, { "EXTCODEHASH", 0, 1, 1, false, Tier::ExtCode } },
{ Instruction::BLOCKHASH, { "BLOCKHASH", 0, 1, 1, false, Tier::Ext } },
{ Instruction::COINBASE, { "COINBASE", 0, 0, 1, false, Tier::Base } },
{ Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1, false, Tier::Base } },
diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h
index 50c1f47d..63424eeb 100644
--- a/libevmasm/Instruction.h
+++ b/libevmasm/Instruction.h
@@ -82,6 +82,7 @@ enum class Instruction: uint8_t
EXTCODECOPY, ///< copy external code (from another contract)
RETURNDATASIZE = 0x3d, ///< get size of return data buffer
RETURNDATACOPY = 0x3e, ///< copy return data in current environment to memory
+ EXTCODEHASH = 0x3f, ///< get external code hash (from another contract)
BLOCKHASH = 0x40, ///< get hash of most recent complete block
COINBASE, ///< get the block's coinbase address
diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp
index 71267ee8..78f3c9c7 100644
--- a/libevmasm/SemanticInformation.cpp
+++ b/libevmasm/SemanticInformation.cpp
@@ -151,6 +151,7 @@ bool SemanticInformation::isDeterministic(AssemblyItem const& _item)
case Instruction::MSIZE: // depends on previous writes and reads, not only on content
case Instruction::BALANCE: // depends on previous calls
case Instruction::EXTCODESIZE:
+ case Instruction::EXTCODEHASH:
case Instruction::RETURNDATACOPY: // depends on previous calls
case Instruction::RETURNDATASIZE:
return false;
@@ -172,6 +173,7 @@ bool SemanticInformation::movable(Instruction _instruction)
case Instruction::KECCAK256:
case Instruction::BALANCE:
case Instruction::EXTCODESIZE:
+ case Instruction::EXTCODEHASH:
case Instruction::RETURNDATASIZE:
case Instruction::SLOAD:
case Instruction::PC:
@@ -233,6 +235,7 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction)
case Instruction::GASPRICE:
case Instruction::EXTCODESIZE:
case Instruction::EXTCODECOPY:
+ case Instruction::EXTCODEHASH:
case Instruction::BLOCKHASH:
case Instruction::COINBASE:
case Instruction::TIMESTAMP:
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp
index 0f2c0f56..947b6d05 100644
--- a/libsolidity/inlineasm/AsmAnalysis.cpp
+++ b/libsolidity/inlineasm/AsmAnalysis.cpp
@@ -568,7 +568,17 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio
// Similarly we assume bitwise shifting and create2 go together.
solAssert(m_evmVersion.hasBitwiseShifting() == m_evmVersion.hasCreate2(), "");
- if ((
+ if (_instr == solidity::Instruction::EXTCODEHASH)
+ m_errorReporter.warning(
+ _location,
+ "The \"" +
+ boost::to_lower_copy(instructionInfo(_instr).name)
+ + "\" instruction is not supported by the VM version \"" +
+ "" + m_evmVersion.name() +
+ "\" you are currently compiling for. " +
+ "It will be interpreted as an invalid instruction on this VM."
+ );
+ else if ((
_instr == solidity::Instruction::RETURNDATACOPY ||
_instr == solidity::Instruction::RETURNDATASIZE ||
_instr == solidity::Instruction::STATICCALL