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

Side by Side Diff: src/asmjs/asm-typer.cc

Issue 2555323003: [wasm][asm.js] Confirm literals are Numbers before using AsNumber, refactor. (Closed)
Patch Set: fix Created 4 years 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 | « no previous file | test/mjsunit/asm/asm-validation.js » ('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 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 DCHECK_NE(type, AsmType::None()); 444 DCHECK_NE(type, AsmType::None());
445 if (in_function_) { 445 if (in_function_) {
446 DCHECK(function_node_types_.find(node) == function_node_types_.end()); 446 DCHECK(function_node_types_.find(node) == function_node_types_.end());
447 function_node_types_.insert(std::make_pair(node, type)); 447 function_node_types_.insert(std::make_pair(node, type));
448 } else { 448 } else {
449 DCHECK(module_node_types_.find(node) == module_node_types_.end()); 449 DCHECK(module_node_types_.find(node) == module_node_types_.end());
450 module_node_types_.insert(std::make_pair(node, type)); 450 module_node_types_.insert(std::make_pair(node, type));
451 } 451 }
452 } 452 }
453 453
454 namespace {
455 bool IsLiteralDouble(Literal* literal) {
456 return literal->raw_value()->IsNumber() &&
457 literal->raw_value()->ContainsDot();
458 }
459
460 bool IsLiteralInt(Literal* literal) {
461 return literal->raw_value()->IsNumber() &&
462 !literal->raw_value()->ContainsDot();
463 }
464
465 bool IsLiteralMinus1(Literal* literal) {
466 return IsLiteralInt(literal) && literal->raw_value()->AsNumber() == -1.0;
467 }
468
469 bool IsLiteral1Dot0(Literal* literal) {
470 return IsLiteralDouble(literal) && literal->raw_value()->AsNumber() == 1.0;
471 }
472
473 bool IsLiteral0(Literal* literal) {
474 return IsLiteralInt(literal) && literal->raw_value()->AsNumber() == 0.0;
475 }
476 } // namespace
477
454 AsmType* AsmTyper::TypeOf(AstNode* node) const { 478 AsmType* AsmTyper::TypeOf(AstNode* node) const {
455 auto node_type_iter = function_node_types_.find(node); 479 auto node_type_iter = function_node_types_.find(node);
456 if (node_type_iter != function_node_types_.end()) { 480 if (node_type_iter != function_node_types_.end()) {
457 return node_type_iter->second; 481 return node_type_iter->second;
458 } 482 }
459 node_type_iter = module_node_types_.find(node); 483 node_type_iter = module_node_types_.find(node);
460 if (node_type_iter != module_node_types_.end()) { 484 if (node_type_iter != module_node_types_.end()) {
461 return node_type_iter->second; 485 return node_type_iter->second;
462 } 486 }
463 487
464 // Sometimes literal nodes are not added to the node_type_ map simply because 488 // Sometimes literal nodes are not added to the node_type_ map simply because
465 // their are not visited with ValidateExpression(). 489 // their are not visited with ValidateExpression().
466 if (auto* literal = node->AsLiteral()) { 490 if (auto* literal = node->AsLiteral()) {
467 if (literal->raw_value()->ContainsDot()) { 491 if (IsLiteralDouble(literal)) {
468 return AsmType::Double(); 492 return AsmType::Double();
469 } 493 }
494 if (!IsLiteralInt(literal)) {
495 return AsmType::None();
496 }
470 uint32_t u; 497 uint32_t u;
471 if (literal->value()->ToUint32(&u)) { 498 if (literal->value()->ToUint32(&u)) {
472 if (u > LargestFixNum) { 499 if (u > LargestFixNum) {
473 return AsmType::Unsigned(); 500 return AsmType::Unsigned();
474 } 501 }
475 return AsmType::FixNum(); 502 return AsmType::FixNum();
476 } 503 }
477 int32_t i; 504 int32_t i;
478 if (literal->value()->ToInt32(&i)) { 505 if (literal->value()->ToInt32(&i)) {
479 return AsmType::Signed(); 506 return AsmType::Signed();
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 // *VIOLATION* The parser replaces uses of +x with x*1.0. 754 // *VIOLATION* The parser replaces uses of +x with x*1.0.
728 if (binop->op() != Token::MUL) { 755 if (binop->op() != Token::MUL) {
729 return false; 756 return false;
730 } 757 }
731 758
732 auto* right_as_literal = binop->right()->AsLiteral(); 759 auto* right_as_literal = binop->right()->AsLiteral();
733 if (right_as_literal == nullptr) { 760 if (right_as_literal == nullptr) {
734 return false; 761 return false;
735 } 762 }
736 763
737 return right_as_literal->raw_value()->ContainsDot() && 764 return IsLiteral1Dot0(right_as_literal);
738 right_as_literal->raw_value()->AsNumber() == 1.0;
739 } 765 }
740 766
741 bool IsIntAnnotation(BinaryOperation* binop) { 767 bool IsIntAnnotation(BinaryOperation* binop) {
742 if (binop->op() != Token::BIT_OR) { 768 if (binop->op() != Token::BIT_OR) {
743 return false; 769 return false;
744 } 770 }
745 771
746 auto* right_as_literal = binop->right()->AsLiteral(); 772 auto* right_as_literal = binop->right()->AsLiteral();
747 if (right_as_literal == nullptr) { 773 if (right_as_literal == nullptr) {
748 return false; 774 return false;
749 } 775 }
750 776
751 return !right_as_literal->raw_value()->ContainsDot() && 777 return IsLiteral0(right_as_literal);
752 right_as_literal->raw_value()->AsNumber() == 0.0;
753 } 778 }
754 } // namespace 779 } // namespace
755 780
756 AsmType* AsmTyper::ValidateGlobalDeclaration(Assignment* assign) { 781 AsmType* AsmTyper::ValidateGlobalDeclaration(Assignment* assign) {
757 DCHECK(!assign->is_compound()); 782 DCHECK(!assign->is_compound());
758 if (assign->is_compound()) { 783 if (assign->is_compound()) {
759 FAIL(assign, 784 FAIL(assign,
760 "Compound assignment not supported when declaring global variables."); 785 "Compound assignment not supported when declaring global variables.");
761 } 786 }
762 787
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 1484
1460 // 6.6 ValidateCase 1485 // 6.6 ValidateCase
1461 namespace { 1486 namespace {
1462 bool ExtractInt32CaseLabel(CaseClause* clause, int32_t* lbl) { 1487 bool ExtractInt32CaseLabel(CaseClause* clause, int32_t* lbl) {
1463 auto* lbl_expr = clause->label()->AsLiteral(); 1488 auto* lbl_expr = clause->label()->AsLiteral();
1464 1489
1465 if (lbl_expr == nullptr) { 1490 if (lbl_expr == nullptr) {
1466 return false; 1491 return false;
1467 } 1492 }
1468 1493
1469 if (lbl_expr->raw_value()->ContainsDot()) { 1494 if (!IsLiteralInt(lbl_expr)) {
1470 return false; 1495 return false;
1471 } 1496 }
1472 1497
1473 return lbl_expr->value()->ToInt32(lbl); 1498 return lbl_expr->value()->ToInt32(lbl);
1474 } 1499 }
1475 } // namespace 1500 } // namespace
1476 1501
1477 AsmType* AsmTyper::ValidateCase(CaseClause* label, int32_t* case_lbl) { 1502 AsmType* AsmTyper::ValidateCase(CaseClause* label, int32_t* case_lbl) {
1478 if (!ExtractInt32CaseLabel(label, case_lbl)) { 1503 if (!ExtractInt32CaseLabel(label, case_lbl)) {
1479 FAIL(label, "Case label must be a 32-bit signed integer."); 1504 FAIL(label, "Case label must be a 32-bit signed integer.");
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 bool IsInvert(BinaryOperation* binop) { 1581 bool IsInvert(BinaryOperation* binop) {
1557 if (binop->op() != Token::BIT_XOR) { 1582 if (binop->op() != Token::BIT_XOR) {
1558 return false; 1583 return false;
1559 } 1584 }
1560 1585
1561 auto* right_as_literal = binop->right()->AsLiteral(); 1586 auto* right_as_literal = binop->right()->AsLiteral();
1562 if (right_as_literal == nullptr) { 1587 if (right_as_literal == nullptr) {
1563 return false; 1588 return false;
1564 } 1589 }
1565 1590
1566 return !right_as_literal->raw_value()->ContainsDot() && 1591 return IsLiteralMinus1(right_as_literal);
1567 right_as_literal->raw_value()->AsNumber() == -1.0;
1568 } 1592 }
1569 1593
1570 bool IsUnaryMinus(BinaryOperation* binop) { 1594 bool IsUnaryMinus(BinaryOperation* binop) {
1571 // *VIOLATION* The parser replaces uses of -x with x*-1. 1595 // *VIOLATION* The parser replaces uses of -x with x*-1.
1572 if (binop->op() != Token::MUL) { 1596 if (binop->op() != Token::MUL) {
1573 return false; 1597 return false;
1574 } 1598 }
1575 1599
1576 auto* right_as_literal = binop->right()->AsLiteral(); 1600 auto* right_as_literal = binop->right()->AsLiteral();
1577 if (right_as_literal == nullptr) { 1601 if (right_as_literal == nullptr) {
1578 return false; 1602 return false;
1579 } 1603 }
1580 1604
1581 return !right_as_literal->raw_value()->ContainsDot() && 1605 return IsLiteralMinus1(right_as_literal);
1582 right_as_literal->raw_value()->AsNumber() == -1.0;
1583 } 1606 }
1584 } // namespace 1607 } // namespace
1585 1608
1586 AsmType* AsmTyper::ValidateBinaryOperation(BinaryOperation* expr) { 1609 AsmType* AsmTyper::ValidateBinaryOperation(BinaryOperation* expr) {
1587 #define UNOP_OVERLOAD(Src, Dest) \ 1610 #define UNOP_OVERLOAD(Src, Dest) \
1588 do { \ 1611 do { \
1589 if (left_type->IsA(AsmType::Src())) { \ 1612 if (left_type->IsA(AsmType::Src())) { \
1590 return AsmType::Dest(); \ 1613 return AsmType::Dest(); \
1591 } \ 1614 } \
1592 } while (0) 1615 } while (0)
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 } 1724 }
1702 1725
1703 // 6.8.2 NumericLiteral 1726 // 6.8.2 NumericLiteral
1704 AsmType* AsmTyper::ValidateNumericLiteral(Literal* literal) { 1727 AsmType* AsmTyper::ValidateNumericLiteral(Literal* literal) {
1705 // *VIOLATION* asm.js does not allow the use of undefined, but our parser 1728 // *VIOLATION* asm.js does not allow the use of undefined, but our parser
1706 // inserts them, so we have to handle them. 1729 // inserts them, so we have to handle them.
1707 if (literal->IsUndefinedLiteral()) { 1730 if (literal->IsUndefinedLiteral()) {
1708 return AsmType::Void(); 1731 return AsmType::Void();
1709 } 1732 }
1710 1733
1711 if (literal->raw_value()->ContainsDot()) { 1734 if (IsLiteralDouble(literal)) {
1712 return AsmType::Double(); 1735 return AsmType::Double();
1713 } 1736 }
1714 1737
1715 // The parser collapses expressions like !0 and !123 to true/false. 1738 // The parser collapses expressions like !0 and !123 to true/false.
1716 // We therefore need to permit these as alternate versions of 0 / 1. 1739 // We therefore need to permit these as alternate versions of 0 / 1.
1717 if (literal->raw_value()->IsTrue() || literal->raw_value()->IsFalse()) { 1740 if (literal->raw_value()->IsTrue() || literal->raw_value()->IsFalse()) {
1718 return AsmType::Int(); 1741 return AsmType::Int();
1719 } 1742 }
1720 1743
1721 uint32_t value; 1744 uint32_t value;
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 } 1904 }
1882 1905
1883 // 6.8.8 MultiplicativeExpression 1906 // 6.8.8 MultiplicativeExpression
1884 namespace { 1907 namespace {
1885 bool IsIntishLiteralFactor(Expression* expr, int32_t* factor) { 1908 bool IsIntishLiteralFactor(Expression* expr, int32_t* factor) {
1886 auto* literal = expr->AsLiteral(); 1909 auto* literal = expr->AsLiteral();
1887 if (literal == nullptr) { 1910 if (literal == nullptr) {
1888 return false; 1911 return false;
1889 } 1912 }
1890 1913
1891 if (literal->raw_value()->ContainsDot()) { 1914 if (!IsLiteralInt(literal)) {
1892 return false; 1915 return false;
1893 } 1916 }
1894 1917
1895 if (!literal->value()->ToInt32(factor)) { 1918 if (!literal->value()->ToInt32(factor)) {
1896 return false; 1919 return false;
1897 } 1920 }
1898 static const int32_t kIntishBound = 1 << 20; 1921 static const int32_t kIntishBound = 1 << 20;
1899 return -kIntishBound < *factor && *factor < kIntishBound; 1922 return -kIntishBound < *factor && *factor < kIntishBound;
1900 } 1923 }
1901 } // namespace 1924 } // namespace
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
2290 } 2313 }
2291 2314
2292 // 6.9 ValidateCall 2315 // 6.9 ValidateCall
2293 namespace { 2316 namespace {
2294 bool ExtractIndirectCallMask(Expression* expr, uint32_t* value) { 2317 bool ExtractIndirectCallMask(Expression* expr, uint32_t* value) {
2295 auto* as_literal = expr->AsLiteral(); 2318 auto* as_literal = expr->AsLiteral();
2296 if (as_literal == nullptr) { 2319 if (as_literal == nullptr) {
2297 return false; 2320 return false;
2298 } 2321 }
2299 2322
2300 if (as_literal->raw_value()->ContainsDot()) { 2323 if (!IsLiteralInt(as_literal)) {
2301 return false; 2324 return false;
2302 } 2325 }
2303 2326
2304 if (!as_literal->value()->ToUint32(value)) { 2327 if (!as_literal->value()->ToUint32(value)) {
2305 return false; 2328 return false;
2306 } 2329 }
2307 2330
2308 return base::bits::IsPowerOfTwo32(1 + *value); 2331 return base::bits::IsPowerOfTwo32(1 + *value);
2309 } 2332 }
2310 } // namespace 2333 } // namespace
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2474 } 2497 }
2475 2498
2476 // 6.10 ValidateHeapAccess 2499 // 6.10 ValidateHeapAccess
2477 namespace { 2500 namespace {
2478 bool ExtractHeapAccessShift(Expression* expr, uint32_t* value) { 2501 bool ExtractHeapAccessShift(Expression* expr, uint32_t* value) {
2479 auto* as_literal = expr->AsLiteral(); 2502 auto* as_literal = expr->AsLiteral();
2480 if (as_literal == nullptr) { 2503 if (as_literal == nullptr) {
2481 return false; 2504 return false;
2482 } 2505 }
2483 2506
2484 if (as_literal->raw_value()->ContainsDot()) { 2507 if (!IsLiteralInt(as_literal)) {
2485 return false; 2508 return false;
2486 } 2509 }
2487 2510
2488 return as_literal->value()->ToUint32(value); 2511 return as_literal->value()->ToUint32(value);
2489 } 2512 }
2490 2513
2491 // Returns whether index is too large to access a heap with the given type. 2514 // Returns whether index is too large to access a heap with the given type.
2492 bool LiteralIndexOutOfBounds(AsmType* obj_type, uint32_t index) { 2515 bool LiteralIndexOutOfBounds(AsmType* obj_type, uint32_t index) {
2493 switch (obj_type->ElementSizeInBytes()) { 2516 switch (obj_type->ElementSizeInBytes()) {
2494 case 1: 2517 case 1:
(...skipping 23 matching lines...) Expand all
2518 FAIL(heap, "Undeclared identifier in heap access."); 2541 FAIL(heap, "Undeclared identifier in heap access.");
2519 } 2542 }
2520 2543
2521 auto* obj_type = obj_info->type(); 2544 auto* obj_type = obj_info->type();
2522 if (!obj_type->IsA(AsmType::Heap())) { 2545 if (!obj_type->IsA(AsmType::Heap())) {
2523 FAIL(heap, "Identifier does not represent a heap view."); 2546 FAIL(heap, "Identifier does not represent a heap view.");
2524 } 2547 }
2525 SetTypeOf(obj, obj_type); 2548 SetTypeOf(obj, obj_type);
2526 2549
2527 if (auto* key_as_literal = heap->key()->AsLiteral()) { 2550 if (auto* key_as_literal = heap->key()->AsLiteral()) {
2528 if (key_as_literal->raw_value()->ContainsDot()) { 2551 if (!IsLiteralInt(key_as_literal)) {
2529 FAIL(key_as_literal, "Heap access index must be int."); 2552 FAIL(key_as_literal, "Heap access index must be int.");
2530 } 2553 }
2531 2554
2532 uint32_t index; 2555 uint32_t index;
2533 if (!key_as_literal->value()->ToUint32(&index)) { 2556 if (!key_as_literal->value()->ToUint32(&index)) {
2534 FAIL(key_as_literal, 2557 FAIL(key_as_literal,
2535 "Heap access index must be a 32-bit unsigned integer."); 2558 "Heap access index must be a 32-bit unsigned integer.");
2536 } 2559 }
2537 2560
2538 if (LiteralIndexOutOfBounds(obj_type, index)) { 2561 if (LiteralIndexOutOfBounds(obj_type, index)) {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2702 2725
2703 if (auto* call = ret_expr->AsCall()) { 2726 if (auto* call = ret_expr->AsCall()) {
2704 if (IsCallToFround(call)) { 2727 if (IsCallToFround(call)) {
2705 return AsmType::Float(); 2728 return AsmType::Float();
2706 } 2729 }
2707 FAIL(statement, "Invalid function call in return statement."); 2730 FAIL(statement, "Invalid function call in return statement.");
2708 } 2731 }
2709 2732
2710 if (auto* literal = ret_expr->AsLiteral()) { 2733 if (auto* literal = ret_expr->AsLiteral()) {
2711 int32_t _; 2734 int32_t _;
2712 if (literal->raw_value()->ContainsDot()) { 2735 if (IsLiteralDouble(literal)) {
2713 return AsmType::Double(); 2736 return AsmType::Double();
2714 } else if (literal->value()->ToInt32(&_)) { 2737 } else if (IsLiteralInt(literal) && literal->value()->ToInt32(&_)) {
2715 return AsmType::Signed(); 2738 return AsmType::Signed();
2716 } else if (literal->IsUndefinedLiteral()) { 2739 } else if (literal->IsUndefinedLiteral()) {
2717 // *VIOLATION* The parser changes 2740 // *VIOLATION* The parser changes
2718 // 2741 //
2719 // return; 2742 // return;
2720 // 2743 //
2721 // into 2744 // into
2722 // 2745 //
2723 // return undefined 2746 // return undefined
2724 return AsmType::Void(); 2747 return AsmType::Void();
(...skipping 20 matching lines...) Expand all
2745 } 2768 }
2746 2769
2747 FAIL(statement, "Invalid return type expression."); 2770 FAIL(statement, "Invalid return type expression.");
2748 } 2771 }
2749 2772
2750 // 5.4 VariableTypeAnnotations 2773 // 5.4 VariableTypeAnnotations
2751 // Also used for 5.5 GlobalVariableTypeAnnotations 2774 // Also used for 5.5 GlobalVariableTypeAnnotations
2752 AsmType* AsmTyper::VariableTypeAnnotations( 2775 AsmType* AsmTyper::VariableTypeAnnotations(
2753 Expression* initializer, VariableInfo::Mutability mutability_type) { 2776 Expression* initializer, VariableInfo::Mutability mutability_type) {
2754 if (auto* literal = initializer->AsLiteral()) { 2777 if (auto* literal = initializer->AsLiteral()) {
2755 if (literal->raw_value()->ContainsDot()) { 2778 if (IsLiteralDouble(literal)) {
2756 SetTypeOf(initializer, AsmType::Double()); 2779 SetTypeOf(initializer, AsmType::Double());
2757 return AsmType::Double(); 2780 return AsmType::Double();
2758 } 2781 }
2782 if (!IsLiteralInt(literal)) {
2783 FAIL(initializer, "Invalid type annotation - forbidden literal.");
2784 }
2759 int32_t i32; 2785 int32_t i32;
2760 uint32_t u32; 2786 uint32_t u32;
2761
2762 AsmType* initializer_type = nullptr; 2787 AsmType* initializer_type = nullptr;
2763 if (literal->value()->ToUint32(&u32)) { 2788 if (literal->value()->ToUint32(&u32)) {
2764 if (u32 > LargestFixNum) { 2789 if (u32 > LargestFixNum) {
2765 initializer_type = AsmType::Unsigned(); 2790 initializer_type = AsmType::Unsigned();
2766 SetTypeOf(initializer, initializer_type); 2791 SetTypeOf(initializer, initializer_type);
2767 } else { 2792 } else {
2768 initializer_type = AsmType::FixNum(); 2793 initializer_type = AsmType::FixNum();
2769 SetTypeOf(initializer, initializer_type); 2794 SetTypeOf(initializer, initializer_type);
2770 initializer_type = AsmType::Signed(); 2795 initializer_type = AsmType::Signed();
2771 } 2796 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2879 return true; 2904 return true;
2880 } 2905 }
2881 2906
2882 *error_message = typer.error_message(); 2907 *error_message = typer.error_message();
2883 return false; 2908 return false;
2884 } 2909 }
2885 2910
2886 } // namespace wasm 2911 } // namespace wasm
2887 } // namespace internal 2912 } // namespace internal
2888 } // namespace v8 2913 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/asm/asm-validation.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698