Browse Source

Merge branch 'develop' of https://github.com/ethereum/cpp-ethereum into develop

cl-refactor
Vlad Gluhovsky 10 years ago
parent
commit
204bce1cbe
  1. 46
      libsolidity/Compiler.cpp
  2. 10
      test/libsolidity/SolidityCompiler.cpp
  3. 17
      test/libsolidity/SolidityEndToEndTest.cpp

46
libsolidity/Compiler.cpp

@ -206,16 +206,9 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract)
void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool _fromMemory) void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool _fromMemory)
{ {
// We do not check the calldata size, everything is zero-padded. // We do not check the calldata size, everything is zero-paddedd
unsigned offset(CompilerUtils::dataStartOffset);
bigint parameterHeadEnd = offset; m_context << u256(CompilerUtils::dataStartOffset);
for (TypePointer const& type: _typeParameters)
parameterHeadEnd += type->isDynamicallySized() ? 32 : type->getCalldataEncodedSize();
solAssert(parameterHeadEnd <= numeric_limits<unsigned>::max(), "Arguments too large.");
unsigned stackHeightOfPreviousDynamicArgument = 0;
ArrayType const* previousDynamicType = nullptr;
for (TypePointer const& type: _typeParameters) for (TypePointer const& type: _typeParameters)
{ {
switch (type->getCategory()) switch (type->getCategory())
@ -223,34 +216,31 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
case Type::Category::Array: case Type::Category::Array:
if (type->isDynamicallySized()) if (type->isDynamicallySized())
{ {
// put on stack: data_offset length // put on stack: data_pointer length
unsigned newStackHeight = m_context.getStackHeight(); CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory);
if (previousDynamicType) // stack: data_offset next_pointer
{ //@todo once we support nested arrays, this offset needs to be dynamic.
// Retrieve data start offset by adding length to start offset of previous dynamic type m_context << eth::Instruction::SWAP1 << u256(CompilerUtils::dataStartOffset);
unsigned stackDepth = m_context.getStackHeight() - stackHeightOfPreviousDynamicArgument; m_context << eth::Instruction::ADD;
solAssert(stackDepth <= 16, "Stack too deep."); // stack: next_pointer data_pointer
m_context << eth::dupInstruction(stackDepth) << eth::dupInstruction(stackDepth); // retrieve length
ArrayUtils(m_context).convertLengthToSize(*previousDynamicType, true); CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory, true);
m_context << eth::Instruction::ADD; // stack: next_pointer length data_pointer
} m_context << eth::Instruction::SWAP2;
else
m_context << u256(parameterHeadEnd);
stackHeightOfPreviousDynamicArgument = newStackHeight;
previousDynamicType = &dynamic_cast<ArrayType const&>(*type);
offset += CompilerUtils(m_context).loadFromMemory(offset, IntegerType(256), !_fromMemory);
} }
else else
{ {
m_context << u256(offset); // leave the pointer on the stack
offset += type->getCalldataEncodedSize(); m_context << eth::Instruction::DUP1;
m_context << u256(type->getCalldataEncodedSize()) << eth::Instruction::ADD;
} }
break; break;
default: default:
solAssert(!type->isDynamicallySized(), "Unknown dynamically sized type: " + type->toString()); solAssert(!type->isDynamicallySized(), "Unknown dynamically sized type: " + type->toString());
offset += CompilerUtils(m_context).loadFromMemory(offset, *type, !_fromMemory, true); CompilerUtils(m_context).loadFromMemoryDynamic(*type, !_fromMemory, true);
} }
} }
m_context << eth::Instruction::POP;
} }
void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters) void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters)

10
test/libsolidity/SolidityCompiler.cpp

@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(smoke_test)
"}\n"; "}\n";
bytes code = compileContract(sourceCode); bytes code = compileContract(sourceCode);
unsigned boilerplateSize = 70; unsigned boilerplateSize = 73;
bytes expectation({byte(Instruction::JUMPDEST), bytes expectation({byte(Instruction::JUMPDEST),
byte(Instruction::PUSH1), 0x0, // initialize local variable x byte(Instruction::PUSH1), 0x0, // initialize local variable x
byte(Instruction::PUSH1), 0x2, byte(Instruction::PUSH1), 0x2,
@ -114,8 +114,8 @@ BOOST_AUTO_TEST_CASE(ifStatement)
" function f() { bool x; if (x) 77; else if (!x) 78; else 79; }" " function f() { bool x; if (x) 77; else if (!x) 78; else 79; }"
"}\n"; "}\n";
bytes code = compileContract(sourceCode); bytes code = compileContract(sourceCode);
unsigned shift = 57; unsigned shift = 60;
unsigned boilerplateSize = 70; unsigned boilerplateSize = 73;
bytes expectation({byte(Instruction::JUMPDEST), bytes expectation({byte(Instruction::JUMPDEST),
byte(Instruction::PUSH1), 0x0, byte(Instruction::PUSH1), 0x0,
byte(Instruction::DUP1), byte(Instruction::DUP1),
@ -155,8 +155,8 @@ BOOST_AUTO_TEST_CASE(loops)
" function f() { while(true){1;break;2;continue;3;return;4;} }" " function f() { while(true){1;break;2;continue;3;return;4;} }"
"}\n"; "}\n";
bytes code = compileContract(sourceCode); bytes code = compileContract(sourceCode);
unsigned shift = 57; unsigned shift = 60;
unsigned boilerplateSize = 70; unsigned boilerplateSize = 73;
bytes expectation({byte(Instruction::JUMPDEST), bytes expectation({byte(Instruction::JUMPDEST),
byte(Instruction::JUMPDEST), byte(Instruction::JUMPDEST),
byte(Instruction::PUSH1), 0x1, byte(Instruction::PUSH1), 0x1,

17
test/libsolidity/SolidityEndToEndTest.cpp

@ -2962,12 +2962,13 @@ BOOST_AUTO_TEST_CASE(bytes_in_arguments)
} }
)"; )";
compileAndRun(sourceCode); compileAndRun(sourceCode);
string innercalldata1 = asString(FixedHash<4>(dev::sha3("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9)); string innercalldata1 = asString(FixedHash<4>(dev::sha3("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9));
bytes calldata1 = encodeArgs(u256(innercalldata1.length()), 12, innercalldata1, 13);
string innercalldata2 = asString(FixedHash<4>(dev::sha3("g(uint256)")).asBytes() + encodeArgs(3)); string innercalldata2 = asString(FixedHash<4>(dev::sha3("g(uint256)")).asBytes() + encodeArgs(3));
bytes calldata = encodeArgs( bytes calldata = encodeArgs(
12, u256(innercalldata1.length()), u256(innercalldata2.length()), 13, 12, 32 * 4, u256(32 * 4 + 32 + (innercalldata1.length() + 31) / 32 * 32), 13,
innercalldata1, innercalldata2); u256(innercalldata1.length()), innercalldata1,
u256(innercalldata2.length()), innercalldata2);
BOOST_CHECK(callContractFunction("test(uint256,bytes,bytes,uint256)", calldata) BOOST_CHECK(callContractFunction("test(uint256,bytes,bytes,uint256)", calldata)
== encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length()))); == encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length())));
} }
@ -3383,9 +3384,10 @@ BOOST_AUTO_TEST_CASE(external_array_args)
compileAndRun(sourceCode); compileAndRun(sourceCode);
bytes params = encodeArgs( bytes params = encodeArgs(
1, 2, 3, 4, 5, 6, 7, 8, // a 1, 2, 3, 4, 5, 6, 7, 8, // a
3, // b.length 32 * (8 + 1 + 5 + 1 + 1 + 1), // offset to b
21, 22, 23, 24, 25, // c 21, 22, 23, 24, 25, // c
0, 1, 2, // (a,b,c)_index 0, 1, 2, // (a,b,c)_index
3, // b.length
11, 12, 13 // b 11, 12, 13 // b
); );
BOOST_CHECK(callContractFunction("test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256)", params) == encodeArgs(1, 12, 23)); BOOST_CHECK(callContractFunction("test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256)", params) == encodeArgs(1, 12, 23));
@ -3422,8 +3424,8 @@ BOOST_AUTO_TEST_CASE(bytes_index_access)
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33}; 30, 31, 32, 33};
BOOST_CHECK(callContractFunction("direct(bytes,uint256)", u256(array.length()), 32, array) == encodeArgs(32)); BOOST_CHECK(callContractFunction("direct(bytes,uint256)", 64, 33, u256(array.length()), array) == encodeArgs(33));
BOOST_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", u256(array.length()), 32, array) == encodeArgs(32)); BOOST_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", 64, 33, u256(array.length()), array) == encodeArgs(33));
BOOST_CHECK(callContractFunction("storageWrite()") == encodeArgs(0x193)); BOOST_CHECK(callContractFunction("storageWrite()") == encodeArgs(0x193));
} }
@ -3474,6 +3476,7 @@ BOOST_AUTO_TEST_CASE(array_copy_calldata_storage)
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("store(uint256[9],uint8[3][])", encodeArgs( BOOST_CHECK(callContractFunction("store(uint256[9],uint8[3][])", encodeArgs(
21, 22, 23, 24, 25, 26, 27, 28, 29, // a 21, 22, 23, 24, 25, 26, 27, 28, 29, // a
u256(32 * (9 + 1)),
4, // size of b 4, // size of b
1, 2, 3, // b[0] 1, 2, 3, // b[0]
11, 12, 13, // b[1] 11, 12, 13, // b[1]
@ -3502,7 +3505,7 @@ BOOST_AUTO_TEST_CASE(array_copy_nested_array)
)"; )";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test(uint256[2][])", encodeArgs( BOOST_CHECK(callContractFunction("test(uint256[2][])", encodeArgs(
3, 32, 3,
7, 8, 7, 8,
9, 10, 9, 10,
11, 12 11, 12

Loading…
Cancel
Save