aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/codegen')
-rw-r--r--libsolidity/codegen/ABIFunctions.cpp21
-rw-r--r--libsolidity/codegen/Compiler.cpp13
-rw-r--r--libsolidity/codegen/Compiler.h6
-rw-r--r--libsolidity/codegen/CompilerContext.cpp2
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp29
-rw-r--r--libsolidity/codegen/ContractCompiler.cpp56
-rw-r--r--libsolidity/codegen/ContractCompiler.h10
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp2
8 files changed, 22 insertions, 117 deletions
diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp
index b3f1bc7e..dda77958 100644
--- a/libsolidity/codegen/ABIFunctions.cpp
+++ b/libsolidity/codegen/ABIFunctions.cpp
@@ -228,7 +228,8 @@ string ABIFunctions::cleanupFunction(Type const& _type, bool _revertOnFailure)
if (type.numBytes() == 32)
templ("body", "cleaned := value");
else if (type.numBytes() == 0)
- templ("body", "cleaned := 0");
+ // This is disallowed in the type system.
+ solAssert(false, "");
else
{
size_t numBits = type.numBytes() * 8;
@@ -471,13 +472,8 @@ string ABIFunctions::abiEncodingFunction(
bool _fromStack
)
{
- solUnimplementedAssert(
- _to.mobileType() &&
- _to.mobileType()->interfaceType(_encodeAsLibraryTypes) &&
- _to.mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType(),
- "Encoding type \"" + _to.toString() + "\" not yet implemented."
- );
- TypePointer toInterface = _to.mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType();
+ TypePointer toInterface = _to.fullEncodingType(_encodeAsLibraryTypes, true, false);
+ solUnimplementedAssert(toInterface, "Encoding type \"" + _to.toString() + "\" not yet implemented.");
Type const& to = *toInterface;
if (_from.category() == Type::Category::StringLiteral)
@@ -886,13 +882,8 @@ string ABIFunctions::abiEncodingFunctionStruct(
solAssert(member.type, "");
if (!member.type->canLiveOutsideStorage())
continue;
- solUnimplementedAssert(
- member.type->mobileType() &&
- member.type->mobileType()->interfaceType(_encodeAsLibraryTypes) &&
- member.type->mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType(),
- "Encoding type \"" + member.type->toString() + "\" not yet implemented."
- );
- auto memberTypeTo = member.type->mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType();
+ TypePointer memberTypeTo = member.type->fullEncodingType(_encodeAsLibraryTypes, true, false);
+ solUnimplementedAssert(memberTypeTo, "Encoding type \"" + member.type->toString() + "\" not yet implemented.");
auto memberTypeFrom = _from.memberType(member.name);
solAssert(memberTypeFrom, "");
bool dynamicMember = memberTypeTo->isDynamicallyEncoded();
diff --git a/libsolidity/codegen/Compiler.cpp b/libsolidity/codegen/Compiler.cpp
index d3afada5..55f1d252 100644
--- a/libsolidity/codegen/Compiler.cpp
+++ b/libsolidity/codegen/Compiler.cpp
@@ -46,19 +46,6 @@ void Compiler::compileContract(
m_context.optimise(m_optimize, m_optimizeRuns);
}
-void Compiler::compileClone(
- ContractDefinition const& _contract,
- map<ContractDefinition const*, eth::Assembly const*> const& _contracts
-)
-{
- solAssert(!_contract.isLibrary(), "");
- ContractCompiler runtimeCompiler(nullptr, m_runtimeContext, m_optimize);
- ContractCompiler cloneCompiler(&runtimeCompiler, m_context, m_optimize);
- m_runtimeSub = cloneCompiler.compileClone(_contract, _contracts);
-
- m_context.optimise(m_optimize, m_optimizeRuns);
-}
-
eth::AssemblyItem Compiler::functionEntryLabel(FunctionDefinition const& _function) const
{
return m_runtimeContext.functionEntryLabelIfExists(_function);
diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h
index f6865d75..4028ae63 100644
--- a/libsolidity/codegen/Compiler.h
+++ b/libsolidity/codegen/Compiler.h
@@ -50,12 +50,6 @@ public:
std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts,
bytes const& _metadata
);
- /// Compiles a contract that uses DELEGATECALL to call into a pre-deployed version of the given
- /// contract at runtime, but contains the full creation-time code.
- void compileClone(
- ContractDefinition const& _contract,
- std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts
- );
/// @returns Entire assembly.
eth::Assembly const& assembly() const { return m_context.assembly(); }
/// @returns The entire assembled object (with constructor).
diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp
index 3b1b4ec0..71b615b8 100644
--- a/libsolidity/codegen/CompilerContext.cpp
+++ b/libsolidity/codegen/CompilerContext.cpp
@@ -411,7 +411,7 @@ FunctionDefinition const& CompilerContext::resolveVirtualFunction(
if (
function->name() == name &&
!function->isConstructor() &&
- FunctionType(*function).hasEqualArgumentTypes(functionType)
+ FunctionType(*function).hasEqualParameterTypes(functionType)
)
return *function;
solAssert(false, "Super function " + name + " not found.");
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index 2d81a106..b30851fb 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -333,26 +333,19 @@ void CompilerUtils::encodeToMemory(
)
{
// stack: <v1> <v2> ... <vn> <mem>
+ bool const encoderV2 = m_context.experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2);
TypePointers targetTypes = _targetTypes.empty() ? _givenTypes : _targetTypes;
solAssert(targetTypes.size() == _givenTypes.size(), "");
for (TypePointer& t: targetTypes)
{
- solUnimplementedAssert(
- t->mobileType() &&
- t->mobileType()->interfaceType(_encodeAsLibraryTypes) &&
- t->mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType(),
- "Encoding type \"" + t->toString() + "\" not yet implemented."
- );
- t = t->mobileType()->interfaceType(_encodeAsLibraryTypes)->encodingType();
+ TypePointer tEncoding = t->fullEncodingType(_encodeAsLibraryTypes, encoderV2, !_padToWordBoundaries);
+ solUnimplementedAssert(tEncoding, "Encoding type \"" + t->toString() + "\" not yet implemented.");
+ t = std::move(tEncoding);
}
if (_givenTypes.empty())
return;
- else if (
- _padToWordBoundaries &&
- !_copyDynamicDataInPlace &&
- m_context.experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2)
- )
+ else if (_padToWordBoundaries && !_copyDynamicDataInPlace && encoderV2)
{
// Use the new Yul-based encoding function
auto stackHeightBefore = m_context.stackHeight();
@@ -954,20 +947,12 @@ void CompilerUtils::convertType(
{
TupleType const& sourceTuple = dynamic_cast<TupleType const&>(_typeOnStack);
TupleType const& targetTuple = dynamic_cast<TupleType const&>(_targetType);
- // fillRight: remove excess values at right side, !fillRight: remove eccess values at left side
- bool fillRight = !targetTuple.components().empty() && (
- !targetTuple.components().back() ||
- targetTuple.components().front()
- );
+ solAssert(targetTuple.components().size() == sourceTuple.components().size(), "");
unsigned depth = sourceTuple.sizeOnStack();
for (size_t i = 0; i < sourceTuple.components().size(); ++i)
{
TypePointer sourceType = sourceTuple.components()[i];
- TypePointer targetType;
- if (fillRight && i < targetTuple.components().size())
- targetType = targetTuple.components()[i];
- else if (!fillRight && targetTuple.components().size() + i >= sourceTuple.components().size())
- targetType = targetTuple.components()[targetTuple.components().size() - (sourceTuple.components().size() - i)];
+ TypePointer targetType = targetTuple.components()[i];
if (!sourceType)
{
solAssert(!targetType, "");
diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp
index bbb3db3d..e26bc13a 100644
--- a/libsolidity/codegen/ContractCompiler.cpp
+++ b/libsolidity/codegen/ContractCompiler.cpp
@@ -50,7 +50,7 @@ class StackHeightChecker
public:
explicit StackHeightChecker(CompilerContext const& _context):
m_context(_context), stackHeight(m_context.stackHeight()) {}
- void check() { solAssert(m_context.stackHeight() == stackHeight, std::string("I sense a disturbance in the stack: ") + std::to_string(m_context.stackHeight()) + " vs " + std::to_string(stackHeight)); }
+ void check() { solAssert(m_context.stackHeight() == stackHeight, std::string("I sense a disturbance in the stack: ") + to_string(m_context.stackHeight()) + " vs " + to_string(stackHeight)); }
private:
CompilerContext const& m_context;
unsigned stackHeight;
@@ -71,7 +71,11 @@ void ContractCompiler::compileContract(
appendDelegatecallCheck();
initializeContext(_contract, _contracts);
+ // This generates the dispatch function for externally visible functions
+ // and adds the function to the compilation queue. Additionally internal functions,
+ // which are referenced directly or indirectly will be added.
appendFunctionSelector(_contract);
+ // This processes the above populated queue until it is empty.
appendMissingFunctions();
}
@@ -90,27 +94,6 @@ size_t ContractCompiler::compileConstructor(
}
}
-size_t ContractCompiler::compileClone(
- ContractDefinition const& _contract,
- map<ContractDefinition const*, eth::Assembly const*> const& _contracts
-)
-{
- initializeContext(_contract, _contracts);
-
- appendInitAndConstructorCode(_contract);
-
- //@todo determine largest return size of all runtime functions
- auto runtimeSub = m_context.addSubroutine(cloneRuntime());
-
- // stack contains sub size
- m_context << Instruction::DUP1 << runtimeSub << u256(0) << Instruction::CODECOPY;
- m_context << u256(0) << Instruction::RETURN;
-
- appendMissingFunctions();
-
- return size_t(runtimeSub.data());
-}
-
void ContractCompiler::initializeContext(
ContractDefinition const& _contract,
map<ContractDefinition const*, eth::Assembly const*> const& _compiledContracts
@@ -796,11 +779,9 @@ bool ContractCompiler::visit(Return const& _return)
return false;
}
-bool ContractCompiler::visit(Throw const& _throw)
+bool ContractCompiler::visit(Throw const&)
{
- CompilerContext::LocationSetter locationSetter(m_context, _throw);
- // Do not send back an error detail.
- m_context.appendRevert();
+ solAssert(false, "Throw statement is disallowed.");
return false;
}
@@ -976,29 +957,6 @@ void ContractCompiler::compileExpression(Expression const& _expression, TypePoin
CompilerUtils(m_context).convertType(*_expression.annotation().type, *_targetType);
}
-eth::AssemblyPointer ContractCompiler::cloneRuntime() const
-{
- eth::Assembly a;
- a << Instruction::CALLDATASIZE;
- a << u256(0) << Instruction::DUP1 << Instruction::CALLDATACOPY;
- //@todo adjust for larger return values, make this dynamic.
- a << u256(0x20) << u256(0) << Instruction::CALLDATASIZE;
- a << u256(0);
- // this is the address which has to be substituted by the linker.
- //@todo implement as special "marker" AssemblyItem.
- a << u256("0xcafecafecafecafecafecafecafecafecafecafe");
- a << u256(eth::GasCosts::callGas(m_context.evmVersion()) + 10) << Instruction::GAS << Instruction::SUB;
- a << Instruction::DELEGATECALL;
- //Propagate error condition (if DELEGATECALL pushes 0 on stack).
- a << Instruction::ISZERO;
- a << Instruction::ISZERO;
- eth::AssemblyItem afterTag = a.appendJumpI().tag();
- a << Instruction::INVALID << afterTag;
- //@todo adjust for larger return values, make this dynamic.
- a << u256(0x20) << u256(0) << Instruction::RETURN;
- return make_shared<eth::Assembly>(a);
-}
-
void ContractCompiler::popScopedVariables(ASTNode const* _node)
{
unsigned blockHeight = m_scopeStackHeight.at(m_modifierDepth).at(_node);
diff --git a/libsolidity/codegen/ContractCompiler.h b/libsolidity/codegen/ContractCompiler.h
index 8516ec2c..5fa650b1 100644
--- a/libsolidity/codegen/ContractCompiler.h
+++ b/libsolidity/codegen/ContractCompiler.h
@@ -56,13 +56,6 @@ public:
ContractDefinition const& _contract,
std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts
);
- /// Compiles a contract that uses DELEGATECALL to call into a pre-deployed version of the given
- /// contract at runtime, but contains the full creation-time code.
- /// @returns the identifier of the runtime sub-assembly.
- size_t compileClone(
- ContractDefinition const& _contract,
- std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts
- );
private:
/// Registers the non-function objects inside the contract with the context and stores the basic
@@ -122,9 +115,6 @@ private:
void appendStackVariableInitialisation(VariableDeclaration const& _variable);
void compileExpression(Expression const& _expression, TypePointer const& _targetType = TypePointer());
- /// @returns the runtime assembly for clone contracts.
- eth::AssemblyPointer cloneRuntime() const;
-
/// Frees the variables of a certain scope (to be used when leaving).
void popScopedVariables(ASTNode const* _node);
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 54518906..412a7255 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -701,7 +701,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
m_context.appendRevert();
break;
}
- case FunctionType::Kind::SHA3:
+ case FunctionType::Kind::KECCAK256:
{
solAssert(arguments.size() == 1, "");
solAssert(!function.padArguments(), "");