mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Slightly cleaner label ids.
This commit is contained in:
parent
c85f9257f8
commit
41236cd08c
@ -36,15 +36,14 @@ using namespace dev::solidity;
|
|||||||
using namespace dev::solidity::assembly;
|
using namespace dev::solidity::assembly;
|
||||||
|
|
||||||
|
|
||||||
bool Scope::registerLabel(string const& _name, size_t _id)
|
bool Scope::registerLabel(string const& _name)
|
||||||
{
|
{
|
||||||
if (exists(_name))
|
if (exists(_name))
|
||||||
return false;
|
return false;
|
||||||
identifiers[_name] = Scope::Label(_id);
|
identifiers[_name] = Label();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Scope::registerVariable(string const& _name)
|
bool Scope::registerVariable(string const& _name)
|
||||||
{
|
{
|
||||||
if (exists(_name))
|
if (exists(_name))
|
||||||
@ -86,7 +85,9 @@ AsmAnalyzer::AsmAnalyzer(AsmAnalyzer::Scopes& _scopes, ErrorList& _errors):
|
|||||||
{
|
{
|
||||||
// Make the Solidity ErrorTag available to inline assembly
|
// Make the Solidity ErrorTag available to inline assembly
|
||||||
m_scopes[nullptr] = make_shared<Scope>();
|
m_scopes[nullptr] = make_shared<Scope>();
|
||||||
m_scopes[nullptr]->identifiers["invalidJumpLabel"] = Scope::Label(Scope::Label::errorLabelId);
|
Scope::Label errorLabel;
|
||||||
|
errorLabel.id = Scope::Label::errorLabelId;
|
||||||
|
m_scopes[nullptr]->identifiers["invalidJumpLabel"] = errorLabel;
|
||||||
m_currentScope = m_scopes[nullptr].get();
|
m_currentScope = m_scopes[nullptr].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +117,7 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr)
|
|||||||
|
|
||||||
bool AsmAnalyzer::operator()(Label const& _item)
|
bool AsmAnalyzer::operator()(Label const& _item)
|
||||||
{
|
{
|
||||||
if (!m_currentScope->registerLabel(_item.name, Scope::Label::unassignedLabelId))
|
if (!m_currentScope->registerLabel(_item.name))
|
||||||
{
|
{
|
||||||
//@TODO secondary location
|
//@TODO secondary location
|
||||||
m_errors.push_back(make_shared<Error>(
|
m_errors.push_back(make_shared<Error>(
|
||||||
|
@ -81,8 +81,7 @@ struct Scope
|
|||||||
|
|
||||||
struct Label
|
struct Label
|
||||||
{
|
{
|
||||||
Label(size_t _id): id(_id) {}
|
size_t id = unassignedLabelId;
|
||||||
size_t id = 0;
|
|
||||||
int stackAdjustment = 0;
|
int stackAdjustment = 0;
|
||||||
bool resetStackHeight = false;
|
bool resetStackHeight = false;
|
||||||
static const size_t errorLabelId = -1;
|
static const size_t errorLabelId = -1;
|
||||||
@ -101,7 +100,7 @@ struct Scope
|
|||||||
using NonconstVisitor = GenericVisitor<Variable, Label, Function>;
|
using NonconstVisitor = GenericVisitor<Variable, Label, Function>;
|
||||||
|
|
||||||
bool registerVariable(std::string const& _name);
|
bool registerVariable(std::string const& _name);
|
||||||
bool registerLabel(std::string const& _name, size_t _id);
|
bool registerLabel(std::string const& _name);
|
||||||
bool registerFunction(std::string const& _name, size_t _arguments, size_t _returns);
|
bool registerFunction(std::string const& _name, size_t _arguments, size_t _returns);
|
||||||
|
|
||||||
/// Looks up the identifier in this or super scopes (stops and function and assembly boundaries)
|
/// Looks up the identifier in this or super scopes (stops and function and assembly boundaries)
|
||||||
|
@ -148,10 +148,7 @@ public:
|
|||||||
},
|
},
|
||||||
[=](Scope::Label& _label)
|
[=](Scope::Label& _label)
|
||||||
{
|
{
|
||||||
if (_label.id == Scope::Label::unassignedLabelId)
|
assignLabelIdIfUnset(_label);
|
||||||
_label.id = m_state.newLabelId();
|
|
||||||
else if (_label.id == Scope::Label::errorLabelId)
|
|
||||||
_label.id = size_t(m_state.assembly.errorTag().data());
|
|
||||||
m_state.assembly.append(eth::AssemblyItem(eth::PushTag, _label.id));
|
m_state.assembly.append(eth::AssemblyItem(eth::PushTag, _label.id));
|
||||||
},
|
},
|
||||||
[=](Scope::Function&)
|
[=](Scope::Function&)
|
||||||
@ -190,10 +187,7 @@ public:
|
|||||||
m_state.assembly.setSourceLocation(_label.location);
|
m_state.assembly.setSourceLocation(_label.location);
|
||||||
solAssert(m_scope.identifiers.count(_label.name), "");
|
solAssert(m_scope.identifiers.count(_label.name), "");
|
||||||
Scope::Label& label = boost::get<Scope::Label>(m_scope.identifiers[_label.name]);
|
Scope::Label& label = boost::get<Scope::Label>(m_scope.identifiers[_label.name]);
|
||||||
if (label.id == Scope::Label::unassignedLabelId)
|
assignLabelIdIfUnset(label);
|
||||||
label.id = m_state.newLabelId();
|
|
||||||
else if (label.id == Scope::Label::errorLabelId)
|
|
||||||
label.id = size_t(m_state.assembly.errorTag().data());
|
|
||||||
if (label.resetStackHeight)
|
if (label.resetStackHeight)
|
||||||
{
|
{
|
||||||
size_t numVariables = boost::range::count_if(
|
size_t numVariables = boost::range::count_if(
|
||||||
@ -318,6 +312,16 @@ private:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Assigns the label's id to a value taken from eth::Assembly if it has not yet been set.
|
||||||
|
void assignLabelIdIfUnset(Scope::Label& _label)
|
||||||
|
{
|
||||||
|
if (_label.id == Scope::Label::unassignedLabelId)
|
||||||
|
_label.id = m_state.newLabelId();
|
||||||
|
else if (_label.id == Scope::Label::errorLabelId)
|
||||||
|
_label.id = size_t(m_state.assembly.errorTag().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GeneratorState& m_state;
|
GeneratorState& m_state;
|
||||||
Scope& m_scope;
|
Scope& m_scope;
|
||||||
int const m_initialDeposit;
|
int const m_initialDeposit;
|
||||||
@ -352,4 +356,3 @@ void assembly::CodeGenerator::assemble(eth::Assembly& _assembly, assembly::CodeG
|
|||||||
solAssert(false, "Assembly error");
|
solAssert(false, "Assembly error");
|
||||||
CodeTransform(state, m_parsedData, _identifierAccess);
|
CodeTransform(state, m_parsedData, _identifierAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user