aboutsummaryrefslogtreecommitdiffstats
path: root/CompilerUtils.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2015-02-13 08:29:21 +0800
committerChristian <c@ethdev.com>2015-02-13 08:29:43 +0800
commit56c6eaf5099db5b86de038866b19356713c1be58 (patch)
tree25a755ffb4d3e206cb6e51cd9e040471cb1cf66f /CompilerUtils.cpp
parent1c3c1f1e5d366ba6d1da03ebaaf03d425037504b (diff)
downloaddexon-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.cpp63
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
{