From 98dcd883e4ee1b3d62a1b9e7d4e5d4e038ea0434 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Tue, 8 Nov 2016 13:37:59 +0100 Subject: codegen: check the value range after converting something to an enum element --- libsolidity/codegen/CompilerUtils.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index e064c1a6..5e045996 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -656,6 +656,14 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp solAssert(_typeOnStack == _targetType, "Invalid type conversion requested."); break; } + + // Check the conversion result fits in a range. + if (targetTypeCategory == Type::Category::Enum) + { + EnumType const& enumType = dynamic_cast(_targetType); + m_context << u256(enumType.numberOfMembers()) << Instruction::DUP2 << Instruction::LT << Instruction::ISZERO; + m_context.appendConditionalJumpTo(m_context.errorTag()); + } } void CompilerUtils::pushZeroValue(Type const& _type) -- cgit v1.2.3 From 0a6c937dcbb3671e2fa5f6d7b50b5a909cf522d0 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Wed, 9 Nov 2016 14:14:18 +0100 Subject: codegen: shorten the overflow checking when converting into enums --- libsolidity/codegen/CompilerUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 5e045996..ad155b13 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -661,7 +661,8 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp if (targetTypeCategory == Type::Category::Enum) { EnumType const& enumType = dynamic_cast(_targetType); - m_context << u256(enumType.numberOfMembers()) << Instruction::DUP2 << Instruction::LT << Instruction::ISZERO; + solAssert(enumType.numberOfMembers() > 0, "empty enum should have caused a parser error."); + m_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT; m_context.appendConditionalJumpTo(m_context.errorTag()); } } -- cgit v1.2.3 From 20c2ca39922f4230b504888644d04f4bc8d6b8f3 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Wed, 9 Nov 2016 17:02:25 +0100 Subject: ast, codegen: disallow conversion between different enum types --- libsolidity/codegen/CompilerUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index ad155b13..2f30f53e 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -348,7 +348,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp } break; case Type::Category::Enum: - solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Enum, ""); + solAssert(_targetType == _typeOnStack || targetTypeCategory == Type::Category::Integer, ""); break; case Type::Category::FixedPoint: solAssert(false, "Not yet implemented - FixedPointType."); -- cgit v1.2.3 From 81f5734cbe029b93aa143e5eb7f57869ab63af7b Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 14 Nov 2016 11:11:39 +0100 Subject: codegen: move the enum overflow checking closer to the conversion into enums --- libsolidity/codegen/CompilerUtils.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 2f30f53e..dd133aea 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -315,6 +315,8 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp Type::Category stackTypeCategory = _typeOnStack.category(); Type::Category targetTypeCategory = _targetType.category(); + bool enumOverflowCheckPending = (targetTypeCategory == Type::Category::Enum); + switch (stackTypeCategory) { case Type::Category::FixedBytes: @@ -349,6 +351,14 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp break; case Type::Category::Enum: solAssert(_targetType == _typeOnStack || targetTypeCategory == Type::Category::Integer, ""); + if (enumOverflowCheckPending) + { + EnumType const& enumType = dynamic_cast(_targetType); + solAssert(enumType.numberOfMembers() > 0, "empty enum should have caused a parser error."); + m_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT; + m_context.appendConditionalJumpTo(m_context.errorTag()); + enumOverflowCheckPending = false; + } break; case Type::Category::FixedPoint: solAssert(false, "Not yet implemented - FixedPointType."); @@ -372,6 +382,11 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp solAssert(_typeOnStack.mobileType(), ""); // just clean convertType(_typeOnStack, *_typeOnStack.mobileType(), true); + EnumType const& enumType = dynamic_cast(_targetType); + solAssert(enumType.numberOfMembers() > 0, "empty enum should have caused a parser error."); + m_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT; + m_context.appendConditionalJumpTo(m_context.errorTag()); + enumOverflowCheckPending = false; } else if (targetTypeCategory == Type::Category::FixedPoint) { @@ -657,14 +672,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp break; } - // Check the conversion result fits in a range. - if (targetTypeCategory == Type::Category::Enum) - { - EnumType const& enumType = dynamic_cast(_targetType); - solAssert(enumType.numberOfMembers() > 0, "empty enum should have caused a parser error."); - m_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT; - m_context.appendConditionalJumpTo(m_context.errorTag()); - } + solAssert(!enumOverflowCheckPending, "enum overflow checking missing."); } void CompilerUtils::pushZeroValue(Type const& _type) -- cgit v1.2.3 From 1ff67b492a821054e5a3990f281500ebc0e56e83 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 14 Nov 2016 16:14:59 +0100 Subject: codegen: add a missing `break;` --- libsolidity/codegen/CompilerUtils.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index dd133aea..54645289 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -666,6 +666,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp solAssert(_targetType == _typeOnStack, "Invalid conversion for bool."); if (_cleanupNeeded) m_context << Instruction::ISZERO << Instruction::ISZERO; + break; default: // All other types should not be convertible to non-equal types. solAssert(_typeOnStack == _targetType, "Invalid type conversion requested."); -- cgit v1.2.3 From dbcbfafda8e44f56a7952993fd9f6699822395d6 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 14 Nov 2016 17:09:53 +0100 Subject: codegen: overflow checking also during conversion from enums --- libsolidity/codegen/CompilerUtils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index dd133aea..9472aac5 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -315,7 +315,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp Type::Category stackTypeCategory = _typeOnStack.category(); Type::Category targetTypeCategory = _targetType.category(); - bool enumOverflowCheckPending = (targetTypeCategory == Type::Category::Enum); + bool enumOverflowCheckPending = (targetTypeCategory == Type::Category::Enum || stackTypeCategory == Type::Category::Enum); switch (stackTypeCategory) { @@ -353,7 +353,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp solAssert(_targetType == _typeOnStack || targetTypeCategory == Type::Category::Integer, ""); if (enumOverflowCheckPending) { - EnumType const& enumType = dynamic_cast(_targetType); + EnumType const& enumType = dynamic_cast(_typeOnStack); solAssert(enumType.numberOfMembers() > 0, "empty enum should have caused a parser error."); m_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT; m_context.appendConditionalJumpTo(m_context.errorTag()); -- cgit v1.2.3 From 58e75c7a48f8166cca41e9017dad351113952ab5 Mon Sep 17 00:00:00 2001 From: Rhett Aultman Date: Mon, 14 Nov 2016 12:41:58 -0800 Subject: Unimplemented features moved to their own exception (#1361) Unimplemented features moved to their own exception InternalCompilerError is an exception that really should be reserved for actual internal errors of the compiler. Unimplemented features can now use either solUnimplemented( ) or, if it should be conditional, then solUnimplementedAssert( ). * Revert some unimplemented exceptions, add handlers The jsonCompiler and CommandLineInterface needed handlers for the new UnimplementedFeatureException, and some cases I had moved on to the new exception were better treated as real internal compiler errors. * Standardize on "Unimplemented feature" message --- libsolidity/codegen/CompilerUtils.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index db4aac34..58d1caa9 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -138,7 +138,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); if (numBytes > 0) { - solAssert( + solUnimplementedAssert( _type.sizeOnStack() == 1, "Memory store of types with stack size != 1 not implemented." ); @@ -161,7 +161,7 @@ void CompilerUtils::encodeToMemory( solAssert(targetTypes.size() == _givenTypes.size(), ""); for (TypePointer& t: targetTypes) { - solAssert( + solUnimplementedAssert( t->mobileType() && t->mobileType()->interfaceType(_encodeAsLibraryTypes) && t->mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType(), @@ -361,7 +361,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp } break; case Type::Category::FixedPoint: - solAssert(false, "Not yet implemented - FixedPointType."); + solUnimplemented("Not yet implemented - FixedPointType."); case Type::Category::Integer: case Type::Category::Contract: case Type::Category::RationalNumber: @@ -401,7 +401,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp if (auto typeOnStack = dynamic_cast(&_typeOnStack)) if (targetFixedPointType.integerBits() > typeOnStack->numBits()) cleanHigherOrderBits(*typeOnStack); - solAssert(false, "Not yet implemented - FixedPointType."); + solUnimplemented("Not yet implemented - FixedPointType."); } else { @@ -414,7 +414,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp RationalNumberType const& constType = dynamic_cast(_typeOnStack); // We know that the stack is clean, we only have to clean for a narrowing conversion // where cleanup is forced. - solAssert(!constType.isFractional(), "Not yet implemented - FixedPointType."); + solUnimplementedAssert(!constType.isFractional(), "Not yet implemented - FixedPointType."); if (targetType.numBits() < constType.integerType()->numBits() && _cleanupNeeded) cleanHigherOrderBits(targetType); } -- cgit v1.2.3 From dd173f83e3a6a9046d1aa7e64cb171598a73b272 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 28 Sep 2016 19:22:23 +0200 Subject: Code generator for function types. --- libsolidity/codegen/CompilerUtils.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 58d1caa9..38a7a23b 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -133,6 +133,17 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound m_context << u256(str->value().size()); m_context << Instruction::ADD; } + else if ( + _type.category() == Type::Category::Function && + dynamic_cast(_type).location() == FunctionType::Location::External + ) + { + solAssert(_padToWordBoundaries, "Non-padded store for function not implemented."); + m_context << u256(0xffffffffUL) << Instruction::AND << (u256(1) << 160) << Instruction::MUL << Instruction::SWAP1; + m_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::OR; + m_context << Instruction::DUP2 << Instruction::MSTORE; + m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD; + } else { unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); @@ -206,7 +217,8 @@ void CompilerUtils::encodeToMemory( else if ( _givenTypes[i]->dataStoredIn(DataLocation::Storage) || _givenTypes[i]->dataStoredIn(DataLocation::CallData) || - _givenTypes[i]->category() == Type::Category::StringLiteral + _givenTypes[i]->category() == Type::Category::StringLiteral || + _givenTypes[i]->category() == Type::Category::Function ) type = _givenTypes[i]; // delay conversion else @@ -678,6 +690,14 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp void CompilerUtils::pushZeroValue(Type const& _type) { + if (auto const* funType = dynamic_cast(&_type)) + { + if (funType->location() == FunctionType::Location::Internal) + { + m_context << m_context.errorTag(); + return; + } + } auto const* referenceType = dynamic_cast(&_type); if (!referenceType || referenceType->location() == DataLocation::Storage) { @@ -839,6 +859,18 @@ unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCallda } } + if (auto const* funType = dynamic_cast(&_type)) + { + if (funType->location() == FunctionType::Location::External) + { + // We have to split the right-aligned
into two stack slots: + // address (right aligned), function identifier (right aligned) + 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; + } + } + return numBytes; } -- cgit v1.2.3 From 95d7555e3c0e8fc4826114a336e0e717fe7a1a2d Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 14 Oct 2016 12:27:46 +0200 Subject: External functions in storage. --- libsolidity/codegen/CompilerUtils.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 38a7a23b..8a06268c 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -139,8 +139,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound ) { solAssert(_padToWordBoundaries, "Non-padded store for function not implemented."); - m_context << u256(0xffffffffUL) << Instruction::AND << (u256(1) << 160) << Instruction::MUL << Instruction::SWAP1; - m_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::OR; + combineExternalFunctionType(); m_context << Instruction::DUP2 << Instruction::MSTORE; m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD; } @@ -316,6 +315,21 @@ void CompilerUtils::memoryCopy() m_context << Instruction::POP; // ignore return value } +void CompilerUtils::splitExternalFunctionType() +{ + // We have to split the right-aligned
into two stack slots: + // address (right aligned), function identifier (right aligned) + 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; +} + +void CompilerUtils::combineExternalFunctionType() +{ + m_context << u256(0xffffffffUL) << Instruction::AND << (u256(1) << 160) << Instruction::MUL << Instruction::SWAP1; + m_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::OR; +} + void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded) { // For a type extension, we need to remove all higher-order bits that we might have ignored in @@ -860,16 +874,8 @@ unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCallda } if (auto const* funType = dynamic_cast(&_type)) - { if (funType->location() == FunctionType::Location::External) - { - // We have to split the right-aligned
into two stack slots: - // address (right aligned), function identifier (right aligned) - 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; - } - } + splitExternalFunctionType(); return numBytes; } -- cgit v1.2.3 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 +++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 23 deletions(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') 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; } -- cgit v1.2.3 From e543bd34c0b4884b5a27555f698f50af6a1c0b81 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 10 Nov 2016 18:16:21 +0100 Subject: Stored combined creation and runtime tags. Includes a change to Assembly to allow tags from sub-assemblies to be used. Sorry, this get a bit bigger than I thought. --- libsolidity/codegen/CompilerUtils.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index dedb53e7..1e21c020 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -340,6 +340,19 @@ void CompilerUtils::combineExternalFunctionType(bool _leftAligned) m_context << Instruction::OR; } +void CompilerUtils::pushCombinedFunctionEntryLabel(Declaration const& _function) +{ + m_context << m_context.functionEntryLabel(_function).pushTag(); + // If there is a runtime context, we have to merge both labels into the same + // stack slot in case we store it in storage. + if (CompilerContext* rtc = m_context.runtimeContext()) + m_context << + (u256(1) << 32) << + Instruction::MUL << + rtc->functionEntryLabel(_function).toSubAssemblyTag(m_context.runtimeSub()) << + Instruction::OR; +} + void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded) { // For a type extension, we need to remove all higher-order bits that we might have ignored in -- cgit v1.2.3 From ec31d08775021de0f3279dbeb115b3e688c5997e Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 14 Nov 2016 13:13:37 +0100 Subject: Change encoding to address-funid and add "function" as ABI type. --- libsolidity/codegen/CompilerUtils.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 1e21c020..1e819ed4 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -317,27 +317,32 @@ void CompilerUtils::memoryCopy() void CompilerUtils::splitExternalFunctionType(bool _leftAligned) { - // We have to split the left-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; - if (!_leftAligned) - m_context << u256(0xffffffffUL) << Instruction::AND; + { + m_context << Instruction::DUP1 << (u256(1) << (64 + 32)) << Instruction::SWAP1 << Instruction::DIV; + //
+ m_context << Instruction::SWAP1 << (u256(1) << 64) << Instruction::SWAP1 << Instruction::DIV; + } + else + { + m_context << Instruction::DUP1 << (u256(1) << 32) << Instruction::SWAP1 << Instruction::DIV; + m_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::SWAP1; + } + m_context << u256(0xffffffffUL) << Instruction::AND; } void CompilerUtils::combineExternalFunctionType(bool _leftAligned) { - 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; + //
+ m_context << u256(0xffffffffUL) << Instruction::AND << Instruction::SWAP1; + if (!_leftAligned) + m_context << ((u256(1) << 160) - 1) << Instruction::AND; + m_context << (u256(1) << 32) << Instruction::MUL; + m_context << Instruction::OR; if (_leftAligned) m_context << (u256(1) << 64) << Instruction::MUL; - m_context << Instruction::OR; } void CompilerUtils::pushCombinedFunctionEntryLabel(Declaration const& _function) -- cgit v1.2.3 From 2c14a96820233809db4360b39f5f02039be5730a Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 16 Nov 2016 15:09:01 +0100 Subject: Some more assertions and style changes. --- libsolidity/codegen/CompilerUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 1e819ed4..bfe5386b 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -138,7 +138,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound dynamic_cast(_type).location() == FunctionType::Location::External ) { - solAssert(_padToWordBoundaries, "Non-padded store for function not implemented."); + solUnimplementedAssert(_padToWordBoundaries, "Non-padded store for function not implemented."); combineExternalFunctionType(true); m_context << Instruction::DUP2 << Instruction::MSTORE; m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD; -- cgit v1.2.3