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

Side by Side 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, 10 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/asmjs/asm-typer.h" 5 #include "src/asmjs/asm-typer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <memory> 9 #include <memory>
10 #include <string> 10 #include <string>
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 1218
1219 do { 1219 do {
1220 if (statements->length() == 0) { 1220 if (statements->length() == 0) {
1221 return_type_ = AsmType::Void(); 1221 return_type_ = AsmType::Void();
1222 } else { 1222 } else {
1223 auto* last_statement = statements->last(); 1223 auto* last_statement = statements->last();
1224 auto* as_block = last_statement->AsBlock(); 1224 auto* as_block = last_statement->AsBlock();
1225 if (as_block != nullptr) { 1225 if (as_block != nullptr) {
1226 statements = as_block->statements(); 1226 statements = as_block->statements();
1227 } else { 1227 } else {
1228 // We don't check whether AsReturnStatement() below returns non-null -- 1228 if (auto* ret_statement = last_statement->AsReturnStatement()) {
1229 // we leave that to the ReturnTypeAnnotations method. 1229 RECURSE(return_type_ =
1230 RECURSE(return_type_ = 1230 ReturnTypeAnnotations(ret_statement->expression()));
1231 ReturnTypeAnnotations(last_statement->AsReturnStatement())); 1231 } else {
1232 return_type_ = AsmType::Void();
1233 }
1232 } 1234 }
1233 } 1235 }
1234 } while (return_type_ == AsmType::None()); 1236 } while (return_type_ == AsmType::None());
1235 1237
1236 DCHECK(return_type_->IsReturnType()); 1238 DCHECK(return_type_->IsReturnType());
1237 1239
1238 for (Declaration* decl : *fun->scope()->declarations()) { 1240 for (Declaration* decl : *fun->scope()->declarations()) {
1239 auto* var_decl = decl->AsVariableDeclaration(); 1241 auto* var_decl = decl->AsVariableDeclaration();
1240 if (var_decl == nullptr) { 1242 if (var_decl == nullptr) {
1241 FAIL(decl, "Functions may only define inner variables."); 1243 FAIL(decl, "Functions may only define inner variables.");
(...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after
2740 FAIL(annotation, 2742 FAIL(annotation,
2741 "Invalid float parameter type annotation - argument to fround is not " 2743 "Invalid float parameter type annotation - argument to fround is not "
2742 "a parameter."); 2744 "a parameter.");
2743 } 2745 }
2744 2746
2745 SetTypeOf(src_expr, AsmType::Float()); 2747 SetTypeOf(src_expr, AsmType::Float());
2746 return AsmType::Float(); 2748 return AsmType::Float();
2747 } 2749 }
2748 2750
2749 // 5.2 ReturnTypeAnnotations 2751 // 5.2 ReturnTypeAnnotations
2750 AsmType* AsmTyper::ReturnTypeAnnotations(ReturnStatement* statement) { 2752 AsmType* AsmTyper::ReturnTypeAnnotations(Expression* ret_expr) {
2751 if (statement == nullptr) { 2753 DCHECK_NOT_NULL(ret_expr);
2752 return AsmType::Void();
2753 }
2754
2755 auto* ret_expr = statement->expression();
2756 if (ret_expr == nullptr) {
2757 return AsmType::Void();
2758 }
2759 2754
2760 if (auto* binop = ret_expr->AsBinaryOperation()) { 2755 if (auto* binop = ret_expr->AsBinaryOperation()) {
2761 if (IsDoubleAnnotation(binop)) { 2756 if (IsDoubleAnnotation(binop)) {
2762 return AsmType::Double(); 2757 return AsmType::Double();
2763 } else if (IsIntAnnotation(binop)) { 2758 } else if (IsIntAnnotation(binop)) {
2764 return AsmType::Signed(); 2759 return AsmType::Signed();
2765 } 2760 }
2766 FAIL(statement, "Invalid return type annotation."); 2761 FAIL(ret_expr, "Invalid return type annotation.");
2767 } 2762 }
2768 2763
2769 if (auto* call = ret_expr->AsCall()) { 2764 if (auto* call = ret_expr->AsCall()) {
2770 if (IsCallToFround(call)) { 2765 if (IsCallToFround(call)) {
2771 return AsmType::Float(); 2766 return AsmType::Float();
2772 } 2767 }
2773 FAIL(statement, "Invalid function call in return statement."); 2768 FAIL(ret_expr, "Invalid function call in return statement.");
2774 } 2769 }
2775 2770
2776 if (auto* literal = ret_expr->AsLiteral()) { 2771 if (auto* literal = ret_expr->AsLiteral()) {
2777 int32_t _; 2772 int32_t _;
2778 if (IsLiteralDouble(literal)) { 2773 if (IsLiteralDouble(literal)) {
2779 return AsmType::Double(); 2774 return AsmType::Double();
2780 } else if (IsLiteralInt(literal) && literal->value()->ToInt32(&_)) { 2775 } else if (IsLiteralInt(literal) && literal->value()->ToInt32(&_)) {
2781 return AsmType::Signed(); 2776 return AsmType::Signed();
2782 } else if (literal->IsUndefinedLiteral()) { 2777 } else if (literal->IsUndefinedLiteral()) {
2783 // *VIOLATION* The parser changes 2778 // *VIOLATION* The parser changes
2784 // 2779 //
2785 // return; 2780 // return;
2786 // 2781 //
2787 // into 2782 // into
2788 // 2783 //
2789 // return undefined 2784 // return undefined
2790 return AsmType::Void(); 2785 return AsmType::Void();
2791 } 2786 }
2792 FAIL(statement, "Invalid literal in return statement."); 2787 FAIL(ret_expr, "Invalid literal in return statement.");
2793 } 2788 }
2794 2789
2795 if (auto* proxy = ret_expr->AsVariableProxy()) { 2790 if (auto* proxy = ret_expr->AsVariableProxy()) {
2796 auto* var_info = Lookup(proxy->var()); 2791 auto* var_info = Lookup(proxy->var());
2797 2792
2798 if (var_info == nullptr) { 2793 if (var_info == nullptr) {
2799 FAIL(statement, "Undeclared identifier in return statement."); 2794 FAIL(ret_expr, "Undeclared identifier in return statement.");
2800 } 2795 }
2801 2796
2802 if (var_info->mutability() != VariableInfo::kConstGlobal) { 2797 if (var_info->mutability() != VariableInfo::kConstGlobal) {
2803 FAIL(statement, "Identifier in return statement is not const."); 2798 FAIL(ret_expr, "Identifier in return statement is not const.");
2804 } 2799 }
2805 2800
2806 if (!var_info->type()->IsReturnType()) { 2801 if (!var_info->type()->IsReturnType()) {
2807 FAIL(statement, "Constant in return must be signed, float, or double."); 2802 FAIL(ret_expr, "Constant in return must be signed, float, or double.");
2808 } 2803 }
2809 2804
2810 return var_info->type(); 2805 return var_info->type();
2811 } 2806 }
2812 2807
2813 FAIL(statement, "Invalid return type expression."); 2808 // NOTE: This is not strictly valid asm.js, but is emitted by some versions of
2809 // Emscripten.
2810 if (auto* cond = ret_expr->AsConditional()) {
2811 AsmType* a = AsmType::None();
2812 AsmType* b = AsmType::None();
2813 RECURSE(a = ReturnTypeAnnotations(cond->then_expression()));
2814 if (a->IsA(AsmType::None())) {
2815 return a;
2816 }
2817 RECURSE(b = ReturnTypeAnnotations(cond->else_expression()));
2818 if (b->IsA(AsmType::None())) {
2819 return b;
2820 }
2821 if (a->IsExactly(b)) {
2822 return a;
2823 }
2824 }
2825
2826 FAIL(ret_expr, "Invalid return type expression.");
2814 } 2827 }
2815 2828
2816 // 5.4 VariableTypeAnnotations 2829 // 5.4 VariableTypeAnnotations
2817 // Also used for 5.5 GlobalVariableTypeAnnotations 2830 // Also used for 5.5 GlobalVariableTypeAnnotations
2818 AsmType* AsmTyper::VariableTypeAnnotations( 2831 AsmType* AsmTyper::VariableTypeAnnotations(
2819 Expression* initializer, VariableInfo::Mutability mutability_type) { 2832 Expression* initializer, VariableInfo::Mutability mutability_type) {
2820 if (auto* literal = initializer->AsLiteral()) { 2833 if (auto* literal = initializer->AsLiteral()) {
2821 if (IsLiteralDouble(literal)) { 2834 if (IsLiteralDouble(literal)) {
2822 SetTypeOf(initializer, AsmType::Double()); 2835 SetTypeOf(initializer, AsmType::Double());
2823 return AsmType::Double(); 2836 return AsmType::Double();
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2940 "Heap view creation parameter should be the module's heap parameter."); 2953 "Heap view creation parameter should be the module's heap parameter.");
2941 } 2954 }
2942 2955
2943 DCHECK(heap_view_info->type()->IsA(AsmType::Heap())); 2956 DCHECK(heap_view_info->type()->IsA(AsmType::Heap()));
2944 return heap_view_info->type(); 2957 return heap_view_info->type();
2945 } 2958 }
2946 2959
2947 } // namespace wasm 2960 } // namespace wasm
2948 } // namespace internal 2961 } // namespace internal
2949 } // namespace v8 2962 } // namespace v8
OLDNEW
« 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