Skip to content

Commit

Permalink
Fix yul ast import for blocks, switches and string literals.
Browse files Browse the repository at this point in the history
  • Loading branch information
ekpyron committed Mar 5, 2020
1 parent 9318dae commit 420f57a
Show file tree
Hide file tree
Showing 9 changed files with 488 additions and 6 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Bugfixes:
* isoltest: Added new keyword `wei` to express function value in semantic tests
* Standard-JSON-Interface: Fix a bug related to empty filenames and imports.
* SMTChecker: Fix internal errors when analysing tuples.
* Yul AST Import: correctly import blocks as statements, switch statements and string literals.


### 0.6.3 (2020-02-18)
Expand Down
19 changes: 14 additions & 5 deletions libsolidity/ast/AsmJsonImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ yul::Statement AsmJsonImporter::createStatement(Json::Value const& _node)
return createContinue(_node);
else if (nodeType == "Leave")
return createLeave(_node);
else if (nodeType == "Block")
return createBlock(_node);
else
astAssert(false, "Invalid nodeType as statement");
}
Expand Down Expand Up @@ -158,10 +160,9 @@ yul::Literal AsmJsonImporter::createLiteral(Json::Value const& _node)
lit.value = YulString{member(_node, "value").asString()};
lit.type= YulString{member(_node, "type").asString()};

langutil::Scanner scanner{langutil::CharStream(lit.value.str(), "")};

if (kind == "number")
{
langutil::Scanner scanner{langutil::CharStream(lit.value.str(), "")};
lit.kind = yul::LiteralKind::Number;
astAssert(
scanner.currentToken() == Token::Number,
Expand All @@ -170,6 +171,7 @@ yul::Literal AsmJsonImporter::createLiteral(Json::Value const& _node)
}
else if (kind == "bool")
{
langutil::Scanner scanner{langutil::CharStream(lit.value.str(), "")};
lit.kind = yul::LiteralKind::Boolean;
astAssert(
scanner.currentToken() == Token::TrueLiteral ||
Expand All @@ -180,7 +182,10 @@ yul::Literal AsmJsonImporter::createLiteral(Json::Value const& _node)
else if (kind == "string")
{
lit.kind = yul::LiteralKind::String;
astAssert(scanner.currentToken() == Token::StringLiteral, "Expected string literal!");
astAssert(
lit.value.str().size() <= 32,
"String literal too long (" + to_string(lit.value.str().size()) + " > 32)"
);
}
else
solAssert(false, "unknown type of literal");
Expand Down Expand Up @@ -268,15 +273,19 @@ yul::If AsmJsonImporter::createIf(Json::Value const& _node)
yul::Case AsmJsonImporter::createCase(Json::Value const& _node)
{
auto caseStatement = createAsmNode<yul::Case>(_node);
caseStatement.value = member(_node, "value").asString() == "default" ? nullptr : make_unique<yul::Literal>(createLiteral(member(_node, "value")));
auto const& value = member(_node, "value");
if (value.isString())
astAssert(value.asString() == "default", "Expected default case");
else
caseStatement.value = make_unique<yul::Literal>(createLiteral(value));
caseStatement.body = createBlock(member(_node, "body"));
return caseStatement;
}

yul::Switch AsmJsonImporter::createSwitch(Json::Value const& _node)
{
auto switchStatement = createAsmNode<yul::Switch>(_node);
switchStatement.expression = make_unique<yul::Expression>(createExpression(member(_node, "value")));
switchStatement.expression = make_unique<yul::Expression>(createExpression(member(_node, "expression")));
for (auto const& var: member(_node, "cases"))
switchStatement.cases.emplace_back(createCase(var));
return switchStatement;
Expand Down
3 changes: 2 additions & 1 deletion scripts/ASTImportTest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SOLC=${REPO_ROOT}/${SOLIDITY_BUILD_DIR}/solc/solc
SPLITSOURCES=${REPO_ROOT}/scripts/splitSources.py

SYNTAXTESTS_DIR="${REPO_ROOT}/test/libsolidity/syntaxTests"
ASTJSONTESTS_DIR="${REPO_ROOT}/test/libsolidity/ASTJSON"
NSOURCES="$(find $SYNTAXTESTS_DIR -type f | wc -l)"

# DEV_DIR="${REPO_ROOT}/../tmp/contracts/"
Expand Down Expand Up @@ -75,7 +76,7 @@ echo "Looking at $NSOURCES .sol files..."
WORKINGDIR=$PWD

# for solfile in $(find $DEV_DIR -name *.sol)
for solfile in $(find $SYNTAXTESTS_DIR -name *.sol)
for solfile in $(find $SYNTAXTESTS_DIR $ASTJSONTESTS_DIR -name *.sol)
do
echo -n "."
# create a temporary sub-directory
Expand Down
95 changes: 95 additions & 0 deletions test/libsolidity/ASTJSON/assembly/empty_block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{
"absolutePath": "a",
"exportedSymbols":
{
"C":
[
6
]
},
"id": 7,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"id": 6,
"linearizedBaseContracts":
[
6
],
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 4,
"nodeType": "Block",
"src": "42:31:1",
"statements":
[
{
"AST":
{
"nodeType": "YulBlock",
"src": "61:6:1",
"statements":
[
{
"nodeType": "YulBlock",
"src": "63:2:1",
"statements": []
}
]
},
"evmVersion": %EVMVERSION%,
"externalReferences": [],
"id": 3,
"nodeType": "InlineAssembly",
"src": "52:15:1"
}
]
},
"documentation": null,
"functionSelector": "e2179b8e",
"id": 5,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "g",
"nodeType": "FunctionDefinition",
"overrides": null,
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "42:0:1"
},
"scope": 6,
"src": "17:56:1",
"stateMutability": "view",
"virtual": false,
"visibility": "public"
}
],
"scope": 7,
"src": "0:75:1"
}
],
"src": "0:76:1"
}
7 changes: 7 additions & 0 deletions test/libsolidity/ASTJSON/assembly/empty_block.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
contract C {
function g() view public {
assembly { {} }
}
}

// ----
123 changes: 123 additions & 0 deletions test/libsolidity/ASTJSON/assembly/empty_block_legacy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{
"attributes":
{
"absolutePath": "a",
"exportedSymbols":
{
"C":
[
6
]
}
},
"children":
[
{
"attributes":
{
"abstract": false,
"baseContracts":
[
null
],
"contractDependencies":
[
null
],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"linearizedBaseContracts":
[
6
],
"name": "C",
"scope": 7
},
"children":
[
{
"attributes":
{
"documentation": null,
"functionSelector": "e2179b8e",
"implemented": true,
"isConstructor": false,
"kind": "function",
"modifiers":
[
null
],
"name": "g",
"overrides": null,
"scope": 6,
"stateMutability": "view",
"virtual": false,
"visibility": "public"
},
"children":
[
{
"attributes":
{
"parameters":
[
null
]
},
"children": [],
"id": 1,
"name": "ParameterList",
"src": "27:2:1"
},
{
"attributes":
{
"parameters":
[
null
]
},
"children": [],
"id": 2,
"name": "ParameterList",
"src": "42:0:1"
},
{
"children":
[
{
"attributes":
{
"evmVersion": %EVMVERSION%,
"externalReferences":
[
null
],
"operations": "{ { } }"
},
"children": [],
"id": 3,
"name": "InlineAssembly",
"src": "52:15:1"
}
],
"id": 4,
"name": "Block",
"src": "42:31:1"
}
],
"id": 5,
"name": "FunctionDefinition",
"src": "17:56:1"
}
],
"id": 6,
"name": "ContractDefinition",
"src": "0:75:1"
}
],
"id": 7,
"name": "SourceUnit",
"src": "0:76:1"
}
Loading

0 comments on commit 420f57a

Please sign in to comment.