From ea628001d5f34ee1d85398a17f93e7c4f55429fe Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 21 Nov 2016 17:07:10 +0100 Subject: codegen: add an option to CovertType so that it can truncate sign bits --- libsolidity/codegen/CompilerUtils.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index fe2b9c7e..21dd2840 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -358,7 +358,7 @@ void CompilerUtils::pushCombinedFunctionEntryLabel(Declaration const& _function) Instruction::OR; } -void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded) +void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded, bool _chopSignBits) { // For a type extension, we need to remove all higher-order bits that we might have ignored in // previous operations. @@ -370,6 +370,12 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp Type::Category targetTypeCategory = _targetType.category(); bool enumOverflowCheckPending = (targetTypeCategory == Type::Category::Enum || stackTypeCategory == Type::Category::Enum); + bool chopSignBitsPending = _chopSignBits && targetTypeCategory == Type::Category::Integer; + if (chopSignBitsPending) + { + const IntegerType& targetIntegerType = dynamic_cast(_targetType); + chopSignBitsPending = targetIntegerType.isSigned(); + } switch (stackTypeCategory) { @@ -482,6 +488,17 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp cleanHigherOrderBits(typeOnStack); else if (_cleanupNeeded) cleanHigherOrderBits(targetType); + if (chopSignBitsPending) + { + if (typeOnStack.numBits() < 256) + m_context + << (u256(1) << (256 - typeOnStack.numBits())) + << Instruction::SWAP1 + << Instruction::DUP2 + << Instruction::MUL + << Instruction::DIV; + chopSignBitsPending = false; + } } } break; @@ -728,6 +745,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp } solAssert(!enumOverflowCheckPending, "enum overflow checking missing."); + solAssert(!chopSignBitsPending, "forgot to chop the sign bits."); } void CompilerUtils::pushZeroValue(Type const& _type) -- cgit v1.2.3 From fa486f5b44790e5abda28ddb2b798d0b1408269f Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Thu, 24 Nov 2016 17:03:17 +0100 Subject: codegen: shorten the bit truncation --- libsolidity/codegen/CompilerUtils.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 21dd2840..41559a42 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -492,11 +492,8 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp { if (typeOnStack.numBits() < 256) m_context - << (u256(1) << (256 - typeOnStack.numBits())) - << Instruction::SWAP1 - << Instruction::DUP2 - << Instruction::MUL - << Instruction::DIV; + << ((u256(1) << typeOnStack.numBits()) - 1) + << Instruction::AND; chopSignBitsPending = false; } } -- cgit v1.2.3 From 0be58595036d3411124bc8b39f9d151790d950b4 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 25 Nov 2016 15:50:46 +0100 Subject: codegen: cleanup values to fit in storage bytes --- libsolidity/codegen/CompilerUtils.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libsolidity/codegen/CompilerUtils.cpp') diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 41559a42..d5361ac6 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -738,6 +738,10 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp default: // All other types should not be convertible to non-equal types. solAssert(_typeOnStack == _targetType, "Invalid type conversion requested."); + if (_cleanupNeeded && _targetType.canBeStored() && _targetType.storageBytes() < 32) + m_context + << ((u256(1) << (8 * _targetType.storageBytes())) - 1) + << Instruction::AND; break; } -- cgit v1.2.3