From ff3553a34895c70c473a27c29464ebfc15375416 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 19 Oct 2016 18:43:31 +0200 Subject: Change alignment. --- libsolidity/codegen/CompilerUtils.cpp | 58 +++++++++++++++++++++-------------- libsolidity/codegen/CompilerUtils.h | 10 +++--- libsolidity/codegen/LValue.cpp | 4 +-- 3 files changed, 42 insertions(+), 30 deletions(-) (limited to 'libsolidity/codegen') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 8a06268c..dedb53e7 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -139,7 +139,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound ) { solAssert(_padToWordBoundaries, "Non-padded store for function not implemented."); - combineExternalFunctionType(); + combineExternalFunctionType(true); m_context << Instruction::DUP2 << Instruction::MSTORE; m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD; } @@ -315,19 +315,29 @@ void CompilerUtils::memoryCopy() m_context << Instruction::POP; // ignore return value } -void CompilerUtils::splitExternalFunctionType() +void CompilerUtils::splitExternalFunctionType(bool _leftAligned) { - // We have to split the right-aligned
into two stack slots: + // We have to split the left-aligned
into two stack slots: // 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 << (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; - m_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::OR; + if (_leftAligned) + 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) @@ -856,27 +866,29 @@ void CompilerUtils::storeStringData(bytesConstRef _data) unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries) { unsigned numBytes = _type.calldataEncodedSize(_padToWordBoundaries); - bool leftAligned = _type.category() == Type::Category::FixedBytes; + bool isExternalFunctionType = false; + if (auto const* funType = dynamic_cast(&_type)) + if (funType->location() == FunctionType::Location::External) + isExternalFunctionType = true; if (numBytes == 0) + { m_context << Instruction::POP << u256(0); - else + 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) { - 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; - } + 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; } - if (auto const* funType = dynamic_cast(&_type)) - if (funType->location() == FunctionType::Location::External) - splitExternalFunctionType(); - return numBytes; } diff --git a/libsolidity/codegen/CompilerUtils.h b/libsolidity/codegen/CompilerUtils.h index 0c9adf29..690452f9 100644 --- a/libsolidity/codegen/CompilerUtils.h +++ b/libsolidity/codegen/CompilerUtils.h @@ -114,12 +114,12 @@ public: /// Stack post: void memoryCopy(); - /// Converts the combined and right-aligned external function type - ///
into two stack slots: + /// Converts the combined and left-aligned (right-aligned if @a _rightAligned is true) + /// external function type
into two stack slots: /// address (right aligned), function identifier (right aligned) - void splitExternalFunctionType(); - /// Performs the opposite operation of splitExternalFunctionType() - void combineExternalFunctionType(); + void splitExternalFunctionType(bool _rightAligned); + /// Performs the opposite operation of splitExternalFunctionType(_rightAligned) + void combineExternalFunctionType(bool _rightAligned); /// 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 diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index 98ab6d41..cb7cbbe3 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -194,7 +194,7 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const m_dataType->category() == Type::Category::Function && dynamic_cast(*m_dataType).location() == FunctionType::Location::External ) - CompilerUtils(m_context).splitExternalFunctionType(); + CompilerUtils(m_context).splitExternalFunctionType(false); else { solAssert(m_dataType->sizeOnStack() == 1, ""); @@ -241,7 +241,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc dynamic_cast(*m_dataType).location() == FunctionType::Location::External ) // Combine the two-item function type into a single stack slot. - utils.combineExternalFunctionType(); + utils.combineExternalFunctionType(false); else if (m_dataType->category() == Type::Category::FixedBytes) m_context << (u256(0x1) << (256 - 8 * dynamic_cast(*m_dataType).numBytes())) -- cgit