mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Implement Dynamic array push and fix test
Still a work in progress. There is a disturbance in the stack at the moment and that's why there are some cout statements left for debugging.
This commit is contained in:
@@ -623,6 +623,43 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
appendExternalFunctionCall(function, arguments);
|
||||
break;
|
||||
}
|
||||
case Location::ArrayPush:
|
||||
{
|
||||
cout << "Beginning " << m_context.stackHeight() << endl;
|
||||
solAssert(function.parameterTypes().size() == 1, "");
|
||||
solAssert(!!function.parameterTypes()[0], "");
|
||||
TypePointer const& paramType = function.parameterTypes()[0];
|
||||
ArrayType arrayType(DataLocation::Storage, paramType);
|
||||
// get the current length
|
||||
ArrayUtils(m_context).retrieveLength(arrayType);
|
||||
m_context << eth::Instruction::DUP1;
|
||||
cout << "After DUP1 " << m_context.stackHeight() << endl;
|
||||
// stack: ArrayReference currentLength currentLength
|
||||
m_context << u256(1) << eth::Instruction::ADD;
|
||||
// stack: ArrayReference currentLength newLength
|
||||
m_context << eth::Instruction::DUP3 << eth::Instruction::DUP2;
|
||||
ArrayUtils(m_context).resizeDynamicArray(arrayType);
|
||||
cout << "After Resize Dynamic Array " << m_context.stackHeight() << endl;
|
||||
m_context << eth::Instruction::SWAP2 << eth::Instruction::SWAP1;
|
||||
// stack: newLength ArrayReference oldLength
|
||||
ArrayUtils(m_context).accessIndex(arrayType, false);
|
||||
cout << "After Access Index " << m_context.stackHeight() << endl;
|
||||
|
||||
// stack: newLength storageSlot slotOffset
|
||||
arguments[0]->accept(*this);
|
||||
// stack: newLength storageSlot slotOffset argValue
|
||||
TypePointer type = arguments[0]->annotation().type;
|
||||
utils().convertType(*type, *type->mobileType());
|
||||
type = type->mobileType();
|
||||
utils().moveToStackTop(1 + type->sizeOnStack());
|
||||
utils().moveToStackTop(1 + type->sizeOnStack());
|
||||
// stack: newLength argValue storageSlot slotOffset
|
||||
StorageItem(m_context, *paramType).storeValue(*type, _functionCall.location(), true);
|
||||
break;
|
||||
}
|
||||
case Location::ByteArrayPush:
|
||||
// TODO
|
||||
break;
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid function type."));
|
||||
}
|
||||
@@ -806,16 +843,12 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (member == "push" && type.isDynamicallySized() && type.location() == DataLocation::Storage)
|
||||
else if (member == "push")
|
||||
{
|
||||
if (type.isByteArray())
|
||||
{
|
||||
solAssert(!type.isString(), "Index access to string is not allowed.");
|
||||
setLValue<StorageByteArrayElement>(_indexAccess);
|
||||
}
|
||||
else
|
||||
setLValueToStorageItem(_indexAccess);
|
||||
setLValue<StorageArrayLength>(_memberAccess, type);
|
||||
solAssert(
|
||||
type.isDynamicallySized() && type.location() == DataLocation::Storage,
|
||||
"Tried to use .push() on a non-dynamically sized array"
|
||||
);
|
||||
}
|
||||
else
|
||||
solAssert(false, "Illegal array member.");
|
||||
|
||||
Reference in New Issue
Block a user