aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/Compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/Compiler.cpp')
-rw-r--r--libsolidity/Compiler.cpp26
1 files changed, 15 insertions, 11 deletions
diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp
index 969c8f74..6fb09def 100644
--- a/libsolidity/Compiler.cpp
+++ b/libsolidity/Compiler.cpp
@@ -68,6 +68,12 @@ void Compiler::compileContract(
packIntoContractCreator(_contract, m_runtimeContext);
if (m_optimize)
m_context.optimise(m_optimizeRuns);
+
+ if (_contract.isLibrary())
+ {
+ solAssert(m_runtimeSub != size_t(-1), "");
+ m_context.injectVersionStampIntoSub(m_runtimeSub);
+ }
}
void Compiler::compileClone(
@@ -252,7 +258,7 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract)
eth::AssemblyItem returnTag = m_context.pushNewTag();
fallback->accept(*this);
m_context << returnTag;
- appendReturnValuePacker(FunctionType(*fallback).returnParameterTypes());
+ appendReturnValuePacker(FunctionType(*fallback).returnParameterTypes(), _contract.isLibrary());
}
else
m_context << eth::Instruction::STOP; // function not found
@@ -268,7 +274,7 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract)
appendCalldataUnpacker(functionType->parameterTypes());
m_context.appendJumpTo(m_context.functionEntryLabel(functionType->declaration()));
m_context << returnTag;
- appendReturnValuePacker(functionType->returnParameterTypes());
+ appendReturnValuePacker(functionType->returnParameterTypes(), _contract.isLibrary());
}
}
@@ -280,15 +286,13 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
// Retain the offset pointer as base_offset, the point from which the data offsets are computed.
m_context << eth::Instruction::DUP1;
- for (TypePointer const& type: _typeParameters)
+ for (TypePointer const& parameterType: _typeParameters)
{
// stack: v1 v2 ... v(k-1) base_offset current_offset
- switch (type->category())
- {
- case Type::Category::Array:
+ TypePointer type = parameterType->decodingType();
+ if (type->category() == Type::Category::Array)
{
auto const& arrayType = dynamic_cast<ArrayType const&>(*type);
- solAssert(arrayType.location() != DataLocation::Storage, "");
solAssert(!arrayType.baseType()->isDynamicallySized(), "Nested arrays not yet implemented.");
if (_fromMemory)
{
@@ -342,9 +346,9 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
CompilerUtils(m_context).moveToStackTop(1 + arrayType.sizeOnStack());
m_context << eth::Instruction::SWAP1;
}
- break;
}
- default:
+ else
+ {
solAssert(!type->isDynamicallySized(), "Unknown dynamically sized type: " + type->toString());
CompilerUtils(m_context).loadFromMemoryDynamic(*type, !_fromMemory, true);
CompilerUtils(m_context).moveToStackTop(1 + type->sizeOnStack());
@@ -355,7 +359,7 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
m_context << eth::Instruction::POP << eth::Instruction::POP;
}
-void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters)
+void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters, bool _isLibrary)
{
CompilerUtils utils(m_context);
if (_typeParameters.empty())
@@ -365,7 +369,7 @@ void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters)
utils.fetchFreeMemoryPointer();
//@todo optimization: if we return a single memory array, there should be enough space before
// its data to add the needed parts and we avoid a memory copy.
- utils.encodeToMemory(_typeParameters, _typeParameters);
+ utils.encodeToMemory(_typeParameters, _typeParameters, true, false, _isLibrary);
utils.toSizeAfterFreeMemoryPointer();
m_context << eth::Instruction::RETURN;
}