Slightly cleaner label ids.

This commit is contained in:
chriseth 2017-02-23 12:56:37 +01:00
parent c85f9257f8
commit 41236cd08c
3 changed files with 20 additions and 17 deletions

View File

@ -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>(

View File

@ -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)

View File

@ -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);
} }