mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Events.
This commit is contained in:
@@ -94,8 +94,11 @@ string IRGenerationContext::newYulVariable()
|
||||
string IRGenerationContext::variable(Expression const& _expression)
|
||||
{
|
||||
unsigned size = _expression.annotation().type->sizeOnStack();
|
||||
solUnimplementedAssert(size == 1, "");
|
||||
return "expr_" + to_string(_expression.id());
|
||||
string var = "expr_" + to_string(_expression.id());
|
||||
if (size == 1)
|
||||
return var;
|
||||
else
|
||||
return YulUtilFunctions::suffixedVariableNameList(move(var) + "_", 1, 1 + size);
|
||||
}
|
||||
|
||||
string IRGenerationContext::internalDispatch(size_t _in, size_t _out)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <libsolidity/codegen/ir/IRGenerationContext.h>
|
||||
#include <libsolidity/codegen/ir/IRLValue.h>
|
||||
#include <libsolidity/codegen/YulUtilFunctions.h>
|
||||
#include <libsolidity/codegen/ABIFunctions.h>
|
||||
#include <libsolidity/codegen/CompilerUtils.h>
|
||||
#include <libsolidity/ast/TypeProvider.h>
|
||||
|
||||
@@ -31,6 +32,7 @@
|
||||
#include <libyul/AsmData.h>
|
||||
#include <libyul/optimiser/ASTCopier.h>
|
||||
|
||||
#include <libdevcore/Whiskers.h>
|
||||
#include <libdevcore/StringUtils.h>
|
||||
#include <libdevcore/Whiskers.h>
|
||||
#include <libdevcore/Keccak256.h>
|
||||
@@ -370,6 +372,65 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
")\n";
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Event:
|
||||
{
|
||||
auto const& event = dynamic_cast<EventDefinition const&>(functionType->declaration());
|
||||
TypePointers paramTypes = functionType->parameterTypes();
|
||||
ABIFunctions abi(m_context.evmVersion(), m_context.functionCollector());
|
||||
|
||||
vector<string> indexedArgs;
|
||||
string nonIndexedArgs;
|
||||
TypePointers nonIndexedArgTypes;
|
||||
TypePointers nonIndexedParamTypes;
|
||||
if (!event.isAnonymous())
|
||||
{
|
||||
indexedArgs.emplace_back(m_context.newYulVariable());
|
||||
string signature = formatNumber(u256(h256::Arith(dev::keccak256(functionType->externalSignature()))));
|
||||
m_code << "let " << indexedArgs.back() << " := " << signature << "\n";
|
||||
}
|
||||
for (size_t i = 0; i < event.parameters().size(); ++i)
|
||||
{
|
||||
Expression const& arg = *arguments[i];
|
||||
if (event.parameters()[i]->isIndexed())
|
||||
{
|
||||
string value;
|
||||
indexedArgs.emplace_back(m_context.newYulVariable());
|
||||
if (auto const& referenceType = dynamic_cast<ReferenceType const*>(paramTypes[i]))
|
||||
value =
|
||||
m_utils.packedHashFunction({arg.annotation().type}, {referenceType}) +
|
||||
"(" +
|
||||
m_context.variable(arg) +
|
||||
")";
|
||||
else
|
||||
value = expressionAsType(arg, *paramTypes[i]);
|
||||
m_code << "let " << indexedArgs.back() << " := " << value << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
string vars = m_context.variable(arg);
|
||||
if (!vars.empty())
|
||||
// In reverse because abi_encode expects it like that.
|
||||
nonIndexedArgs = ", " + move(vars) + nonIndexedArgs;
|
||||
nonIndexedArgTypes.push_back(arg.annotation().type);
|
||||
nonIndexedParamTypes.push_back(paramTypes[i]);
|
||||
}
|
||||
}
|
||||
solAssert(indexedArgs.size() <= 4, "Too many indexed arguments.");
|
||||
Whiskers templ(R"({
|
||||
let <pos> := mload(<freeMemoryPointer>)
|
||||
let <end> := <encode>(<pos> <nonIndexedArgs>)
|
||||
<log>(<pos>, sub(<end>, <pos>) <indexedArgs>)
|
||||
})");
|
||||
templ("pos", m_context.newYulVariable());
|
||||
templ("end", m_context.newYulVariable());
|
||||
templ("freeMemoryPointer", to_string(CompilerUtils::freeMemoryPointer));
|
||||
templ("encode", abi.tupleEncoder(nonIndexedArgTypes, nonIndexedParamTypes));
|
||||
templ("nonIndexedArgs", nonIndexedArgs);
|
||||
templ("log", "log" + to_string(indexedArgs.size()));
|
||||
templ("indexedArgs", joinHumanReadablePrefixed(indexedArgs));
|
||||
m_code << templ.render();
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Assert:
|
||||
case FunctionType::Kind::Require:
|
||||
{
|
||||
@@ -596,8 +657,26 @@ void IRGeneratorForStatements::endVisit(Identifier const& _identifier)
|
||||
|
||||
setLValue(_identifier, move(lvalue));
|
||||
}
|
||||
else if (auto contract = dynamic_cast<ContractDefinition const*>(declaration))
|
||||
{
|
||||
solUnimplementedAssert(!contract->isLibrary(), "Libraries not yet supported.");
|
||||
}
|
||||
else if (dynamic_cast<EventDefinition const*>(declaration))
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else if (dynamic_cast<EnumDefinition const*>(declaration))
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else if (dynamic_cast<StructDefinition const*>(declaration))
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else
|
||||
solUnimplemented("Identifier of type " + declaration->type()->toString() + " not implemented.");
|
||||
{
|
||||
solAssert(false, "Identifier type not expected in expression context.");
|
||||
}
|
||||
}
|
||||
|
||||
bool IRGeneratorForStatements::visit(Literal const& _literal)
|
||||
|
||||
Reference in New Issue
Block a user