diff options
-rw-r--r-- | docs/assembly.rst | 25 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 40 |
2 files changed, 48 insertions, 17 deletions
diff --git a/docs/assembly.rst b/docs/assembly.rst index 2f5b8812..bdb708a9 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -96,6 +96,31 @@ you really know what you are doing. } } } + + // Same as above, but accomplish the entire code within inline assembly. + function sumPureAsm(uint[] _data) returns (uint o_sum) { + assembly { + // Load the length (first 32 bytes) + let len := mload(_data) + + // Skip over the length field. + // + // Keep temporary variable so it can be incremented in place. + // + // NOTE: incrementing _data would result in an unusable + // _data variable after this assembly block + let data := add(_data, 0x20) + + // Iterate until the bound is not met. + for + { let end := add(data, len) } + lt(data, end) + { data := add(data, 0x20) } + { + o_sum := add(o_sum, mload(data)) + } + } + } } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index abcfeb25..a66ccda5 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2221,6 +2221,8 @@ string FunctionType::identifier() const } if (isConstant()) id += "_constant"; + if (isPayable()) + id += "_payable"; id += identifierList(m_parameterTypes) + "returns" + identifierList(m_returnParameterTypes); if (m_gasSet) id += "gas"; @@ -2235,23 +2237,22 @@ bool FunctionType::operator==(Type const& _other) const { if (_other.category() != category()) return false; - FunctionType const& other = dynamic_cast<FunctionType const&>(_other); - if (m_kind != other.m_kind) - return false; - if (m_isConstant != other.isConstant()) + FunctionType const& other = dynamic_cast<FunctionType const&>(_other); + if ( + m_kind != other.m_kind || + m_isConstant != other.isConstant() || + m_isPayable != other.isPayable() || + m_parameterTypes.size() != other.m_parameterTypes.size() || + m_returnParameterTypes.size() != other.m_returnParameterTypes.size() + ) return false; - if (m_parameterTypes.size() != other.m_parameterTypes.size() || - m_returnParameterTypes.size() != other.m_returnParameterTypes.size()) - return false; auto typeCompare = [](TypePointer const& _a, TypePointer const& _b) -> bool { return *_a == *_b; }; - - if (!equal(m_parameterTypes.cbegin(), m_parameterTypes.cend(), - other.m_parameterTypes.cbegin(), typeCompare)) - return false; - if (!equal(m_returnParameterTypes.cbegin(), m_returnParameterTypes.cend(), - other.m_returnParameterTypes.cbegin(), typeCompare)) + if ( + !equal(m_parameterTypes.cbegin(), m_parameterTypes.cend(), other.m_parameterTypes.cbegin(), typeCompare) || + !equal(m_returnParameterTypes.cbegin(), m_returnParameterTypes.cend(), other.m_returnParameterTypes.cbegin(), typeCompare) + ) return false; //@todo this is ugly, but cannot be prevented right now if (m_gasSet != other.m_gasSet || m_valueSet != other.m_valueSet) @@ -2412,10 +2413,15 @@ FunctionTypePointer FunctionType::interfaceFunctionType() const return FunctionTypePointer(); return make_shared<FunctionType>( - paramTypes, retParamTypes, - m_parameterNames, m_returnParameterNames, - m_kind, m_arbitraryParameters, - m_declaration, m_isConstant, m_isPayable + paramTypes, + retParamTypes, + m_parameterNames, + m_returnParameterNames, + m_kind, + m_arbitraryParameters, + m_declaration, + m_isConstant, + m_isPayable ); } |