diff options
author | Christian <c@ethdev.com> | 2015-02-15 09:00:33 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2015-02-17 02:25:27 +0800 |
commit | 971cc9b5b9242f36c1fa288615e2bf2d762fbd52 (patch) | |
tree | 100c83123364475d95e5331750578d2ce2602dc7 /Compiler.cpp | |
parent | d630a67812900036ba4aa7bfd47f07c7adddb247 (diff) | |
download | dexon-solidity-971cc9b5b9242f36c1fa288615e2bf2d762fbd52.tar dexon-solidity-971cc9b5b9242f36c1fa288615e2bf2d762fbd52.tar.gz dexon-solidity-971cc9b5b9242f36c1fa288615e2bf2d762fbd52.tar.bz2 dexon-solidity-971cc9b5b9242f36c1fa288615e2bf2d762fbd52.tar.lz dexon-solidity-971cc9b5b9242f36c1fa288615e2bf2d762fbd52.tar.xz dexon-solidity-971cc9b5b9242f36c1fa288615e2bf2d762fbd52.tar.zst dexon-solidity-971cc9b5b9242f36c1fa288615e2bf2d762fbd52.zip |
Unpacking of dynamically sized arguments.
Diffstat (limited to 'Compiler.cpp')
-rw-r--r-- | Compiler.cpp | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/Compiler.cpp b/Compiler.cpp index e1493587..98c9ffaa 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -178,15 +178,40 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) } } -unsigned 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. - unsigned dataOffset = CompilerUtils::dataStartOffset; // the 4 bytes of the function hash signature - + unsigned offset(CompilerUtils::dataStartOffset); bool const c_padToWords = true; + + unsigned dynamicParameterCount = 0; for (TypePointer const& type: _typeParameters) - dataOffset += CompilerUtils(m_context).loadFromMemory(dataOffset, *type, !_fromMemory, c_padToWords); - return dataOffset; + if (type->isDynamicallySized()) + dynamicParameterCount++; + offset += dynamicParameterCount * 32; + unsigned currentDynamicParameter = 0; + for (TypePointer const& type: _typeParameters) + if (type->isDynamicallySized()) + { + // value on stack: [memory_offset] (only if we are already in dynamic mode) + if (currentDynamicParameter == 0) + // switch from static to dynamic + m_context << u256(offset); + CompilerUtils(m_context).loadFromMemory( + CompilerUtils::dataStartOffset + currentDynamicParameter * 32, + IntegerType(256), !_fromMemory, c_padToWords); + // store new memory pointer + m_context << eth::Instruction::DUP2 << eth::Instruction::DUP2 << eth::Instruction::ADD; + currentDynamicParameter++; + // value on stack: offset length next_memory_offset + } + else if (currentDynamicParameter == 0) + // we can still use static load + offset += CompilerUtils(m_context).loadFromMemory(offset, *type, !_fromMemory, c_padToWords); + else + CompilerUtils(m_context).loadFromMemoryDynamic(*type, !_fromMemory, c_padToWords); + if (dynamicParameterCount > 0) + m_context << eth::Instruction::POP; } void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters) |