push() for byte arrays also properly implemented

This commit is contained in:
Lefteris Karapetsas 2015-10-15 14:37:11 +02:00
parent 9224c1f712
commit a823de2d58
2 changed files with 16 additions and 13 deletions

View File

@ -624,7 +624,6 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
break; break;
} }
case Location::ByteArrayPush: case Location::ByteArrayPush:
solAssert(false, "Not properly implemented yet");
case Location::ArrayPush: case Location::ArrayPush:
{ {
_functionCall.expression().accept(*this); _functionCall.expression().accept(*this);
@ -651,12 +650,15 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
arguments[0]->accept(*this); arguments[0]->accept(*this);
// stack: newLength storageSlot slotOffset argValue // stack: newLength storageSlot slotOffset argValue
TypePointer type = arguments[0]->annotation().type; TypePointer type = arguments[0]->annotation().type;
utils().convertType(*type, *type->mobileType()); utils().convertType(*type, *arrayType->baseType());
type = type->mobileType(); type = arrayType->baseType();
utils().moveToStackTop(1 + type->sizeOnStack()); utils().moveToStackTop(1 + type->sizeOnStack());
utils().moveToStackTop(1 + type->sizeOnStack()); utils().moveToStackTop(1 + type->sizeOnStack());
// stack: newLength argValue storageSlot slotOffset // stack: newLength argValue storageSlot slotOffset
StorageItem(m_context, *paramType).storeValue(*type, _functionCall.location(), true); if (function.location() == Location::ArrayPush)
StorageItem(m_context, *paramType).storeValue(*type, _functionCall.location(), true);
else
StorageByteArrayElement(m_context).storeValue(*type, _functionCall.location(), true);
break; break;
} }
default: default:

View File

@ -3495,26 +3495,27 @@ BOOST_AUTO_TEST_CASE(array_push)
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test()") == encodeArgs(5, 4, 3, 3)); BOOST_CHECK(callContractFunction("test()") == encodeArgs(5, 4, 3, 3));
} }
#if 0 // reactivate once ByteArrayPush is properly implemented
BOOST_AUTO_TEST_CASE(byte_array_push) BOOST_AUTO_TEST_CASE(byte_array_push)
{ {
char const* sourceCode = R"( char const* sourceCode = R"(
contract c { contract c {
bytes data; bytes data;
function test() returns (byte x, byte y, byte z, uint l) { function test() returns (bool x) {
data.push(5); if (data.push(5) != 1) return true;
x = data[0]; if (data[0] != 5) return true;
data.push(4); data.push(4);
y = data[1]; if (data[1] != 4) return true;
l = data.push(3); uint l = data.push(3);
z = data[2]; if (data[2] != 3) return true;
if (l != 3) return true;
} }
} }
)"; )";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test()") == encodeArgs(5, 4, 3, 3)); BOOST_CHECK(callContractFunction("test()") == encodeArgs(false));
} }
#endif
BOOST_AUTO_TEST_CASE(external_array_args) BOOST_AUTO_TEST_CASE(external_array_args)
{ {
char const* sourceCode = R"( char const* sourceCode = R"(