diff options
author | Christian <c@ethdev.com> | 2015-01-08 05:54:56 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2015-01-10 01:31:36 +0800 |
commit | c5c893319285993dd9a1c6a790537e7acc35e5d0 (patch) | |
tree | feee7124a0982ca8e44d142caf6774969305829b | |
parent | 501ad14ed1a6b1c40e0b0437683bae6246a6eeeb (diff) | |
download | dexon-solidity-c5c893319285993dd9a1c6a790537e7acc35e5d0.tar dexon-solidity-c5c893319285993dd9a1c6a790537e7acc35e5d0.tar.gz dexon-solidity-c5c893319285993dd9a1c6a790537e7acc35e5d0.tar.bz2 dexon-solidity-c5c893319285993dd9a1c6a790537e7acc35e5d0.tar.lz dexon-solidity-c5c893319285993dd9a1c6a790537e7acc35e5d0.tar.xz dexon-solidity-c5c893319285993dd9a1c6a790537e7acc35e5d0.tar.zst dexon-solidity-c5c893319285993dd9a1c6a790537e7acc35e5d0.zip |
Contracts are Addresses.
-rw-r--r-- | ExpressionCompiler.cpp | 20 | ||||
-rw-r--r-- | Types.cpp | 15 | ||||
-rw-r--r-- | Types.h | 9 |
3 files changed, 30 insertions, 14 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index 33c10aa3..e882c198 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -345,6 +345,18 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) ASTString const& member = _memberAccess.getMemberName(); switch (_memberAccess.getExpression().getType()->getCategory()) { + case Type::Category::CONTRACT: + { + ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.getExpression().getType()); + u256 identifier = type.getFunctionIdentifier(member); + if (identifier != Invalid256) + { + appendTypeConversion(type, IntegerType(0, IntegerType::Modifier::ADDRESS), true); + m_context << identifier; + break; + } + // fall-through to "integer" otherwise (address) + } case Type::Category::INTEGER: if (member == "balance") { @@ -358,14 +370,6 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to integer.")); break; - case Type::Category::CONTRACT: - { - appendTypeConversion(*_memberAccess.getExpression().getType(), - IntegerType(0, IntegerType::Modifier::ADDRESS), true); - ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.getExpression().getType()); - m_context << type.getFunctionIdentifier(member); - break; - } case Type::Category::MAGIC: // we can ignore the kind of magic and only look at the name of the member if (member == "coinbase") @@ -424,15 +424,20 @@ TypePointer BoolType::binaryOperatorResult(Token::Value _operator, TypePointer c return TypePointer(); } -bool ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const +bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const { - if (isImplicitlyConvertibleTo(_convertTo)) + if (*this == _convertTo) return true; if (_convertTo.getCategory() == Category::INTEGER) return dynamic_cast<IntegerType const&>(_convertTo).isAddress(); return false; } +bool ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const +{ + return isImplicitlyConvertibleTo(_convertTo) || _convertTo.getCategory() == Category::INTEGER; +} + bool ContractType::operator==(Type const& _other) const { if (_other.getCategory() != getCategory()) @@ -459,7 +464,9 @@ MemberList const& ContractType::getMembers() const // We need to lazy-initialize it because of recursive references. if (!m_members) { - map<string, shared_ptr<Type const>> members; + // All address members and all interface functions + map<string, shared_ptr<Type const>> members(IntegerType::AddressMemberList.begin(), + IntegerType::AddressMemberList.end()); for (auto const& it: m_contract.getInterfaceFunctions()) members[it.second->getName()] = make_shared<FunctionType>(*it.second, false); m_members.reset(new MemberList(members)); @@ -487,7 +494,7 @@ u256 ContractType::getFunctionIdentifier(string const& _functionName) const if (it->second->getName() == _functionName) return FixedHash<4>::Arith(it->first); - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Index of non-existing contract function requested.")); + return Invalid256; } bool StructType::operator==(Type const& _other) const @@ -179,10 +179,11 @@ public: bool isAddress() const { return m_modifier == Modifier::ADDRESS; } int isSigned() const { return m_modifier == Modifier::SIGNED; } + static const MemberList AddressMemberList; + private: int m_bits; Modifier m_modifier; - static const MemberList AddressMemberList; }; /** @@ -278,7 +279,9 @@ class ContractType: public Type public: virtual Category getCategory() const override { return Category::CONTRACT; } ContractType(ContractDefinition const& _contract): m_contract(_contract) {} - /// Contracts can be converted to themselves and to addresses. + /// Contracts can be implicitly converted to super classes and to addresses. + virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; + /// Contracts can be converted to themselves and to integers. virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; virtual bool operator==(Type const& _other) const override; virtual u256 getStorageSize() const override; @@ -291,6 +294,8 @@ public: /// is not used, as this type cannot be the type of a variable or expression. std::shared_ptr<FunctionType const> const& getConstructorType() const; + /// @returns the identifier of the function with the given name or Invalid256 if such a name does + /// not exist. u256 getFunctionIdentifier(std::string const& _functionName) const; private: |