From 74972f5fa6c0e59a5178e17ebdb48453528c7169 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 19 Sep 2017 19:02:16 +0100 Subject: Avoid switch fallthrough in ExpressionCompiler --- libsolidity/codegen/ExpressionCompiler.cpp | 58 ++++++++++++++++-------------- 1 file changed, 32 insertions(+), 26 deletions(-) (limited to 'libsolidity/codegen/ExpressionCompiler.cpp') diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index c94baa10..63d7f1e6 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1014,41 +1014,46 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) switch (_memberAccess.expression().annotation().type->category()) { case Type::Category::Contract: + case Type::Category::Integer: { bool alsoSearchInteger = false; - ContractType const& type = dynamic_cast(*_memberAccess.expression().annotation().type); - if (type.isSuper()) + if (_memberAccess.expression().annotation().type->category() == Type::Category::Contract) { - solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved."); - utils().pushCombinedFunctionEntryLabel(m_context.superFunction( - dynamic_cast(*_memberAccess.annotation().referencedDeclaration), - type.contractDefinition() - )); - } - else - { - // ordinary contract type - if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration) + ContractType const& type = dynamic_cast(*_memberAccess.expression().annotation().type); + if (type.isSuper()) { - u256 identifier; - if (auto const* variable = dynamic_cast(declaration)) - identifier = FunctionType(*variable).externalIdentifier(); - else if (auto const* function = dynamic_cast(declaration)) - identifier = FunctionType(*function).externalIdentifier(); - else - solAssert(false, "Contract member is neither variable nor function."); - utils().convertType(type, IntegerType(0, IntegerType::Modifier::Address), true); - m_context << identifier; + solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved."); + utils().pushCombinedFunctionEntryLabel(m_context.superFunction( + dynamic_cast(*_memberAccess.annotation().referencedDeclaration), + type.contractDefinition() + )); } else - // not found in contract, search in members inherited from address - alsoSearchInteger = true; + { + // ordinary contract type + if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration) + { + u256 identifier; + if (auto const* variable = dynamic_cast(declaration)) + identifier = FunctionType(*variable).externalIdentifier(); + else if (auto const* function = dynamic_cast(declaration)) + identifier = FunctionType(*function).externalIdentifier(); + else + solAssert(false, "Contract member is neither variable nor function."); + utils().convertType(type, IntegerType(0, IntegerType::Modifier::Address), true); + m_context << identifier; + } + else + // not found in contract, search in members inherited from address + alsoSearchInteger = true; + } } + else + alsoSearchInteger = true; + if (!alsoSearchInteger) break; - } - // fall-through - case Type::Category::Integer: + if (member == "balance") { utils().convertType( @@ -1067,6 +1072,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) else solAssert(false, "Invalid member access to integer"); break; + } case Type::Category::Function: if (member == "selector") { -- cgit v1.2.3 From cb6cdfe7801a3362a489d0fd39cc0ce5a7075fea Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 25 Sep 2017 09:41:04 +0100 Subject: Simplify switch statements by refactoring internal break statements --- libsolidity/codegen/ExpressionCompiler.cpp | 36 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'libsolidity/codegen/ExpressionCompiler.cpp') diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 63d7f1e6..b286594a 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1051,26 +1051,26 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) else alsoSearchInteger = true; - if (!alsoSearchInteger) - break; - - if (member == "balance") + if (alsoSearchInteger) { - utils().convertType( - *_memberAccess.expression().annotation().type, - IntegerType(0, IntegerType::Modifier::Address), - true - ); - m_context << Instruction::BALANCE; + if (member == "balance") + { + utils().convertType( + *_memberAccess.expression().annotation().type, + IntegerType(0, IntegerType::Modifier::Address), + true + ); + m_context << Instruction::BALANCE; + } + else if ((set{"send", "transfer", "call", "callcode", "delegatecall"}).count(member)) + utils().convertType( + *_memberAccess.expression().annotation().type, + IntegerType(0, IntegerType::Modifier::Address), + true + ); + else + solAssert(false, "Invalid member access to integer"); } - else if ((set{"send", "transfer", "call", "callcode", "delegatecall"}).count(member)) - utils().convertType( - *_memberAccess.expression().annotation().type, - IntegerType(0, IntegerType::Modifier::Address), - true - ); - else - solAssert(false, "Invalid member access to integer"); break; } case Type::Category::Function: -- cgit v1.2.3 From ee65ecfb3b80d9c027bade21df883e897b1234c5 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 26 Sep 2017 22:46:33 +0100 Subject: Ensure that address types are always declared as 160bit --- libsolidity/codegen/ExpressionCompiler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libsolidity/codegen/ExpressionCompiler.cpp') diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index b286594a..58c64bce 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1040,7 +1040,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) identifier = FunctionType(*function).externalIdentifier(); else solAssert(false, "Contract member is neither variable nor function."); - utils().convertType(type, IntegerType(0, IntegerType::Modifier::Address), true); + utils().convertType(type, IntegerType(160, IntegerType::Modifier::Address), true); m_context << identifier; } else @@ -1057,7 +1057,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) { utils().convertType( *_memberAccess.expression().annotation().type, - IntegerType(0, IntegerType::Modifier::Address), + IntegerType(160, IntegerType::Modifier::Address), true ); m_context << Instruction::BALANCE; @@ -1065,7 +1065,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) else if ((set{"send", "transfer", "call", "callcode", "delegatecall"}).count(member)) utils().convertType( *_memberAccess.expression().annotation().type, - IntegerType(0, IntegerType::Modifier::Address), + IntegerType(160, IntegerType::Modifier::Address), true ); else -- cgit v1.2.3 From a657d3b1a165d9ec14f9875db2380954f9ca37cf Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 26 Sep 2017 18:50:43 +0100 Subject: Make most of the parameters mandatory in encodeToMemory --- libsolidity/codegen/ExpressionCompiler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libsolidity/codegen/ExpressionCompiler.cpp') diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 58c64bce..5de24136 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -581,7 +581,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) _context << Instruction::ADD; } ); - utils().encodeToMemory(argumentTypes, function.parameterTypes()); + utils().encodeToMemory(argumentTypes, function.parameterTypes(), true, false); // now on stack: memory_end_ptr // need: size, offset, endowment utils().toSizeAfterFreeMemoryPointer(); @@ -751,7 +751,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) nonIndexedParamTypes.push_back(function.parameterTypes()[arg]); } utils().fetchFreeMemoryPointer(); - utils().encodeToMemory(nonIndexedArgTypes, nonIndexedParamTypes); + utils().encodeToMemory(nonIndexedArgTypes, nonIndexedParamTypes, true, false); // need: topic1 ... topicn memsize memstart utils().toSizeAfterFreeMemoryPointer(); m_context << logInstruction(numIndexed); -- cgit v1.2.3 From 204214f0700179e3d8fa97c77d4f92acd349f015 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 26 Sep 2017 22:10:30 +0100 Subject: Split encodeToMemory to packedEncode and abiEncode --- libsolidity/codegen/ExpressionCompiler.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'libsolidity/codegen/ExpressionCompiler.cpp') diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 5de24136..c2bf0f5c 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -581,7 +581,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) _context << Instruction::ADD; } ); - utils().encodeToMemory(argumentTypes, function.parameterTypes(), true, false); + utils().abiEncode(argumentTypes, function.parameterTypes()); // now on stack: memory_end_ptr // need: size, offset, endowment utils().toSizeAfterFreeMemoryPointer(); @@ -675,7 +675,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) argumentTypes.push_back(arg->annotation().type); } utils().fetchFreeMemoryPointer(); - utils().encodeToMemory(argumentTypes, TypePointers(), function.padArguments(), true); + solAssert(!function.padArguments(), ""); + utils().packedEncode(argumentTypes, TypePointers()); utils().toSizeAfterFreeMemoryPointer(); m_context << Instruction::KECCAK256; break; @@ -694,11 +695,10 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } arguments.front()->accept(*this); utils().fetchFreeMemoryPointer(); - utils().encodeToMemory( + utils().packedEncode( {arguments.front()->annotation().type}, - {function.parameterTypes().front()}, - false, - true); + {function.parameterTypes().front()} + ); utils().toSizeAfterFreeMemoryPointer(); m_context << logInstruction(logNumber); break; @@ -717,11 +717,9 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) if (auto const& arrayType = dynamic_pointer_cast(function.parameterTypes()[arg - 1])) { utils().fetchFreeMemoryPointer(); - utils().encodeToMemory( + utils().packedEncode( {arguments[arg - 1]->annotation().type}, - {arrayType}, - false, - true + {arrayType} ); utils().toSizeAfterFreeMemoryPointer(); m_context << Instruction::KECCAK256; @@ -751,7 +749,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) nonIndexedParamTypes.push_back(function.parameterTypes()[arg]); } utils().fetchFreeMemoryPointer(); - utils().encodeToMemory(nonIndexedArgTypes, nonIndexedParamTypes, true, false); + utils().abiEncode(nonIndexedArgTypes, nonIndexedParamTypes); // need: topic1 ... topicn memsize memstart utils().toSizeAfterFreeMemoryPointer(); m_context << logInstruction(numIndexed); @@ -1212,11 +1210,9 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) utils().fetchFreeMemoryPointer(); // stack: base index mem // note: the following operations must not allocate memory! - utils().encodeToMemory( + utils().packedEncode( TypePointers{_indexAccess.indexExpression()->annotation().type}, - TypePointers{keyType}, - false, - true + TypePointers{keyType} ); m_context << Instruction::SWAP1; utils().storeInMemoryDynamic(IntegerType(256)); -- cgit v1.2.3 From 69ea5c43f3ef2fe08bed0edbe1d45d4553cbbee4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 5 Oct 2017 11:56:36 +0200 Subject: Send all gas for 0.5.0. --- libsolidity/codegen/ExpressionCompiler.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libsolidity/codegen/ExpressionCompiler.cpp') diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index c2bf0f5c..fe37baac 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1714,6 +1714,9 @@ void ExpressionCompiler::appendExternalFunctionCall( if (_functionType.gasSet()) m_context << dupInstruction(m_context.baseToCurrentStackOffset(gasStackPos)); + else if (m_context.experimentalFeatureActive(ExperimentalFeature::V050)) + // Send all gas (requires tangerine whistle EVM) + m_context << Instruction::GAS; else { // send all gas except the amount needed to execute "SUB" and "CALL" -- cgit v1.2.3 From 6001bd1406e7adbb6607485afb775bbb5b6c2ac3 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 11 Oct 2017 12:28:21 +0200 Subject: Allocate one byte per memory byte array element instead of 32. --- libsolidity/codegen/ExpressionCompiler.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'libsolidity/codegen/ExpressionCompiler.cpp') diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index fe37baac..bb8c4a94 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -858,8 +858,15 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) m_context << Instruction::DUP1 << Instruction::DUP3 << Instruction::MSTORE; // Stack: memptr requested_length // update free memory pointer - m_context << Instruction::DUP1 << arrayType.baseType()->memoryHeadSize(); - m_context << Instruction::MUL << u256(32) << Instruction::ADD; + m_context << Instruction::DUP1; + // Stack: memptr requested_length requested_length + if (arrayType.isByteArray()) + // Round up to multiple of 32 + m_context << u256(31) << Instruction::ADD << u256(31) << Instruction::NOT << Instruction::AND; + else + m_context << arrayType.baseType()->memoryHeadSize() << Instruction::MUL; + // stacK: memptr requested_length data_size + m_context << u256(32) << Instruction::ADD; m_context << Instruction::DUP3 << Instruction::ADD; utils().storeFreeMemoryPointer(); // Stack: memptr requested_length -- cgit v1.2.3