aboutsummaryrefslogtreecommitdiffstats
path: root/Compiler.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2015-02-15 09:00:33 +0800
committerChristian <c@ethdev.com>2015-02-17 02:25:27 +0800
commit971cc9b5b9242f36c1fa288615e2bf2d762fbd52 (patch)
tree100c83123364475d95e5331750578d2ce2602dc7 /Compiler.cpp
parentd630a67812900036ba4aa7bfd47f07c7adddb247 (diff)
downloaddexon-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.cpp35
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)