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