diff options
author | chriseth <c@ethdev.com> | 2015-06-05 23:32:13 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-09 06:27:56 +0800 |
commit | 35ec81971acc31f16253bd1702fb81adbee85f48 (patch) | |
tree | 3e8e3b1079a01ab03ed1b2d86d203f3bfe56f435 /Compiler.cpp | |
parent | c2a9419e495e931a825e8146aec49ffc34e44954 (diff) | |
download | dexon-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.cpp | 51 |
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); } |