aboutsummaryrefslogtreecommitdiffstats
path: root/Compiler.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-06-17 18:01:39 +0800
committerchriseth <c@ethdev.com>2015-06-17 20:25:00 +0800
commit1ff8dbebab1aa450e6800fd188e21aa7944b898c (patch)
tree0b1c58115344a07fd4bced57c66c2907258ac21b /Compiler.cpp
parent17efc422996979289a9c5aa02959066578b09aa8 (diff)
downloaddexon-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.cpp40
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;
}