diff options
Diffstat (limited to 'SolidityExpressionCompiler.cpp')
-rw-r--r-- | SolidityExpressionCompiler.cpp | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/SolidityExpressionCompiler.cpp b/SolidityExpressionCompiler.cpp index 579af5bb..a0cca3a3 100644 --- a/SolidityExpressionCompiler.cpp +++ b/SolidityExpressionCompiler.cpp @@ -86,17 +86,26 @@ Declaration const& resolveDeclaration(vector<string> const& _namespacedName, } bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _functions = {}, - vector<vector<string>> _localVariables = {}) + vector<vector<string>> _localVariables = {}, + vector<shared_ptr<MagicVariableDeclaration const>> _globalDeclarations = {}) { Parser parser; ASTPointer<SourceUnit> sourceUnit; BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode)))); - NameAndTypeResolver resolver({}); + + vector<Declaration const*> declarations; + declarations.reserve(_globalDeclarations.size() + 1); + for (ASTPointer<Declaration const> const& variable: _globalDeclarations) + declarations.push_back(variable.get()); + NameAndTypeResolver resolver(declarations); resolver.registerDeclarations(*sourceUnit); + + vector<ContractDefinition const*> inheritanceHierarchy; for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) { BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); + inheritanceHierarchy = vector<ContractDefinition const*>(1, contract); } for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) @@ -110,10 +119,12 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _ BOOST_REQUIRE(extractor.getExpression() != nullptr); CompilerContext context; - for (vector<string> const& function: _functions) - context.addFunction(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver))); + context.setInheritanceHierarchy(inheritanceHierarchy); + unsigned parametersSize = _localVariables.size(); // assume they are all one slot on the stack + context.adjustStackOffset(parametersSize); for (vector<string> const& variable: _localVariables) - context.addVariable(dynamic_cast<VariableDeclaration const&>(resolveDeclaration(variable, resolver))); + context.addVariable(dynamic_cast<VariableDeclaration const&>(resolveDeclaration(variable, resolver)), + parametersSize--); ExpressionCompiler::compileExpression(context, *extractor.getExpression()); @@ -390,6 +401,21 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals) BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } +BOOST_AUTO_TEST_CASE(blockhash) +{ + char const* sourceCode = "contract test {\n" + " function f() {\n" + " block.blockhash(3);\n" + " }\n" + "}\n"; + bytes code = compileFirstExpression(sourceCode, {}, {}, + {make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::BLOCK))}); + + bytes expectation({byte(eth::Instruction::PUSH1), 0x03, + byte(eth::Instruction::BLOCKHASH)}); + BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); +} + BOOST_AUTO_TEST_SUITE_END() } |