From 66edaf43f4330a4a88de867bec2209f6e63f57a7 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Fri, 24 Apr 2020 16:33:43 -0500 Subject: [PATCH] [Sol - Yul] Add support for built-in logN(). --- .../codegen/ir/IRGeneratorForStatements.cpp | 27 ++++ test/libsolidity/SolidityEndToEndTest.cpp | 146 ++++++++++-------- 2 files changed, 108 insertions(+), 65 deletions(-) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 1dd6dcdd1..d8cb8f49c 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -818,6 +818,33 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) define(_functionCall) << "selfdestruct(" << expressionAsType(*arguments.front(), *parameterTypes.front()) << ")\n"; break; } + case FunctionType::Kind::Log0: + case FunctionType::Kind::Log1: + case FunctionType::Kind::Log2: + case FunctionType::Kind::Log3: + case FunctionType::Kind::Log4: + { + unsigned logNumber = int(functionType->kind()) - int(FunctionType::Kind::Log0); + solAssert(arguments.size() == logNumber + 1, ""); + ABIFunctions abi(m_context.evmVersion(), m_context.revertStrings(), m_context.functionCollector()); + string indexedArgs; + for (unsigned arg = 0; arg < logNumber; ++arg) + indexedArgs += ", " + expressionAsType(*arguments[arg + 1], *(parameterTypes[arg + 1])); + Whiskers templ(R"({ + let := + let := (, ) + (, sub(, ) ) + })"); + templ("pos", m_context.newYulVariable()); + templ("end", m_context.newYulVariable()); + templ("freeMemory", freeMemory()); + templ("encode", abi.tupleEncoder({arguments.front()->annotation().type},{parameterTypes.front()})); + templ("nonIndexedArgs", IRVariable(*arguments.front()).commaSeparatedList()); + templ("log", "log" + to_string(logNumber)); + templ("indexedArgs", indexedArgs); + m_code << templ.render(); + break; + } default: solUnimplemented("FunctionKind " + toString(static_cast(functionType->kind())) + " not yet implemented"); } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index a0e59170b..153d6a8f4 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1126,12 +1126,14 @@ BOOST_AUTO_TEST_CASE(log0) } } )"; - compileAndRun(sourceCode); - callContractFunction("a()"); - BOOST_REQUIRE_EQUAL(numLogs(), 1); - BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); - BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); - BOOST_CHECK_EQUAL(numLogTopics(0), 0); + ALSO_VIA_YUL( + compileAndRun(sourceCode); + callContractFunction("a()"); + BOOST_REQUIRE_EQUAL(numLogs(), 1); + BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); + BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); + BOOST_CHECK_EQUAL(numLogTopics(0), 0); + ) } BOOST_AUTO_TEST_CASE(log1) @@ -1143,13 +1145,15 @@ BOOST_AUTO_TEST_CASE(log1) } } )"; - compileAndRun(sourceCode); - callContractFunction("a()"); - BOOST_REQUIRE_EQUAL(numLogs(), 1); - BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); - BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); - BOOST_REQUIRE_EQUAL(numLogTopics(0), 1); - BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2))); + ALSO_VIA_YUL( + compileAndRun(sourceCode); + callContractFunction("a()"); + BOOST_REQUIRE_EQUAL(numLogs(), 1); + BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); + BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); + BOOST_REQUIRE_EQUAL(numLogTopics(0), 1); + BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2))); + ) } BOOST_AUTO_TEST_CASE(log2) @@ -1161,14 +1165,16 @@ BOOST_AUTO_TEST_CASE(log2) } } )"; - compileAndRun(sourceCode); - callContractFunction("a()"); - BOOST_REQUIRE_EQUAL(numLogs(), 1); - BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); - BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); - BOOST_REQUIRE_EQUAL(numLogTopics(0), 2); - for (unsigned i = 0; i < 2; ++i) - BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2))); + ALSO_VIA_YUL( + compileAndRun(sourceCode); + callContractFunction("a()"); + BOOST_REQUIRE_EQUAL(numLogs(), 1); + BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); + BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); + BOOST_REQUIRE_EQUAL(numLogTopics(0), 2); + for (unsigned i = 0; i < 2; ++i) + BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2))); + ) } BOOST_AUTO_TEST_CASE(log3) @@ -1180,14 +1186,16 @@ BOOST_AUTO_TEST_CASE(log3) } } )"; - compileAndRun(sourceCode); - callContractFunction("a()"); - BOOST_REQUIRE_EQUAL(numLogs(), 1); - BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); - BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); - BOOST_REQUIRE_EQUAL(numLogTopics(0), 3); - for (unsigned i = 0; i < 3; ++i) - BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2))); + ALSO_VIA_YUL( + compileAndRun(sourceCode); + callContractFunction("a()"); + BOOST_REQUIRE_EQUAL(numLogs(), 1); + BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); + BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); + BOOST_REQUIRE_EQUAL(numLogTopics(0), 3); + for (unsigned i = 0; i < 3; ++i) + BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2))); + ) } BOOST_AUTO_TEST_CASE(log4) @@ -1199,14 +1207,16 @@ BOOST_AUTO_TEST_CASE(log4) } } )"; - compileAndRun(sourceCode); - callContractFunction("a()"); - BOOST_REQUIRE_EQUAL(numLogs(), 1); - BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); - BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); - BOOST_REQUIRE_EQUAL(numLogTopics(0), 4); - for (unsigned i = 0; i < 4; ++i) - BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2))); + ALSO_VIA_YUL( + compileAndRun(sourceCode); + callContractFunction("a()"); + BOOST_REQUIRE_EQUAL(numLogs(), 1); + BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); + BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); + BOOST_REQUIRE_EQUAL(numLogTopics(0), 4); + for (unsigned i = 0; i < 4; ++i) + BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2))); + ) } BOOST_AUTO_TEST_CASE(log_in_constructor) @@ -1218,12 +1228,14 @@ BOOST_AUTO_TEST_CASE(log_in_constructor) } } )"; - compileAndRun(sourceCode); - BOOST_REQUIRE_EQUAL(numLogs(), 1); - BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); - BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); - BOOST_REQUIRE_EQUAL(numLogTopics(0), 1); - BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2))); + ALSO_VIA_YUL( + compileAndRun(sourceCode); + BOOST_REQUIRE_EQUAL(numLogs(), 1); + BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); + BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1))); + BOOST_REQUIRE_EQUAL(numLogTopics(0), 1); + BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2))); + ) } BOOST_AUTO_TEST_CASE(selfdestruct) @@ -1776,20 +1788,22 @@ BOOST_AUTO_TEST_CASE(event) } } )"; - compileAndRun(sourceCode); - u256 value(18); - u256 id(0x1234); - for (bool manually: {true, false}) - { - callContractFunctionWithValue("deposit(bytes32,bool)", value, id, manually); - BOOST_REQUIRE_EQUAL(numLogs(), 1); - BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); - BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(value))); - BOOST_REQUIRE_EQUAL(numLogTopics(0), 3); - BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Deposit(address,bytes32,uint256)"))); - BOOST_CHECK_EQUAL(logTopic(0, 1), h256(m_sender, h256::AlignRight)); - BOOST_CHECK_EQUAL(logTopic(0, 2), h256(id)); - } + ALSO_VIA_YUL( + compileAndRun(sourceCode); + u256 value(18); + u256 id(0x1234); + for (bool manually: {true, false}) + { + callContractFunctionWithValue("deposit(bytes32,bool)", value, id, manually); + BOOST_REQUIRE_EQUAL(numLogs(), 1); + BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); + BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(value))); + BOOST_REQUIRE_EQUAL(numLogTopics(0), 3); + BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Deposit(address,bytes32,uint256)"))); + BOOST_CHECK_EQUAL(logTopic(0, 1), h256(m_sender, h256::AlignRight)); + BOOST_CHECK_EQUAL(logTopic(0, 2), h256(id)); + } + ) } BOOST_AUTO_TEST_CASE(event_emit) @@ -1803,7 +1817,7 @@ BOOST_AUTO_TEST_CASE(event_emit) } )"; ALSO_VIA_YUL( - compileAndRun(sourceCode); + compileAndRun(sourceCode); u256 value(18); u256 id(0x1234); callContractFunctionWithValue("deposit(bytes32)", value, id); @@ -1852,13 +1866,15 @@ BOOST_AUTO_TEST_CASE(event_access_through_base_name_emit) } } )"; - compileAndRun(sourceCode); - callContractFunction("f()"); - BOOST_REQUIRE_EQUAL(numLogs(), 1); - BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); - BOOST_CHECK(logData(0).empty()); - BOOST_REQUIRE_EQUAL(numLogTopics(0), 1); - BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("x()"))); + ALSO_VIA_YUL( + compileAndRun(sourceCode); + callContractFunction("f()"); + BOOST_REQUIRE_EQUAL(numLogs(), 1); + BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); + BOOST_CHECK(logData(0).empty()); + BOOST_REQUIRE_EQUAL(numLogTopics(0), 1); + BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("x()"))); + ); } BOOST_AUTO_TEST_CASE(events_with_same_name)