From 69693f17f626a5ff365c5002b15f5d386f6a388e Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 8 May 2015 16:54:39 +0200 Subject: New ABI encoding for dynamic types. --- Compiler.cpp | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/Compiler.cpp b/Compiler.cpp index fb2ab315..bcd4f9d6 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -206,16 +206,9 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool _fromMemory) { - // We do not check the calldata size, everything is zero-padded. - unsigned offset(CompilerUtils::dataStartOffset); + // We do not check the calldata size, everything is zero-paddedd - bigint parameterHeadEnd = offset; - for (TypePointer const& type: _typeParameters) - parameterHeadEnd += type->isDynamicallySized() ? 32 : type->getCalldataEncodedSize(); - solAssert(parameterHeadEnd <= numeric_limits::max(), "Arguments too large."); - - unsigned stackHeightOfPreviousDynamicArgument = 0; - ArrayType const* previousDynamicType = nullptr; + m_context << u256(CompilerUtils::dataStartOffset); for (TypePointer const& type: _typeParameters) { switch (type->getCategory()) @@ -223,34 +216,31 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool case Type::Category::Array: if (type->isDynamicallySized()) { - // put on stack: data_offset length - unsigned newStackHeight = m_context.getStackHeight(); - if (previousDynamicType) - { - // Retrieve data start offset by adding length to start offset of previous dynamic type - unsigned stackDepth = m_context.getStackHeight() - stackHeightOfPreviousDynamicArgument; - solAssert(stackDepth <= 16, "Stack too deep."); - m_context << eth::dupInstruction(stackDepth) << eth::dupInstruction(stackDepth); - ArrayUtils(m_context).convertLengthToSize(*previousDynamicType, true); - m_context << eth::Instruction::ADD; - } - else - m_context << u256(parameterHeadEnd); - stackHeightOfPreviousDynamicArgument = newStackHeight; - previousDynamicType = &dynamic_cast(*type); - offset += CompilerUtils(m_context).loadFromMemory(offset, IntegerType(256), !_fromMemory); + // put on stack: data_pointer length + CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory); + // stack: data_offset next_pointer + //@todo once we support nested arrays, this offset needs to be dynamic. + m_context << eth::Instruction::SWAP1 << u256(CompilerUtils::dataStartOffset); + m_context << eth::Instruction::ADD; + // stack: next_pointer data_pointer + // retrieve length + CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory, true); + // stack: next_pointer length data_pointer + m_context << eth::Instruction::SWAP2; } else { - m_context << u256(offset); - offset += type->getCalldataEncodedSize(); + // leave the pointer on the stack + m_context << eth::Instruction::DUP1; + m_context << u256(type->getCalldataEncodedSize()) << eth::Instruction::ADD; } break; default: 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) -- cgit v1.2.3