mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into breaking
This commit is contained in:
@@ -167,6 +167,17 @@ void AsmAnalyzer::operator()(Assignment const& _assignment)
|
||||
size_t const numVariables = _assignment.variableNames.size();
|
||||
yulAssert(numVariables >= 1, "");
|
||||
|
||||
set<YulString> variables;
|
||||
for (auto const& _variableName: _assignment.variableNames)
|
||||
if (!variables.insert(_variableName.name).second)
|
||||
m_errorReporter.declarationError(
|
||||
9005_error,
|
||||
_assignment.location,
|
||||
"Variable " +
|
||||
_variableName.name.str() +
|
||||
" occurs multiple times on the left-hand side of the assignment."
|
||||
);
|
||||
|
||||
vector<YulString> types = std::visit(*this, *_assignment.value);
|
||||
|
||||
if (types.size() != numVariables)
|
||||
|
||||
@@ -297,20 +297,6 @@ Expression Parser::parseExpression()
|
||||
}
|
||||
}
|
||||
|
||||
std::map<evmasm::Instruction, string> const& Parser::instructionNames()
|
||||
{
|
||||
static map<evmasm::Instruction, string> s_instructionNames;
|
||||
if (s_instructionNames.empty())
|
||||
{
|
||||
for (auto const& instr: instructions())
|
||||
s_instructionNames[instr.second] = instr.first;
|
||||
// set the ambiguous instructions to a clear default
|
||||
s_instructionNames[evmasm::Instruction::SELFDESTRUCT] = "selfdestruct";
|
||||
s_instructionNames[evmasm::Instruction::KECCAK256] = "keccak256";
|
||||
}
|
||||
return s_instructionNames;
|
||||
}
|
||||
|
||||
Parser::ElementaryOperation Parser::parseElementaryOperation()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
|
||||
@@ -86,7 +86,6 @@ protected:
|
||||
ForLoop parseForLoop();
|
||||
/// Parses a functional expression that has to push exactly one stack element
|
||||
Expression parseExpression();
|
||||
static std::map<evmasm::Instruction, std::string> const& instructionNames();
|
||||
/// Parses an elementary operation, i.e. a literal, identifier, instruction or
|
||||
/// builtin functian call (only the name).
|
||||
ElementaryOperation parseElementaryOperation();
|
||||
|
||||
@@ -50,6 +50,7 @@ class AbstractAssembly
|
||||
public:
|
||||
using LabelID = size_t;
|
||||
using SubID = size_t;
|
||||
enum class JumpType { Ordinary, IntoFunction, OutOfFunction };
|
||||
|
||||
virtual ~AbstractAssembly() = default;
|
||||
|
||||
@@ -78,13 +79,13 @@ public:
|
||||
/// Append a jump instruction.
|
||||
/// @param _stackDiffAfter the stack adjustment after this instruction.
|
||||
/// This is helpful to stack height analysis if there is no continuing control flow.
|
||||
virtual void appendJump(int _stackDiffAfter) = 0;
|
||||
virtual void appendJump(int _stackDiffAfter, JumpType _jumpType = JumpType::Ordinary) = 0;
|
||||
|
||||
/// Append a jump-to-immediate operation.
|
||||
/// @param _stackDiffAfter the stack adjustment after this instruction.
|
||||
virtual void appendJumpTo(LabelID _labelId, int _stackDiffAfter = 0) = 0;
|
||||
virtual void appendJumpTo(LabelID _labelId, int _stackDiffAfter = 0, JumpType _jumpType = JumpType::Ordinary) = 0;
|
||||
/// Append a jump-to-if-immediate operation.
|
||||
virtual void appendJumpToIf(LabelID _labelId) = 0;
|
||||
virtual void appendJumpToIf(LabelID _labelId, JumpType _jumpType = JumpType::Ordinary) = 0;
|
||||
/// Start a subroutine identified by @a _labelId that takes @a _arguments
|
||||
/// stack slots as arguments.
|
||||
virtual void appendBeginsub(LabelID _labelId, int _arguments) = 0;
|
||||
|
||||
@@ -98,22 +98,22 @@ void EthAssemblyAdapter::appendLinkerSymbol(std::string const& _linkerSymbol)
|
||||
m_assembly.appendLibraryAddress(_linkerSymbol);
|
||||
}
|
||||
|
||||
void EthAssemblyAdapter::appendJump(int _stackDiffAfter)
|
||||
void EthAssemblyAdapter::appendJump(int _stackDiffAfter, JumpType _jumpType)
|
||||
{
|
||||
appendInstruction(evmasm::Instruction::JUMP);
|
||||
appendJumpInstruction(evmasm::Instruction::JUMP, _jumpType);
|
||||
m_assembly.adjustDeposit(_stackDiffAfter);
|
||||
}
|
||||
|
||||
void EthAssemblyAdapter::appendJumpTo(LabelID _labelId, int _stackDiffAfter)
|
||||
void EthAssemblyAdapter::appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType)
|
||||
{
|
||||
appendLabelReference(_labelId);
|
||||
appendJump(_stackDiffAfter);
|
||||
appendJump(_stackDiffAfter, _jumpType);
|
||||
}
|
||||
|
||||
void EthAssemblyAdapter::appendJumpToIf(LabelID _labelId)
|
||||
void EthAssemblyAdapter::appendJumpToIf(LabelID _labelId, JumpType _jumpType)
|
||||
{
|
||||
appendLabelReference(_labelId);
|
||||
appendInstruction(evmasm::Instruction::JUMPI);
|
||||
appendJumpInstruction(evmasm::Instruction::JUMPI, _jumpType);
|
||||
}
|
||||
|
||||
void EthAssemblyAdapter::appendBeginsub(LabelID, int)
|
||||
@@ -189,6 +189,25 @@ EthAssemblyAdapter::LabelID EthAssemblyAdapter::assemblyTagToIdentifier(evmasm::
|
||||
return LabelID(id);
|
||||
}
|
||||
|
||||
void EthAssemblyAdapter::appendJumpInstruction(evmasm::Instruction _instruction, JumpType _jumpType)
|
||||
{
|
||||
yulAssert(_instruction == evmasm::Instruction::JUMP || _instruction == evmasm::Instruction::JUMPI, "");
|
||||
evmasm::AssemblyItem jump(_instruction);
|
||||
switch (_jumpType)
|
||||
{
|
||||
case JumpType::Ordinary:
|
||||
yulAssert(jump.getJumpType() == evmasm::AssemblyItem::JumpType::Ordinary, "");
|
||||
break;
|
||||
case JumpType::IntoFunction:
|
||||
jump.setJumpType(evmasm::AssemblyItem::JumpType::IntoFunction);
|
||||
break;
|
||||
case JumpType::OutOfFunction:
|
||||
jump.setJumpType(evmasm::AssemblyItem::JumpType::OutOfFunction);
|
||||
break;
|
||||
}
|
||||
m_assembly.append(std::move(jump));
|
||||
}
|
||||
|
||||
void CodeGenerator::assemble(
|
||||
Block const& _parsedData,
|
||||
AsmAnalysisInfo& _analysisInfo,
|
||||
|
||||
@@ -49,9 +49,9 @@ public:
|
||||
size_t newLabelId() override;
|
||||
size_t namedLabel(std::string const& _name) override;
|
||||
void appendLinkerSymbol(std::string const& _linkerSymbol) override;
|
||||
void appendJump(int _stackDiffAfter) override;
|
||||
void appendJumpTo(LabelID _labelId, int _stackDiffAfter) override;
|
||||
void appendJumpToIf(LabelID _labelId) override;
|
||||
void appendJump(int _stackDiffAfter, JumpType _jumpType) override;
|
||||
void appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType) override;
|
||||
void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;
|
||||
void appendBeginsub(LabelID, int) override;
|
||||
void appendJumpsub(LabelID, int, int) override;
|
||||
void appendReturnsub(int, int) override;
|
||||
@@ -66,6 +66,7 @@ public:
|
||||
|
||||
private:
|
||||
static LabelID assemblyTagToIdentifier(evmasm::AssemblyItem const& _tag);
|
||||
void appendJumpInstruction(evmasm::Instruction _instruction, JumpType _jumpType);
|
||||
|
||||
evmasm::Assembly& m_assembly;
|
||||
std::map<SubID, u256> m_dataHashBySubId;
|
||||
|
||||
@@ -91,14 +91,14 @@ void EVMAssembly::appendLinkerSymbol(string const&)
|
||||
yulAssert(false, "Linker symbols not yet implemented.");
|
||||
}
|
||||
|
||||
void EVMAssembly::appendJump(int _stackDiffAfter)
|
||||
void EVMAssembly::appendJump(int _stackDiffAfter, JumpType)
|
||||
{
|
||||
yulAssert(!m_evm15, "Plain JUMP used for EVM 1.5");
|
||||
appendInstruction(evmasm::Instruction::JUMP);
|
||||
m_stackHeight += _stackDiffAfter;
|
||||
}
|
||||
|
||||
void EVMAssembly::appendJumpTo(LabelID _labelId, int _stackDiffAfter)
|
||||
void EVMAssembly::appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType)
|
||||
{
|
||||
if (m_evm15)
|
||||
{
|
||||
@@ -109,11 +109,11 @@ void EVMAssembly::appendJumpTo(LabelID _labelId, int _stackDiffAfter)
|
||||
else
|
||||
{
|
||||
appendLabelReference(_labelId);
|
||||
appendJump(_stackDiffAfter);
|
||||
appendJump(_stackDiffAfter, _jumpType);
|
||||
}
|
||||
}
|
||||
|
||||
void EVMAssembly::appendJumpToIf(LabelID _labelId)
|
||||
void EVMAssembly::appendJumpToIf(LabelID _labelId, JumpType)
|
||||
{
|
||||
if (m_evm15)
|
||||
{
|
||||
|
||||
@@ -64,11 +64,11 @@ public:
|
||||
|
||||
/// Append a jump instruction.
|
||||
/// @param _stackDiffAfter the stack adjustment after this instruction.
|
||||
void appendJump(int _stackDiffAfter) override;
|
||||
void appendJump(int _stackDiffAfter, JumpType _jumpType) override;
|
||||
/// Append a jump-to-immediate operation.
|
||||
void appendJumpTo(LabelID _labelId, int _stackDiffAfter) override;
|
||||
void appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType) override;
|
||||
/// Append a jump-to-if-immediate operation.
|
||||
void appendJumpToIf(LabelID _labelId) override;
|
||||
void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;
|
||||
/// Start a subroutine.
|
||||
void appendBeginsub(LabelID _labelId, int _arguments) override;
|
||||
/// Call a subroutine.
|
||||
|
||||
@@ -291,7 +291,8 @@ void CodeTransform::operator()(FunctionCall const& _call)
|
||||
{
|
||||
m_assembly.appendJumpTo(
|
||||
functionEntryID(_call.functionName.name, *function),
|
||||
static_cast<int>(function->returns.size() - function->arguments.size()) - 1
|
||||
static_cast<int>(function->returns.size() - function->arguments.size()) - 1,
|
||||
AbstractAssembly::JumpType::IntoFunction
|
||||
);
|
||||
m_assembly.appendLabel(returnLabel);
|
||||
}
|
||||
@@ -511,7 +512,10 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
|
||||
if (m_evm15)
|
||||
m_assembly.appendReturnsub(static_cast<int>(_function.returnVariables.size()), stackHeightBefore);
|
||||
else
|
||||
m_assembly.appendJump(stackHeightBefore - static_cast<int>(_function.returnVariables.size()));
|
||||
m_assembly.appendJump(
|
||||
stackHeightBefore - static_cast<int>(_function.returnVariables.size()),
|
||||
AbstractAssembly::JumpType::OutOfFunction
|
||||
);
|
||||
m_assembly.setStackHeight(stackHeightBefore);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,25 +70,25 @@ void NoOutputAssembly::appendLinkerSymbol(string const&)
|
||||
yulAssert(false, "Linker symbols not yet implemented.");
|
||||
}
|
||||
|
||||
void NoOutputAssembly::appendJump(int _stackDiffAfter)
|
||||
void NoOutputAssembly::appendJump(int _stackDiffAfter, JumpType)
|
||||
{
|
||||
yulAssert(!m_evm15, "Plain JUMP used for EVM 1.5");
|
||||
appendInstruction(evmasm::Instruction::JUMP);
|
||||
m_stackHeight += _stackDiffAfter;
|
||||
}
|
||||
|
||||
void NoOutputAssembly::appendJumpTo(LabelID _labelId, int _stackDiffAfter)
|
||||
void NoOutputAssembly::appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType)
|
||||
{
|
||||
if (m_evm15)
|
||||
m_stackHeight += _stackDiffAfter;
|
||||
else
|
||||
{
|
||||
appendLabelReference(_labelId);
|
||||
appendJump(_stackDiffAfter);
|
||||
appendJump(_stackDiffAfter, _jumpType);
|
||||
}
|
||||
}
|
||||
|
||||
void NoOutputAssembly::appendJumpToIf(LabelID _labelId)
|
||||
void NoOutputAssembly::appendJumpToIf(LabelID _labelId, JumpType)
|
||||
{
|
||||
if (m_evm15)
|
||||
m_stackHeight--;
|
||||
|
||||
@@ -58,9 +58,9 @@ public:
|
||||
LabelID namedLabel(std::string const& _name) override;
|
||||
void appendLinkerSymbol(std::string const& _name) override;
|
||||
|
||||
void appendJump(int _stackDiffAfter) override;
|
||||
void appendJumpTo(LabelID _labelId, int _stackDiffAfter) override;
|
||||
void appendJumpToIf(LabelID _labelId) override;
|
||||
void appendJump(int _stackDiffAfter, JumpType _jumpType) override;
|
||||
void appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType) override;
|
||||
void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;
|
||||
void appendBeginsub(LabelID _labelId, int _arguments) override;
|
||||
void appendJumpsub(LabelID _labelId, int _arguments, int _returns) override;
|
||||
void appendReturnsub(int _returns, int _stackDiffAfter) override;
|
||||
|
||||
Reference in New Issue
Block a user