Browse Source

Some changes to the log functions.

cl-refactor
Christian 10 years ago
parent
commit
8ad6951f38
  1. 8
      libevmcore/Instruction.h
  2. 56
      libsolidity/ExpressionCompiler.cpp
  3. 45
      test/SolidityEndToEndTest.cpp

8
libevmcore/Instruction.h

@ -215,6 +215,14 @@ inline Instruction swapInstruction(unsigned _number)
return Instruction(unsigned(Instruction::SWAP1) + _number - 1); return Instruction(unsigned(Instruction::SWAP1) + _number - 1);
} }
/// @returns the LOG<_number> instruction
inline Instruction logInstruction(unsigned _number)
{
if (asserts(_number <= 4))
BOOST_THROW_EXCEPTION(InvalidOpcode() << errinfo_comment("Invalid LOG instruction requested."));
return Instruction(unsigned(Instruction::LOG0) + _number);
}
/// Information structure for a particular instruction. /// Information structure for a particular instruction.
struct InstructionInfo struct InstructionInfo
{ {

56
libsolidity/ExpressionCompiler.cpp

@ -257,60 +257,22 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
m_context << u256(32) << u256(0) << eth::Instruction::SHA3; m_context << u256(32) << u256(0) << eth::Instruction::SHA3;
break; break;
case Location::LOG0: case Location::LOG0:
arguments.front()->accept(*this);
appendTypeConversion(*arguments.front()->getType(), *function.getParameterTypes().front(), true);
// @todo move this once we actually use memory
CompilerUtils(m_context).storeInMemory(0);
m_context << u256(32) << u256(0) << eth::Instruction::LOG0;
break;
case Location::LOG1: case Location::LOG1:
arguments[1]->accept(*this);
arguments[0]->accept(*this);
appendTypeConversion(*arguments[1]->getType(), *function.getParameterTypes()[1], true);
appendTypeConversion(*arguments[0]->getType(), *function.getParameterTypes()[0], true);
// @todo move this once we actually use memory
CompilerUtils(m_context).storeInMemory(0);
m_context << u256(32) << u256(0) << eth::Instruction::LOG1;
break;
case Location::LOG2: case Location::LOG2:
arguments[2]->accept(*this);
arguments[1]->accept(*this);
arguments[0]->accept(*this);
appendTypeConversion(*arguments[2]->getType(), *function.getParameterTypes()[2], true);
appendTypeConversion(*arguments[1]->getType(), *function.getParameterTypes()[1], true);
appendTypeConversion(*arguments[0]->getType(), *function.getParameterTypes()[0], true);
// @todo move this once we actually use memory
CompilerUtils(m_context).storeInMemory(0);
m_context << u256(32) << u256(0) << eth::Instruction::LOG2;
break;
case Location::LOG3: case Location::LOG3:
arguments[3]->accept(*this);
arguments[2]->accept(*this);
arguments[1]->accept(*this);
arguments[0]->accept(*this);
appendTypeConversion(*arguments[3]->getType(), *function.getParameterTypes()[3], true);
appendTypeConversion(*arguments[2]->getType(), *function.getParameterTypes()[2], true);
appendTypeConversion(*arguments[1]->getType(), *function.getParameterTypes()[1], true);
appendTypeConversion(*arguments[0]->getType(), *function.getParameterTypes()[0], true);
// @todo move this once we actually use memory
CompilerUtils(m_context).storeInMemory(0);
m_context << u256(32) << u256(0) << eth::Instruction::LOG3;
break;
case Location::LOG4: case Location::LOG4:
arguments[4]->accept(*this); {
arguments[3]->accept(*this); unsigned logNumber = int(function.getLocation()) - int(Location::LOG0);
arguments[2]->accept(*this); for (int arg = logNumber; arg >= 0; --arg)
arguments[1]->accept(*this); {
arguments[0]->accept(*this); arguments[arg]->accept(*this);
appendTypeConversion(*arguments[4]->getType(), *function.getParameterTypes()[4], true); appendTypeConversion(*arguments[arg]->getType(), *function.getParameterTypes()[arg], true);
appendTypeConversion(*arguments[3]->getType(), *function.getParameterTypes()[3], true); }
appendTypeConversion(*arguments[2]->getType(), *function.getParameterTypes()[2], true);
appendTypeConversion(*arguments[1]->getType(), *function.getParameterTypes()[1], true);
appendTypeConversion(*arguments[0]->getType(), *function.getParameterTypes()[0], true);
// @todo move this once we actually use memory // @todo move this once we actually use memory
CompilerUtils(m_context).storeInMemory(0); CompilerUtils(m_context).storeInMemory(0);
m_context << u256(32) << u256(0) << eth::Instruction::LOG4; m_context << u256(32) << u256(0) << eth::logInstruction(logNumber);
break; break;
}
case Location::ECRECOVER: case Location::ECRECOVER:
case Location::SHA256: case Location::SHA256:
case Location::RIPEMD160: case Location::RIPEMD160:

45
test/SolidityEndToEndTest.cpp

@ -857,10 +857,8 @@ BOOST_AUTO_TEST_CASE(log0)
" log0(1);\n" " log0(1);\n"
" }\n" " }\n"
"}\n"; "}\n";
u256 amount(130); compileAndRun(sourceCode);
compileAndRun(sourceCode, amount + 1); callContractFunction("a()");
u160 address(23);
callContractFunction("a()", address, amount);
BOOST_CHECK_EQUAL(m_logs.size(), 1); BOOST_CHECK_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1))); BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
@ -874,10 +872,8 @@ BOOST_AUTO_TEST_CASE(log1)
" log1(1, 2);\n" " log1(1, 2);\n"
" }\n" " }\n"
"}\n"; "}\n";
u256 amount(130); compileAndRun(sourceCode);
compileAndRun(sourceCode, amount + 1); callContractFunction("a()");
u160 address(23);
callContractFunction("a()", address, amount);
BOOST_CHECK_EQUAL(m_logs.size(), 1); BOOST_CHECK_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1))); BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
@ -892,10 +888,8 @@ BOOST_AUTO_TEST_CASE(log2)
" log2(1, 2, 3);\n" " log2(1, 2, 3);\n"
" }\n" " }\n"
"}\n"; "}\n";
u256 amount(130); compileAndRun(sourceCode);
compileAndRun(sourceCode, amount + 1); callContractFunction("a()");
u160 address(23);
callContractFunction("a()", address, amount);
BOOST_CHECK_EQUAL(m_logs.size(), 1); BOOST_CHECK_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1))); BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
@ -911,10 +905,8 @@ BOOST_AUTO_TEST_CASE(log3)
" log3(1, 2, 3, 4);\n" " log3(1, 2, 3, 4);\n"
" }\n" " }\n"
"}\n"; "}\n";
u256 amount(130); compileAndRun(sourceCode);
compileAndRun(sourceCode, amount + 1); callContractFunction("a()");
u160 address(23);
callContractFunction("a()", address, amount);
BOOST_CHECK_EQUAL(m_logs.size(), 1); BOOST_CHECK_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1))); BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
@ -930,10 +922,8 @@ BOOST_AUTO_TEST_CASE(log4)
" log4(1, 2, 3, 4, 5);\n" " log4(1, 2, 3, 4, 5);\n"
" }\n" " }\n"
"}\n"; "}\n";
u256 amount(130); compileAndRun(sourceCode);
compileAndRun(sourceCode, amount + 1); callContractFunction("a()");
u160 address(23);
callContractFunction("a()", address, amount);
BOOST_CHECK_EQUAL(m_logs.size(), 1); BOOST_CHECK_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1))); BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
@ -942,6 +932,21 @@ BOOST_AUTO_TEST_CASE(log4)
BOOST_CHECK_EQUAL(m_logs[0].topics[i], h256(u256(i + 2))); BOOST_CHECK_EQUAL(m_logs[0].topics[i], h256(u256(i + 2)));
} }
BOOST_AUTO_TEST_CASE(log_in_constructor)
{
char const* sourceCode = "contract test {\n"
" function test() {\n"
" log1(1, 2);\n"
" }\n"
"}\n";
compileAndRun(sourceCode);
BOOST_CHECK_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
BOOST_CHECK_EQUAL(m_logs[0].topics.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].topics[0], h256(u256(2)));
}
BOOST_AUTO_TEST_CASE(suicide) BOOST_AUTO_TEST_CASE(suicide)
{ {
char const* sourceCode = "contract test {\n" char const* sourceCode = "contract test {\n"

Loading…
Cancel
Save