Adding event and error selector fields on the lines of the function selector fields

This commit is contained in:
nishant-sachdeva
2022-05-23 10:49:16 +02:00
committed by chriseth
parent 2cb29dbd35
commit d4c06d2b4e
13 changed files with 273 additions and 5 deletions
+1 -1
View File
@@ -1216,7 +1216,7 @@ public:
FunctionTypePointer functionType(bool /*_internal*/) const override;
bool isVisibleInDerivedContracts() const override { return true; }
bool isVisibleViaContractTypeAccess() const override { return false; /* TODO */ }
bool isVisibleViaContractTypeAccess() const override { return true; }
EventDefinitionAnnotation& annotation() const override;
+6
View File
@@ -3335,6 +3335,12 @@ MemberList::MemberMap FunctionType::nativeMembers(ASTNode const* _scope) const
}
case Kind::Error:
return {{"selector", TypeProvider::fixedBytes(4)}};
case Kind::Event:
{
if (!(dynamic_cast<EventDefinition const&>(declaration()).isAnonymous()))
return {{"selector", TypeProvider::fixedBytes(32)}};
return MemberList::MemberMap();
}
default:
return MemberList::MemberMap();
}
+12 -3
View File
@@ -1602,9 +1602,14 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
{
if (functionType->hasDeclaration())
{
m_context << functionType->externalIdentifier();
/// need to store it as bytes4
utils().leftShiftNumberOnStack(224);
if (functionType->kind() == FunctionType::Kind::Event)
m_context << u256(h256::Arith(util::keccak256(functionType->externalSignature())));
else
{
m_context << functionType->externalIdentifier();
/// need to store it as bytes4
utils().leftShiftNumberOnStack(224);
}
return false;
}
else if (auto const* expr = dynamic_cast<MemberAccess const*>(&_memberAccess.expression()))
@@ -1775,9 +1780,13 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
if (member == "selector")
{
auto const& functionType = dynamic_cast<FunctionType const&>(*_memberAccess.expression().annotation().type);
// all events should have already been caught by this stage
solAssert(!(functionType.kind() == FunctionType::Kind::Event));
if (functionType.kind() == FunctionType::Kind::External)
CompilerUtils(m_context).popStackSlots(functionType.sizeOnStack() - 2);
m_context << Instruction::SWAP1 << Instruction::POP;
/// need to store it as bytes4
utils().leftShiftNumberOnStack(224);
}
@@ -1785,7 +1785,20 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
functionType.declaration().isPartOfExternalInterface(),
""
);
define(IRVariable{_memberAccess}) << formatNumber(functionType.externalIdentifier() << 224) << "\n";
define(IRVariable{_memberAccess}) << formatNumber(
util::selectorFromSignature(functionType.externalSignature())
) << "\n";
}
else if (functionType.kind() == FunctionType::Kind::Event)
{
solAssert(functionType.hasDeclaration());
solAssert(functionType.kind() == FunctionType::Kind::Event);
solAssert(
!(dynamic_cast<EventDefinition const&>(functionType.declaration()).isAnonymous())
);
define(IRVariable{_memberAccess}) << formatNumber(
u256(h256::Arith(util::keccak256(functionType.externalSignature())))
) << "\n";
}
else
solAssert(false, "Invalid use of .selector: " + functionType.toString(false));