mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #1029 from chriseth/sol_bytesContinuation
length member for bytes
This commit is contained in:
commit
0e40b21c56
@ -184,17 +184,14 @@ void CompilerUtils::copyByteArrayToStorage(ByteArrayType const& _targetType,
|
||||
<< eth::Instruction::SWAP1;
|
||||
// stack here: target_ref target_data_end target_data_ref
|
||||
// store length (in bytes)
|
||||
if (_sourceType.getOffset() == 0)
|
||||
m_context << eth::Instruction::CALLDATASIZE;
|
||||
else
|
||||
m_context << _sourceType.getOffset() << eth::Instruction::CALLDATASIZE << eth::Instruction::SUB;
|
||||
m_context << eth::Instruction::CALLDATASIZE;
|
||||
m_context << eth::Instruction::DUP1 << eth::Instruction::DUP5 << eth::Instruction::SSTORE;
|
||||
// jump to end if length is zero
|
||||
m_context << eth::Instruction::ISZERO;
|
||||
eth::AssemblyItem copyLoopEnd = m_context.newTag();
|
||||
m_context.appendConditionalJumpTo(copyLoopEnd);
|
||||
|
||||
m_context << _sourceType.getOffset();
|
||||
// store start offset
|
||||
m_context << u256(0);
|
||||
// stack now: target_ref target_data_end target_data_ref calldata_offset
|
||||
eth::AssemblyItem copyLoopStart = m_context.newTag();
|
||||
m_context << copyLoopStart
|
||||
|
@ -504,6 +504,12 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
|
||||
}
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString()));
|
||||
}
|
||||
case Type::Category::ByteArray:
|
||||
{
|
||||
solAssert(member == "length", "Illegal bytearray member.");
|
||||
m_context << eth::Instruction::SLOAD;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Member access to unknown type."));
|
||||
}
|
||||
|
14
Types.cpp
14
Types.cpp
@ -58,7 +58,7 @@ TypePointer Type::fromElementaryTypeName(Token::Value _typeToken)
|
||||
else if (Token::String0 <= _typeToken && _typeToken <= Token::String32)
|
||||
return make_shared<StaticStringType>(int(_typeToken) - int(Token::String0));
|
||||
else if (_typeToken == Token::Bytes)
|
||||
return make_shared<ByteArrayType>(ByteArrayType::Location::Storage, 0, 0, true);
|
||||
return make_shared<ByteArrayType>(ByteArrayType::Location::Storage);
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " +
|
||||
std::string(Token::toString(_typeToken)) + " to type."));
|
||||
@ -515,12 +515,7 @@ TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const
|
||||
|
||||
bool ByteArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const
|
||||
{
|
||||
if (*this == _convertTo)
|
||||
return true;
|
||||
if (_convertTo.getCategory() != Category::ByteArray)
|
||||
return false;
|
||||
auto const& other = dynamic_cast<ByteArrayType const&>(_convertTo);
|
||||
return (m_dynamicLength == other.m_dynamicLength || m_length == other.m_length);
|
||||
return _convertTo.getCategory() == getCategory();
|
||||
}
|
||||
|
||||
TypePointer ByteArrayType::unaryOperatorResult(Token::Value _operator) const
|
||||
@ -535,8 +530,7 @@ bool ByteArrayType::operator==(Type const& _other) const
|
||||
if (_other.getCategory() != getCategory())
|
||||
return false;
|
||||
ByteArrayType const& other = dynamic_cast<ByteArrayType const&>(_other);
|
||||
return other.m_location == m_location && other.m_dynamicLength == m_dynamicLength
|
||||
&& other.m_length == m_length && other.m_offset == m_offset;
|
||||
return other.m_location == m_location;
|
||||
}
|
||||
|
||||
unsigned ByteArrayType::getSizeOnStack() const
|
||||
@ -547,6 +541,8 @@ unsigned ByteArrayType::getSizeOnStack() const
|
||||
return 1;
|
||||
}
|
||||
|
||||
const MemberList ByteArrayType::s_byteArrayMemberList = MemberList({{"length", make_shared<IntegerType >(256)}});
|
||||
|
||||
bool ContractType::operator==(Type const& _other) const
|
||||
{
|
||||
if (_other.getCategory() != getCategory())
|
||||
|
12
Types.h
12
Types.h
@ -286,25 +286,19 @@ public:
|
||||
enum class Location { Storage, CallData, Memory };
|
||||
|
||||
virtual Category getCategory() const override { return Category::ByteArray; }
|
||||
explicit ByteArrayType(Location _location, u256 const& _offset = 0, u256 const& _length = 0,
|
||||
bool _dynamicLength = false):
|
||||
m_location(_location), m_offset(_offset), m_length(_length), m_dynamicLength(_dynamicLength) {}
|
||||
explicit ByteArrayType(Location _location): m_location(_location) {}
|
||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||
virtual bool operator==(const Type& _other) const override;
|
||||
virtual unsigned getSizeOnStack() const override;
|
||||
virtual std::string toString() const override { return "bytes"; }
|
||||
virtual MemberList const& getMembers() const override { return s_byteArrayMemberList; }
|
||||
|
||||
Location getLocation() const { return m_location; }
|
||||
u256 const& getOffset() const { return m_offset; }
|
||||
u256 const& getLength() const { return m_length; }
|
||||
bool hasDynamicLength() const { return m_dynamicLength; }
|
||||
|
||||
private:
|
||||
Location m_location;
|
||||
u256 m_offset;
|
||||
u256 m_length;
|
||||
bool m_dynamicLength;
|
||||
static const MemberList s_byteArrayMemberList;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user