mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[yul] Adding support for accessing subobjects via .
Co-authored-by: Kamil Śliwak <kamil.sliwak@codepoets.it>
This commit is contained in:
co-authored by
Kamil Śliwak
parent
952101996c
commit
6f97e6153c
+51
-9
@@ -24,9 +24,10 @@
|
||||
#include <libyul/AsmPrinter.h>
|
||||
#include <libyul/Exceptions.h>
|
||||
|
||||
#include <libsolutil/Visitor.h>
|
||||
#include <libsolutil/CommonData.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
using namespace std;
|
||||
@@ -62,13 +63,54 @@ string Object::toString(Dialect const* _dialect) const
|
||||
return "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}";
|
||||
}
|
||||
|
||||
set<YulString> Object::dataNames() const
|
||||
set<YulString> Object::qualifiedDataNames() const
|
||||
{
|
||||
set<YulString> names;
|
||||
names.insert(name);
|
||||
for (auto const& subObject: subIndexByName)
|
||||
names.insert(subObject.first);
|
||||
// The empty name is not valid
|
||||
names.erase(YulString{});
|
||||
return names;
|
||||
set<YulString> qualifiedNames = name.empty() ? set<YulString>{} : set<YulString>{name};
|
||||
for (shared_ptr<ObjectNode> const& subObjectNode: subObjects)
|
||||
{
|
||||
yulAssert(qualifiedNames.count(subObjectNode->name) == 0, "");
|
||||
qualifiedNames.insert(subObjectNode->name);
|
||||
if (auto const* subObject = dynamic_cast<Object const*>(subObjectNode.get()))
|
||||
for (YulString const& subSubObj: subObject->qualifiedDataNames())
|
||||
if (subObject->name != subSubObj)
|
||||
{
|
||||
yulAssert(qualifiedNames.count(YulString{subObject->name.str() + "." + subSubObj.str()}) == 0, "");
|
||||
qualifiedNames.insert(YulString{subObject->name.str() + "." + subSubObj.str()});
|
||||
}
|
||||
}
|
||||
|
||||
yulAssert(qualifiedNames.count(YulString{}) == 0, "");
|
||||
qualifiedNames.erase(YulString{});
|
||||
return qualifiedNames;
|
||||
}
|
||||
|
||||
vector<size_t> Object::pathToSubObject(YulString _qualifiedName) const
|
||||
{
|
||||
yulAssert(_qualifiedName != name, "");
|
||||
yulAssert(subIndexByName.count(name) == 0, "");
|
||||
|
||||
if (boost::algorithm::starts_with(_qualifiedName.str(), name.str() + "."))
|
||||
_qualifiedName = YulString{_qualifiedName.str().substr(name.str().length() + 1)};
|
||||
yulAssert(!_qualifiedName.empty(), "");
|
||||
|
||||
vector<string> subObjectPathComponents;
|
||||
boost::algorithm::split(subObjectPathComponents, _qualifiedName.str(), boost::is_any_of("."));
|
||||
|
||||
vector<size_t> path;
|
||||
Object const* object = this;
|
||||
for (string const& currentSubObjectName: subObjectPathComponents)
|
||||
{
|
||||
yulAssert(!currentSubObjectName.empty(), "");
|
||||
auto subIndexIt = object->subIndexByName.find(YulString{currentSubObjectName});
|
||||
yulAssert(
|
||||
subIndexIt != object->subIndexByName.end(),
|
||||
"Assembly object <" + _qualifiedName.str() + "> not found or does not contain code."
|
||||
);
|
||||
object = dynamic_cast<Object const*>(object->subObjects[subIndexIt->second].get());
|
||||
yulAssert(object, "Assembly object <" + _qualifiedName.str() + "> not found or does not contain code.");
|
||||
yulAssert(object->subId != numeric_limits<size_t>::max(), "");
|
||||
path.push_back({object->subId});
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user