Skip to content

Commit

Permalink
eof: auxdatastore in EOF
Browse files Browse the repository at this point in the history
  • Loading branch information
rodiazet committed Oct 21, 2024
1 parent 5b54415 commit 35e0796
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 1 deletion.
30 changes: 30 additions & 0 deletions libevmasm/Assembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,11 @@ AssemblyItem Assembly::newAuxDataLoadN(size_t _offset)
return AssemblyItem{AuxDataLoadN, _offset};
}

AssemblyItem Assembly::newAuxDataStore()
{
return AssemblyItem{AuxDataStore};
}

Assembly& Assembly::optimise(OptimiserSettings const& _settings)
{
optimiseInternal(_settings, {});
Expand Down Expand Up @@ -1393,6 +1398,24 @@ LinkerObject const& Assembly::assembleEOF() const
m_tagPositionsInBytecode = std::vector<size_t>(m_usedTags, std::numeric_limits<size_t>::max());
std::map<size_t, uint16_t> dataSectionRef;

bool storesAuxData = false;
bool loadsAuxData = false;

for (auto& codeSection: m_codeSections)
{
for (auto const& item: codeSection.items)
if (item.type() == AuxDataStore)
storesAuxData = true;
else if (item.type() == AuxDataLoadN)
loadsAuxData = true;
if (storesAuxData || loadsAuxData)
solRequire(
storesAuxData != loadsAuxData,
AssemblyException,
"Cannot store and load auxiliary data in the same assembly subroutine."
);
}

for (auto&& [codeSectionIndex, codeSection]: m_codeSections | ranges::views::enumerate)
{
auto const sectionStart = ret.bytecode.size();
Expand Down Expand Up @@ -1437,6 +1460,13 @@ LinkerObject const& Assembly::assembleEOF() const
appendBigEndianUint16(ret.bytecode, item.data());
break;
}
case AuxDataStore:
{
// Expect 3 elements on stack (source, dest_base, value_offset_dest)
ret.bytecode.push_back(uint8_t(Instruction::ADD));
ret.bytecode.push_back(uint8_t(Instruction::MSTORE));
break;
}
default:
solThrow(InvalidOpcode, "Unexpected opcode while assembling.");
}
Expand Down
2 changes: 2 additions & 0 deletions libevmasm/Assembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class Assembly
AssemblyItem newPushImmutable(std::string const& _identifier);
AssemblyItem newImmutableAssignment(std::string const& _identifier);
AssemblyItem newAuxDataLoadN(size_t offset);
AssemblyItem newAuxDataStore();

AssemblyItem const& append(AssemblyItem _i);
AssemblyItem const& append(bytes const& _data) { return append(newData(_data)); }
Expand All @@ -93,6 +94,7 @@ class Assembly
void appendImmutable(std::string const& _identifier) { append(newPushImmutable(_identifier)); }
void appendImmutableAssignment(std::string const& _identifier) { append(newImmutableAssignment(_identifier)); }
void appendAuxDataLoadN(uint16_t _offset) { append(newAuxDataLoadN(_offset));}
void appendAuxDataStore() { append(newAuxDataStore());}

void appendVerbatim(bytes _data, size_t _arguments, size_t _returnVariables)
{
Expand Down
14 changes: 14 additions & 0 deletions libevmasm/AssemblyItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ std::pair<std::string, std::string> AssemblyItem::nameAndData(langutil::EVMVersi
return {"VERBATIM", util::toHex(verbatimData())};
case AuxDataLoadN:
return {"AUXDATALOADN", util::toString(data())};
case AuxDataStore:
return {"AUXDATASTORE", ""};
case UndefinedItem:
solAssert(false);
}
Expand Down Expand Up @@ -167,6 +169,8 @@ size_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _
return std::get<2>(*m_verbatimBytecode).size();
case AuxDataLoadN:
return 1 + 2;
case AuxDataStore:
return 1;
case UndefinedItem:
solAssert(false);
}
Expand All @@ -184,6 +188,8 @@ size_t AssemblyItem::arguments() const
return std::get<0>(*m_verbatimBytecode);
else if (type() == AssignImmutable)
return 2;
else if (type() == AuxDataStore)
return 3;
else
return 0;
}
Expand Down Expand Up @@ -213,6 +219,7 @@ size_t AssemblyItem::returnValues() const
case AuxDataLoadN:
return 1;
case AssignImmutable:
case AuxDataStore:
case UndefinedItem:
break;
}
Expand Down Expand Up @@ -242,6 +249,7 @@ bool AssemblyItem::canBeFunctional() const
return false;
case AssignImmutable:
case VerbatimBytecode:
case AuxDataStore:
case UndefinedItem:
break;
}
Expand Down Expand Up @@ -344,6 +352,9 @@ std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const
assertThrow(data() <= std::numeric_limits<size_t>::max(), AssemblyException, "Invalid auxdataloadn argument.");
text = "auxdataloadn(" + std::to_string(static_cast<size_t>(data())) + ")";
break;
case AuxDataStore:
text = "auxdatastore()";
break;
}
if (m_jumpType == JumpType::IntoFunction || m_jumpType == JumpType::OutOfFunction)
{
Expand Down Expand Up @@ -414,6 +425,9 @@ std::ostream& solidity::evmasm::operator<<(std::ostream& _out, AssemblyItem cons
case AuxDataLoadN:
_out << " AuxDataLoadN " << util::toString(_item.data());
break;
case AuxDataStore:
_out << " AuxDataStore";
break;
case UndefinedItem:
_out << " ???";
break;
Expand Down
1 change: 1 addition & 0 deletions libevmasm/AssemblyItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ enum AssemblyItemType
/// Loads 32 bytes from static auxiliary data of EOF data section. The offset does *not* have to be always from the beginning
/// of the data EOF section. More details here: https://github.com/ipsilon/eof/blob/main/spec/eof.md#data-section-lifecycle
AuxDataLoadN,
AuxDataStore, ///< Stores value in memory which will be appended to EOF data section as static auxiliary data.
VerbatimBytecode ///< Contains data that is inserted into the bytecode code section without modification.
};

Expand Down
5 changes: 4 additions & 1 deletion libyul/backends/evm/AbstractAssembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ class AbstractAssembly
/// Appends loading an immutable variable.
virtual void appendImmutable(std::string const& _identifier) = 0;
/// Appends an assignment to an immutable variable.
virtual void appendImmutableAssignment(std::string const& _identifier) = 0;
virtual void appendImmutableAssignment(std::string const&) = 0;

/// Appends store to a memory used fill aux data section of EOF container
virtual void appendAuxDataStore() = 0;

/// Appends an operation that loads 32 bytes of data from a known offset relative to the start of the static_aux_data area of the EOF data section.
/// Note that static_aux_data is only a part or the data section.
Expand Down
25 changes: 25 additions & 0 deletions libyul/backends/evm/EVMDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ std::set<YulName> createReservedIdentifiers(langutil::EVMVersion _evmVersion)
"setimmutable"_yulname,
"loadimmutable"_yulname,
"auxdataloadn"_yulname,
"auxdatastore"_yulname,
};
return reserved;
}
Expand Down Expand Up @@ -349,6 +350,30 @@ std::map<YulName, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _ev
}
else // EOF context
{
builtins.emplace(createFunction(
"auxdatastore",
3,
0,
SideEffects{
false, // movable
false, // movableApartFromEffects
false, // canBeRemoved
false, // canBeRemovedIfNotMSize
true, // cannotLoop
SideEffects::None, // otherState
SideEffects::None, // storage
SideEffects::Write, // memory
SideEffects::None // transientStorage
},
{std::nullopt, std::nullopt, std::nullopt},
[](
FunctionCall const&,
AbstractAssembly& _assembly,
BuiltinContext&
) {
_assembly.appendAuxDataStore();
}
));
builtins.emplace(createFunction(
"auxdataloadn",
1,
Expand Down
5 changes: 5 additions & 0 deletions libyul/backends/evm/EthAssemblyAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ void EthAssemblyAdapter::appendImmutableAssignment(std::string const& _identifie
m_assembly.appendImmutableAssignment(_identifier);
}

void EthAssemblyAdapter::appendAuxDataStore()
{
m_assembly.appendAuxDataStore();
}

void EthAssemblyAdapter::appendAuxDataLoadN(uint16_t _offset)
{
m_assembly.appendAuxDataLoadN(_offset);
Expand Down
1 change: 1 addition & 0 deletions libyul/backends/evm/EthAssemblyAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class EthAssemblyAdapter: public AbstractAssembly
void appendImmutable(std::string const& _identifier) override;
void appendImmutableAssignment(std::string const& _identifier) override;

void appendAuxDataStore() override;
void appendAuxDataLoadN(uint16_t _offset) override;

void markAsInvalid() override;
Expand Down
5 changes: 5 additions & 0 deletions libyul/backends/evm/NoOutputAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ void NoOutputAssembly::appendAuxDataLoadN(uint16_t)
yulAssert(false, "auxdataloadn not implemented.");
}

void NoOutputAssembly::appendAuxDataStore()
{
yulAssert(false, "auxdatastore not implemented.");
}

NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom):
EVMDialect(_copyFrom.evmVersion(), _copyFrom.eofVersion(), _copyFrom.providesObjectAccess())
{
Expand Down
1 change: 1 addition & 0 deletions libyul/backends/evm/NoOutputAssembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class NoOutputAssembly: public AbstractAssembly
void appendImmutable(std::string const& _identifier) override;
void appendImmutableAssignment(std::string const& _identifier) override;

void appendAuxDataStore() override;
void appendAuxDataLoadN(uint16_t) override;

void markAsInvalid() override {}
Expand Down
59 changes: 59 additions & 0 deletions test/libyul/objectCompiler/eof/auxdata_load_store.yul
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
object "a" {
code {
{
auxdatastore(0, 32, 0x1122334455667788990011223344556677889900112233445566778899001122)
return(0, 32)
}
}

object "b" {
code {
{
mstore(0, auxdataloadn(32))
return(0, 32)
}
}
}

data "data1" hex"48656c6c6f2c20576f726c6421"
}

// ====
// bytecodeFormat: >=EOFv1
// EVMVersion: >=prague
// ----
// Assembly:
// /* "source":66:132 */
// 0x1122334455667788990011223344556677889900112233445566778899001122
// /* "source":62:64 */
// 0x20
// /* "source":59:60 */
// 0x00
// /* "source":46:133 */
// auxdatastore()
// /* "source":156:158 */
// 0x20
// /* "source":153:154 */
// 0x00
// /* "source":146:159 */
// return
// stop
// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421
//
// sub_0: assembly {
// /* "source":248:264 */
// auxdataloadn(32)
// /* "source":245:246 */
// 0x00
// /* "source":238:265 */
// mstore
// /* "source":292:294 */
// 0x20
// /* "source":289:290 */
// 0x00
// /* "source":282:295 */
// return
// }
// Bytecode: ef0001010004020001002a030001001c04000d000080ffff7f112233445566778899001122334455667788990011223344556677889900112260205f015260205ff3ef00010100040200010009040040000080ffffd100205f5260205ff348656c6c6f2c20576f726c6421
// Opcodes: 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP 0x2A SUB STOP ADD STOP SHR DIV STOP 0xD STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT PUSH32 0x1122334455667788990011223344556677889900112233445566778899001122 PUSH1 0x20 PUSH0 ADD MSTORE PUSH1 0x20 PUSH0 RETURN 0xEF STOP ADD ADD STOP DIV MUL STOP ADD STOP MULMOD DIV STOP BLOCKHASH STOP STOP DUP1 SELFDESTRUCT SELFDESTRUCT DATALOADN 0x20 PUSH0 MSTORE PUSH1 0x20 PUSH0 RETURN BASEFEE PUSH6 0x6C6C6F2C2057 PUSH16 0x726C6421000000000000000000000000
// SourceMappings: 66:66:0:-:0;62:2;59:1;46:87;156:2;153:1;146:13
9 changes: 9 additions & 0 deletions test/libyul/yulSyntaxTests/eof/auxdatastore.yul
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
object "b" {
code {
auxdatastore(32, 0, 0x111111111)
}
}

// ====
// EVMVersion: >=shanghai
// bytecodeFormat: >=EOFv1
15 changes: 15 additions & 0 deletions test/libyul/yulSyntaxTests/eof/auxdatastore_in_legacy.yul
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
object "a" {
code {
{
auxdatastore(0, 32, 0x1122334455667788990011223344556677889900112233445566778899001122)
return(0, 32)
}
}

data "data1" hex"48656c6c6f2c20576f726c6421"
}

// ====
// bytecodeFormat: legacy
// ----
// DeclarationError 4619: (46-58): Function "auxdatastore" not found.

0 comments on commit 35e0796

Please sign in to comment.