diff options
author | chriseth <c@ethdev.com> | 2015-06-23 02:50:29 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-23 02:55:46 +0800 |
commit | fd1a01bbce5b5b6491e05b87fb183a55e9804f4e (patch) | |
tree | 52ff5eea7bb2b3d4579fc64f84413130c863aa47 | |
parent | 8639cf8e3df10bedf8ce808aa7146ac88624df44 (diff) | |
download | dexon-solidity-fd1a01bbce5b5b6491e05b87fb183a55e9804f4e.tar dexon-solidity-fd1a01bbce5b5b6491e05b87fb183a55e9804f4e.tar.gz dexon-solidity-fd1a01bbce5b5b6491e05b87fb183a55e9804f4e.tar.bz2 dexon-solidity-fd1a01bbce5b5b6491e05b87fb183a55e9804f4e.tar.lz dexon-solidity-fd1a01bbce5b5b6491e05b87fb183a55e9804f4e.tar.xz dexon-solidity-fd1a01bbce5b5b6491e05b87fb183a55e9804f4e.tar.zst dexon-solidity-fd1a01bbce5b5b6491e05b87fb183a55e9804f4e.zip |
Decoding for constructor.
-rw-r--r-- | Compiler.cpp | 15 | ||||
-rw-r--r-- | CompilerUtils.cpp | 2 | ||||
-rw-r--r-- | Types.cpp | 28 | ||||
-rw-r--r-- | Types.h | 9 |
4 files changed, 31 insertions, 23 deletions
diff --git a/Compiler.cpp b/Compiler.cpp index 0b88ed8a..68052e27 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -163,14 +163,14 @@ void Compiler::appendConstructor(FunctionDefinition const& _constructor) { CompilerContext::LocationSetter locationSetter(m_context, _constructor); // copy constructor arguments from code to memory and then to stack, they are supplied after the actual program - unsigned argumentSize = 0; - for (ASTPointer<VariableDeclaration> const& var: _constructor.getParameters()) - argumentSize += var->getType()->getCalldataEncodedSize(); - - if (argumentSize > 0) + if (!_constructor.getParameters().empty()) { CompilerUtils(m_context).fetchFreeMemoryPointer(); - m_context << u256(argumentSize) << eth::Instruction::DUP1; + m_context.appendProgramSize(); // program itself + // CODESIZE is program plus manually added arguments + m_context << eth::Instruction::CODESIZE << eth::Instruction::SUB; + // stack: <memptr> <argument size> + m_context << eth::Instruction::DUP1; m_context.appendProgramSize(); m_context << eth::Instruction::DUP4 << eth::Instruction::CODECOPY; m_context << eth::Instruction::ADD; @@ -265,8 +265,9 @@ void Compiler::appendCalldataUnpacker( { solAssert(arrayType.location() == DataLocation::Memory, ""); // compute data pointer + m_context << eth::Instruction::DUP1 << eth::Instruction::MLOAD; //@todo once we support nested arrays, this offset needs to be dynamic. - m_context << eth::Instruction::DUP1 << _startOffset << eth::Instruction::ADD; + m_context << _startOffset << eth::Instruction::ADD; m_context << eth::Instruction::SWAP1 << u256(0x20) << eth::Instruction::ADD; } else diff --git a/CompilerUtils.cpp b/CompilerUtils.cpp index 4d57dc92..5bd6de13 100644 --- a/CompilerUtils.cpp +++ b/CompilerUtils.cpp @@ -135,7 +135,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound m_context << u256(0) << u256(identityContractAddress); //@TODO do not use ::CALL if less than 32 bytes? //@todo in production, we should not have to pair c_callNewAccountGas. - m_context << u256(eth::c_callGas + 10 + eth::c_callNewAccountGas) << eth::Instruction::GAS; + m_context << u256(eth::c_callGas + 15 + eth::c_callNewAccountGas) << eth::Instruction::GAS; m_context << eth::Instruction::SUB << eth::Instruction::CALL; m_context << eth::Instruction::POP; // ignore return value @@ -822,16 +822,16 @@ string ArrayType::toString(bool _short) const TypePointer ArrayType::externalType() const { if (m_arrayKind != ArrayKind::Ordinary) - return this->copyForLocation(DataLocation::Memory, true); + return this->copyForLocation(DataLocation::CallData, true); if (!m_baseType->externalType()) return TypePointer(); if (m_baseType->getCategory() == Category::Array && m_baseType->isDynamicallySized()) return TypePointer(); if (isDynamicallySized()) - return std::make_shared<ArrayType>(DataLocation::Memory, m_baseType->externalType()); + return std::make_shared<ArrayType>(DataLocation::CallData, m_baseType->externalType()); else - return std::make_shared<ArrayType>(DataLocation::Memory, m_baseType->externalType(), m_length); + return std::make_shared<ArrayType>(DataLocation::CallData, m_baseType->externalType(), m_length); } TypePointer ArrayType::copyForLocation(DataLocation _location, bool _isPointer) const @@ -903,7 +903,7 @@ MemberList const& ContractType::getMembers() const for (auto const& it: m_contract.getInterfaceFunctions()) members.push_back(MemberList::Member( it.second->getDeclaration().getName(), - it.second->removeDynamicReturnTypes(), + it.second->asMemberFunction(), &it.second->getDeclaration() )); m_members.reset(new MemberList(members)); @@ -1084,11 +1084,7 @@ FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal for (ASTPointer<VariableDeclaration> const& var: _function.getParameters()) { paramNames.push_back(var->getName()); - if (_isInternal) - params.push_back(var->getType()); - else - params.push_back(var->getType()->externalType()); - solAssert(!!params.back(), "Function argument type not valid in this context."); + params.push_back(var->getType()); } retParams.reserve(_function.getReturnParameters().size()); retParamNames.reserve(_function.getReturnParameters().size()); @@ -1416,8 +1412,18 @@ TypePointer FunctionType::copyAndSetGasOrValue(bool _setGas, bool _setValue) con ); } -FunctionTypePointer FunctionType::removeDynamicReturnTypes() const +FunctionTypePointer FunctionType::asMemberFunction() const { + TypePointers parameterTypes; + for (auto const& t: m_parameterTypes) + { + auto refType = dynamic_cast<ReferenceType const*>(t.get()); + if (refType && refType->location() == DataLocation::CallData) + parameterTypes.push_back(refType->copyForLocation(DataLocation::Memory, false)); + else + parameterTypes.push_back(t); + } + //@todo make this more intelligent once we support destructuring assignments TypePointers returnParameterTypes; vector<string> returnParameterNames; @@ -1427,7 +1433,7 @@ FunctionTypePointer FunctionType::removeDynamicReturnTypes() const returnParameterNames.push_back(m_returnParameterNames.front()); } return make_shared<FunctionType>( - m_parameterTypes, + parameterTypes, returnParameterTypes, m_parameterNames, returnParameterNames, @@ -735,10 +735,11 @@ public: /// of the parameters to fals. TypePointer copyAndSetGasOrValue(bool _setGas, bool _setValue) const; - /// @returns a copy of this function type where all return parameters of dynamic size are removed. - /// This is needed if external functions are called internally, as they cannot return dynamic - /// values. - FunctionTypePointer removeDynamicReturnTypes() const; + /// @returns a copy of this function type where all return parameters of dynamic size are + /// removed and the location of reference types is changed from CallData to Memory. + /// This is needed if external functions are called on other contracts, as they cannot return + /// dynamic values. + FunctionTypePointer asMemberFunction() const; private: static TypePointers parseElementaryTypeVector(strings const& _types); |