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/ContractCompiler.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 2aec3055..9cd893e8 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -293,6 +293,7 @@ void ContractCompiler::appendCalldataUnpacker(TypePointers const& _typeParameter { // stack: v1 v2 ... v(k-1) base_offset current_offset TypePointer type = parameterType->decodingType(); + solAssert(type, "No decoding type found."); if (type->category() == Type::Category::Array) { auto const& arrayType = dynamic_cast(*type); -- 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/ContractCompiler.cpp | 43 ++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 9cd893e8..79987af6 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -60,14 +60,13 @@ void ContractCompiler::compileContract( } size_t ContractCompiler::compileConstructor( - CompilerContext const& _runtimeContext, ContractDefinition const& _contract, std::map const& _contracts ) { CompilerContext::LocationSetter locationSetter(m_context, _contract); initializeContext(_contract, _contracts); - return packIntoContractCreator(_contract, _runtimeContext); + return packIntoContractCreator(_contract); } size_t ContractCompiler::compileClone( @@ -141,21 +140,31 @@ void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _c appendBaseConstructor(*c); } -size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _contract, CompilerContext const& _runtimeContext) +size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _contract) { + solAssert(!!m_runtimeCompiler, ""); + appendInitAndConstructorCode(_contract); - eth::AssemblyItem runtimeSub = m_context.addSubroutine(_runtimeContext.assembly()); + // We jump to the deploy routine because we first have to append all missing functions, + // which can cause further functions to be added to the runtime context. + eth::AssemblyItem deployRoutine = m_context.appendJumpToNew(); + + // We have to include copies of functions in the construction time and runtime context + // because of absolute jumps. + appendMissingFunctions(); + m_runtimeCompiler->appendMissingFunctions(); + + m_context << deployRoutine; + + solAssert(m_context.runtimeSub() != size_t(-1), "Runtime sub not registered"); + m_context.appendSubroutineSize(m_context.runtimeSub()); // stack contains sub size - m_context << Instruction::DUP1 << runtimeSub << u256(0) << Instruction::CODECOPY; + m_context << Instruction::DUP1 << m_context.runtimeSub() << u256(0) << Instruction::CODECOPY; m_context << u256(0) << Instruction::RETURN; - // note that we have to include the functions again because of absolute jump labels - appendMissingFunctions(); - - solAssert(runtimeSub.data() < numeric_limits::max(), ""); - return size_t(runtimeSub.data()); + return m_context.runtimeSub(); } void ContractCompiler::appendBaseConstructor(FunctionDefinition const& _constructor) @@ -516,7 +525,19 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) { solAssert(!!decl->type(), "Type of declaration required but not yet determined."); if (FunctionDefinition const* functionDef = dynamic_cast(decl)) - _assembly.append(m_context.virtualFunctionEntryLabel(*functionDef).pushTag()); + { + functionDef = &m_context.resolveVirtualFunction(*functionDef); + _assembly.append(m_context.functionEntryLabel(*functionDef).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()) + { + _assembly.append(u256(1) << 32); + _assembly.append(Instruction::MUL); + _assembly.append(rtc->functionEntryLabel(*functionDef).toSubAssemblyTag(m_context.runtimeSub())); + _assembly.append(Instruction::OR); + } + } else if (auto variable = dynamic_cast(decl)) { solAssert(!variable->isConstant(), ""); -- cgit v1.2.3 From e51f852504556f952ae1350c070409e3c4981cc0 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 11 Nov 2016 11:41:50 +0100 Subject: Converted sub assembly to smart pointer. --- libsolidity/codegen/ContractCompiler.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'libsolidity/codegen/ContractCompiler.cpp') diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 79987af6..2e3f5d7f 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -79,7 +79,7 @@ size_t ContractCompiler::compileClone( appendInitAndConstructorCode(_contract); //@todo determine largest return size of all runtime functions - eth::AssemblyItem runtimeSub = m_context.addSubroutine(cloneRuntime()); + auto runtimeSub = m_context.addSubroutine(cloneRuntime()); // stack contains sub size m_context << Instruction::DUP1 << runtimeSub << u256(0) << Instruction::CODECOPY; @@ -87,7 +87,6 @@ size_t ContractCompiler::compileClone( appendMissingFunctions(); - solAssert(runtimeSub.data() < numeric_limits::max(), ""); return size_t(runtimeSub.data()); } @@ -158,10 +157,10 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont m_context << deployRoutine; solAssert(m_context.runtimeSub() != size_t(-1), "Runtime sub not registered"); - m_context.appendSubroutineSize(m_context.runtimeSub()); - - // stack contains sub size - m_context << Instruction::DUP1 << m_context.runtimeSub() << u256(0) << Instruction::CODECOPY; + m_context.pushSubroutineSize(m_context.runtimeSub()); + m_context << Instruction::DUP1; + m_context.pushSubroutineOffset(m_context.runtimeSub()); + m_context << u256(0) << Instruction::CODECOPY; m_context << u256(0) << Instruction::RETURN; return m_context.runtimeSub(); @@ -893,7 +892,7 @@ void ContractCompiler::compileExpression(Expression const& _expression, TypePoin CompilerUtils(m_context).convertType(*_expression.annotation().type, *_targetType); } -eth::Assembly ContractCompiler::cloneRuntime() +eth::AssemblyPointer ContractCompiler::cloneRuntime() { eth::Assembly a; a << Instruction::CALLDATASIZE; @@ -911,5 +910,5 @@ eth::Assembly ContractCompiler::cloneRuntime() a.appendJumpI(a.errorTag()); //@todo adjust for larger return values, make this dynamic. a << u256(0x20) << u256(0) << Instruction::RETURN; - return a; + return make_shared(a); } -- cgit v1.2.3