mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Change alignment.
This commit is contained in:
parent
679ea2820f
commit
ff3553a348
@ -2078,7 +2078,7 @@ TypePointer FunctionType::encodingType() const
|
|||||||
TypePointer FunctionType::interfaceType(bool /*_inLibrary*/) const
|
TypePointer FunctionType::interfaceType(bool /*_inLibrary*/) const
|
||||||
{
|
{
|
||||||
if (m_location == Location::External)
|
if (m_location == Location::External)
|
||||||
return make_shared<IntegerType>(8 * storageBytes());
|
return make_shared<FixedBytesType>(storageBytes());
|
||||||
else
|
else
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
solAssert(_padToWordBoundaries, "Non-padded store for function not implemented.");
|
solAssert(_padToWordBoundaries, "Non-padded store for function not implemented.");
|
||||||
combineExternalFunctionType();
|
combineExternalFunctionType(true);
|
||||||
m_context << Instruction::DUP2 << Instruction::MSTORE;
|
m_context << Instruction::DUP2 << Instruction::MSTORE;
|
||||||
m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD;
|
m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD;
|
||||||
}
|
}
|
||||||
@ -315,19 +315,29 @@ void CompilerUtils::memoryCopy()
|
|||||||
m_context << Instruction::POP; // ignore return value
|
m_context << Instruction::POP; // ignore return value
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerUtils::splitExternalFunctionType()
|
void CompilerUtils::splitExternalFunctionType(bool _leftAligned)
|
||||||
{
|
{
|
||||||
// We have to split the right-aligned <function identifier><address> into two stack slots:
|
// We have to split the left-aligned <function identifier><address> into two stack slots:
|
||||||
// address (right aligned), function identifier (right aligned)
|
// address (right aligned), function identifier (right aligned)
|
||||||
|
if (_leftAligned)
|
||||||
|
m_context << (u256(1) << 64) << Instruction::SWAP1 << Instruction::DIV;
|
||||||
m_context << Instruction::DUP1 << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::SWAP1;
|
m_context << Instruction::DUP1 << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::SWAP1;
|
||||||
m_context << (u256(1) << 160) << Instruction::SWAP1 << Instruction::DIV;
|
m_context << (u256(1) << 160) << Instruction::SWAP1 << Instruction::DIV;
|
||||||
m_context << u256(0xffffffffUL) << Instruction::AND;
|
if (!_leftAligned)
|
||||||
|
m_context << u256(0xffffffffUL) << Instruction::AND;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerUtils::combineExternalFunctionType()
|
void CompilerUtils::combineExternalFunctionType(bool _leftAligned)
|
||||||
{
|
{
|
||||||
m_context << u256(0xffffffffUL) << Instruction::AND << (u256(1) << 160) << Instruction::MUL << Instruction::SWAP1;
|
if (_leftAligned)
|
||||||
m_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::OR;
|
m_context << (u256(1) << 224);
|
||||||
|
else
|
||||||
|
m_context << u256(0xffffffffUL) << Instruction::AND << (u256(1) << 160);
|
||||||
|
m_context << Instruction::MUL << Instruction::SWAP1;
|
||||||
|
m_context << ((u256(1) << 160) - 1) << Instruction::AND;
|
||||||
|
if (_leftAligned)
|
||||||
|
m_context << (u256(1) << 64) << Instruction::MUL;
|
||||||
|
m_context << Instruction::OR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded)
|
void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded)
|
||||||
@ -856,26 +866,28 @@ void CompilerUtils::storeStringData(bytesConstRef _data)
|
|||||||
unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries)
|
unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries)
|
||||||
{
|
{
|
||||||
unsigned numBytes = _type.calldataEncodedSize(_padToWordBoundaries);
|
unsigned numBytes = _type.calldataEncodedSize(_padToWordBoundaries);
|
||||||
bool leftAligned = _type.category() == Type::Category::FixedBytes;
|
bool isExternalFunctionType = false;
|
||||||
if (numBytes == 0)
|
|
||||||
m_context << Instruction::POP << u256(0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
solAssert(numBytes <= 32, "Static memory load of more than 32 bytes requested.");
|
|
||||||
m_context << (_fromCalldata ? Instruction::CALLDATALOAD : Instruction::MLOAD);
|
|
||||||
if (numBytes != 32)
|
|
||||||
{
|
|
||||||
// add leading or trailing zeros by dividing/multiplying depending on alignment
|
|
||||||
u256 shiftFactor = u256(1) << ((32 - numBytes) * 8);
|
|
||||||
m_context << shiftFactor << Instruction::SWAP1 << Instruction::DIV;
|
|
||||||
if (leftAligned)
|
|
||||||
m_context << shiftFactor << Instruction::MUL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto const* funType = dynamic_cast<FunctionType const*>(&_type))
|
if (auto const* funType = dynamic_cast<FunctionType const*>(&_type))
|
||||||
if (funType->location() == FunctionType::Location::External)
|
if (funType->location() == FunctionType::Location::External)
|
||||||
splitExternalFunctionType();
|
isExternalFunctionType = true;
|
||||||
|
if (numBytes == 0)
|
||||||
|
{
|
||||||
|
m_context << Instruction::POP << u256(0);
|
||||||
|
return numBytes;
|
||||||
|
}
|
||||||
|
solAssert(numBytes <= 32, "Static memory load of more than 32 bytes requested.");
|
||||||
|
m_context << (_fromCalldata ? Instruction::CALLDATALOAD : Instruction::MLOAD);
|
||||||
|
if (isExternalFunctionType)
|
||||||
|
splitExternalFunctionType(true);
|
||||||
|
else if (numBytes != 32)
|
||||||
|
{
|
||||||
|
bool leftAligned = _type.category() == Type::Category::FixedBytes;
|
||||||
|
// add leading or trailing zeros by dividing/multiplying depending on alignment
|
||||||
|
u256 shiftFactor = u256(1) << ((32 - numBytes) * 8);
|
||||||
|
m_context << shiftFactor << Instruction::SWAP1 << Instruction::DIV;
|
||||||
|
if (leftAligned)
|
||||||
|
m_context << shiftFactor << Instruction::MUL;
|
||||||
|
}
|
||||||
|
|
||||||
return numBytes;
|
return numBytes;
|
||||||
}
|
}
|
||||||
|
@ -114,12 +114,12 @@ public:
|
|||||||
/// Stack post:
|
/// Stack post:
|
||||||
void memoryCopy();
|
void memoryCopy();
|
||||||
|
|
||||||
/// Converts the combined and right-aligned external function type
|
/// Converts the combined and left-aligned (right-aligned if @a _rightAligned is true)
|
||||||
/// <function identifier><address> into two stack slots:
|
/// external function type <function identifier><address> into two stack slots:
|
||||||
/// address (right aligned), function identifier (right aligned)
|
/// address (right aligned), function identifier (right aligned)
|
||||||
void splitExternalFunctionType();
|
void splitExternalFunctionType(bool _rightAligned);
|
||||||
/// Performs the opposite operation of splitExternalFunctionType()
|
/// Performs the opposite operation of splitExternalFunctionType(_rightAligned)
|
||||||
void combineExternalFunctionType();
|
void combineExternalFunctionType(bool _rightAligned);
|
||||||
|
|
||||||
/// Appends code for an implicit or explicit type conversion. This includes erasing higher
|
/// Appends code for an implicit or explicit type conversion. This includes erasing higher
|
||||||
/// order bits (@see appendHighBitCleanup) when widening integer but also copy to memory
|
/// order bits (@see appendHighBitCleanup) when widening integer but also copy to memory
|
||||||
|
@ -194,7 +194,7 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const
|
|||||||
m_dataType->category() == Type::Category::Function &&
|
m_dataType->category() == Type::Category::Function &&
|
||||||
dynamic_cast<FunctionType const&>(*m_dataType).location() == FunctionType::Location::External
|
dynamic_cast<FunctionType const&>(*m_dataType).location() == FunctionType::Location::External
|
||||||
)
|
)
|
||||||
CompilerUtils(m_context).splitExternalFunctionType();
|
CompilerUtils(m_context).splitExternalFunctionType(false);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
solAssert(m_dataType->sizeOnStack() == 1, "");
|
solAssert(m_dataType->sizeOnStack() == 1, "");
|
||||||
@ -241,7 +241,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
|
|||||||
dynamic_cast<FunctionType const&>(*m_dataType).location() == FunctionType::Location::External
|
dynamic_cast<FunctionType const&>(*m_dataType).location() == FunctionType::Location::External
|
||||||
)
|
)
|
||||||
// Combine the two-item function type into a single stack slot.
|
// Combine the two-item function type into a single stack slot.
|
||||||
utils.combineExternalFunctionType();
|
utils.combineExternalFunctionType(false);
|
||||||
else if (m_dataType->category() == Type::Category::FixedBytes)
|
else if (m_dataType->category() == Type::Category::FixedBytes)
|
||||||
m_context
|
m_context
|
||||||
<< (u256(0x1) << (256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes()))
|
<< (u256(0x1) << (256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes()))
|
||||||
|
Loading…
Reference in New Issue
Block a user