--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -1224,93 +1224,122 @@ ASTReader::parseExpression(SimpleTokenRe
// FIXME: Implement
break;
case BinKind::unary_expression:
// FIXME: Implement
break;
case BinKind::update_expression:
// FIXME: Implement
break;
- case BinKind::binary_expression: {
+ case BinKind::binary_expression: MOZ_FALLTHROUGH;
+ case BinKind::logical_expression: {
UniquePtr<ParseNode> left;
UniquePtr<ParseNode> right;
- std::string op;
+ std::string operation;
for (auto field: fields) {
switch (field) {
case BinField::left:
if (!this->parseExpression(&sub, left)) {
return false;
}
break;
case BinField::right:
if (!this->parseExpression(&sub, right)) {
return false;
}
break;
case BinField::operator_:
- if (!this->readString(&sub, op)) {
+ if (!this->readString(&sub, operation)) {
return false;
}
break;
default:
return this->raiseError();
}
}
- if (!left || !right) {
+ if (!left || !right || operation.length() == 0) {
return this->raiseError();
}
// FIXME: Instead of std::string, we should use atoms and comparison
// between atom ptr.
// FIXME: We should probably turn associative operations into lists.
ParseNodeKind pnk = PNK_LIMIT;
- if (op == "==") {
+ JSOp op;
+ if (operation == "==") {
pnk = PNK_EQ;
- } else if (op == "!=") {
+ op = JSOP_EQ;
+ } else if (operation == "!=") {
pnk = PNK_NE;
- } else if (op == "===") {
+ op = JSOP_NE;
+ } else if (operation == "===") {
pnk = PNK_STRICTEQ;
- } else if (op == "!==") {
+ op = JSOP_STRICTEQ;
+ } else if (operation == "!==") {
pnk = PNK_STRICTNE;
- } else if (op == "<") {
+ op = JSOP_STRICTNE;
+ } else if (operation == "<") {
pnk = PNK_LT;
- } else if (op == "<=") {
+ op = JSOP_LT;
+ } else if (operation == "<=") {
pnk = PNK_LE;
- } else if (op == ">") {
+ op = JSOP_LE;
+ } else if (operation == ">") {
pnk = PNK_GT;
- } else if (op == ">=") {
+ op = JSOP_GT;
+ } else if (operation == ">=") {
pnk = PNK_GE;
- } else if (op == "<<") {
+ op = JSOP_GE;
+ } else if (operation == "<<") {
pnk = PNK_LSH;
- } else if (op == ">>") {
+ op = JSOP_LSH;
+ } else if (operation == ">>") {
pnk = PNK_RSH;
- } else if (op == ">>>") {
+ op = JSOP_RSH;
+ } else if (operation == ">>>") {
pnk = PNK_URSH;
- } else if (op == "+") {
+ op = JSOP_URSH;
+ } else if (operation == "+") {
pnk = PNK_ADD;
- } else if (op == "-") {
+ op = JSOP_ADD;
+ } else if (operation == "-") {
pnk = PNK_SUB;
- } else if (op == "*") {
+ op = JSOP_SUB;
+ } else if (operation == "*") {
pnk = PNK_STAR;
- } else if (op == "/") {
+ op = JSOP_MUL;
+ } else if (operation == "/") {
pnk = PNK_DIV;
- } else if (op == "%") {
+ op = JSOP_DIV;
+ } else if (operation == "%") {
pnk = PNK_MOD;
- } else if (op == "|") {
+ op = JSOP_MOD;
+ } else if (operation == "|") {
pnk = PNK_BITOR;
- } else if (op == "^") {
+ op = JSOP_BITOR;
+ } else if (operation == "^") {
pnk = PNK_BITXOR;
- } else if (op == "&") {
+ op = JSOP_BITXOR;
+ } else if (operation == "&") {
pnk = PNK_BITAND;
- } else if (op == "in") {
+ op = JSOP_BITAND;
+ } else if (operation == "in") {
pnk = PNK_IN;
- } else if (op == "instanceof") {
+ op = JSOP_IN;
+ } else if (operation == "instanceof") {
pnk = PNK_INSTANCEOF;
+ op = JSOP_INSTANCEOF;
+ } else if (operation == "||") {
+ pnk = PNK_OR;
+ op = JSOP_OR;
+ } else if (operation == "&&" ) {
+ pnk = PNK_AND;
+ op = JSOP_AND;
} else {
return this->raiseError();
}
UniquePtr<ParseNode> list(new_<ListNode>(pnk, JSOP_NOP, TokenPos()));
if (!list) {
return false;
}
@@ -1318,91 +1347,143 @@ ASTReader::parseExpression(SimpleTokenRe
list->append(left.release());
list->append(right.release());
out = Move(list);
break;
}
case BinKind::assignment_expression: {
UniquePtr<ParseNode> left;
UniquePtr<ParseNode> right;
- std::string op;
+ std::string operation;
for (auto field: fields) {
switch (field) {
case BinField::left:
if (!this->parseExpression(&sub, left)) {
return false;
}
break;
case BinField::right:
if (!this->parseExpression(&sub, right)) {
return false;
}
break;
case BinField::operator_:
- if (!this->readString(&sub, op)) {
+ if (!this->readString(&sub, operation)) {
return false;
}
break;
default:
return this->raiseError();
}
}
- if (!left || !right) {
+ if (!left || !right || operation.length() == 0) {
return this->raiseError();
}
// FIXME: Instead of std::string, we should use atoms and comparison
// between atom ptr.
// FIXME: We should probably turn associative operations into lists.
ParseNodeKind pnk = PNK_LIMIT;
- if (op == "=") {
+ JSOp op = JSOP_NOP;
+ if (operation == "=") {
pnk = PNK_ASSIGN;
- } else if (op == "+=") {
+ } else if (operation == "+=") {
pnk = PNK_ADDASSIGN;
- } else if (op == "-=") {
+ op = JSOP_ADD;
+ } else if (operation == "-=") {
pnk = PNK_SUBASSIGN;
- } else if (op == "*=") {
+ op = JSOP_SUB;
+ } else if (operation == "*=") {
pnk = PNK_MULASSIGN;
- } else if (op == "/=") {
+ op = JSOP_MUL;
+ } else if (operation == "/=") {
pnk = PNK_DIVASSIGN;
- } else if (op == "%=") {
+ op = JSOP_DIV;
+ } else if (operation == "%=") {
pnk = PNK_MODASSIGN;
- } else if (op == "<<=") {
+ op = JSOP_MOD;
+ } else if (operation == "<<=") {
pnk = PNK_LSHASSIGN;
- } else if (op == ">>=") {
+ op = JSOP_LSH;
+ } else if (operation == ">>=") {
pnk = PNK_RSHASSIGN;
- } else if (op == ">>>=") {
+ op = JSOP_RSH;
+ } else if (operation == ">>>=") {
pnk = PNK_URSHASSIGN;
- } else if (op == "|=") {
+ op = JSOP_URSH;
+ } else if (operation == "|=") {
pnk = PNK_BITORASSIGN;
- } else if (op == "^=") {
+ op = JSOP_BITOR;
+ } else if (operation == "^=") {
pnk = PNK_BITXORASSIGN;
- } else if (op == "&=") {
+ op = JSOP_BITXOR;
+ } else if (operation == "&=") {
pnk = PNK_BITANDASSIGN;
+ op = JSOP_BITAND;
} else {
return this->raiseError();
}
UniquePtr<ParseNode> list(new_<BinaryNode>(pnk, JSOP_NOP, TokenPos(), left.get(), right.get()));
if (!list) {
return false;
}
Unused << left.release();
Unused << right.release();
+
+ out = Move(list);
+ break;
}
- case BinKind::logical_expression:
- // FIXME: Implement
- break;
case BinKind::member_expression:
// FIXME: Implement
break;
- case BinKind::conditional_expression:
- // FIXME: Implement
+ case BinKind::conditional_expression: {
+ UniquePtr<ParseNode> test;
+ UniquePtr<ParseNode> alternate;
+ UniquePtr<ParseNode> consequent;
+
+ for (auto field: fields) {
+ switch (field) {
+ case BinField::test:
+ if (!this->parseExpression(&sub, test)) {
+ return false;
+ }
+ break;
+ case BinField::alternate:
+ if (!this->parseExpression(&sub, alternate)) {
+ return false;
+ }
+ break;
+ case BinField::consequent:
+ if (!this->parseExpression(&sub, consequent)) {
+ return false;
+ }
+ break;
+ default:
+ return this->raiseError();
+ }
+ }
+
+ if (!test || !alternate || !consequent) {
+ return this->raiseError();
+ }
+
+ UniquePtr<ParseNode> result(new_<ConditionalExpression>(test.get(), consequent.get(), alternate.get()));
+ if (!result) {
+ return false;
+ }
+
+ Unused << test.release();
+ Unused << alternate.release();
+ Unused << consequent.release();
+
+ out = Move(result);
break;
+ }
case BinKind::call_expression:
// FIXME: Implement
break;
case BinKind::new_expression:
// FIXME: Implement
break;
case BinKind::sequence_expression:
// FIXME: Implement