From fd62adebf3e594298c171e43e78153dbefc42759 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 18:14:40 +0100 Subject: Tests for labels with stack information. --- test/libsolidity/InlineAssembly.cpp | 10 ++++++++++ test/libsolidity/SolidityEndToEndTest.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 9035599b..824fce95 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -200,6 +200,11 @@ BOOST_AUTO_TEST_CASE(blocks) BOOST_CHECK(successParse("{ let x := 7 { let y := 3 } { let z := 2 } }")); } +BOOST_AUTO_TEST_CASE(labels_with_stack_info) +{ + BOOST_CHECK(successParse("{ x[-1]: y[a]: z[d, e]: h[100]: g[]: }")); +} + BOOST_AUTO_TEST_CASE(function_definitions) { BOOST_CHECK(successParse("{ function f() { } function g(a) -> (x) { } }")); @@ -244,6 +249,11 @@ BOOST_AUTO_TEST_CASE(print_label) parsePrintCompare("{\n loop:\n jump(loop)\n}"); } +BOOST_AUTO_TEST_CASE(print_label_with_stack) +{ + parsePrintCompare("{\n loop[x, y]:\n other[-2]:\n third[10]:\n}"); +} + BOOST_AUTO_TEST_CASE(print_assignments) { parsePrintCompare("{\n let x := mul(2, 3)\n 7\n =: x\n x := add(1, 2)\n}"); diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index cb0cc168..d2028344 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7418,6 +7418,33 @@ BOOST_AUTO_TEST_CASE(inline_assembly_function_access) BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(10))); } +BOOST_AUTO_TEST_CASE(inline_assembly_labels_with_stack_info) +{ + char const* sourceCode = R"( + contract C { + function f(uint y) { + assembly { + y 7 + jump(fun) + exit[-1]: + y add + 0 mstore + return(0, 0x20) + fun: + { + entry[a, b]: + a := div(a, b) + pop + jump(exit) + } + } + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f(uint256)", u256(15)) == encodeArgs(15 / 7 + 15)); +} + BOOST_AUTO_TEST_CASE(index_access_with_type_conversion) { // Test for a bug where higher order bits cleanup was not done for array index access. -- cgit From 98e343b3fc11f3e94297b016c3f625e3b319b09b Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 1 Feb 2017 21:40:50 +0100 Subject: Parsing of labels with stack info. --- libsolidity/inlineasm/AsmCodeGen.cpp | 1 + libsolidity/inlineasm/AsmData.h | 4 ++-- libsolidity/inlineasm/AsmParser.cpp | 32 ++++++++++++++++++++++++++++++++ libsolidity/inlineasm/AsmPrinter.cpp | 6 +++++- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libsolidity/inlineasm/AsmCodeGen.cpp index faa7dabd..abc0ca01 100644 --- a/libsolidity/inlineasm/AsmCodeGen.cpp +++ b/libsolidity/inlineasm/AsmCodeGen.cpp @@ -91,6 +91,7 @@ public: void operator()(T const& /*_item*/) { } void operator()(Label const& _item) { + solAssert(_item.stackInfo.empty(), "Labels with stack info not yet supported."); if (m_state.labels.count(_item.name)) //@TODO secondary location m_state.addError( diff --git a/libsolidity/inlineasm/AsmData.h b/libsolidity/inlineasm/AsmData.h index d61b5803..5969bf96 100644 --- a/libsolidity/inlineasm/AsmData.h +++ b/libsolidity/inlineasm/AsmData.h @@ -42,8 +42,8 @@ struct Literal { SourceLocation location; bool isNumber; std::string value; }; /// External / internal identifier or label reference struct Identifier { SourceLocation location; std::string name; }; struct FunctionalInstruction; -/// Jump label ("name:") -struct Label { SourceLocation location; std::string name; }; +/// Jump label ("name:" or "name [x, y, z]:" or "name [-3]:") +struct Label { SourceLocation location; std::string name; std::vector stackInfo; }; /// Assignemnt (":= x", moves stack top into x, potentially multiple slots) struct Assignment { SourceLocation location; Identifier variableName; }; struct FunctionalAssignment; diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 0fc0a34f..5d439b2f 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -121,6 +121,38 @@ assembly::Statement Parser::parseStatement() return label; } } + case Token::LBrack: + { + if (statement.type() != typeid(assembly::Identifier)) + fatalParserError("Label name must precede \"[\"."); + assembly::Identifier const& identifier = boost::get(statement); + Label label = createWithLocation