reader/wgsl: Tail-call optimize expression methods
Fixes stack overflows in complex arithmetic expressions Fixed: chromium:1182709 Change-Id: I5f5470cf59525725a437f26672904e9653b447a7 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/43940 Reviewed-by: David Neto <dneto@google.com> Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
d1781fd0af
commit
dee7d36f8a
|
@ -2256,6 +2256,7 @@ Maybe<ast::Expression*> ParserImpl::unary_expression() {
|
||||||
// | MODULO unary_expression multiplicative_expr
|
// | MODULO unary_expression multiplicative_expr
|
||||||
Expect<ast::Expression*> ParserImpl::expect_multiplicative_expr(
|
Expect<ast::Expression*> ParserImpl::expect_multiplicative_expr(
|
||||||
ast::Expression* lhs) {
|
ast::Expression* lhs) {
|
||||||
|
while (synchronized_) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
|
|
||||||
ast::BinaryOp op = ast::BinaryOp::kNone;
|
ast::BinaryOp op = ast::BinaryOp::kNone;
|
||||||
|
@ -2280,8 +2281,9 @@ Expect<ast::Expression*> ParserImpl::expect_multiplicative_expr(
|
||||||
"unable to parse right side of " + name + " expression");
|
"unable to parse right side of " + name + " expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
return expect_multiplicative_expr(
|
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
||||||
create<ast::BinaryExpression>(source, op, lhs, rhs.value));
|
}
|
||||||
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// multiplicative_expression
|
// multiplicative_expression
|
||||||
|
@ -2302,6 +2304,7 @@ Maybe<ast::Expression*> ParserImpl::multiplicative_expression() {
|
||||||
// | MINUS multiplicative_expression additive_expr
|
// | MINUS multiplicative_expression additive_expr
|
||||||
Expect<ast::Expression*> ParserImpl::expect_additive_expr(
|
Expect<ast::Expression*> ParserImpl::expect_additive_expr(
|
||||||
ast::Expression* lhs) {
|
ast::Expression* lhs) {
|
||||||
|
while (synchronized_) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
|
|
||||||
ast::BinaryOp op = ast::BinaryOp::kNone;
|
ast::BinaryOp op = ast::BinaryOp::kNone;
|
||||||
|
@ -2321,8 +2324,9 @@ Expect<ast::Expression*> ParserImpl::expect_additive_expr(
|
||||||
if (!rhs.matched)
|
if (!rhs.matched)
|
||||||
return add_error(peek(), "unable to parse right side of + expression");
|
return add_error(peek(), "unable to parse right side of + expression");
|
||||||
|
|
||||||
return expect_additive_expr(
|
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
||||||
create<ast::BinaryExpression>(source, op, lhs, rhs.value));
|
}
|
||||||
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// additive_expression
|
// additive_expression
|
||||||
|
@ -2342,6 +2346,7 @@ Maybe<ast::Expression*> ParserImpl::additive_expression() {
|
||||||
// | SHIFT_LEFT additive_expression shift_expr
|
// | SHIFT_LEFT additive_expression shift_expr
|
||||||
// | SHIFT_RIGHT additive_expression shift_expr
|
// | SHIFT_RIGHT additive_expression shift_expr
|
||||||
Expect<ast::Expression*> ParserImpl::expect_shift_expr(ast::Expression* lhs) {
|
Expect<ast::Expression*> ParserImpl::expect_shift_expr(ast::Expression* lhs) {
|
||||||
|
while (synchronized_) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
auto source = t.source();
|
auto source = t.source();
|
||||||
|
|
||||||
|
@ -2366,9 +2371,11 @@ Expect<ast::Expression*> ParserImpl::expect_shift_expr(ast::Expression* lhs) {
|
||||||
return add_error(peek(), std::string("unable to parse right side of ") +
|
return add_error(peek(), std::string("unable to parse right side of ") +
|
||||||
name + " expression");
|
name + " expression");
|
||||||
}
|
}
|
||||||
return expect_shift_expr(
|
|
||||||
create<ast::BinaryExpression>(source, op, lhs, rhs.value));
|
return lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
||||||
} // namespace wgsl
|
}
|
||||||
|
return Failure::kErrored;
|
||||||
|
}
|
||||||
|
|
||||||
// shift_expression
|
// shift_expression
|
||||||
// : additive_expression shift_expr
|
// : additive_expression shift_expr
|
||||||
|
@ -2390,6 +2397,7 @@ Maybe<ast::Expression*> ParserImpl::shift_expression() {
|
||||||
// | GREATER_THAN_EQUAL shift_expression relational_expr
|
// | GREATER_THAN_EQUAL shift_expression relational_expr
|
||||||
Expect<ast::Expression*> ParserImpl::expect_relational_expr(
|
Expect<ast::Expression*> ParserImpl::expect_relational_expr(
|
||||||
ast::Expression* lhs) {
|
ast::Expression* lhs) {
|
||||||
|
while (synchronized_) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
ast::BinaryOp op = ast::BinaryOp::kNone;
|
ast::BinaryOp op = ast::BinaryOp::kNone;
|
||||||
if (t.IsLessThan())
|
if (t.IsLessThan())
|
||||||
|
@ -2415,8 +2423,9 @@ Expect<ast::Expression*> ParserImpl::expect_relational_expr(
|
||||||
"unable to parse right side of " + name + " expression");
|
"unable to parse right side of " + name + " expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
return expect_relational_expr(
|
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
||||||
create<ast::BinaryExpression>(source, op, lhs, rhs.value));
|
}
|
||||||
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// relational_expression
|
// relational_expression
|
||||||
|
@ -2437,6 +2446,7 @@ Maybe<ast::Expression*> ParserImpl::relational_expression() {
|
||||||
// | NOT_EQUAL relational_expression equality_expr
|
// | NOT_EQUAL relational_expression equality_expr
|
||||||
Expect<ast::Expression*> ParserImpl::expect_equality_expr(
|
Expect<ast::Expression*> ParserImpl::expect_equality_expr(
|
||||||
ast::Expression* lhs) {
|
ast::Expression* lhs) {
|
||||||
|
while (synchronized_) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
ast::BinaryOp op = ast::BinaryOp::kNone;
|
ast::BinaryOp op = ast::BinaryOp::kNone;
|
||||||
if (t.IsEqualEqual())
|
if (t.IsEqualEqual())
|
||||||
|
@ -2458,8 +2468,9 @@ Expect<ast::Expression*> ParserImpl::expect_equality_expr(
|
||||||
"unable to parse right side of " + name + " expression");
|
"unable to parse right side of " + name + " expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
return expect_equality_expr(
|
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
||||||
create<ast::BinaryExpression>(source, op, lhs, rhs.value));
|
}
|
||||||
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// equality_expression
|
// equality_expression
|
||||||
|
@ -2478,6 +2489,7 @@ Maybe<ast::Expression*> ParserImpl::equality_expression() {
|
||||||
// :
|
// :
|
||||||
// | AND equality_expression and_expr
|
// | AND equality_expression and_expr
|
||||||
Expect<ast::Expression*> ParserImpl::expect_and_expr(ast::Expression* lhs) {
|
Expect<ast::Expression*> ParserImpl::expect_and_expr(ast::Expression* lhs) {
|
||||||
|
while (synchronized_) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (!t.IsAnd())
|
if (!t.IsAnd())
|
||||||
return lhs;
|
return lhs;
|
||||||
|
@ -2491,8 +2503,10 @@ Expect<ast::Expression*> ParserImpl::expect_and_expr(ast::Expression* lhs) {
|
||||||
if (!rhs.matched)
|
if (!rhs.matched)
|
||||||
return add_error(peek(), "unable to parse right side of & expression");
|
return add_error(peek(), "unable to parse right side of & expression");
|
||||||
|
|
||||||
return expect_and_expr(create<ast::BinaryExpression>(
|
lhs = create<ast::BinaryExpression>(source, ast::BinaryOp::kAnd, lhs,
|
||||||
source, ast::BinaryOp::kAnd, lhs, rhs.value));
|
rhs.value);
|
||||||
|
}
|
||||||
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and_expression
|
// and_expression
|
||||||
|
@ -2512,6 +2526,7 @@ Maybe<ast::Expression*> ParserImpl::and_expression() {
|
||||||
// | XOR and_expression exclusive_or_expr
|
// | XOR and_expression exclusive_or_expr
|
||||||
Expect<ast::Expression*> ParserImpl::expect_exclusive_or_expr(
|
Expect<ast::Expression*> ParserImpl::expect_exclusive_or_expr(
|
||||||
ast::Expression* lhs) {
|
ast::Expression* lhs) {
|
||||||
|
while (synchronized_) {
|
||||||
Source source;
|
Source source;
|
||||||
if (!match(Token::Type::kXor, &source))
|
if (!match(Token::Type::kXor, &source))
|
||||||
return lhs;
|
return lhs;
|
||||||
|
@ -2522,8 +2537,10 @@ Expect<ast::Expression*> ParserImpl::expect_exclusive_or_expr(
|
||||||
if (!rhs.matched)
|
if (!rhs.matched)
|
||||||
return add_error(peek(), "unable to parse right side of ^ expression");
|
return add_error(peek(), "unable to parse right side of ^ expression");
|
||||||
|
|
||||||
return expect_exclusive_or_expr(create<ast::BinaryExpression>(
|
lhs = create<ast::BinaryExpression>(source, ast::BinaryOp::kXor, lhs,
|
||||||
source, ast::BinaryOp::kXor, lhs, rhs.value));
|
rhs.value);
|
||||||
|
}
|
||||||
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// exclusive_or_expression
|
// exclusive_or_expression
|
||||||
|
@ -2543,6 +2560,7 @@ Maybe<ast::Expression*> ParserImpl::exclusive_or_expression() {
|
||||||
// | OR exclusive_or_expression inclusive_or_expr
|
// | OR exclusive_or_expression inclusive_or_expr
|
||||||
Expect<ast::Expression*> ParserImpl::expect_inclusive_or_expr(
|
Expect<ast::Expression*> ParserImpl::expect_inclusive_or_expr(
|
||||||
ast::Expression* lhs) {
|
ast::Expression* lhs) {
|
||||||
|
while (synchronized_) {
|
||||||
Source source;
|
Source source;
|
||||||
if (!match(Token::Type::kOr))
|
if (!match(Token::Type::kOr))
|
||||||
return lhs;
|
return lhs;
|
||||||
|
@ -2553,8 +2571,10 @@ Expect<ast::Expression*> ParserImpl::expect_inclusive_or_expr(
|
||||||
if (!rhs.matched)
|
if (!rhs.matched)
|
||||||
return add_error(peek(), "unable to parse right side of | expression");
|
return add_error(peek(), "unable to parse right side of | expression");
|
||||||
|
|
||||||
return expect_inclusive_or_expr(create<ast::BinaryExpression>(
|
lhs = create<ast::BinaryExpression>(source, ast::BinaryOp::kOr, lhs,
|
||||||
source, ast::BinaryOp::kOr, lhs, rhs.value));
|
rhs.value);
|
||||||
|
}
|
||||||
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// inclusive_or_expression
|
// inclusive_or_expression
|
||||||
|
@ -2574,6 +2594,7 @@ Maybe<ast::Expression*> ParserImpl::inclusive_or_expression() {
|
||||||
// | AND_AND inclusive_or_expression logical_and_expr
|
// | AND_AND inclusive_or_expression logical_and_expr
|
||||||
Expect<ast::Expression*> ParserImpl::expect_logical_and_expr(
|
Expect<ast::Expression*> ParserImpl::expect_logical_and_expr(
|
||||||
ast::Expression* lhs) {
|
ast::Expression* lhs) {
|
||||||
|
while (synchronized_) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (!t.IsAndAnd())
|
if (!t.IsAndAnd())
|
||||||
return lhs;
|
return lhs;
|
||||||
|
@ -2587,8 +2608,10 @@ Expect<ast::Expression*> ParserImpl::expect_logical_and_expr(
|
||||||
if (!rhs.matched)
|
if (!rhs.matched)
|
||||||
return add_error(peek(), "unable to parse right side of && expression");
|
return add_error(peek(), "unable to parse right side of && expression");
|
||||||
|
|
||||||
return expect_logical_and_expr(create<ast::BinaryExpression>(
|
lhs = create<ast::BinaryExpression>(source, ast::BinaryOp::kLogicalAnd, lhs,
|
||||||
source, ast::BinaryOp::kLogicalAnd, lhs, rhs.value));
|
rhs.value);
|
||||||
|
}
|
||||||
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// logical_and_expression
|
// logical_and_expression
|
||||||
|
@ -2608,6 +2631,7 @@ Maybe<ast::Expression*> ParserImpl::logical_and_expression() {
|
||||||
// | OR_OR logical_and_expression logical_or_expr
|
// | OR_OR logical_and_expression logical_or_expr
|
||||||
Expect<ast::Expression*> ParserImpl::expect_logical_or_expr(
|
Expect<ast::Expression*> ParserImpl::expect_logical_or_expr(
|
||||||
ast::Expression* lhs) {
|
ast::Expression* lhs) {
|
||||||
|
while (synchronized_) {
|
||||||
Source source;
|
Source source;
|
||||||
if (!match(Token::Type::kOrOr))
|
if (!match(Token::Type::kOrOr))
|
||||||
return lhs;
|
return lhs;
|
||||||
|
@ -2618,8 +2642,10 @@ Expect<ast::Expression*> ParserImpl::expect_logical_or_expr(
|
||||||
if (!rhs.matched)
|
if (!rhs.matched)
|
||||||
return add_error(peek(), "unable to parse right side of || expression");
|
return add_error(peek(), "unable to parse right side of || expression");
|
||||||
|
|
||||||
return expect_logical_or_expr(create<ast::BinaryExpression>(
|
lhs = create<ast::BinaryExpression>(source, ast::BinaryOp::kLogicalOr, lhs,
|
||||||
source, ast::BinaryOp::kLogicalOr, lhs, rhs.value));
|
rhs.value);
|
||||||
|
}
|
||||||
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// logical_or_expression
|
// logical_or_expression
|
||||||
|
|
Loading…
Reference in New Issue