aboutsummaryrefslogtreecommitdiffstats
path: root/Compiler.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-06-05 23:32:13 +0800
committerchriseth <c@ethdev.com>2015-06-09 06:27:56 +0800
commit35ec81971acc31f16253bd1702fb81adbee85f48 (patch)
tree3e8e3b1079a01ab03ed1b2d86d203f3bfe56f435 /Compiler.cpp
parentc2a9419e495e931a825e8146aec49ffc34e44954 (diff)
downloaddexon-solidity-35ec81971acc31f16253bd1702fb81adbee85f48.tar
dexon-solidity-35ec81971acc31f16253bd1702fb81adbee85f48.tar.gz
dexon-solidity-35ec81971acc31f16253bd1702fb81adbee85f48.tar.bz2
dexon-solidity-35ec81971acc31f16253bd1702fb81adbee85f48.tar.lz
dexon-solidity-35ec81971acc31f16253bd1702fb81adbee85f48.tar.xz
dexon-solidity-35ec81971acc31f16253bd1702fb81adbee85f48.tar.zst
dexon-solidity-35ec81971acc31f16253bd1702fb81adbee85f48.zip
Dynamic memory.
Diffstat (limited to 'Compiler.cpp')
-rw-r--r--Compiler.cpp51
1 files changed, 32 insertions, 19 deletions
diff --git a/Compiler.cpp b/Compiler.cpp
index 0a75e55a..0d7fbbfe 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -52,6 +52,7 @@ void Compiler::compileContract(ContractDefinition const& _contract,
map<ContractDefinition const*, bytes const*> const& _contracts)
{
m_context = CompilerContext(); // clear it just in case
+ CompilerUtils(m_context).initialiseFreeMemoryPointer();
initializeContext(_contract, _contracts);
appendFunctionSelector(_contract);
set<Declaration const*> functions = m_context.getFunctionsWithoutCode();
@@ -67,6 +68,7 @@ void Compiler::compileContract(ContractDefinition const& _contract,
// Swap the runtime context with the creation-time context
swap(m_context, m_runtimeContext);
+ CompilerUtils(m_context).initialiseFreeMemoryPointer();
initializeContext(_contract, _contracts);
packIntoContractCreator(_contract, m_runtimeContext);
if (m_optimize)
@@ -233,31 +235,42 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
m_context << u256(CompilerUtils::dataStartOffset);
for (TypePointer const& type: _typeParameters)
{
- switch (type->getCategory())
+ if (type->getCategory() == Type::Category::Array)
{
- case Type::Category::Array:
- if (type->isDynamicallySized())
+ auto const& arrayType = dynamic_cast<ArrayType const&>(*type);
+ if (arrayType.location() == ReferenceType::Location::CallData)
{
- // put on stack: data_pointer length
- CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory);
- // stack: data_offset next_pointer
- //@todo once we support nested arrays, this offset needs to be dynamic.
- m_context << eth::Instruction::SWAP1 << u256(CompilerUtils::dataStartOffset);
- m_context << eth::Instruction::ADD;
- // stack: next_pointer data_pointer
- // retrieve length
- CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory, true);
- // stack: next_pointer length data_pointer
- m_context << eth::Instruction::SWAP2;
+ if (type->isDynamicallySized())
+ {
+ // put on stack: data_pointer length
+ CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory);
+ // stack: data_offset next_pointer
+ //@todo once we support nested arrays, this offset needs to be dynamic.
+ m_context << eth::Instruction::SWAP1 << u256(CompilerUtils::dataStartOffset);
+ m_context << eth::Instruction::ADD;
+ // stack: next_pointer data_pointer
+ // retrieve length
+ CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory, true);
+ // stack: next_pointer length data_pointer
+ m_context << eth::Instruction::SWAP2;
+ }
+ else
+ {
+ // leave the pointer on the stack
+ m_context << eth::Instruction::DUP1;
+ m_context << u256(type->getCalldataEncodedSize()) << eth::Instruction::ADD;
+ }
}
else
{
- // leave the pointer on the stack
- m_context << eth::Instruction::DUP1;
- m_context << u256(type->getCalldataEncodedSize()) << eth::Instruction::ADD;
+ solAssert(arrayType.location() == ReferenceType::Location::Memory, "");
+ CompilerUtils(m_context).fetchFreeMemoryPointer();
+ CompilerUtils(m_context).storeInMemoryDynamic(*type);
+ CompilerUtils(m_context).storeFreeMemoryPointer();
}
- break;
- default:
+ }
+ else
+ {
solAssert(!type->isDynamicallySized(), "Unknown dynamically sized type: " + type->toString());
CompilerUtils(m_context).loadFromMemoryDynamic(*type, !_fromMemory, true);
}