mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Store whether a subassembly is creation code and optimize accordingly.
This commit is contained in:
parent
7c91dd05a7
commit
d5b2d94cb7
@ -203,7 +203,7 @@ void Assembly::assemblyStream(
|
|||||||
for (size_t i = 0; i < m_subs.size(); ++i)
|
for (size_t i = 0; i < m_subs.size(); ++i)
|
||||||
{
|
{
|
||||||
_out << endl << _prefix << "sub_" << i << ": assembly {\n";
|
_out << endl << _prefix << "sub_" << i << ": assembly {\n";
|
||||||
m_subs[i]->assemblyStream(_out, _debugInfoSelection, _prefix + " ", _sourceCodes);
|
m_subs[i].first->assemblyStream(_out, _debugInfoSelection, _prefix + " ", _sourceCodes);
|
||||||
_out << _prefix << "}" << endl;
|
_out << _prefix << "}" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,7 +352,7 @@ Json::Value Assembly::assemblyJSON(map<string, unsigned> const& _sourceIndices)
|
|||||||
{
|
{
|
||||||
std::stringstream hexStr;
|
std::stringstream hexStr;
|
||||||
hexStr << hex << i;
|
hexStr << hex << i;
|
||||||
data[hexStr.str()] = m_subs[i]->assemblyJSON(_sourceIndices);
|
data[hexStr.str()] = m_subs[i].first->assemblyJSON(_sourceIndices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,9 +435,8 @@ map<u256, u256> const& Assembly::optimiseInternal(
|
|||||||
for (size_t subId = 0; subId < m_subs.size(); ++subId)
|
for (size_t subId = 0; subId < m_subs.size(); ++subId)
|
||||||
{
|
{
|
||||||
OptimiserSettings settings = _settings;
|
OptimiserSettings settings = _settings;
|
||||||
// Disable creation mode for sub-assemblies.
|
settings.isCreation = m_subs[subId].second;
|
||||||
settings.isCreation = false;
|
map<u256, u256> const& subTagReplacements = m_subs[subId].first->optimiseInternal(
|
||||||
map<u256, u256> const& subTagReplacements = m_subs[subId]->optimiseInternal(
|
|
||||||
settings,
|
settings,
|
||||||
JumpdestRemover::referencedTags(m_items, subId)
|
JumpdestRemover::referencedTags(m_items, subId)
|
||||||
);
|
);
|
||||||
@ -582,7 +581,7 @@ LinkerObject const& Assembly::assemble() const
|
|||||||
map<u256, pair<string, vector<size_t>>> immutableReferencesBySub;
|
map<u256, pair<string, vector<size_t>>> immutableReferencesBySub;
|
||||||
for (auto const& sub: m_subs)
|
for (auto const& sub: m_subs)
|
||||||
{
|
{
|
||||||
auto const& linkerObject = sub->assemble();
|
auto const& linkerObject = sub.first->assemble();
|
||||||
if (!linkerObject.immutableReferences.empty())
|
if (!linkerObject.immutableReferences.empty())
|
||||||
{
|
{
|
||||||
assertThrow(
|
assertThrow(
|
||||||
@ -592,7 +591,7 @@ LinkerObject const& Assembly::assemble() const
|
|||||||
);
|
);
|
||||||
immutableReferencesBySub = linkerObject.immutableReferences;
|
immutableReferencesBySub = linkerObject.immutableReferences;
|
||||||
}
|
}
|
||||||
for (size_t tagPos: sub->m_tagPositionsInBytecode)
|
for (size_t tagPos: sub.first->m_tagPositionsInBytecode)
|
||||||
if (tagPos != numeric_limits<size_t>::max() && tagPos > subTagSize)
|
if (tagPos != numeric_limits<size_t>::max() && tagPos > subTagSize)
|
||||||
subTagSize = tagPos;
|
subTagSize = tagPos;
|
||||||
}
|
}
|
||||||
@ -626,7 +625,7 @@ LinkerObject const& Assembly::assemble() const
|
|||||||
|
|
||||||
unsigned bytesRequiredIncludingData = bytesRequiredForCode + 1 + static_cast<unsigned>(m_auxiliaryData.size());
|
unsigned bytesRequiredIncludingData = bytesRequiredForCode + 1 + static_cast<unsigned>(m_auxiliaryData.size());
|
||||||
for (auto const& sub: m_subs)
|
for (auto const& sub: m_subs)
|
||||||
bytesRequiredIncludingData += static_cast<unsigned>(sub->assemble().bytecode.size());
|
bytesRequiredIncludingData += static_cast<unsigned>(sub.first->assemble().bytecode.size());
|
||||||
|
|
||||||
unsigned bytesPerDataRef = numberEncodingSize(bytesRequiredIncludingData);
|
unsigned bytesPerDataRef = numberEncodingSize(bytesRequiredIncludingData);
|
||||||
uint8_t dataRefPush = static_cast<uint8_t>(pushInstruction(bytesPerDataRef));
|
uint8_t dataRefPush = static_cast<uint8_t>(pushInstruction(bytesPerDataRef));
|
||||||
@ -780,7 +779,7 @@ LinkerObject const& Assembly::assemble() const
|
|||||||
vector<size_t> const& tagPositions =
|
vector<size_t> const& tagPositions =
|
||||||
subId == numeric_limits<size_t>::max() ?
|
subId == numeric_limits<size_t>::max() ?
|
||||||
m_tagPositionsInBytecode :
|
m_tagPositionsInBytecode :
|
||||||
m_subs[subId]->m_tagPositionsInBytecode;
|
m_subs[subId].first->m_tagPositionsInBytecode;
|
||||||
assertThrow(tagId < tagPositions.size(), AssemblyException, "Reference to non-existing tag.");
|
assertThrow(tagId < tagPositions.size(), AssemblyException, "Reference to non-existing tag.");
|
||||||
size_t pos = tagPositions[tagId];
|
size_t pos = tagPositions[tagId];
|
||||||
assertThrow(pos != numeric_limits<size_t>::max(), AssemblyException, "Reference to tag without position.");
|
assertThrow(pos != numeric_limits<size_t>::max(), AssemblyException, "Reference to tag without position.");
|
||||||
@ -870,7 +869,7 @@ Assembly const* Assembly::subAssemblyById(size_t _subId) const
|
|||||||
Assembly const* currentAssembly = this;
|
Assembly const* currentAssembly = this;
|
||||||
for (size_t currentSubId: subIds)
|
for (size_t currentSubId: subIds)
|
||||||
{
|
{
|
||||||
currentAssembly = currentAssembly->m_subs.at(currentSubId).get();
|
currentAssembly = currentAssembly->m_subs.at(currentSubId).first.get();
|
||||||
assertThrow(currentAssembly, AssemblyException, "");
|
assertThrow(currentAssembly, AssemblyException, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@ public:
|
|||||||
AssemblyItem namedTag(std::string const& _name, size_t _params, size_t _returns, std::optional<uint64_t> _sourceID);
|
AssemblyItem namedTag(std::string const& _name, size_t _params, size_t _returns, std::optional<uint64_t> _sourceID);
|
||||||
AssemblyItem newData(bytes const& _data) { util::h256 h(util::keccak256(util::asString(_data))); m_data[h] = _data; return AssemblyItem(PushData, h); }
|
AssemblyItem newData(bytes const& _data) { util::h256 h(util::keccak256(util::asString(_data))); m_data[h] = _data; return AssemblyItem(PushData, h); }
|
||||||
bytes const& data(util::h256 const& _i) const { return m_data.at(_i); }
|
bytes const& data(util::h256 const& _i) const { return m_data.at(_i); }
|
||||||
AssemblyItem newSub(AssemblyPointer const& _sub) { m_subs.push_back(_sub); return AssemblyItem(PushSub, m_subs.size() - 1); }
|
AssemblyItem newSub(AssemblyPointer const& _sub, bool _creation) { m_subs.emplace_back(_sub, _creation); return AssemblyItem(PushSub, m_subs.size() - 1); }
|
||||||
Assembly const& sub(size_t _sub) const { return *m_subs.at(_sub); }
|
Assembly const& sub(size_t _sub) const { return *m_subs.at(_sub).first; }
|
||||||
Assembly& sub(size_t _sub) { return *m_subs.at(_sub); }
|
Assembly& sub(size_t _sub) { return *m_subs.at(_sub).first; }
|
||||||
size_t numSubs() const { return m_subs.size(); }
|
size_t numSubs() const { return m_subs.size(); }
|
||||||
AssemblyItem newPushSubSize(u256 const& _subId) { return AssemblyItem(PushSubSize, _subId); }
|
AssemblyItem newPushSubSize(u256 const& _subId) { return AssemblyItem(PushSubSize, _subId); }
|
||||||
AssemblyItem newPushLibraryAddress(std::string const& _identifier);
|
AssemblyItem newPushLibraryAddress(std::string const& _identifier);
|
||||||
@ -89,7 +89,7 @@ public:
|
|||||||
|
|
||||||
/// Adds a subroutine to the code (in the data section) and pushes its size (via a tag)
|
/// Adds a subroutine to the code (in the data section) and pushes its size (via a tag)
|
||||||
/// on the stack. @returns the pushsub assembly item.
|
/// on the stack. @returns the pushsub assembly item.
|
||||||
AssemblyItem appendSubroutine(AssemblyPointer const& _assembly) { auto sub = newSub(_assembly); append(newPushSubSize(size_t(sub.data()))); return sub; }
|
AssemblyItem appendSubroutine(AssemblyPointer const& _assembly, bool _creation) { auto sub = newSub(_assembly, _creation); append(newPushSubSize(size_t(sub.data()))); return sub; }
|
||||||
void pushSubroutineSize(size_t _subRoutine) { append(newPushSubSize(_subRoutine)); }
|
void pushSubroutineSize(size_t _subRoutine) { append(newPushSubSize(_subRoutine)); }
|
||||||
/// Pushes the offset of the subroutine.
|
/// Pushes the offset of the subroutine.
|
||||||
void pushSubroutineOffset(size_t _subRoutine) { append(AssemblyItem(PushSub, _subRoutine)); }
|
void pushSubroutineOffset(size_t _subRoutine) { append(AssemblyItem(PushSub, _subRoutine)); }
|
||||||
@ -204,7 +204,7 @@ protected:
|
|||||||
std::map<util::h256, bytes> m_data;
|
std::map<util::h256, bytes> m_data;
|
||||||
/// Data that is appended to the very end of the contract.
|
/// Data that is appended to the very end of the contract.
|
||||||
bytes m_auxiliaryData;
|
bytes m_auxiliaryData;
|
||||||
std::vector<std::shared_ptr<Assembly>> m_subs;
|
std::vector<std::pair<std::shared_ptr<Assembly>, bool>> m_subs;
|
||||||
std::map<util::h256, std::string> m_strings;
|
std::map<util::h256, std::string> m_strings;
|
||||||
std::map<util::h256, std::string> m_libraries; ///< Identifiers of libraries to be linked.
|
std::map<util::h256, std::string> m_libraries; ///< Identifiers of libraries to be linked.
|
||||||
std::map<util::h256, std::string> m_immutables; ///< Identifiers of immutables.
|
std::map<util::h256, std::string> m_immutables; ///< Identifiers of immutables.
|
||||||
|
@ -74,7 +74,7 @@ public:
|
|||||||
m_yulUtilFunctions(m_evmVersion, m_revertStrings, m_yulFunctionCollector)
|
m_yulUtilFunctions(m_evmVersion, m_revertStrings, m_yulFunctionCollector)
|
||||||
{
|
{
|
||||||
if (m_runtimeContext)
|
if (m_runtimeContext)
|
||||||
m_runtimeSub = size_t(m_asm->newSub(m_runtimeContext->m_asm).data());
|
m_runtimeSub = size_t(m_asm->newSub(m_runtimeContext->m_asm, false).data());
|
||||||
}
|
}
|
||||||
|
|
||||||
langutil::EVMVersion const& evmVersion() const { return m_evmVersion; }
|
langutil::EVMVersion const& evmVersion() const { return m_evmVersion; }
|
||||||
@ -224,7 +224,7 @@ public:
|
|||||||
}
|
}
|
||||||
/// Adds a subroutine to the code (in the data section) and pushes its size (via a tag)
|
/// Adds a subroutine to the code (in the data section) and pushes its size (via a tag)
|
||||||
/// on the stack. @returns the pushsub assembly item.
|
/// on the stack. @returns the pushsub assembly item.
|
||||||
evmasm::AssemblyItem addSubroutine(evmasm::AssemblyPointer const& _assembly) { return m_asm->appendSubroutine(_assembly); }
|
evmasm::AssemblyItem addSubroutine(evmasm::AssemblyPointer const& _assembly, bool _creation) { return m_asm->appendSubroutine(_assembly, _creation); }
|
||||||
/// Pushes the size of the subroutine.
|
/// Pushes the size of the subroutine.
|
||||||
void pushSubroutineSize(size_t _subRoutine) { m_asm->pushSubroutineSize(_subRoutine); }
|
void pushSubroutineSize(size_t _subRoutine) { m_asm->pushSubroutineSize(_subRoutine); }
|
||||||
/// Pushes the offset of the subroutine.
|
/// Pushes the offset of the subroutine.
|
||||||
|
@ -1521,7 +1521,7 @@ void CompilerUtils::copyContractCodeToMemory(ContractDefinition const& contract,
|
|||||||
_context.compiledContract(contract) :
|
_context.compiledContract(contract) :
|
||||||
_context.compiledContractRuntime(contract);
|
_context.compiledContractRuntime(contract);
|
||||||
// pushes size
|
// pushes size
|
||||||
auto subroutine = _context.addSubroutine(assembly);
|
auto subroutine = _context.addSubroutine(assembly, _creation);
|
||||||
_context << Instruction::DUP1 << subroutine;
|
_context << Instruction::DUP1 << subroutine;
|
||||||
_context << Instruction::DUP4 << Instruction::CODECOPY;
|
_context << Instruction::DUP4 << Instruction::CODECOPY;
|
||||||
_context << Instruction::ADD;
|
_context << Instruction::ADD;
|
||||||
|
@ -37,9 +37,13 @@
|
|||||||
#include <libyul/optimiser/Suite.h>
|
#include <libyul/optimiser/Suite.h>
|
||||||
|
|
||||||
#include <libevmasm/Assembly.h>
|
#include <libevmasm/Assembly.h>
|
||||||
|
|
||||||
#include <liblangutil/Scanner.h>
|
#include <liblangutil/Scanner.h>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
@ -194,7 +198,11 @@ void AssemblyStack::optimize(Object& _object, bool _isCreation)
|
|||||||
yulAssert(_object.analysisInfo, "");
|
yulAssert(_object.analysisInfo, "");
|
||||||
for (auto& subNode: _object.subObjects)
|
for (auto& subNode: _object.subObjects)
|
||||||
if (auto subObject = dynamic_cast<Object*>(subNode.get()))
|
if (auto subObject = dynamic_cast<Object*>(subNode.get()))
|
||||||
optimize(*subObject, false);
|
{
|
||||||
|
// TODO: determine this more properly, resp. store it earlier when the subobject is created
|
||||||
|
bool isCreation = !boost::ends_with(subObject->name.str(), "_deployed");
|
||||||
|
optimize(*subObject, isCreation);
|
||||||
|
}
|
||||||
|
|
||||||
Dialect const& dialect = languageToDialect(m_language, m_evmVersion);
|
Dialect const& dialect = languageToDialect(m_language, m_evmVersion);
|
||||||
unique_ptr<GasMeter> meter;
|
unique_ptr<GasMeter> meter;
|
||||||
|
@ -98,7 +98,7 @@ public:
|
|||||||
/// Append the assembled size as a constant.
|
/// Append the assembled size as a constant.
|
||||||
virtual void appendAssemblySize() = 0;
|
virtual void appendAssemblySize() = 0;
|
||||||
/// Creates a new sub-assembly, which can be referenced using dataSize and dataOffset.
|
/// Creates a new sub-assembly, which can be referenced using dataSize and dataOffset.
|
||||||
virtual std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(std::string _name = "") = 0;
|
virtual std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(std::string _name, bool _creation) = 0;
|
||||||
/// Appends the offset of the given sub-assembly or data.
|
/// Appends the offset of the given sub-assembly or data.
|
||||||
virtual void appendDataOffset(std::vector<SubID> const& _subPath) = 0;
|
virtual void appendDataOffset(std::vector<SubID> const& _subPath) = 0;
|
||||||
/// Appends the size of the given sub-assembly or data.
|
/// Appends the size of the given sub-assembly or data.
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include <libyul/Object.h>
|
#include <libyul/Object.h>
|
||||||
#include <libyul/Exceptions.h>
|
#include <libyul/Exceptions.h>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -46,7 +48,9 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize)
|
|||||||
for (auto const& subNode: _object.subObjects)
|
for (auto const& subNode: _object.subObjects)
|
||||||
if (auto* subObject = dynamic_cast<Object*>(subNode.get()))
|
if (auto* subObject = dynamic_cast<Object*>(subNode.get()))
|
||||||
{
|
{
|
||||||
auto subAssemblyAndID = m_assembly.createSubAssembly(subObject->name.str());
|
// TODO: determine this more properly, resp. store it earlier when the subobject is created
|
||||||
|
bool isCreation = !boost::ends_with(subObject->name.str(), "_deployed");
|
||||||
|
auto subAssemblyAndID = m_assembly.createSubAssembly(subObject->name.str(), isCreation);
|
||||||
context.subIDs[subObject->name] = subAssemblyAndID.second;
|
context.subIDs[subObject->name] = subAssemblyAndID.second;
|
||||||
subObject->subId = subAssemblyAndID.second;
|
subObject->subId = subAssemblyAndID.second;
|
||||||
compile(*subObject, *subAssemblyAndID.first, m_dialect, _optimize);
|
compile(*subObject, *subAssemblyAndID.first, m_dialect, _optimize);
|
||||||
|
@ -122,10 +122,10 @@ void EthAssemblyAdapter::appendAssemblySize()
|
|||||||
m_assembly.appendProgramSize();
|
m_assembly.appendProgramSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly(string _name)
|
pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly(string _name, bool _creation)
|
||||||
{
|
{
|
||||||
shared_ptr<evmasm::Assembly> assembly{make_shared<evmasm::Assembly>(std::move(_name))};
|
shared_ptr<evmasm::Assembly> assembly{make_shared<evmasm::Assembly>(std::move(_name))};
|
||||||
auto sub = m_assembly.newSub(assembly);
|
auto sub = m_assembly.newSub(assembly, _creation);
|
||||||
return {make_shared<EthAssemblyAdapter>(*assembly), static_cast<size_t>(sub.data())};
|
return {make_shared<EthAssemblyAdapter>(*assembly), static_cast<size_t>(sub.data())};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
void appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType) override;
|
void appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType) override;
|
||||||
void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;
|
void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;
|
||||||
void appendAssemblySize() override;
|
void appendAssemblySize() override;
|
||||||
std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(std::string _name = {}) override;
|
std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(std::string _name, bool _creation) override;
|
||||||
void appendDataOffset(std::vector<SubID> const& _subPath) override;
|
void appendDataOffset(std::vector<SubID> const& _subPath) override;
|
||||||
void appendDataSize(std::vector<SubID> const& _subPath) override;
|
void appendDataSize(std::vector<SubID> const& _subPath) override;
|
||||||
SubID appendData(bytes const& _data) override;
|
SubID appendData(bytes const& _data) override;
|
||||||
|
@ -98,7 +98,7 @@ void NoOutputAssembly::appendAssemblySize()
|
|||||||
appendInstruction(evmasm::Instruction::PUSH1);
|
appendInstruction(evmasm::Instruction::PUSH1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(std::string)
|
pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(std::string, bool)
|
||||||
{
|
{
|
||||||
yulAssert(false, "Sub assemblies not implemented.");
|
yulAssert(false, "Sub assemblies not implemented.");
|
||||||
return {};
|
return {};
|
||||||
|
@ -65,7 +65,7 @@ public:
|
|||||||
void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;
|
void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;
|
||||||
|
|
||||||
void appendAssemblySize() override;
|
void appendAssemblySize() override;
|
||||||
std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(std::string _name = "") override;
|
std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(std::string _name, bool _creation) override;
|
||||||
void appendDataOffset(std::vector<SubID> const& _subPath) override;
|
void appendDataOffset(std::vector<SubID> const& _subPath) override;
|
||||||
void appendDataSize(std::vector<SubID> const& _subPath) override;
|
void appendDataSize(std::vector<SubID> const& _subPath) override;
|
||||||
SubID appendData(bytes const& _data) override;
|
SubID appendData(bytes const& _data) override;
|
||||||
|
@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
|
|||||||
// PushData
|
// PushData
|
||||||
_assembly.append(bytes{0x1, 0x2, 0x3, 0x4});
|
_assembly.append(bytes{0x1, 0x2, 0x3, 0x4});
|
||||||
// PushSubSize
|
// PushSubSize
|
||||||
auto sub = _assembly.appendSubroutine(_subAsmPtr);
|
auto sub = _assembly.appendSubroutine(_subAsmPtr, false);
|
||||||
// PushSub
|
// PushSub
|
||||||
_assembly.pushSubroutineOffset(static_cast<size_t>(sub.data()));
|
_assembly.pushSubroutineOffset(static_cast<size_t>(sub.data()));
|
||||||
// PushDeployTimeAddress
|
// PushDeployTimeAddress
|
||||||
@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(immutables_and_its_source_maps)
|
|||||||
assembly.appendImmutableAssignment(string(1, char('a' + i - 1)));
|
assembly.appendImmutableAssignment(string(1, char('a' + i - 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
assembly.appendSubroutine(subAsm);
|
assembly.appendSubroutine(subAsm, false);
|
||||||
|
|
||||||
checkCompilation(assembly);
|
checkCompilation(assembly);
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ BOOST_AUTO_TEST_CASE(immutable)
|
|||||||
_assembly.append(u256(0));
|
_assembly.append(u256(0));
|
||||||
_assembly.appendImmutableAssignment("someOtherImmutable");
|
_assembly.appendImmutableAssignment("someOtherImmutable");
|
||||||
|
|
||||||
auto sub = _assembly.appendSubroutine(_subAsmPtr);
|
auto sub = _assembly.appendSubroutine(_subAsmPtr, false);
|
||||||
_assembly.pushSubroutineOffset(static_cast<size_t>(sub.data()));
|
_assembly.pushSubroutineOffset(static_cast<size_t>(sub.data()));
|
||||||
|
|
||||||
checkCompilation(_assembly);
|
checkCompilation(_assembly);
|
||||||
@ -354,8 +354,8 @@ BOOST_AUTO_TEST_CASE(subobject_encode_decode)
|
|||||||
shared_ptr<Assembly> subAsmPtr = make_shared<Assembly>();
|
shared_ptr<Assembly> subAsmPtr = make_shared<Assembly>();
|
||||||
shared_ptr<Assembly> subSubAsmPtr = make_shared<Assembly>();
|
shared_ptr<Assembly> subSubAsmPtr = make_shared<Assembly>();
|
||||||
|
|
||||||
assembly.appendSubroutine(subAsmPtr);
|
assembly.appendSubroutine(subAsmPtr, false);
|
||||||
subAsmPtr->appendSubroutine(subSubAsmPtr);
|
subAsmPtr->appendSubroutine(subSubAsmPtr, false);
|
||||||
|
|
||||||
BOOST_CHECK(assembly.encodeSubPath({0}) == 0);
|
BOOST_CHECK(assembly.encodeSubPath({0}) == 0);
|
||||||
BOOST_REQUIRE_THROW(assembly.encodeSubPath({1}), solidity::evmasm::AssemblyException);
|
BOOST_REQUIRE_THROW(assembly.encodeSubPath({1}), solidity::evmasm::AssemblyException);
|
||||||
|
@ -1272,7 +1272,7 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies)
|
|||||||
sub->append(t4.pushTag());
|
sub->append(t4.pushTag());
|
||||||
sub->append(Instruction::JUMP);
|
sub->append(Instruction::JUMP);
|
||||||
|
|
||||||
size_t subId = static_cast<size_t>(main.appendSubroutine(sub).data());
|
size_t subId = static_cast<size_t>(main.appendSubroutine(sub, false).data());
|
||||||
main.append(t1.toSubAssemblyTag(subId));
|
main.append(t1.toSubAssemblyTag(subId));
|
||||||
main.append(t1.toSubAssemblyTag(subId));
|
main.append(t1.toSubAssemblyTag(subId));
|
||||||
main.append(u256(8));
|
main.append(u256(8));
|
||||||
|
Loading…
Reference in New Issue
Block a user