Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inline assembly to AST in json export #7537

Merged
merged 1 commit into from
Nov 13, 2019
Merged

Conversation

djudjuu
Copy link
Contributor

@djudjuu djudjuu commented Oct 15, 2019

Description

resolves #2419

creates different kinds of Json nodes for each kind of AsmData-struct.
similar to the solidityAST, there is a "nodeType" field and a "src"-location.

Goal: It should be possible to recreate the AsmData from the Json.

TEST added: I added a contract with a bunch of inlineAssembly (assebly.sol from the syntaxTests) to /test/libsolidity/ASTJSON
Then I ran the testsuite and used its output from the error-message to create assembly.json and assembly_legacy.json.

Checklist

  • Code compiles correctly
  • All tests are passing
  • New tests have been created which fail without the change (if possible)
  • README / documentation was extended, if necessary
    -> left a note on [DOCS] Add AST output #7387
  • Changelog entry (if change is visible to the user)
  • Used meaningful commit messages

@djudjuu djudjuu force-pushed the asmAST branch 3 times, most recently from 0110af0 to 7489e46 Compare October 17, 2019 11:51
@djudjuu djudjuu mentioned this pull request Oct 17, 2019
6 tasks
@djudjuu djudjuu force-pushed the asmAST branch 2 times, most recently from 3fc863d to 9d1d7fc Compare October 17, 2019 15:02
@djudjuu djudjuu changed the title WIP: inline assembly to AST in json export inline assembly to AST in json export Oct 17, 2019
@djudjuu djudjuu force-pushed the asmAST branch 3 times, most recently from 6a17696 to 22e4d69 Compare October 24, 2019 12:54
@djudjuu
Copy link
Contributor Author

djudjuu commented Oct 24, 2019

HELP NEEDED: All test that fail are related to the fuzzer testing soljson.

I don't really know how to debug that or make sense of it. any pointers?

UPDATE: All solved

@djudjuu djudjuu mentioned this pull request Oct 25, 2019
9 tasks
@bshastry
Copy link
Contributor

bshastry commented Oct 28, 2019

HELP NEEDED: All test that fail are related to the fuzzer testing soljson.

I don't really know how to debug that or make sense of it. any pointers?

@djudjuu I didn't take a look at all failures. One failure that I spent some time on is from the t_ubu_release_cli that looks like so

Invalid error: "InternalCompilerError"
Fuzzer failed on test_254ca6c11f2f9744a828fdf899fa357a2bff321ec25630224b2ce8a4031b9a04_solidityendtoendtest_cpp.solInvalid error: "InternalCompilerError"
Fuzzer failed on test_5897c478c6ab519fb05b145b1fcbc940d8b3ebaa7e9b65b1fec7c2033e29d60b_solidityendtoendtest_cpp.solxargs: /root/project/build/test/tools/solfuzzer: terminated by signal 11
Exited with code 123

What I tried to do is the following

  • Located failing print to here
    printTask "Testing soljson via the fuzzer..."
    SOLTMPDIR=$(mktemp -d)
    (
    set -e
    cd "$SOLTMPDIR"
    "$REPO_ROOT"/scripts/isolate_tests.py "$REPO_ROOT"/test/
    "$REPO_ROOT"/scripts/isolate_tests.py "$REPO_ROOT"/docs/ docs
    echo *.sol | xargs -P 4 -n 50 "$REPO_ROOT"/${SOLIDITY_BUILD_DIR}/test/tools/solfuzzer --quiet --input-files
    echo *.sol | xargs -P 4 -n 50 "$REPO_ROOT"/${SOLIDITY_BUILD_DIR}/test/tools/solfuzzer --without-optimizer --quiet --input-files
    )
    rm -rf "$SOLTMPDIR"
  • Since the failing test is obfuscated by a hash string, added a print statement in the isolate_scripts.py script here
    open('test_%s_%s.sol' % (hashlib.sha256(test).hexdigest(), cleaned_filename), 'wb').write(remainder)
  • Located the failing solidity test case (corresponding to the error output test_254ca6c11f2f9744a828fdf899fa357a2bff321ec25630224b2ce8a4031b9a04_solidityendtoendtest_cpp) to be this
    contract C {
    function f(uint a) public returns (uint b) {
    assembly {
    function fac(n) -> nf {
    switch n
    case 0 { nf := 1 }
    case 1 { nf := 1 }
    default { nf := mul(n, fac(sub(n, 1))) }
    }
    b := fac(a)
    }
    }
    }

One option to debug this specific failure further is to copy paste the highlighted solidity test case into a standalone file and run it against solfuzzer. My guess is that the run should failure with an internal compiler error, and then you can debug the issue further. Hope this helps you :)

@djudjuu djudjuu mentioned this pull request Oct 28, 2019
2 tasks
@djudjuu djudjuu force-pushed the asmAST branch 2 times, most recently from 7f3ae64 to 1883b69 Compare October 28, 2019 17:24
@chriseth
Copy link
Contributor

chriseth commented Nov 4, 2019

Please retarget to 0.6.0 - I think this might break some tools.

@Marenz Marenz changed the base branch from develop to develop_060 November 11, 2019 17:00
@Marenz
Copy link
Contributor

Marenz commented Nov 11, 2019

I retargeted it, but I can't retrigger the tests

Copy link
Member

@leonardoalt leonardoalt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Why does it sometimes use (*this)(...) and sometimes boost::apply_visitor(*this, ...);?
  • It would be nice to have some smaller tests also. It's impossible to review 1000 lines of JSON output.

@@ -24,6 +24,7 @@
#include <libsolidity/ast/AST.h>
#include <libyul/AsmData.h>
#include <libyul/AsmPrinter.h>
#include <libsolidity/ast/AsmJsonConverter.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be moved two lines up.

int sourceIndex{-1};
if (_location.source && m_sourceIndices.count(_location.source->name()))
sourceIndex = m_sourceIndices.at(_location.source->name());
size_t sourceIndex = sourceIndexFromLocation(_location);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before, if the condition was false, sourceIndex == -1. Now it asserts. Why is the latter true?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can be rather sure to have a source, but better to not assert, I think.

*/

#include <libyul/AsmDataForward.h>
#include <liblangutil/SourceLocation.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This include should be moved up.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing: I think liblangutil is more basic than libyul.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, got confused

using TypedNameList = std::vector<yul::TypedName>;

/**
* Converter of the yul AST into JSON format
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this converts Yul to JSON, shouldn't it go into libyul instead of libsolidity?

/**
* Converter of the yul AST into JSON format
*/
class AsmJsonConverter : public boost::static_visitor<Json::Value>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class AsmJsonConverter : public boost::static_visitor<Json::Value>
class AsmJsonConverter: public boost::static_visitor<Json::Value>

private:
Json::Value createAstNode(langutil::SourceLocation const& _location, std::string _nodeType) const;
template <class T>
Json::Value vectorOfVariantsToJson(std::vector<T> const& vec ) const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Json::Value vectorOfVariantsToJson(std::vector<T> const& vec ) const;
Json::Value vectorOfVariantsToJson(std::vector<T> const& vec) const;

#include <libsolidity/ast/AsmJsonConverter.h>
#include <libyul/AsmData.h>
#include <liblangutil/Exceptions.h>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra blank line.


#include <libsolidity/ast/AsmJsonConverter.h>
#include <libyul/AsmData.h>
#include <liblangutil/Exceptions.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should be moved one up. It should still come after AsmJsonConverter.h, since that's the header of this cpp.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't liblangutil more basic than libyul?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah sorry, that's correct

namespace solidity
{

Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _location, string _nodeType) const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this and the next function should go to the end of the file to follow the same order as the header.

@chriseth
Copy link
Contributor

Why does it sometimes use (*this)(...) and sometimes boost::apply_visitor(*this, ...);?: Depends on whether the argument is a variant (then you have to use apply_visitor), or a specific type (then (*this)(...) has to be used).

@chriseth chriseth force-pushed the asmAST branch 2 times, most recently from 3d7b9b3 to 641c4c0 Compare November 13, 2019 10:55
"statements":
[
{
"AST":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually what's this AST key?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a node-type-specific key for the node type "InlineAssembly".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually - it would probably be better to prefix all the Yul AST node types by Yul wouldn't it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds quite generic. Why not call it something closer to InlineAssembly?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually - it would probably be better to prefix all the Yul AST node types by Yul wouldn't it?

Yea I agree

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the keys that depend on the node type are always "generic" because they are only seen in the context of the node type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants