Named assembly labels.

This commit is contained in:
chriseth
2017-09-15 20:44:49 +01:00
committed by Alex Beregszaszi
parent 7dd372ce5c
commit 73771f5bb2
13 changed files with 108 additions and 28 deletions
+2
View File
@@ -66,6 +66,8 @@ public:
virtual void appendLabelReference(LabelID _labelId) = 0;
/// Generate a new unique label.
virtual LabelID newLabelId() = 0;
/// Returns a label identified by the given name. Creates it if it does not yet exist.
virtual LabelID namedLabel(std::string const& _name) = 0;
/// Append a reference to a to-be-linked symobl.
/// Currently, we assume that the value is always a 20 byte number.
virtual void appendLinkerSymbol(std::string const& _name) = 0;
+8
View File
@@ -77,6 +77,14 @@ EVMAssembly::LabelID EVMAssembly::newLabelId()
return m_nextLabelId++;
}
AbstractAssembly::LabelID EVMAssembly::namedLabel(string const& _name)
{
solAssert(!_name.empty(), "");
if (!m_namedLabels.count(_name))
m_namedLabels[_name] = newLabelId();
return m_namedLabels[_name];
}
void EVMAssembly::appendLinkerSymbol(string const&)
{
solAssert(false, "Linker symbols not yet implemented.");
+3
View File
@@ -52,6 +52,8 @@ public:
virtual void appendLabelReference(LabelID _labelId) override;
/// Generate a new unique label.
virtual LabelID newLabelId() override;
/// Returns a label identified by the given name. Creates it if it does not yet exist.
virtual LabelID namedLabel(std::string const& _name) override;
/// Append a reference to a to-be-linked symobl.
/// Currently, we assume that the value is always a 20 byte number.
virtual void appendLinkerSymbol(std::string const& _name) override;
@@ -85,6 +87,7 @@ private:
LabelID m_nextLabelId = 0;
int m_stackHeight = 0;
bytes m_bytecode;
std::map<std::string, LabelID> m_namedLabels;
std::map<LabelID, size_t> m_labelPositions;
std::map<size_t, LabelID> m_labelReferences;
std::vector<size_t> m_assemblySizePositions;
+22 -8
View File
@@ -108,10 +108,10 @@ void CodeTransform::operator()(FunctionCall const& _call)
visitExpression(arg);
m_assembly.setSourceLocation(_call.location);
if (m_evm15)
m_assembly.appendJumpsub(functionEntryID(*function), function->arguments.size(), function->returns.size());
m_assembly.appendJumpsub(functionEntryID(_call.functionName.name, *function), function->arguments.size(), function->returns.size());
else
{
m_assembly.appendJumpTo(functionEntryID(*function), function->returns.size() - function->arguments.size() - 1);
m_assembly.appendJumpTo(functionEntryID(_call.functionName.name, *function), function->returns.size() - function->arguments.size() - 1);
m_assembly.appendLabel(returnLabel);
m_stackAdjustment--;
}
@@ -286,12 +286,12 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
if (m_evm15)
{
m_assembly.appendJumpTo(afterFunction, -stackHeightBefore);
m_assembly.appendBeginsub(functionEntryID(function), _function.arguments.size());
m_assembly.appendBeginsub(functionEntryID(_function.name, function), _function.arguments.size());
}
else
{
m_assembly.appendJumpTo(afterFunction, -stackHeightBefore + height);
m_assembly.appendLabel(functionEntryID(function));
m_assembly.appendLabel(functionEntryID(_function.name, function));
}
m_stackAdjustment += localStackAdjustment;
@@ -303,8 +303,16 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
m_assembly.appendConstant(u256(0));
}
CodeTransform(m_assembly, m_info, m_julia, m_evm15, m_identifierAccess, localStackAdjustment, m_context)
(_function.body);
CodeTransform(
m_assembly,
m_info,
m_julia,
m_evm15,
m_identifierAccess,
m_useNamedLabelsForFunctions,
localStackAdjustment,
m_context
)(_function.body);
{
// The stack layout here is:
@@ -421,10 +429,16 @@ AbstractAssembly::LabelID CodeTransform::labelID(Scope::Label const& _label)
return m_context->labelIDs[&_label];
}
AbstractAssembly::LabelID CodeTransform::functionEntryID(Scope::Function const& _function)
AbstractAssembly::LabelID CodeTransform::functionEntryID(string const& _name, Scope::Function const& _function)
{
if (!m_context->functionEntryIDs.count(&_function))
m_context->functionEntryIDs[&_function] = m_assembly.newLabelId();
{
AbstractAssembly::LabelID id =
m_useNamedLabelsForFunctions ?
m_assembly.namedLabel(_name) :
m_assembly.newLabelId();
m_context->functionEntryIDs[&_function] = id;
}
return m_context->functionEntryIDs[&_function];
}
+7 -2
View File
@@ -50,13 +50,15 @@ public:
solidity::assembly::AsmAnalysisInfo& _analysisInfo,
bool _julia = false,
bool _evm15 = false,
ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess()
ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess(),
bool _useNamedLabelsForFunctions = false
): CodeTransform(
_assembly,
_analysisInfo,
_julia,
_evm15,
_identifierAccess,
_useNamedLabelsForFunctions,
_assembly.stackHeight(),
std::make_shared<Context>()
)
@@ -78,6 +80,7 @@ protected:
bool _julia,
bool _evm15,
ExternalIdentifierAccess const& _identifierAccess,
bool _useNamedLabelsForFunctions,
int _stackAdjustment,
std::shared_ptr<Context> _context
):
@@ -85,6 +88,7 @@ protected:
m_info(_analysisInfo),
m_julia(_julia),
m_evm15(_evm15),
m_useNamedLabelsForFunctions(_useNamedLabelsForFunctions),
m_identifierAccess(_identifierAccess),
m_stackAdjustment(_stackAdjustment),
m_context(_context)
@@ -110,7 +114,7 @@ private:
/// @returns the label ID corresponding to the given label, allocating a new one if
/// necessary.
AbstractAssembly::LabelID labelID(solidity::assembly::Scope::Label const& _label);
AbstractAssembly::LabelID functionEntryID(solidity::assembly::Scope::Function const& _function);
AbstractAssembly::LabelID functionEntryID(std::string const& _name, solidity::assembly::Scope::Function const& _function);
/// Generates code for an expression that is supposed to return a single value.
void visitExpression(solidity::assembly::Statement const& _expression);
@@ -136,6 +140,7 @@ private:
solidity::assembly::Scope* m_scope = nullptr;
bool m_julia = false;
bool m_evm15 = false;
bool m_useNamedLabelsForFunctions = false;
ExternalIdentifierAccess m_identifierAccess;
/// Adjustment between the stack height as determined during the analysis phase
/// and the stack height in the assembly. This is caused by an initial stack being present