mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Named assembly labels.
This commit is contained in:
committed by
Alex Beregszaszi
parent
7dd372ce5c
commit
73771f5bb2
@@ -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;
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user