Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(837)

Unified Diff: src/asmjs/asm-typer.cc

Issue 2648353010: [wasm][asm.js] Permit ternary operator in asm.js returns in some cases. (Closed)
Patch Set: fix Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/asmjs/asm-typer.h ('k') | test/cctest/asmjs/test-asm-typer.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/asmjs/asm-typer.cc
diff --git a/src/asmjs/asm-typer.cc b/src/asmjs/asm-typer.cc
index b265884bd0b8eb26c91f6ab30669edd25e1f2d87..d123e5637ace7df2576826b6c8d1f800f31ba199 100644
--- a/src/asmjs/asm-typer.cc
+++ b/src/asmjs/asm-typer.cc
@@ -1225,10 +1225,12 @@ AsmType* AsmTyper::ValidateFunction(FunctionDeclaration* fun_decl) {
if (as_block != nullptr) {
statements = as_block->statements();
} else {
- // We don't check whether AsReturnStatement() below returns non-null --
- // we leave that to the ReturnTypeAnnotations method.
- RECURSE(return_type_ =
- ReturnTypeAnnotations(last_statement->AsReturnStatement()));
+ if (auto* ret_statement = last_statement->AsReturnStatement()) {
+ RECURSE(return_type_ =
+ ReturnTypeAnnotations(ret_statement->expression()));
+ } else {
+ return_type_ = AsmType::Void();
+ }
}
}
} while (return_type_ == AsmType::None());
@@ -2747,15 +2749,8 @@ AsmType* AsmTyper::ParameterTypeAnnotations(Variable* parameter,
}
// 5.2 ReturnTypeAnnotations
-AsmType* AsmTyper::ReturnTypeAnnotations(ReturnStatement* statement) {
- if (statement == nullptr) {
- return AsmType::Void();
- }
-
- auto* ret_expr = statement->expression();
- if (ret_expr == nullptr) {
- return AsmType::Void();
- }
+AsmType* AsmTyper::ReturnTypeAnnotations(Expression* ret_expr) {
+ DCHECK_NOT_NULL(ret_expr);
if (auto* binop = ret_expr->AsBinaryOperation()) {
if (IsDoubleAnnotation(binop)) {
@@ -2763,14 +2758,14 @@ AsmType* AsmTyper::ReturnTypeAnnotations(ReturnStatement* statement) {
} else if (IsIntAnnotation(binop)) {
return AsmType::Signed();
}
- FAIL(statement, "Invalid return type annotation.");
+ FAIL(ret_expr, "Invalid return type annotation.");
}
if (auto* call = ret_expr->AsCall()) {
if (IsCallToFround(call)) {
return AsmType::Float();
}
- FAIL(statement, "Invalid function call in return statement.");
+ FAIL(ret_expr, "Invalid function call in return statement.");
}
if (auto* literal = ret_expr->AsLiteral()) {
@@ -2789,28 +2784,46 @@ AsmType* AsmTyper::ReturnTypeAnnotations(ReturnStatement* statement) {
// return undefined
return AsmType::Void();
}
- FAIL(statement, "Invalid literal in return statement.");
+ FAIL(ret_expr, "Invalid literal in return statement.");
}
if (auto* proxy = ret_expr->AsVariableProxy()) {
auto* var_info = Lookup(proxy->var());
if (var_info == nullptr) {
- FAIL(statement, "Undeclared identifier in return statement.");
+ FAIL(ret_expr, "Undeclared identifier in return statement.");
}
if (var_info->mutability() != VariableInfo::kConstGlobal) {
- FAIL(statement, "Identifier in return statement is not const.");
+ FAIL(ret_expr, "Identifier in return statement is not const.");
}
if (!var_info->type()->IsReturnType()) {
- FAIL(statement, "Constant in return must be signed, float, or double.");
+ FAIL(ret_expr, "Constant in return must be signed, float, or double.");
}
return var_info->type();
}
- FAIL(statement, "Invalid return type expression.");
+ // NOTE: This is not strictly valid asm.js, but is emitted by some versions of
+ // Emscripten.
+ if (auto* cond = ret_expr->AsConditional()) {
+ AsmType* a = AsmType::None();
+ AsmType* b = AsmType::None();
+ RECURSE(a = ReturnTypeAnnotations(cond->then_expression()));
+ if (a->IsA(AsmType::None())) {
+ return a;
+ }
+ RECURSE(b = ReturnTypeAnnotations(cond->else_expression()));
+ if (b->IsA(AsmType::None())) {
+ return b;
+ }
+ if (a->IsExactly(b)) {
+ return a;
+ }
+ }
+
+ FAIL(ret_expr, "Invalid return type expression.");
}
// 5.4 VariableTypeAnnotations
« no previous file with comments | « src/asmjs/asm-typer.h ('k') | test/cctest/asmjs/test-asm-typer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698