diff options
author | Christian <c@ethdev.com> | 2015-02-13 08:29:21 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2015-02-13 08:29:43 +0800 |
commit | 56c6eaf5099db5b86de038866b19356713c1be58 (patch) | |
tree | 25a755ffb4d3e206cb6e51cd9e040471cb1cf66f /CompilerUtils.cpp | |
parent | 1c3c1f1e5d366ba6d1da03ebaaf03d425037504b (diff) | |
download | dexon-solidity-56c6eaf5099db5b86de038866b19356713c1be58.tar.gz dexon-solidity-56c6eaf5099db5b86de038866b19356713c1be58.tar.zst dexon-solidity-56c6eaf5099db5b86de038866b19356713c1be58.zip |
Copying calldata directly to memory.
Diffstat (limited to 'CompilerUtils.cpp')
-rw-r--r-- | CompilerUtils.cpp | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/CompilerUtils.cpp b/CompilerUtils.cpp index 73be3817..dda1736d 100644 --- a/CompilerUtils.cpp +++ b/CompilerUtils.cpp @@ -76,35 +76,44 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound if (_type.getCategory() == Type::Category::ByteArray) { auto const& type = dynamic_cast<ByteArrayType const&>(_type); - solAssert(type.getLocation() == ByteArrayType::Location::Storage, "Non-storage byte arrays not yet implemented."); - m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD; - // stack here: memory_offset storage_offset length_bytes - // jump to end if length is zero - m_context << eth::Instruction::DUP1 << eth::Instruction::ISZERO; - eth::AssemblyItem loopEnd = m_context.newTag(); - m_context.appendConditionalJumpTo(loopEnd); - // compute memory end offset - m_context << eth::Instruction::DUP3 << eth::Instruction::ADD << eth::Instruction::SWAP2; - // actual array data is stored at SHA3(storage_offset) - m_context << eth::Instruction::SWAP1; - CompilerUtils(m_context).computeHashStatic(); - m_context << eth::Instruction::SWAP1; + if (type.getLocation() == ByteArrayType::Location::CallData) + { + m_context << eth::Instruction::CALLDATASIZE << u256(0) << eth::Instruction::DUP3 + << eth::Instruction::CALLDATACOPY + << eth::Instruction::CALLDATASIZE << eth::Instruction::ADD; + } + else + { + solAssert(type.getLocation() == ByteArrayType::Location::Storage, "Memory byte arrays not yet implemented."); + m_context << eth::Instruction::DUP1 << eth::Instruction::SLOAD; + // stack here: memory_offset storage_offset length_bytes + // jump to end if length is zero + m_context << eth::Instruction::DUP1 << eth::Instruction::ISZERO; + eth::AssemblyItem loopEnd = m_context.newTag(); + m_context.appendConditionalJumpTo(loopEnd); + // compute memory end offset + m_context << eth::Instruction::DUP3 << eth::Instruction::ADD << eth::Instruction::SWAP2; + // actual array data is stored at SHA3(storage_offset) + m_context << eth::Instruction::SWAP1; + CompilerUtils(m_context).computeHashStatic(); + m_context << eth::Instruction::SWAP1; - // stack here: memory_end_offset storage_data_offset memory_offset - eth::AssemblyItem loopStart = m_context.newTag(); - m_context << loopStart - // load and store - << eth::Instruction::DUP2 << eth::Instruction::SLOAD - << eth::Instruction::DUP2 << eth::Instruction::MSTORE - // increment storage_data_offset by 1 - << eth::Instruction::SWAP1 << u256(1) << eth::Instruction::ADD - // increment memory offset by 32 - << eth::Instruction::SWAP1 << u256(32) << eth::Instruction::ADD - // check for loop condition - << eth::Instruction::DUP1 << eth::Instruction::DUP4 << eth::Instruction::GT; - m_context.appendConditionalJumpTo(loopStart); - m_context << loopEnd << eth::Instruction::POP << eth::Instruction::POP; + // stack here: memory_end_offset storage_data_offset memory_offset + eth::AssemblyItem loopStart = m_context.newTag(); + m_context << loopStart + // load and store + << eth::Instruction::DUP2 << eth::Instruction::SLOAD + << eth::Instruction::DUP2 << eth::Instruction::MSTORE + // increment storage_data_offset by 1 + << eth::Instruction::SWAP1 << u256(1) << eth::Instruction::ADD + // increment memory offset by 32 + << eth::Instruction::SWAP1 << u256(32) << eth::Instruction::ADD + // check for loop condition + << eth::Instruction::DUP1 << eth::Instruction::DUP4 << eth::Instruction::GT; + m_context.appendConditionalJumpTo(loopStart); + m_context << loopEnd << eth::Instruction::POP << eth::Instruction::POP; + } } else { |