mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Split Instruction and FunctionalInstruction in Julia
This commit is contained in:
parent
a08d853bbb
commit
745eefa36f
@ -125,11 +125,11 @@ void CodeTransform::operator()(FunctionCall const& _call)
|
|||||||
void CodeTransform::operator()(FunctionalInstruction const& _instruction)
|
void CodeTransform::operator()(FunctionalInstruction const& _instruction)
|
||||||
{
|
{
|
||||||
if (m_evm15 && (
|
if (m_evm15 && (
|
||||||
_instruction.instruction.instruction == solidity::Instruction::JUMP ||
|
_instruction.instruction == solidity::Instruction::JUMP ||
|
||||||
_instruction.instruction.instruction == solidity::Instruction::JUMPI
|
_instruction.instruction == solidity::Instruction::JUMPI
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
bool const isJumpI = _instruction.instruction.instruction == solidity::Instruction::JUMPI;
|
bool const isJumpI = _instruction.instruction == solidity::Instruction::JUMPI;
|
||||||
if (isJumpI)
|
if (isJumpI)
|
||||||
{
|
{
|
||||||
solAssert(_instruction.arguments.size() == 2, "");
|
solAssert(_instruction.arguments.size() == 2, "");
|
||||||
@ -150,7 +150,8 @@ void CodeTransform::operator()(FunctionalInstruction const& _instruction)
|
|||||||
{
|
{
|
||||||
for (auto const& arg: _instruction.arguments | boost::adaptors::reversed)
|
for (auto const& arg: _instruction.arguments | boost::adaptors::reversed)
|
||||||
visitExpression(arg);
|
visitExpression(arg);
|
||||||
(*this)(_instruction.instruction);
|
m_assembly.setSourceLocation(_instruction.location);
|
||||||
|
m_assembly.appendInstruction(_instruction.instruction);
|
||||||
}
|
}
|
||||||
checkStackHeight(&_instruction);
|
checkStackHeight(&_instruction);
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,10 @@ using namespace dev;
|
|||||||
using namespace dev::julia;
|
using namespace dev::julia;
|
||||||
|
|
||||||
|
|
||||||
Statement ASTCopier::operator()(Instruction const& _instruction)
|
Statement ASTCopier::operator()(Instruction const&)
|
||||||
{
|
{
|
||||||
return _instruction;
|
solAssert(false, "Invalid operation.");
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement ASTCopier::operator()(VariableDeclaration const& _varDecl)
|
Statement ASTCopier::operator()(VariableDeclaration const& _varDecl)
|
||||||
|
@ -40,16 +40,13 @@ public:
|
|||||||
void operator()(assembly::Label const&) { }
|
void operator()(assembly::Label const&) { }
|
||||||
void operator()(assembly::Instruction const& _instruction)
|
void operator()(assembly::Instruction const& _instruction)
|
||||||
{
|
{
|
||||||
if (eth::SemanticInformation::invalidInViewFunctions(_instruction.instruction))
|
checkInstruction(_instruction.location, _instruction.instruction);
|
||||||
m_reportMutability(StateMutability::NonPayable, _instruction.location);
|
|
||||||
else if (eth::SemanticInformation::invalidInPureFunctions(_instruction.instruction))
|
|
||||||
m_reportMutability(StateMutability::View, _instruction.location);
|
|
||||||
}
|
}
|
||||||
void operator()(assembly::Literal const&) {}
|
void operator()(assembly::Literal const&) {}
|
||||||
void operator()(assembly::Identifier const&) {}
|
void operator()(assembly::Identifier const&) {}
|
||||||
void operator()(assembly::FunctionalInstruction const& _instr)
|
void operator()(assembly::FunctionalInstruction const& _instr)
|
||||||
{
|
{
|
||||||
(*this)(_instr.instruction);
|
checkInstruction(_instr.location, _instr.instruction);
|
||||||
for (auto const& arg: _instr.arguments)
|
for (auto const& arg: _instr.arguments)
|
||||||
boost::apply_visitor(*this, arg);
|
boost::apply_visitor(*this, arg);
|
||||||
}
|
}
|
||||||
@ -102,6 +99,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void(StateMutability, SourceLocation const&)> m_reportMutability;
|
std::function<void(StateMutability, SourceLocation const&)> m_reportMutability;
|
||||||
|
void checkInstruction(SourceLocation _location, solidity::Instruction _instruction)
|
||||||
|
{
|
||||||
|
if (eth::SemanticInformation::invalidInViewFunctions(_instruction))
|
||||||
|
m_reportMutability(StateMutability::NonPayable, _location);
|
||||||
|
else if (eth::SemanticInformation::invalidInPureFunctions(_instruction))
|
||||||
|
m_reportMutability(StateMutability::View, _location);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -146,10 +146,11 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr)
|
|||||||
if (!expectExpression(arg))
|
if (!expectExpression(arg))
|
||||||
success = false;
|
success = false;
|
||||||
// Parser already checks that the number of arguments is correct.
|
// Parser already checks that the number of arguments is correct.
|
||||||
solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), "");
|
auto const& info = instructionInfo(_instr.instruction);
|
||||||
if (!(*this)(_instr.instruction))
|
solAssert(info.args == int(_instr.arguments.size()), "");
|
||||||
success = false;
|
m_stackHeight += info.ret - info.args;
|
||||||
m_info.stackHeightInfo[&_instr] = m_stackHeight;
|
m_info.stackHeightInfo[&_instr] = m_stackHeight;
|
||||||
|
warnOnInstructions(_instr.instruction, _instr.location);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ struct StackAssignment { SourceLocation location; Identifier variableName; };
|
|||||||
/// the same amount of items as the number of variables.
|
/// the same amount of items as the number of variables.
|
||||||
struct Assignment { SourceLocation location; std::vector<Identifier> variableNames; std::shared_ptr<Statement> value; };
|
struct Assignment { SourceLocation location; std::vector<Identifier> variableNames; std::shared_ptr<Statement> value; };
|
||||||
/// Functional instruction, e.g. "mul(mload(20:u256), add(2:u256, x))"
|
/// Functional instruction, e.g. "mul(mload(20:u256), add(2:u256, x))"
|
||||||
struct FunctionalInstruction { SourceLocation location; Instruction instruction; std::vector<Statement> arguments; };
|
struct FunctionalInstruction { SourceLocation location; solidity::Instruction instruction; std::vector<Statement> arguments; };
|
||||||
struct FunctionCall { SourceLocation location; Identifier functionName; std::vector<Statement> arguments; };
|
struct FunctionCall { SourceLocation location; Identifier functionName; std::vector<Statement> arguments; };
|
||||||
/// Block-scope variable declaration ("let x:u256 := mload(20:u256)"), non-hoisted
|
/// Block-scope variable declaration ("let x:u256 := mload(20:u256)"), non-hoisted
|
||||||
struct VariableDeclaration { SourceLocation location; TypedNameList variables; std::shared_ptr<Statement> value; };
|
struct VariableDeclaration { SourceLocation location; TypedNameList variables; std::shared_ptr<Statement> value; };
|
||||||
|
@ -448,10 +448,11 @@ assembly::Statement Parser::parseCall(assembly::Statement&& _instruction)
|
|||||||
if (_instruction.type() == typeid(Instruction))
|
if (_instruction.type() == typeid(Instruction))
|
||||||
{
|
{
|
||||||
solAssert(!m_julia, "Instructions are invalid in JULIA");
|
solAssert(!m_julia, "Instructions are invalid in JULIA");
|
||||||
|
Instruction const& instruction = std::move(boost::get<Instruction>(_instruction));
|
||||||
FunctionalInstruction ret;
|
FunctionalInstruction ret;
|
||||||
ret.instruction = std::move(boost::get<Instruction>(_instruction));
|
ret.instruction = instruction.instruction;
|
||||||
ret.location = ret.instruction.location;
|
ret.location = std::move(instruction.location);
|
||||||
solidity::Instruction instr = ret.instruction.instruction;
|
solidity::Instruction instr = ret.instruction;
|
||||||
InstructionInfo instrInfo = instructionInfo(instr);
|
InstructionInfo instrInfo = instructionInfo(instr);
|
||||||
if (solidity::isDupInstruction(instr))
|
if (solidity::isDupInstruction(instr))
|
||||||
fatalParserError("DUPi instructions not allowed for functional notation");
|
fatalParserError("DUPi instructions not allowed for functional notation");
|
||||||
|
@ -94,7 +94,7 @@ string AsmPrinter::operator()(assembly::FunctionalInstruction const& _functional
|
|||||||
{
|
{
|
||||||
solAssert(!m_julia, "");
|
solAssert(!m_julia, "");
|
||||||
return
|
return
|
||||||
(*this)(_functionalInstruction.instruction) +
|
boost::to_lower_copy(instructionInfo(_functionalInstruction.instruction).name) +
|
||||||
"(" +
|
"(" +
|
||||||
boost::algorithm::join(
|
boost::algorithm::join(
|
||||||
_functionalInstruction.arguments | boost::adaptors::transformed(boost::apply_visitor(*this)),
|
_functionalInstruction.arguments | boost::adaptors::transformed(boost::apply_visitor(*this)),
|
||||||
|
Loading…
Reference in New Issue
Block a user