diff options
author | chriseth <c@ethdev.com> | 2015-10-15 06:42:36 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-10-15 23:38:42 +0800 |
commit | 029b8194892b6b08ce70075bd66f43f66c40e301 (patch) | |
tree | 3cce6cff28599d09ce612633c2d13d76ebe9e7da | |
parent | 039b2a764f3944768bb253102f4c4b788f2dca9c (diff) | |
download | dexon-solidity-029b8194892b6b08ce70075bd66f43f66c40e301.tar.gz dexon-solidity-029b8194892b6b08ce70075bd66f43f66c40e301.tar.zst dexon-solidity-029b8194892b6b08ce70075bd66f43f66c40e301.zip |
Wildcards.
-rw-r--r-- | libsolidity/CompilerUtils.cpp | 32 | ||||
-rw-r--r-- | libsolidity/ExpressionCompiler.cpp | 4 | ||||
-rw-r--r-- | libsolidity/LValue.cpp | 21 | ||||
-rw-r--r-- | libsolidity/Types.cpp | 2 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 9 |
5 files changed, 35 insertions, 33 deletions
diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 34bb08ba..f0dea708 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -552,29 +552,37 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp } case Type::Category::Tuple: { - //@TODO wildcards TupleType const& sourceTuple = dynamic_cast<TupleType const&>(_typeOnStack); TupleType const& targetTuple = dynamic_cast<TupleType const&>(_targetType); - solAssert(sourceTuple.components().size() == targetTuple.components().size(), ""); + // fillRight: remove excess values at right side, !fillRight: remove eccess values at left side + bool fillRight = !targetTuple.components().empty() && ( + !targetTuple.components().back() || + targetTuple.components().front() + ); unsigned depth = sourceTuple.sizeOnStack(); for (size_t i = 0; i < sourceTuple.components().size(); ++i) { - TypePointer const& sourceType = sourceTuple.components()[i]; - TypePointer const& targetType = targetTuple.components()[i]; + TypePointer sourceType = sourceTuple.components()[i]; + TypePointer targetType; + if (fillRight && i < targetTuple.components().size()) + targetType = targetTuple.components()[i]; + else if (!fillRight && targetTuple.components().size() + i >= sourceTuple.components().size()) + targetType = targetTuple.components()[targetTuple.components().size() - (sourceTuple.components().size() - i)]; if (!sourceType) { solAssert(!targetType, ""); continue; } unsigned sourceSize = sourceType->sizeOnStack(); - unsigned targetSize = targetType->sizeOnStack(); - if (*sourceType != *targetType || _cleanupNeeded) + unsigned targetSize = targetType ? targetType->sizeOnStack() : 0; + if (!targetType || *sourceType != *targetType || _cleanupNeeded) { - if (sourceSize > 0) - copyToStackTop(depth, sourceSize); - - convertType(*sourceType, *targetType, _cleanupNeeded); - + if (targetType) + { + if (sourceSize > 0) + copyToStackTop(depth, sourceSize); + convertType(*sourceType, *targetType, _cleanupNeeded); + } if (sourceSize > 0 || targetSize > 0) { // Move it back into its place. @@ -582,8 +590,6 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp m_context << eth::swapInstruction(depth + targetSize - sourceSize) << eth::Instruction::POP; - if (targetSize < sourceSize) - moveToStackTop(sourceSize - targetSize, depth ); // Value shrank for (unsigned j = targetSize; j < sourceSize; ++j) { diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 8109c03b..909d3fe5 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -177,7 +177,6 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& bool ExpressionCompiler::visit(Assignment const& _assignment) { -// cout << "-----Assignment" << endl; CompilerContext::LocationSetter locationSetter(m_context, _assignment); _assignment.rightHandSide().accept(*this); // Perform some conversion already. This will convert storage types to memory and literals @@ -185,10 +184,8 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) TypePointer type = _assignment.rightHandSide().annotation().type->closestTemporaryType( _assignment.leftHandSide().annotation().type ); -// cout << "-----Type conversion" << endl; utils().convertType(*_assignment.rightHandSide().annotation().type, *type); -// cout << "-----LHS" << endl; _assignment.leftHandSide().accept(*this); solAssert(!!m_currentLValue, "LValue not retrieved."); @@ -214,7 +211,6 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP; } } -// cout << "-----Store" << endl; m_currentLValue->storeValue(*type, _assignment.location()); m_currentLValue.reset(); return false; diff --git a/libsolidity/LValue.cpp b/libsolidity/LValue.cpp index 20aa59e1..52441836 100644 --- a/libsolidity/LValue.cpp +++ b/libsolidity/LValue.cpp @@ -496,10 +496,8 @@ void TupleObject::storeValue(Type const& _sourceType, SourceLocation const& _loc { // values are below the lvalue references unsigned valuePos = sizeOnStack(); - - //@TODO wildcards - TypePointers const& valueTypes = dynamic_cast<TupleType const&>(_sourceType).components(); + solAssert(valueTypes.size() == m_lvalues.size(), ""); // valuePos .... refPos ... // We will assign from right to left to optimize stack layout. for (size_t i = 0; i < m_lvalues.size(); ++i) @@ -507,16 +505,15 @@ void TupleObject::storeValue(Type const& _sourceType, SourceLocation const& _loc unique_ptr<LValue> const& lvalue = m_lvalues[m_lvalues.size() - i - 1]; TypePointer const& valType = valueTypes[valueTypes.size() - i - 1]; unsigned stackHeight = m_context.stackHeight(); - solAssert(!!valType, ""); + solAssert(!valType == !lvalue, ""); + if (!lvalue) + continue; valuePos += valType->sizeOnStack(); - if (lvalue) - { - // copy value to top - CompilerUtils(m_context).copyToStackTop(valuePos, valType->sizeOnStack()); - // move lvalue ref above value - CompilerUtils(m_context).moveToStackTop(valType->sizeOnStack(), lvalue->sizeOnStack()); - lvalue->storeValue(*valType, _location, true); - } + // copy value to top + CompilerUtils(m_context).copyToStackTop(valuePos, valType->sizeOnStack()); + // move lvalue ref above value + CompilerUtils(m_context).moveToStackTop(valType->sizeOnStack(), lvalue->sizeOnStack()); + lvalue->storeValue(*valType, _location, true); valuePos += m_context.stackHeight() - stackHeight; } // As the type of an assignment to a tuple type is the empty tuple, we always move. diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index aca959b3..02b86a7f 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -1328,7 +1328,7 @@ TypePointer TupleType::closestTemporaryType(TypePointer const& _targetType) cons size_t si = fillRight ? i : components().size() - i - 1; size_t ti = fillRight ? i : targetComponents.size() - i - 1; if (components()[si] && targetComponents[ti]) - tempComponents[ti] = components()[si]->closestTemporaryType(targetComponents[si]); + tempComponents[ti] = components()[si]->closestTemporaryType(targetComponents[ti]); } return make_shared<TupleType>(tempComponents); } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 36114689..75e43b73 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -5699,8 +5699,8 @@ BOOST_AUTO_TEST_CASE(tuples) if (a != 1 || b != 2 || c[0] != 3) return 2; (a, b) = (b, a); if (a != 2 || b != 1) return 3; -// (a, , b, ) = (8, 9, 10, 11, 12); -// if (a != 8 || b != 10) return 3; + (a, , b, ) = (8, 9, 10, 11, 12); + if (a != 8 || b != 10) return 4; } } )"; @@ -5724,7 +5724,7 @@ BOOST_AUTO_TEST_CASE(destructuring_assignment) } function f(bytes s) returns (uint) { uint loc; - uint[] memArray; + uint[] memory memArray; (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2); if (loc != 8) return 1; if (x != 4) return 2; @@ -5737,6 +5737,9 @@ BOOST_AUTO_TEST_CASE(destructuring_assignment) (memArray, loc) = (arrayData, 3); if (loc != 3) return 9; if (memArray.length != arrayData.length) return 10; + bytes memory memBytes; + (x, memBytes, y[2], ) = (456, s, 789, 101112, 131415); + if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11; } } )"; |