From 9c82cbeddf1b03cc99660a867de8720d1d174b9c Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 9 Mar 2015 19:22:43 +0100 Subject: [PATCH 1/4] Global variable "now" (alias for block.timestamp). --- ExpressionCompiler.cpp | 12 +++++++++++- GlobalContext.cpp | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index b02aecf5f..d2457e676 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -825,10 +825,20 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier) Declaration const* declaration = _identifier.getReferencedDeclaration(); if (MagicVariableDeclaration const* magicVar = dynamic_cast(declaration)) { - if (magicVar->getType()->getCategory() == Type::Category::Contract) + switch (magicVar->getType()->getCategory()) + { + case Type::Category::Contract: // "this" or "super" if (!dynamic_cast(*magicVar->getType()).isSuper()) m_context << eth::Instruction::ADDRESS; + break; + case Type::Category::Integer: + // "now" + m_context << eth::Instruction::TIMESTAMP; + break; + default: + break; + } } else if (FunctionDefinition const* functionDef = dynamic_cast(declaration)) m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag(); diff --git a/GlobalContext.cpp b/GlobalContext.cpp index 60de5105f..411e99abb 100644 --- a/GlobalContext.cpp +++ b/GlobalContext.cpp @@ -37,6 +37,7 @@ GlobalContext::GlobalContext(): m_magicVariables(vector>{make_shared("block", make_shared(MagicType::Kind::Block)), make_shared("msg", make_shared(MagicType::Kind::Message)), make_shared("tx", make_shared(MagicType::Kind::Transaction)), + make_shared("now", make_shared(256)), make_shared("suicide", make_shared(strings{"address"}, strings{}, FunctionType::Location::Suicide)), make_shared("sha3", From 74a01826ee9587ef9413e2ec808fcd53564f0b9d Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Mon, 9 Mar 2015 19:22:24 +0100 Subject: [PATCH 2/4] added information about jump type for jump instructions Conflicts: libevmcore/Assembly.cpp libsolidity/Compiler.cpp --- Compiler.cpp | 11 ++++++++--- CompilerContext.cpp | 7 +++++++ CompilerContext.h | 2 +- ExpressionCompiler.cpp | 5 +++-- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Compiler.cpp b/Compiler.cpp index 7ff846bdb..46888683e 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -177,7 +177,9 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) { callDataUnpackerEntryPoints.insert(std::make_pair(it.first, m_context.newTag())); m_context << eth::dupInstruction(1) << u256(FixedHash<4>::Arith(it.first)) << eth::Instruction::EQ; - m_context.appendConditionalJumpTo(callDataUnpackerEntryPoints.at(it.first)); + auto assemblyItem = callDataUnpackerEntryPoints.at(it.first); + //assemblyItem.setJumpType(eth::AssemblyItem::JumpType::IntoFunction); + m_context.appendConditionalJumpTo(assemblyItem); } if (FunctionDefinition const* fallback = _contract.getFallbackFunction()) { @@ -197,7 +199,9 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) m_context << callDataUnpackerEntryPoints.at(it.first); eth::AssemblyItem returnTag = m_context.pushNewTag(); appendCalldataUnpacker(functionType->getParameterTypes()); - m_context.appendJumpTo(m_context.getFunctionEntryLabel(functionType->getDeclaration())); + auto assemblyItem = m_context.getFunctionEntryLabel(functionType->getDeclaration()); + //assemblyItem.setJumpType(eth::AssemblyItem::JumpType::IntoFunction); + m_context.appendJumpTo(assemblyItem); m_context << returnTag; appendReturnValuePacker(functionType->getReturnParameterTypes()); } @@ -378,8 +382,9 @@ bool Compiler::visit(FunctionDefinition const& _function) m_context.removeVariable(*localVariable); m_context.adjustStackOffset(-(int)c_returnValuesSize); + if (!_function.isConstructor()) - m_context << eth::Instruction::JUMP; + m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); return false; } diff --git a/CompilerContext.cpp b/CompilerContext.cpp index 1dea62e93..f2bb1de20 100644 --- a/CompilerContext.cpp +++ b/CompilerContext.cpp @@ -177,6 +177,13 @@ u256 CompilerContext::getStorageLocationOfVariable(const Declaration& _declarati return it->second; } +CompilerContext& CompilerContext::appendJump(eth::AssemblyItem::JumpType _jumpType) +{ + eth::AssemblyItem item(eth::Instruction::JUMP); + item.setJumpType(_jumpType); + return *this << item; +} + void CompilerContext::resetVisitedNodes(ASTNode const* _node) { stack newStack; diff --git a/CompilerContext.h b/CompilerContext.h index 4d63d8ba0..f468d29c4 100644 --- a/CompilerContext.h +++ b/CompilerContext.h @@ -91,7 +91,7 @@ public: /// Appends a JUMP to a new tag and @returns the tag eth::AssemblyItem appendJumpToNew() { return m_asm.appendJump().tag(); } /// Appends a JUMP to a tag already on the stack - CompilerContext& appendJump() { return *this << eth::Instruction::JUMP; } + CompilerContext& appendJump(eth::AssemblyItem::JumpType _jumpType = eth::AssemblyItem::JumpType::Ordinary); /// Appends a JUMP to a specific tag CompilerContext& appendJumpTo(eth::AssemblyItem const& _tag) { m_asm.appendJump(_tag); return *this; } /// Appends pushing of a new tag and @returns the new tag. diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index d2457e676..129261120 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -108,7 +108,8 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& retSizeOnStack = returnType->getSizeOnStack(); } solAssert(retSizeOnStack <= 15, "Stack too deep."); - m_context << eth::dupInstruction(retSizeOnStack + 1) << eth::Instruction::JUMP; + m_context << eth::dupInstruction(retSizeOnStack + 1); + m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); } void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded) @@ -405,7 +406,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } _functionCall.getExpression().accept(*this); - m_context.appendJump(); + m_context.appendJump(eth::AssemblyItem::JumpType::IntoFunction); m_context << returnLabel; unsigned returnParametersSize = CompilerUtils::getSizeOnStack(function.getReturnParameterTypes()); From d5cbb2acd2ffd1323524cb1d7e596eb768518e3e Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Tue, 10 Mar 2015 12:00:23 +0100 Subject: [PATCH 3/4] added brackets for printing in/out cleaned up --- Compiler.cpp | 8 ++------ CompilerContext.h | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Compiler.cpp b/Compiler.cpp index 46888683e..dc6e2c5a8 100644 --- a/Compiler.cpp +++ b/Compiler.cpp @@ -177,9 +177,7 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) { callDataUnpackerEntryPoints.insert(std::make_pair(it.first, m_context.newTag())); m_context << eth::dupInstruction(1) << u256(FixedHash<4>::Arith(it.first)) << eth::Instruction::EQ; - auto assemblyItem = callDataUnpackerEntryPoints.at(it.first); - //assemblyItem.setJumpType(eth::AssemblyItem::JumpType::IntoFunction); - m_context.appendConditionalJumpTo(assemblyItem); + m_context.appendConditionalJumpTo(callDataUnpackerEntryPoints.at(it.first)); } if (FunctionDefinition const* fallback = _contract.getFallbackFunction()) { @@ -199,9 +197,7 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) m_context << callDataUnpackerEntryPoints.at(it.first); eth::AssemblyItem returnTag = m_context.pushNewTag(); appendCalldataUnpacker(functionType->getParameterTypes()); - auto assemblyItem = m_context.getFunctionEntryLabel(functionType->getDeclaration()); - //assemblyItem.setJumpType(eth::AssemblyItem::JumpType::IntoFunction); - m_context.appendJumpTo(assemblyItem); + m_context.appendJumpTo(m_context.getFunctionEntryLabel(functionType->getDeclaration())); m_context << returnTag; appendReturnValuePacker(functionType->getReturnParameterTypes()); } diff --git a/CompilerContext.h b/CompilerContext.h index f468d29c4..76923a77a 100644 --- a/CompilerContext.h +++ b/CompilerContext.h @@ -120,7 +120,7 @@ public: eth::Assembly const& getAssembly() const { return m_asm; } /// @arg _sourceCodes is the map of input files to source code strings - void streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const { m_asm.streamRLP(_stream, "", _sourceCodes); } + void streamAssembly(std::ostream& _stream, StringMap const& _sourceCodes = StringMap()) const { m_asm.stream(_stream, "", _sourceCodes); } bytes getAssembledBytecode(bool _optimize = false) { return m_asm.optimise(_optimize).assemble(); } From d41c51a8106ff20b347d95adf453e58a20d89513 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 10 Mar 2015 15:11:13 +0100 Subject: [PATCH 4/4] Fixed some checker warnings. --- Compiler.h | 4 ++-- Parser.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Compiler.h b/Compiler.h index 76f16f3ab..4b1e1b4d6 100644 --- a/Compiler.h +++ b/Compiler.h @@ -94,8 +94,8 @@ private: std::vector m_continueTags; ///< tag to jump to for a "continue" statement eth::AssemblyItem m_returnTag; ///< tag to jump to for a "return" statement unsigned m_modifierDepth = 0; - FunctionDefinition const* m_currentFunction; - unsigned m_stackCleanupForReturn; ///< this number of stack elements need to be removed before jump to m_returnTag + FunctionDefinition const* m_currentFunction = nullptr; + unsigned m_stackCleanupForReturn = 0; ///< this number of stack elements need to be removed before jump to m_returnTag // arguments for base constructors, filled in derived-to-base order std::map> const*> m_baseArguments; }; diff --git a/Parser.h b/Parser.h index 87eb2f8ff..cc0b2ca17 100644 --- a/Parser.h +++ b/Parser.h @@ -34,6 +34,8 @@ class Scanner; class Parser { public: + Parser() {} + ASTPointer parse(std::shared_ptr const& _scanner); std::shared_ptr const& getSourceName() const;