mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add markAsInvalid to the various assemblies.
This commit is contained in:
parent
579e4b5a69
commit
92cd1ddb7d
@ -521,6 +521,7 @@ map<u256, u256> Assembly::optimiseInternal(
|
||||
|
||||
LinkerObject const& Assembly::assemble() const
|
||||
{
|
||||
assertThrow(!m_invalid, AssemblyException, "Attempted to assemble invalid Assembly object.");
|
||||
// Return the already assembled object, if present.
|
||||
if (!m_assembledObject.bytecode.empty())
|
||||
return m_assembledObject;
|
||||
|
@ -142,6 +142,9 @@ public:
|
||||
std::map<std::string, unsigned> const& _sourceIndices = std::map<std::string, unsigned>()
|
||||
) const;
|
||||
|
||||
/// Mark this assembly as invalid. Calling ``assemble`` on it will throw.
|
||||
void markAsInvalid() { m_invalid = true; }
|
||||
|
||||
protected:
|
||||
/// Does the same operations as @a optimise, but should only be applied to a sub and
|
||||
/// returns the replaced tags. Also takes an argument containing the tags of this assembly
|
||||
@ -161,6 +164,7 @@ private:
|
||||
);
|
||||
static std::string toStringInHex(u256 _value);
|
||||
|
||||
bool m_invalid = false;
|
||||
protected:
|
||||
/// 0 is reserved for exception
|
||||
unsigned m_usedTags = 1;
|
||||
|
@ -111,6 +111,9 @@ public:
|
||||
virtual void appendImmutable(std::string const& _identifier) = 0;
|
||||
/// Appends an assignment to an immutable variable.
|
||||
virtual void appendImmutableAssignment(std::string const& _identifier) = 0;
|
||||
|
||||
/// Mark this assembly as invalid. Any attempt to request bytecode from it should throw.
|
||||
virtual void markAsInvalid() = 0;
|
||||
};
|
||||
|
||||
enum class IdentifierContext { LValue, RValue, VariableDeclaration };
|
||||
|
@ -182,6 +182,11 @@ void EthAssemblyAdapter::appendImmutableAssignment(std::string const& _identifie
|
||||
m_assembly.appendImmutableAssignment(_identifier);
|
||||
}
|
||||
|
||||
void EthAssemblyAdapter::markAsInvalid()
|
||||
{
|
||||
m_assembly.markAsInvalid();
|
||||
}
|
||||
|
||||
EthAssemblyAdapter::LabelID EthAssemblyAdapter::assemblyTagToIdentifier(evmasm::AssemblyItem const& _tag)
|
||||
{
|
||||
u256 id = _tag.data();
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
void appendImmutable(std::string const& _identifier) override;
|
||||
void appendImmutableAssignment(std::string const& _identifier) override;
|
||||
|
||||
void markAsInvalid() override;
|
||||
|
||||
private:
|
||||
static LabelID assemblyTagToIdentifier(evmasm::AssemblyItem const& _tag);
|
||||
void appendJumpInstruction(evmasm::Instruction _instruction, JumpType _jumpType);
|
||||
|
@ -156,6 +156,7 @@ void EVMAssembly::appendReturnsub(int _returns, int _stackDiffAfter)
|
||||
|
||||
evmasm::LinkerObject EVMAssembly::finalize()
|
||||
{
|
||||
yulAssert(!m_invalid, "Attempted to finalize invalid assembly object.");
|
||||
size_t bytecodeSize = m_bytecode.size();
|
||||
for (auto const& ref: m_assemblySizePositions)
|
||||
updateReference(ref, assemblySizeReferenceSize, u256(bytecodeSize));
|
||||
|
@ -86,6 +86,8 @@ public:
|
||||
void appendImmutable(std::string const& _identifier) override;
|
||||
void appendImmutableAssignment(std::string const& _identifier) override;
|
||||
|
||||
void markAsInvalid() override { m_invalid = true; }
|
||||
|
||||
/// Resolves references inside the bytecode and returns the linker object.
|
||||
evmasm::LinkerObject finalize();
|
||||
|
||||
@ -102,6 +104,7 @@ private:
|
||||
std::map<LabelID, size_t> m_labelPositions;
|
||||
std::map<size_t, LabelID> m_labelReferences;
|
||||
std::vector<size_t> m_assemblySizePositions;
|
||||
bool m_invalid = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -237,6 +237,7 @@ void CodeTransform::stackError(StackTooDeepError _error, int _targetStackHeight)
|
||||
m_assembly.appendConstant(u256(0));
|
||||
// Store error.
|
||||
m_stackErrors.emplace_back(std::move(_error));
|
||||
m_assembly.markAsInvalid();
|
||||
}
|
||||
|
||||
void CodeTransform::operator()(Assignment const& _assignment)
|
||||
@ -448,12 +449,16 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
|
||||
m_context
|
||||
);
|
||||
subTransform(_function.body);
|
||||
for (auto& stackError: subTransform.m_stackErrors)
|
||||
if (!subTransform.m_stackErrors.empty())
|
||||
{
|
||||
m_assembly.markAsInvalid();
|
||||
for (StackTooDeepError& stackError: subTransform.m_stackErrors)
|
||||
{
|
||||
if (stackError.functionName.empty())
|
||||
stackError.functionName = _function.name;
|
||||
m_stackErrors.emplace_back(std::move(stackError));
|
||||
}
|
||||
}
|
||||
|
||||
m_assembly.appendLabel(m_context->functionExitPoints.top().label);
|
||||
m_context->functionExitPoints.pop();
|
||||
@ -718,7 +723,7 @@ size_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulString
|
||||
to_string(heightDiff - limit) +
|
||||
" slot(s) too deep inside the stack."
|
||||
);
|
||||
// TODO: maybe make this return something special that results in producing INVALID instead.
|
||||
m_assembly.markAsInvalid();
|
||||
return _forSwap ? 2 : 1;
|
||||
}
|
||||
return heightDiff;
|
||||
|
@ -74,6 +74,8 @@ public:
|
||||
void appendImmutable(std::string const& _identifier) override;
|
||||
void appendImmutableAssignment(std::string const& _identifier) override;
|
||||
|
||||
void markAsInvalid() override {}
|
||||
|
||||
private:
|
||||
bool m_evm15 = false; ///< if true, switch to evm1.5 mode
|
||||
int m_stackHeight = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user