diff options
author | chriseth <c@ethdev.com> | 2015-06-17 18:01:39 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-17 20:25:00 +0800 |
commit | 1ff8dbebab1aa450e6800fd188e21aa7944b898c (patch) | |
tree | 0b1c58115344a07fd4bced57c66c2907258ac21b /Compiler.cpp | |
parent | 17efc422996979289a9c5aa02959066578b09aa8 (diff) | |
download | dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar.gz dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar.bz2 dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar.lz dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar.xz dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.tar.zst dexon-solidity-1ff8dbebab1aa450e6800fd188e21aa7944b898c.zip |
Accessors for strings.
Diffstat (limited to 'Compiler.cpp')
-rw-r--r-- | Compiler.cpp | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/Compiler.cpp b/Compiler.cpp index 82e98dff..0b88ed8a 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -245,21 +245,35 @@ void Compiler::appendCalldataUnpacker( { // We do not check the calldata size, everything is zero-paddedd + //@todo this does not yet support nested arrays + if (_startOffset == u256(-1)) _startOffset = u256(CompilerUtils::dataStartOffset); m_context << _startOffset; for (TypePointer const& type: _typeParameters) { + // stack: v1 v2 ... v(k-1) mem_offset switch (type->getCategory()) { case Type::Category::Array: { auto const& arrayType = dynamic_cast<ArrayType const&>(*type); - if (arrayType.location() == ReferenceType::Location::CallData) + solAssert(arrayType.location() != DataLocation::Storage, ""); + solAssert(!arrayType.getBaseType()->isDynamicallySized(), "Nested arrays not yet implemented."); + if (_fromMemory) + { + solAssert(arrayType.location() == DataLocation::Memory, ""); + // compute data pointer + //@todo once we support nested arrays, this offset needs to be dynamic. + m_context << eth::Instruction::DUP1 << _startOffset << eth::Instruction::ADD; + m_context << eth::Instruction::SWAP1 << u256(0x20) << eth::Instruction::ADD; + } + else { - solAssert(!_fromMemory, ""); - if (type->isDynamicallySized()) + // first load from calldata and potentially convert to memory if arrayType is memory + TypePointer calldataType = arrayType.copyForLocation(DataLocation::CallData, false); + if (calldataType->isDynamicallySized()) { // put on stack: data_pointer length CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory); @@ -276,17 +290,17 @@ void Compiler::appendCalldataUnpacker( { // leave the pointer on the stack m_context << eth::Instruction::DUP1; - m_context << u256(type->getCalldataEncodedSize()) << eth::Instruction::ADD; + m_context << u256(calldataType->getCalldataEncodedSize()) << eth::Instruction::ADD; + } + if (arrayType.location() == DataLocation::Memory) + { + // copy to memory + // move calldata type up again + CompilerUtils(m_context).moveIntoStack(calldataType->getSizeOnStack()); + CompilerUtils(m_context).convertType(*calldataType, arrayType); + // fetch next pointer again + CompilerUtils(m_context).moveToStackTop(arrayType.getSizeOnStack()); } - } - else - { - solAssert(arrayType.location() == ReferenceType::Location::Memory, ""); - // compute data pointer - m_context << eth::Instruction::DUP1 << _startOffset << eth::Instruction::ADD; - if (!_fromMemory) - solAssert(false, "Not yet implemented."); - m_context << eth::Instruction::SWAP1 << u256(0x20) << eth::Instruction::ADD; } break; } |